remote application sends as non_persistent however need to s

Posted by Admin on 05-Jul-2011 09:24

Hi,

(Sonic MQ 7.6)

My Oracle OAS JMS Router sends messages without specifying the persistence, and the default persistence in the SonicMQ libraries is set to non_persistent.

However, the JMS Router uses some technical messages in the queue q.jmsrouter.log to store its internal configuration.

So when the messaging container is bounced, these non-persistent config messages are gone, and my JMS Router job definition is gone, and needs recreation (manually in a GUI...).

So the question is: how can I make my messages survive a container bounce (yes, the backup may bounce or go down more or less at the same time), without having the ability to influence the persistence property as set by the poster?

We have opened an SR a while ago with Oracle Support to suggest them to set the persistence explictly on the message, but until now to no avail.

One option could be to use a customized version of the Sonic MQ library that implements the default persistence, maybe Progress support can realize that?

Thanks in advance,

Erik

All Replies

Posted by pmeadows on 05-Jul-2011 09:47

There's an option on the SonicMQ Connection Factory to set the default delivery mode to 'persistent'. (Ref' progress.message.jclient.ConnectionFactory.setPersistentDelivery()/setPersistentDeliveryBoolean())

Presumably Oracle OAS is getting the connction factory via JNDI? If so you should be able to update the connection factory definition in the JNDI store and enable this option. This can be done via the JMS Administered Object utility within the Sonic Management Console. Connect to the JNDI store, find the connection factory, then check the 'Persistent' box in the 'Messaging' tab. Don't forget to click the 'Update' button after making the change.

Posted by Admin on 06-Jul-2011 04:56

Hi Paul,

It first sounded to me like you were spot on.

However, I checked the properties of the JNDI connection factories in the management console, and the persistent flag for 'Default Delivery Mode' was already set to PERSISTENT - and at the same time these messages are non-persistent.

A Java-savvy consultant has found out a while ago for us in the internals of the Oracle Application Server JMS Router, when it publishes a message to Sonic MQ, the persistence mode is not specified:

In line 06 you can see that the creation of the byte message that will be sent is delegated to the getSession() that ultimately delegates to the associated resource adapter client libraries

After creating the byte message the JMS Router enqueues the message (through the associated resource adapter).

06:  msg = getSession().createBytesMessage();
...
12:      prod.send(msg, msg.getJMSDeliveryMode(), msg.getJMSPriority(), ttl);

You can  observe from the code above that the message is being sent by the producer with a delivery mode that is resolved from the created byte message object. The router is not explicitly setting it to persistent!
The resource adapter/provider is built around some SonicMQ libraries:

 

 

 

 

Could it be that the createBytesMessage() method is implemented in these classes and is explicitly set to NON_PERSISTENT, hence overriding the ConnectionFactory setting?
Can the ConnectionFactory default delivery mode be overriden at all?
I can make no more than a guess. Somewhere the persistence is set, but where?
Thanks and best regards,
Erik

Posted by pmeadows on 06-Jul-2011 06:09

Reading the delivery mode from a newly created message seems wrong to me.  A message's JMSDeliveryMode header is set when the message is sent.  Prior to the send() the header's value is undefined.

The following discussion is somewhat related:

  http://communities.progress.com/pcom/message/77643

To pick up the message producer's default delivery mode and priority when sending a message the client should use:

  prod.send(msg, Message.DEFAULT_DELIVERY_MODE, Message.DEFAULT_PRIORITY, ttl);

Alternatively the send() could explicitly choose persistent delivery by passing DeliveryMode.PERSISTENT.

With SonicMQ the code extract you sent also results in messages being sent with priority 0, rather than the default priority of 4.  Again, because the value of the JMSPriority header on a newly created message is undefined prior to the message being sent.  I doubt this aspect will cause you problems, but I thought it worth noting.

Thanks, Paul.

Posted by Admin on 06-Jul-2011 06:33

Thanks Paul,

I will follow that up with Oracle, very clear explanation, also the referenced thread helped me.

Can you shine some light on that apparently, the persistence property as set by the send method does override the default property of the JNDI CF?

Cheers,

Erik

Posted by pmeadows on 06-Jul-2011 07:13

Yes, if a delivery mode is set explicitly on the send call then this overrides the default delivery mode specified via the connection factory.

So, walking throught the details, the 'persistent delivery' option on the connection factory sets the default delivery mode to be used by message producers created from connections that have been created by the factory.  The message producer uses its default delivery mode if send() is called either without specifying a delivery mode or if Message.DEFAULT_DELIVERY_MODE is passed as the delivery mode.

If a delivery mode (other than Message.DEFAULT_DELIVERY_MODE) is specified on the send() call then that delivery mode is used, regardless of the producer's default delivery mode.

In your case the client is getting a delivery mode from the message's uninitialized JMSDeliveryMode header, which with SonicMQ happens to return NON_PERSISTENT, and passes this to send().  The end result is therefore that send() is called with the delivery mode explicitly set to NON_PERSISTENT; this overrides the producer's default delivery mode that's come from the connection factory config.

This thread is closed