Missing body in JMS / websocket message - java

I'm trying to understand why serialized objects are being stripped out when received.
Here is the general layout :
1. Produce JMS messages and send to a topic on an external ActiveMQ broker. The code is based off the Spring boot JMS message and can be viewed at http://bit.ly/QECQ21 . In my example, I generate various types of messages (text , POJO, Map)
2. I have 2 JMS consumers that subscribe to this topic.
a. One is a java client. This client correctly identifies all the various message types.
b. The 2nd client is a javascript client based on websockets + stomp.js . This correctly identifies text messages but not messages that contain POJOs generated by my producer.
Here is the sample output from the web client (source at http://bit.ly/Od0noF ) .
What am I doing wrong? Something wrong with the the addressing or something else in the code? Something about the way I'm using (or misusing) STOMP? I had to use "tcp://localhost:61616" in the Application.java class to correctly contact the broker.
Thanks
MESSAGE priority:4 persistent:true subscription:sub-0 expires:0 timestamp:1396418227090 destination:/topic/greetings message-id:ID:blackbox-53461-1396418226684-1:1:2:1:1 content-length:4 ping
Body:ping
MESSAGE priority:4 persistent:true subscription:sub-0 expires:0 timestamp:1396418227117 destination:/topic/greetings message-id:ID:blackbox-53461-1396418226684-1:1:2:1:2
Body: ======> missing body
MESSAGE priority:4 persistent:true subscription:sub-0 expires:0 timestamp:1396418227122 destination:/topic/greetings message-id:ID:blackbox-53461-1396418226684-1:1:2:1:3
Body: ======> missing body
MESSAGE priority:4 persistent:true subscription:sub-0 expires:0 timestamp:1396418227125 destination:/topic/greetings message-id:ID:blackbox-53461-1396418226684-1:1:2:1:4 content-length:5 close
Body:close

No answers yet so I'll add my findings. STOMP is a text based protocol and as such the body needs to be converted to a text format (such as JSON). In my case, this can be done using the spring websockets framework (which internally uses Jackson) or by explicitly coding the object into JSON using Jackson and them transmitting as a text message

Related

How to differentiate between the automatic reply and the normal mail received

I am working on receiving mails in my springboot application. In order to fetch and store the receive mails. I am using imap mail listener. There are two types of mails which I am storing. One is multipart payload type and the other is string payload type.
After receiving mail I am trying to send an auto-generated mails using java mail.
The issue which I am facing is worst case scenario of generating auto-reply from my application i.e infinite loop.
Can someone help ow can I differentiate between a normal mail received and auto-reply received in my mail box and generate auto-replies from my system only for those mails which are not auto-reply type.
It would be nice if explained via code for headers check. I came across through few headers like x-Autosubmitted. But they are returning null if I am trying to print the values in console.
The auto-submmitted markers are described below that you may find helpful:
auto-generated - Indicates that a message was generated by an automatic process, and is not a direct response to another message.
auto-replied - Indicates that a message was automatically generated as a direct response to another message.
auto-notified - Indicates that a message was generated by a Sieve notification system.
no - Indicates that a message was NOT automatically generated, but was created by a human. It is the equivalent to the absence of an Auto-Submitted header altogether.
The RFC 2822 states the following:
Though optional, every message SHOULD have a "Message-ID:" field.
Furthermore, reply messages SHOULD have "In-Reply-To:"
So, you may check for the "In-Reply-To:" value in the header.
Also you may add your own value to the outgoing email, so you may distinguish between an automatically generated reply from your system and manually created.

JMS with content-base filter

Is it possible to do content-based filter with JMS?
IBM MQ publish/subscribe seem to allow content-base filtering
https://www.ibm.com/support/knowledgecenter/en/SSKM8N_8.0.0/com.ibm.etools.mft.doc/bq13460_.htm
https://www.ibm.com/support/knowledgecenter/en/SSKM8N_8.0.0/com.ibm.etools.mft.doc/bq13360_.htm
I've tried to find a way with my JMSListener to filter on a Body elment but I couldn't manage to make it work..
IBM MQ can not directly filter based on the body, only based on message properties. IBM states that a extended message selection provider can do message selection based on the message payload, but as far as I know the only extended message selection provider available is ACE/IIB/WMB.
Please review IBM Knowledge Center page IBM MQ 9.1.x>IBM MQ>Developing applications>Developing JMS and Java applications>Using IBM MQ classes for JMS>Writing IBM MQ classes for JMS applications>JMS messages>Message selectors in JMS:
A property value might duplicate a value in a message body. JMS does not define a policy for what might be made into a property. However, application developers must be aware that JMS providers probably handle data in a message body more efficiently than data in message properties. For best performance, applications must use message properties only when they need to customize a message header. The primary reason for doing this is to support customized message selection.
A JMS message selector allows a client to specify the messages that it is interested in by using the message header. Only messages with headers that match the selector are delivered.
Message selectors cannot refer to message body values.
A message selector matches a message when the selector evaluates to true when the message header field and property values are substituted for their corresponding identifiers in the selector.
A message selector is a String, with syntax that is based on a subset of the SQL92 conditional expression syntax. The order in which a message selector is evaluated is from left to right within a precedence level. You can use parentheses to change this order. Predefined selector literals and operator names are written here in uppercase; however, they are not case-sensitive.
Please also review IBM Knowledge Center page IBM MQ 9.0.x>IBM MQ>Developing applications>Application development concepts>IBM MQ messages>Selecting messages from queues>Selecting on the content of a message
It is possible to subscribe based on a selection of message payload content (also known as content filtering), but the decision about which messages should be delivered to such a subscription cannot be performed directly by IBM® MQ; instead an extended message selection provider, for example IBM Integration Bus, is required to process the messages.

How to send plain text JmsMessage with empty header

I want to send a message to an activeMQ and receive it via MQTT.js in the frontend.
jmsTemplate.convertAndSend("topic", "Hello World!");
I am getting the message, but with a header, that I can not decode.
S�A S�)�x-opt-jms-destQ�x-opt-jms-msg-typeQ Ss� f
�/ID:myID#�topic://myTopic####� j��< St�e Sw� Hello World!
Now I am trying to remove the header from my message.
This thread mentions the targetClient property, but this doesn't seam to work with a topic: Spring JMS Template - remove RFH Header information
I also found the MessageBuilder, where I should be able to set an empty header, but this MessageBuilder doesn't work with the jmsTemplate. jmsTemplate only supports the MessageCreator, which doesn't support an empty header.
How can I send a JMS Message in plain text without any header?
Thanks for any suggestions.
Updating the Queue Broker to work with JMS2 fixed this issue.

