To identify the xsd of xml message which is received from MQ - ibm-mq

In IBM MQ, I have a requirement where I can get many types of xml from the queue. The xml messages will be conformed to already specified xsd (there are say, 5 xsd - which means I can get 5 different xml). When I get the message from queue, I would like to know the type of xml (if its xsd1 or xsd2 or so on)
The reason why I would want to know is, I am using a JaxB interface with SAX implementation, for which I need to give the java object corresponding to the xml as parameter. So I have to know which xsd the input and is and assign the parameter correspondingly.
The options I have is to set a property in the header to the message, but the party who is dropping the message into MQ is not ready.
What other options do I have? Can I get the file name (of xml) from the mq and find the xsd based on the name of the file? Or do I have to do I sax parsing and identify the root tag and derive the xsd type? Any other better option anybody has in mind?

Think of MQ like the Post Office. When you get a letter, the post office doesn't mess with anything on the inside (the payload) and if it changes the outside, it only changes routing information. If you want to sort incoming mail to different recipients, whoever is sending it has to put the data against which the sort criteria operate on the outside of the envelope. If that doesn't work, you must open the envelope and look for the recipient name, department, or whatever on the papers inside.
Your MQ message is that envelope. The sort criteria can be different queue names, a property of the message, a property of the message header, or something in the payload. But unless the sender explicitly sets the destination queue name based on the selection criteria, or sets the message or header property, your only option is to inspect the payload and figure it out.
If you have to inspect the payload, this is a perfect scenario for IBM Integration Broker. But you can also write an application to perform this function. Very often this is performed by a Dispatch app which gets the message, figures out where it goes, then puts it onto another queue and COMMITs the GET and PUT operations. But if the dispatch app must parse the XML to determine the correct queue, the message has to be parsed twice - once by the dispatcher, once by the receiving app.

I think you can do:
Does the incoming message has the file name at the beginning of the message body? In that case, after receiving the message your application can read first few bytes to get the file name. Based on the file name, application can use appropriate Xsd and pass the entire message body.

Related

Spring-integration: keep a context for a Message throught a chain

I am using spring-integration, and I have messages that goes through an int:chain with multiple elements: int:service-activator, int:transformers, etc. In the end, a message is sent to another app's Rest endpoint. There is also an errorHandler that will save any Exception in a text file.
For administration purpose, I would like to keep some information about what happened in the chain (ex: "this DB call returned this", "during this transformation, this rule was applied", etc.). This would be equivalent to a log file, but bound to a Message. Of course there is already a logger, but in the end, I need to create (either after the Rest called is made, or when an error occurs) a file for this specific Message with the data.
I was wondering if there was some kind of "context" for the Message that I could call through any part of the chain, and where I could store stuff. I didn't found anything in the official documentation, but I'm not really sure about what to look for.
I've been thinking about putting it all in the Message itself, but:
It's an immutable object, so I would need to rebuild it each time I want to add something to its header (or the payload).
I wouldn't be able to retrieve any new data from the error handler in case of Exception, because it takes the original message.
I can't really add it to the payload object because some native transformers/service-activators are directly using it (and that would also mean rewriting a lot of code ...)
I've been also thinking to some king of "thread-bound" bean that would act as a context for each Message, but I see too many problem arising from this.
Maybe I'm wrong about some of these ideas. Anyway, I just need a way to keep data though multiple element of a Spring integration chain and also be able to access it in the error handler.
Add a header, e.g. a map or list, and add to it in each stage.
The framework does something similar when message history is enabled.

How to do routing and avoid deserialization in Grpc / Protobuf?

In our Java app we need to accept a (large) Grpc message, extract a field, and then based on the value of that field forward the message on to another server.
I'm trying to avoid the overhead of completely deserializing the message before passing it on.
One way to do this would be to send the field as a separate query or header parameter, but Grpc doesn't support them.
Another way would be to extract just the field of interest from the payload, but Protobuf doesn't support partial or selective deserialization.
How else can I do this?
One way you can do this is by doing it on the server side. When the server is about to send a response, it can extract the field and set it as part of the initial headers sent. You can do this by using a ServerInterceptor to extract the field that you want from the response and add it to the Metadata.
Aside from that, Protocol buffers currently require that you parse the message before accessing the internal fields.

