0

I am sending message to the queue in the following manner:

I want to schedule repeat my message. I mean, whatever message my this line jsmClient.send(identifier); in the controller(shown below) is sending, I want to keep on sending, say for 10 or 100 times (depending upon the timer I set). My consumer(not shown below) will keep on consuming the same message until I ask it to stop. For example, even though my producer is going to send the message 10 or 100 times, if I want to stop receiving the message at 5th time(in case of producer sending message 10 times) or 50th time (in case of producer sending message 100 times), I should be able to do that.

Since I am using JMS 2 and ActiveMQ (version 5.15.8), I am not able to figure out the following:

The Delay and Schedule Message Delivery documentation talks about the AMQ_SCHEDULED_REPEAT in the following section:

MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage("test msg");
long delay = 30 * 1000;
long period = 10 * 1000;
int repeat = 9;
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay);
message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD, period);
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);
producer.send(message);

If I understood correctly, the above code isn't considering JMS 2 but JMS 1.1? I am wondering what changes I need to make in my code below so that I could do something like this message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT, repeat);. I couldn't find much useful info regarding schedule repeat in the Spring documentation.

My JmsProducer class :

@Component
public class JmsProducer {
    @Autowired
    JmsTemplate jmsTemplate;

    @Value("${jms.queue.destination}")
    String destinationQueue;

    public void send(String msg){
        jmsTemplate.convertAndSend(destinationQueue, msg);
    }
}

JmsClient Interface:

public interface JmsClient {
    public void send(String msg);

}

JmsClientImpl class :

@Service
public class JmsClientImpl implements JmsClient{


    @Autowired
    JmsProducer jmsProducer;

    @Override
    public void send(String msg) {
        jmsProducer.send(msg);
    }


}

In my REST Controller, I am sending a message like this :

try {

            DataRetrieverDao dataRetrieverDao = (DataRetrieverDao) context.getBean("dataRetrieverDao");
            String identifier=dataRetrieverDao.sendDownloadInfo(user_id);
            logger.info("VALUE OF STRING: "+identifier);
            jsmClient.send(identifier);



        }

Based on my Research:

In this stackoverflow thread, JMS 2.0 is not supported in the activemq package, so should I switch to artemis instead? But then, the questions I asked from jmsTemplate side above are still in my mind. Please advise what's the best course of action in this situation for me. Thanks

Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
John
  • 1,210
  • 5
  • 23
  • 51

1 Answers1

0

The way delayed & scheduled message delivery works in ActiveMQ 5.x is that the producer sets the delay/schedule on the message using special properties and sends the message once. Once the broker receives the message it will then deliver the message to the queue based on the delay & schedule set on the message. Therefore, it is not accurate to say, "...my producer is going to send the message 10 or 100 times..." in the context of delayed & scheduled messages.

Delayed & scheduled message delivery is a feature of ActiveMQ 5.x and not part of the JMS specification. Spring JMS libraries and/or documentation won't mention this feature since it is unique to ActiveMQ 5.x.

As you note, ActiveMQ 5.x doesn't support JMS 2.0 so if you want JMS 2.0 support you'll need to switch to ActiveMQ Artemis. However, ActiveMQ Artemis doesn't support delayed & scheduled messages as discussed on the user mailing list. Therefore, if you want to delayed & scheduled messages you might want to stick with JMS 1.1 or figure out a different way to implement the functionality you're looking for with JMS 2.0 and ActiveMQ Artemis.

Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
  • Thanks. So, if I switch to JMS 1.x 1) Do you think what I am looking for as described in `my producer is going to send the message 10 or 100 times` line is achievable? 2) Do I completely need to get rid of Spring JMS in order to use JMS 1.x ? Thanks – John Feb 25 '19 at 17:09
  • As I already explained, if you use the delayed & scheduled message functionality of ActiveMQ 5.x then your producer isn't going to send the message 10 or 100 times; the ActiveMQ 5.x broker will do that assuming you've configured the appropriate properties on the message. I'm not sure why you keep insisting on stating this point incorrectly. If you use it correctly it should work as you expect although you'll be locking yourself into ActiveMQ 5.x as your broker since no other brokers implement this feature. I'm not familiar enough with it to know if it has a hard requirement on JMS 2.0. – Justin Bertram Feb 25 '19 at 21:24
  • Cool. Got the point. Thanks for explaining. Good to know that ActiveMQ 5.x is the only broker I could use to achieve what I am looking for. – John Feb 26 '19 at 00:23
  • For what it's worth, vendor lock-in (even if that "vendor" is an open source project) is generally a bad idea so consider yourself warned. – Justin Bertram Feb 26 '19 at 00:26