OpenLiberty / open-liberty

Open Liberty is a highly composable, fast to start, dynamic application server runtime environment
https://openliberty.io
Eclipse Public License 2.0
1.15k stars 592 forks source link

Message send with explicit timeToLive not working #9842

Open dhaggart opened 4 years ago

dhaggart commented 4 years ago

Using MessageProducer.send() to send a message with an explicit TTL value doesn't respect this and uses the queue defined TTL (default 0: no time-out) instead.

This is missed in the WS-CD com.ibm.ws.messaging.clientcontainer_fat 'testTimetoLiveVariation' FAT test (the result isn't reported). I'm in the process of porting this over to open-liberty which is where/why I've encountered it.

Simple reproduction:

QueueConnection connection = ((QueueConnectionFactory)jndi.lookup("java:comp/env/jndi_JMS_BASE_QCF")).createQueueConnection();
Queue queue = (Queue) jndi.lookup("java:comp/env/jndi_QUEUE");
QueueSession session = connection.createQueueSession(false,javax.jms.Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(null);
MessageConsumer consumer = session.createConsumer(queue);

producer.send(queue,session.createMessage(),DeliveryMode.NON_PERSISTENT,0,500);  // 500 ms life
Thread.sleep(2000); // much longer than message life
if (null!=consumer.receiveNoWait()) System.out.println("failed");

Printing the message will show:

JMSExpiration: 0 JMSDestination: queue://QUEUE

If TTL is set to a fixed value in the client container's server.xml, e.g.

<properties.wasJms queueName="QUEUE" timeToLive="750"/>                                                                     

The message expires but if read in time and printed it shows, e.g.

JMSExpiration: 1574177165300 JMSDestination: queue://QUEUE_ONE?timeToLive=750

It is expected that the TTL value in the send() call be used and that the message expires before it can be consumed in the example.

dhaggart commented 3 years ago

We know the issue is down to the override defined in the metatype having a default of 0 -

com.ibm.ws.messaging.jms.common/resources/OSGI-INF/metatype/metatype.xml:

<OCD id="com.ibm.ws.jca.jmsQueue.properties.wasJms.javax.jms.Queue-com.ibm.ws.sib.api.jms.impl.JmsQueueImpl" ibm:extendsAlias="wasJms" ibm:extends="com.ibm.ws.jca.jmsQueue.properties" name="%properties.wasJms.Queue" description="%properties.wasJms.Queue.desc" >  
...
  <AD id="timeToLive" type="String" ibm:type="duration(s)" default="0s" min="0" name="%jms.common.timetolive" description="%jms.common.timetolive.desc" />  
...

It is documented as a default time:

https://www.ibm.com/support/knowledgecenter/SSAW57_liberty/com.ibm.websphere.liberty.autogen.nd.doc/ae/rwlp_config_jmsQueue.html#properties.wasJms

This is different to traditional WebSphere (affects porting):

https://www.ibm.com/support/knowledgecenter/en/SSEQTP_9.0.5/com.ibm.websphere.base.doc/ae/SIBJMSQueue_DetailForm.html#SIBJMSQueue_DetailForm

where the property is null by default allowing the application to determine the setting. (i.e. it is an override value in WAS)

It behaves like it does in tWAS so perhaps the correct solution is to correct the documentation and not have a default value for it?