I need to create a topic and a durable subscriber for ActiveMQ, my problem is that I don't know where to specify that. I am able to create the topic and consume the messages, but when I turn off the subscriber then keep sending messages and turn on the subscriber again, it won't read them.
This is what I have so far:
Sending the message :
JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
jmsTemplate.setPubSubDomain(true);
jmsTemplate.setDeliveryMode(DeliveryMode.PERSISTENT);
jmsTemplate.setDeliveryPersistent(true);
jmsTemplate.convertAndSend("venta.topic",venta);
Receiving the 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 the durable subscriber.
I've also read the spring docs
And I think it has something to do with the DefaultJmsListenerContainerFactory
(which I didn't implement, I am using the default configuration), the docs shows:
@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 the durable session. Both my producer and my subscriber are connected to a standalone activemq binary.
I hope you can help me , thanks in advance.
As the previous answers pointed out, it was necessary to set the client id and the durable subscription on the factory :
@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 alone did not register the client as a durable subscriber, that is because the JMSListener
needed the containerFactory
specified, otherwise it would just take 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 mentioning that, this post was the one that made me realize my mistake.
I Hope this will help someone else
The DefaultJmsListenerContainerFactory should have unique clientId and durable sub. true set like below code :
@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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With