Build robust spring boot jms theme and subscriber using ActiveMQ
I need to create a theme and a strong subscriber for ActiveMQ, my problem is I don't know where to point this. I can create a topic and consume messages, but when I turn off the subscriber, keep sending messages and turn the subscriber back on, they won't read them.
This is what I have so far:
Sending a message:
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
jmsTemplate.setPubSubDomain(true);
jmsTemplate.setDeliveryMode(DeliveryMode.PERSISTENT);
jmsTemplate.setDeliveryPersistent(true);
jmsTemplate.convertAndSend("venta.topic",venta);
Receiving a message:
@JmsListener(destination = "venta.topic",id = "comercial",subscription = "venta.topic")
public void receiveMessage(Venta venta) {
logger.log(Level.INFO, "RECEIVED : {0}",venta);
repository.save(venta);
}
I have read this article and I understand that I need to create a lasting subscriber.
I also read the spring docs
And I think it has something to do with DefaultJmsListenerContainerFactory
(which I have not implemented, I am using the default config) the docs show:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setConcurrency("3-10");
return factory;
}
But I can't seem to find where to create a long running session. Both my producer and my subscriber are connected to a standalone activemq binary.
Hope you can help me, thanks in advance.
source to share
As stated in the previous answers, the factory needed to set the customer ID and persistent subscription:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setConcurrency("3-10");
factory.setClientID("brokerClientId");
factory.setSubscriptionDurable(true);
return factory;
}
but that by itself didn't register the client as a permanent subscriber because it JMSListener
had to be specified containerFactory
, otherwise it would just accept the defaults:
@JmsListener(
destination = "venta.topic",
id = "comercial",
subscription = "venta.topic",
//this was also needed with the same name as the bean above
containerFactory = "jmsListenerContainerFactory"
)
public void receiveMessage(Venta venta) {
logger.log(Level.INFO, "RECEIVED : {0}",venta);
repository.save(venta);
}
It's worth noting that this post made me realize my mistake.
Hope this helps someone else
source to share
DefaultJmsListenerContainerFactory must have a unique clientId and a durable sub. true as shown below:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setConcurrency("3-10");
factory.setClientID("brokerClientId");
factory.setSubscriptionDurable(true);
return factory;
}
source to share