0

I'm trying to set up spring JMS for activemq, and I'd like individual DLQs for easier monitoring rather than everything being lumped on one DLQ.

However my bean for this doesn't seem to be picked up. Could anyone point me out what I'm doing wrong as the documentation's pretty vague on how to do this programatically?

My Queue config:

@Bean
public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
}

@Bean
public DeadLetterStrategy deadLetterStrategy() {
    IndividualDeadLetterStrategy deadLetterStrategy = new IndividualDeadLetterStrategy();
    deadLetterStrategy.setQueueSuffix(".dlq");
    return deadLetterStrategy;
}

@Bean
public RedeliveryPolicy redeliveryPolicy() {
    RedeliveryPolicy redeliveryPolicy = new RedeliveryPolicy();
    redeliveryPolicy.setInitialRedeliveryDelay(5000);
    redeliveryPolicy.setBackOffMultiplier(2);
    redeliveryPolicy.setUseExponentialBackOff(true);
    redeliveryPolicy.setMaximumRedeliveries(5);
    return redeliveryPolicy;
}

@Bean
public Queue myQueue() {
    ActiveMQQueue queue = new ActiveMQQueue("myQueue");
    return queue;
}
Kristof Plennings
  • 469
  • 1
  • 6
  • 17

1 Answers1

2

You can apply Individual Dead Letter Strategy using configurations something like this

@Bean
DeadLetterStrategy deadLetterStrategy(){

    IndividualDeadLetterStrategy dlq = new IndividualDeadLetterStrategy();      //Messages of each will get to their respective Dead Letter Queues. if Original queue = 'x', its DLQ = 'prefix + x'
    dlq.setQueueSuffix(".dlq");
    dlq.setUseQueueForQueueMessages(true);

    return dlq;
}

@Bean
    public BrokerService brokerService(@Autowired DeadLetterStrategy strategy) throws Exception {
        BrokerService broker = new BrokerService();
        TransportConnector connector = new TransportConnector();
        connector.setUri(new URI("your broker url")); //default/embedded broker url: vm://localhost?broker.persistent=true
        broker.addConnector(connector);

        PolicyEntry entry = new PolicyEntry();
        entry.setDestination(new ActiveMQQueue("*"));           //given DeadLetterStrategy will be applied to all types of Queues; ',' can also be used
        entry.setDeadLetterStrategy(strategy);
        PolicyMap map = new PolicyMap();
        map.setPolicyEntries(Arrays.asList(entry));
        broker.setDestinationPolicy(map);

        return broker;
    }

And finally your queue should look like this:

@JmsListener(destination = "main_queue_name" + ".dlq")
    protected void processFailedItem(YourCustomPojo data) {
        //do whatever you want
    }
Afridi
  • 6,753
  • 2
  • 18
  • 27
  • Any way to skip the setUri bit? Spring boot's currently autoconfiguring that for me when I add `spring.activemq.broker-url` to my application.properties – Kristof Plennings Apr 11 '18 at 07:43
  • Same issue was with me. Actually you need to add new PolicyEntry for broker service, for which you need to define BrokerService bean manually. BTW you can read your application.properties file here for getting that url using either @Value or Environment class. – Afridi Apr 11 '18 at 07:50
  • hmm, I'm using spring boot 1.5.11. First I got an error on kahadb missing. And after adding that I got: NoSuchMethodError: org.apache.activemq.util.ByteSequence.remaining()I. Did you also encounter this? – Kristof Plennings Apr 11 '18 at 08:20
  • I am using the same spring boot version(1.5.1.RELEASE), and everything is working fine. Using these dependencies: org.springframework.boot spring-boot-starter-activemq org.apache.activemq activemq-kahadb-store – Afridi Apr 11 '18 at 10:08
  • With that it seems to run, but it seems to be connecting to the embedded activemq rather than my configured one. (I removed all queues and don't see them popping up, yet my receiver's triggered) – Kristof Plennings Apr 12 '18 at 05:05
  • I think you are using embedded ActiveMQ broker url instead of your configured one. Try to set broker url of the configured one(in brokerService bean definition) because it will not read your property file for broker related configuration automatically. – Afridi Apr 12 '18 at 06:24