Is it possible to programmatically create / teardown Spring Integration channels, as opposed to declaring them statically in Spring config?
My situation is this:
I have a webapp that requires push notifications, so I'm using long polling. Those long polling calls need to block on the server until they get an event.
What I'm envisioning (open to alternatives, of course), is a Spring Integration queue channel for each session, each listening to a single pubsub channel. So, when a server event happens it will be published to the pubsub, which will then pipe down to the individual session queues where they'll be popped off and sent to the client that's polling.
In order to do this, when a session is created I'd have to register new queue channel listing on the pubsub channel. When the session is destroyed, that new queue will also be destroyed.
Is something like this possible?
I don't want to have the the session listening directly to the pubsub because there's a risk of losing messages, so I want to have a queue in between to buffer them.
Thanks,
Roy
Yes, you can simply instantiate a QueueChannel and make it the outputChannel of a BridgeHandler. Then create an EventDrivenConsumer, passing the pubSub and bridge handler in the constructor.
Call start() on the consumer to make it subscribe to the pubSub, and stop() to unsubscribe when the session is closed.
If you don't want to hand-wire these components, simply declare the queue channel, and bridge in a small application context; make it a child of your main context and it will automatically subscribe to the pubSub in the parent context. Call context.destroy() to disconnect.
Related
I have an application where I created 2 message listener containers for external system A which listens two queues respectively.
Also I have 1 message listener container which running and listening another queue of external system B. I am using spring DefaultMessageListenerContainer.
My application is running on clustered environment, while defining my message listener container I injected to it my listener which implements javax MessageListener interface and acts as kind of MDB.
So my questions are:
Is it normal to have instance of message listener container per queue?
Will my message driven pojo (MDP) execute onMessage() on each application node?
If yes, how can I avoid it? I want each message to be consumed once on some of the application nodes.
What is default behavior of DefaultMessageListenerContainer, message is acknowledged as soon as I reached onMessage or after I finished execution of onMessage? Or maybe I need to acknowledge it manually?
See the spring framework JMS documentation and the JMS specification.
Yes it is normal - a container can only listen to one destination.
It depends on the destination type; for a topic, each instance will get a copy of the message; for a queue, multiple listeners (consumers) will compete for messages. This has nothing to do with Spring, it's the way JMS works.
See #2.
With the DMLC, it is acknowledged immediately before calling the container; set sessionTransacted = true so the ack is not committed until the listener exits. With a SimpleMessageListenerContainer, the message is ack'd when the listener exits. See the Javadocs for the DMLC and SMLC (as well as the abstract classes they subclass) for the differences.
My spring boot application's is functionality it to listen to the messages on rabbitmq queue, do some processing in onMessage, and then publish the message on another rabbitmq queue. We are using spring-rabbit (1.7.2.RELEASE). We have configured listener using SimpleMessageListenerContainer.
My question is can i publish using he same channel on which I am reading he messages. Does spring-rabbit provides access to channel used by listener? so that same channel can be reused to publish?
Thanks,
Smita
If you use transactions (listener container), any operations performed by a transactional RabbitTemplate on the container thread will participate in the transaction and use the same channel.
If you are not using transactions, you can use a ChannelAwareMessageListener to access the channel the message was received on. See Message Listeners.
If you are using #RabbitListener you can add the Channel as a method parameter.
The current 1.7.x release is 1.7.9.
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.
I would like to know if using a JMS in the below scenario is feasible or not.
I am adding a feature of calling an API service which will dispatch the emails to the customer.
So i thought of implementing a JMS in my application where i would put the events or messages in the queue and write a listener in the same application which will process the message and call the rest API service call which will dispatch the message to the customers.
My question was is it good to have a JMS in between the rest call and our application ?
Or should i directly call the rest api to dispatch the messages to the customer ?
I think that depends on the availability and overhead of your rest service.
If you know there will be times that your service will be down, but don't want to impact the process using the API, then JMS queues make since.
Or if you feel the rest service is causing a bottle neck from the API service side and want to queue up the messages somewhere where they can survive an outage of your own, JMS with a provider that supports persistent messages makes since in this case.
Using JMS would also open the door for completely decoupling the two. Whatever application hosts the rest service could just as easily be converted to pull messages from the JMS queue without a need to make a rest call if that seemed more efficient.
Just a few examples of how you could justify using JMS in this scenario.
If I have a JMS queue and I wish to put a message on the queue from a publishing client, I need to first open a session, get the queue from its jndi name and then send the message to the queue.
But on the consumer side, how come I do not manually need to open a session and receive the message. Does the container always keep one open session per MDB (considering one MDB listening on one queue)
If you're using MDB's, which are container-managed objects, the connection, session, queue/topic, and actual consumer are all managed by the container.
You just write the code for onMessage(Message m), that's it.