Web Socket - Spring : Confirm of message received

I am sending a message through WebSocket with Spring from Tomcat Server to a SockJSClient with the method:
WebSocketSession.sendMessage(WebSocketMessage<?> message)
and I would like to know when the message has been received (eventually with complementary information, for example whether the logic on client successfully processed), then go for next message.
This is an Activity diagram that explains the use case.
How can I receive confirmation of reception or result from client?
As Erwin pointed, you can adopt some higher protocol providing such feature like STOMP. However, if you are afraid to adopt it only for that feature, you can implement that feature by yourself.
The first thing is to give each message id to identify each message, type to recognize the purpose of each message, data to transport a message's content and reply which is a flag to see whether or not ACK is required and to use a format like JSON to serialize/deserialize an object containing these data into/from WebSocket message.
When sending a message, it creates an object by issuing a new id for that message, setting type to message and data to given message and reply to true if ACK is required or false if not. And it serializes it into JSON and sends it as a WebSocket message. - https://github.com/cettia/cettia-protocol/blob/1.0.0-Alpha1/lib/server.js#L88-L110
When receiving a message, it deserializes JSON to the above object. If reply is true, it sends a special message whose type is reply setting data to id of that message. Then, the counterpart can confirm that its counterpart has received a message whose id is id. - https://github.com/cettia/cettia-protocol/blob/1.0.0-Alpha1/lib/server.js#L46-L76
The above links point similar implementation in Cettia which is a real-time web application framework I wrote. Though that implementation is a little bit complex as it is designed to allow for user to handle callbacks with result, you are likely to get the basic idea.
API implemented by that link looks like the following.
A server or client which requires a result of event processing.
// Using Java server with lambda
socket.send("foo", "bar", result -> /* resolved */, reason -> /* rejected */);
The corresponding client or server which has a responsibility to submit the result.
// Using JavaScript client with arrow functions
socket.on("foo", (data, reply) => {
// data is 'bar'
// 'reply.resolve(result)' if it successes
// 'reply.reject(reason)' if it fails
});

BIP4435The Aggregation Reply node has received a reply message which has a blank reply ID:

I am getting the following error when I try to do a Fan-In using aggregate node in IBM integration bus.
( T24_Integ_Node.default ) The Aggregation Reply node has received a reply message which has a blank reply ID: ''.
This is not allowed because the reply ID is needed so that a reply message can be matched to the original request message. If you are using WebSphere MQ to send and receive aggregation requests, the reply ID must be stored in the correlation identifier (CorrelId) field of the message descriptor (MQMD) and it must be set to the value of the message ID in the request message's MQMD
The message flow is like below:
FILE<1> -->AggregateControl<1>-->FAN-OUT-COMPUTE-NODES<1,2,3> -->FILE-OUTPUT-NODES<1,2,3> --> AGGREGATE-REQUEST-NODES<1,2,3> --> AGGREGATE-REPLY-NODE<1> --> FAN-IN-COMPUTE-NODE<1> --> FILE-OUTPUT-NODE<1>
Please note I am not using MQ nodes
Kindly suggest.
What you are attempting will not work because you are not using a request/reply protocol on the inside of the aggregation. As stated in the Knowledge Center article at this link, "The aggregation nodes work correctly only for transports that use a request/reply model", and writing to and reading from files does not fulfill that requirement. Some nodes that do fulfill this requirement are the MQ nodes, the SOAP Asynchronous nodes, and the HTTP Asynchronous nodes. Additionally, you need to use an AggregateControl node to mark the start of the fan-out, and I do not see an AggregateControl node in your flow sketch.
I suspect that you want to submit files to an external application(s), have that application(s)'s instances run independently and in parallel, receive response files, then group the response files based upon a flag(s) in the files' names or in the files' content. If so, use the Collector node.
An alternative would be to use the aggregation nodes with MQ nodes inside of the aggregation, with these MQ nodes feeding an intermediate flow that changed the fan-out protocol from MQ to file, then conversely, the fan-in protocol from file to MQ. See IIB's web services aggregation sample for an example of this technique.

Categories

Resources