Asynchronous push of messages in channel (spring-integration) - spring

I have a simple JMS topic listener that i would like to hook with a spring-integration chain.
Basically, when a JMS message is received in the listener it has to be pushed into the chain's channel. Eventually the message is processed and pushed to an outbound-channel-adapter to be consumed.
The Spring Integration documentation mentions the use of asynchronous gateways but that uses Futures.
Isn't there a simple way to just put the message on a channel?
If there is an example that you can point to it would be great.
Thanks
Regards
Martin

If you want to run the flow on the listener thread, simply use a regular gateway (not an async one); this will allow the message to roll-back if the flow fails for any reason.
If you want to "fire and forget" you can make the request channel from the gateway an ExecutorChannel - see here.

Related

Create thread and route message from Camel to microservice and back

I'm using Camel with JMS and Spring Boot and would like to build a route for next scenario:
User 1 (MQTT client) sends a message (topic) to ActiveMQ Artemis.
Camel (by using from) catch that message and print it out with a help of log.
Thing I would like to do is - create a new thread (asynchronous) for caught message. Send that message from Camel to microservice (python program) that should take message and insert some extra strings, and then send changed message back to Camel and ActiveMQ.
On the end, from ActiveMQ changed message will be sent to User 2.
Can you give me some directions or route examples of how to do something like that?
So, key points are to create new thread for every message and create route to and back from that microservice.
The route could look like this
from("jms:queue:inputQueue")
.log("${body}")
.to("http://oldhost")
.to("jms:queue:outputQueue")
Some notes:
You can call a downstream HTTP endpoint with .to(). The current message body is used as request body. The response of the service overwrites the message body.
I don't know why you want to create a new thread for a synchronous call. You can leverage parallel processing by consuming multiple messages from Artemis in parallel with multiple consumers. Like this, every message is processed in its own thread. If your motivation is resilience, there is also a Circuit Breaker EIP in Camel
If you use Camel 2.x, use the HTTP4 Component ("http4://") to use the newer HTTP client lib. In Camel 3.x the old one was dropped and the new one is simply called HTTP component

Can we restrict spring boot rabbitmq message processing only between specific timings?

Using Spring boot #RabbitListener, we are able to process the AMQP messages.
Whenever a message sent to queue its immediately publish to destination exchange.
Using #RabbitListener we are able to process the message immediately.
But we need to process the message only between specific timings example 1AM to 6AM.
How to achieve that ?
First of all you can take a look into Delayed Exchange feature of RabbitMQ: https://docs.spring.io/spring-amqp/docs/current/reference/html/#delayed-message-exchange
So, this way on the producer side you should determine how long the message should be delayed before it is routed to the main exchange for the actual consuming afterwards.
Another way is to take a look into Spring Integration and its Delayer component: https://docs.spring.io/spring-integration/docs/5.2.0.BUILD-SNAPSHOT/reference/html/messaging-endpoints.html#delayer
This way you will consume messages from the RabbitMQ, but will delay them in the target application logic.
And another way I see like start()/stop() the listener container for consumption and after according your timing requirements. This way the message is going to stay in the RabbitMQ until you start the listener container: https://docs.spring.io/spring-amqp/docs/current/reference/html/#containerAttributes

Spring Integration handle http outbound gateway failures

There are multiple servers that are listening to activemq. The chain is configured to make the http [outbound gateway] call. Suppose one of the server picks up the message and in-between if the http call fails for some reason. The message should be put back to the queue, so that another server can pick up the message and process. Can this be achieved using Spring Integration. I read lot on Transaction, however unable to find workable way.
Yes, simply set acknowledge="transacted" on the <int-jms:message-driven-channel-adapter/> and, as long as you use only direct channels (no <queue/> on the channel or task-executor on the channel's dispatcher) then any failure will cause the message to roll back.

ActiveMQ / JMS Message Handler Test

This is not totally on JMS Queue handler test. So, continue reading.
We have an architecture where spring channel listens to a queue from ActiveMQ. The listener of this queue will receive messages and has a static list of sub-listeners (identified by unique subjects). All the messages will have some parameters including the subject to which this message has to be delivered.
SMSService will drop its messages to the activemq with a subject SEND_SMS. It will be listened either by some HTTP Service or SMPP Service. You can even design your own Listener and wire that as a spring component with the required "subject".
Problem:
There is a better chance that this internal subject might change. This doesn't even throw an explicit Runtime Exception when there are no listeners. Is there a way to test this message being actually received by the intended listener?
`
As tim Bish siad, your problem statement is much too vague.
Have you tried to create your own ActivemMQ interceptor (I do not know if it could be usefull for your problem)

JMS request/reply pattern in grails

I am creating a grails web app which makes use of JMS messaging. I have installed the JMS plugin for grails and using activemq as the messaging provider. I want to implement a request/response pattern in grails.
I was successfully able to send a message to the queue using the
sendQueueJMSMessage("queueName",Map message) from a controller.
I then created a service which contains the onMessage() method that listens to the "queueName" as stated above.
The onMessage() method does some processing and successfully sends an email to the user.
The above scenario has been implemented successfully.
Now, I would like to receive a response from this onMessage() method.
Lets say I want to implement the below scenario.
The request is added to the queue and waits for a response. I looked around but I couldnt find any help.
Please give me a lead on this. I really appreciate it.
Spring JMS adds support for auto replies, which the Grails plugin supports. See: http://gpc.github.com/grails-jms/docs/manual/guide/5.%20Receiving%20Messages.html#5.3%20Listener%20Return%20Values
Here is a test exercising this stuff: https://github.com/gpc/grails-jms/blob/master/test/integration/grails/plugin/jms/test/reply/ReplyingListenerServiceSpec.groovy#L12
The other option is to just send another message from your first message receiving method.
you did not provide much to work with here so the my suggestion is to take a look at the samples in the Grails JMS Plugin - Reference Documentation: 5. Receiving Messages, or provide some code

Resources