HornetQ message splitter

I'm new to JMS and HornetQ.
I'm wondering if there is a way to implement Message Translator Pattern using HornetQ to split data from a message in a set of smaller data and send them. I explored Bridge and Divert solutions but I can't get how to do it using org.hornetq.core.server.cluster.Transformer and org.hornetq.core.server.ServerMessage. Where can I find some docs about it? Am I looking in the right direction?
In short no(I've no Idea on camel). You cannot modify the jms body once sent until its consumed by a client(body is immutable). However you can change message headers and message properties. The org.hornetq.core.server.cluster.Transformer interface is used for modifying the headers/properties. Hence you are left with two options.
Consume the message, chunk the message based on your algorithem and send to other queues or put back to the queue(but be careful to avoid loop, by having suitable selector).
Other approach is chunk the message then send with message property to differentiate the message. And use the diverter with filter based on the message property(you can use exclusive/non exclusive strategy to send only/send copy of message to the other queue.)

HTTP POST - nameless data VS named data

Our server A notifies 3rd party server B with an XML-formatted message, sent as HTTP POST request. It's us who specify the message format and other aspects of interaction.
We can specify that the XML is sent as
a) raw data (just the XML)
b) single POST parameter having some specific name (say, xml=XML)
The question is which way is better for the 3rd party in general, if we don't know the platform and language they are using.
I thought I had seen some problems in certain languages to easily parse the nameless raw data, though I don't remember any specific case. While my colleague insists that the parameter name is redundant, and it's really better to send the raw data without any name.
If you don't need send extra information in other post parameters the xml parameter name is redundant and innecesary as your teammate said, if the 3rd party waits only for a XML data only send the raw data in the POST body with the correct mime type and encoding and and do not complicate.
The process for Getting raw data is easy in most application server containers, so you dont care about that, most of them uses a Reader to get received data and manipulate it.

ActiveMQ LIFO ordering?

Is there any option to change queue order without using out of box "Resequencer"? Maybe it can be done using JMS client to get last message in queue instead of first?
I think that you should give more info about what you're trying to achieve...
Anyway if you read the specs of some JMS implementation like MQ you'll see that the FIFO order is not guaranteed at 100%.
That means that if you relay on the order of the messages received, you can get easily in trouble.
It's good practice to add a progressive number to the message header and use it to handle the messages as you please. If you adopt this solution you have 2 options to achieve your goal:
1) modify the receiver business logic to check the the header of the message;
2) (probably the cleaner approach if you're using MQ) use something called MESSAGE SELECTOR.
Message Selectors allow content based retrieval of specific messages using SQL92-query functions. MQ spec states:
The JMS message provides a facility to provide user-defined metadata
to the JMS message header (outside the actual body of the message).
JMS programs can take advantage of this facility to select a subset
of messages based on a selection criteria or, in other words, a JMS
client can choose only those messages that it is interested in.
Here some more info about the implementation of the two solutions...
The property that you're probably interested in and that you should set before sending the message is JMSCorrelationID that will be set to 1 for the first message, 2 for the second one and so on.
1) Since you're more interested in the message selector, you can skip to the next bullet. Anyway just for reference, if you decide to adopt the solution 1 you can find some good reference in:
http://activemq.apache.org/maven/apidocs/org/apache/activemq/ActiveMQQueueBrowser.html
2) Message Selector.
Your message selector will be an sql string like: JMSCorrelationID = max(JMSCorrelationID)
If you wanna implement a message selector in java the syntax is:
MessageConsumer consumer = session.createConsumer(destination, messageSelectorString, true);
ActiveMQObjectMessage objMsg = (ActiveMQObjectMessage) consumer.receiveNoWait();

Resources