Announcement Announcement Module
Collapse
No announcement yet.
Setting message priority inside message converter Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Setting message priority inside message converter

    We tried two things to set message priority

    first is JMS Template

    Code:
            <util:constant id="common.deliveryMode" static-field="javax.jms.Message.DEFAULT_DELIVERY_MODE"/>
        <util:constant id="common.timeToLive" static-field="javax.jms.Message.DEFAULT_TIME_TO_LIVE"/>
            
            <bean id="common.qosEnabledTopicJmsTemplate" abstract="true" class="com.xx.QoSEnabledJmsTemplate">
                    <property name="connectionFactory" ref="common.topicConnectionFactory"/>
                    <property name="explicitQosEnabled" value="true"/>
                    <property name="priority" value="7"/>
                    <property name="deliveryMode" ref="common.deliveryMode"/>
                    <property name="timeToLive" ref="common.timeToLive"/>
            </bean>        
    
    
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageProducer;
    
    import org.springframework.jms.core.JmsTemplate;
    
    public class QoSEnabledJmsTemplate extends JmsTemplate {
            
            protected void doSend(MessageProducer producer, Message message) throws  JMSException {
                    System.out.println("Params while sending = DM" + getDeliveryMode() + " Priority" + message.getJMSPriority() + " TTL"+ getTimeToLive());
                    System.out.println("QOS status =" + isExplicitQosEnabled());
                    setPriority(message.getJMSPriority());
                    producer.setPriority(message.getJMSPriority());
                    producer.send(message, getDeliveryMode(), message.getJMSPriority(), getTimeToLive());
            }        
    
    }
    Second is directly setting message priority inside MessageConverter

    Code:
        @Override
        public Message toMessage(Object o, Session session)
                throws JMSException, MessageConversionException
        {
                    MTO mto =(MTO) o;
    	        BytesMessage msg = session.createBytesMessage();
    	        msg.writeBytes(mto.toByteArray());
                    msg.setJMSPriority(1);
            	return msg;
            }
    Both of them are not working. Please suggest.

  • #2
    What do you mean by "not working". Are you actually not seeing the priority property on the result Message? or are you not seeing the expected behavior from the JMS broker?

    Comment


    • #3
      Seeing the default priority instead of set priority.

      QoSEnabledJmsTemplate is working. But not sure why I couldn't see the priority getting reflected on Gems.
      Last edited by srikanthradix; Jun 24th, 2010, 10:00 AM. Reason: Working

      Comment


      • #4
        If you can reproduce this with a test case, then please create a JIRA issue and attach it. Or, if it turns out that something else is wrong (perhaps you just didn't have qos enabled before?), it would be good to know that as well.

        Thanks,
        Mark

        Comment


        • #5
          The second example can't work. Setting the priority of a javax.jms.Message prior to sending has no practical effect according to the javadoc:
          JMS providers set this field when a message is sent. This method can be used to change the value for a message that has been received.

          Comment


          • #6
            I can confirm that this doesn't work with the following JMS template in spite of the explicitQosEnabled set to true.

            But I have noticed that not only the priority (JMSPriority) is not set in the JMS headers (I have checked on the JMS server directly), but also the timeToLive property (JMSExpiration). [EDIT: Other JMS headers may also be concerned but I haven't checked as this looks like a general issue]
            However, the MessageHeaders ($file_name, $timestamp, ...) are correctly set.

            Code:
            <bean id="testJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            	<property name="connectionFactory" ref="connectionFactoryQueueMce" />
            	<property name="destinationResolver" ref="destinationResolverMce" />
            	<property name="defaultDestinationName" value="MCEHoldingForexErrorQueue" />
            	<property name="explicitQosEnabled" value="true" />
            	<property name="priority" value="9" />
            	<property name="timeToLive" value="20000" />
            </bean>
            Pierre

            Comment


            • #7
              JIRA open : INT-1440

              Comment


              • #8
                Hi Mark/All,
                Just to confirm, if I set the "priority" value from Spring Integration ( MessageHeaders.PRIORITY) then this does not get mapped to JMSPriority.

                Basically, I am setting the priority on SI message depending on certain business rules and then pass the message to Queue. But I see this not refelced in JMSPriority header.

                Please let me know if I doing something wrong.

                Comment


                • #9
                  The only out-of-the-box role of the priority header on a Spring Integration Message is to determine precedence within Spring Integration's own PriorityChannels.

                  It's also worth pointing out that the JMS "priority" header itself does not actually drive the prioritization; that is done at the level of the MessageProducer send() call. You can see a bit more about that, and you could provide your own comments/suggestions on this issue:
                  https://jira.springsource.org/browse/INT-1435

                  Thanks,
                  Mark

                  Comment


                  • #10
                    Thanks Mark.

                    I will verify the Header-Mapper thing as specified in INT-1435 JIRA comments with a small sample and update you.

                    I think If I set the priority in SI header message and I have a header-mapper to map the SI prioirty header to JMSPrioirty header( just subclased SI header-mapper class). then the JMSPrioirty should be reflected in the JMSMessage on the queue and queue should give the message to receiver on priority. In theory this should be the case but I will have to check.

                    Thanks

                    Comment


                    • #11
                      Yes, the header-mapper thing does not work as commented in the JIRA.

                      I thought of subclassing the JmsTemplate and overriding it the doSend as

                      Code:
                       protected void doSend(MessageProducer producer, Message message) throws JMSException {
                            producer.send(message, getDeliveryMode(), message.getJMSPriority(), getTimeToLive());
                         }
                      But this again is not flexible as it will pass on the JMSPriority.

                      Mark,

                      I am thinking of your another workaround that you suggested that have two High and Low Jms Adaptor. But how do I corodinate the adaptor listeners so that Low JMS adaptor listener does not start picking messages when there are messages in High-Priority one.

                      Thanks

                      Comment


                      • #12
                        I'm not sure if I understand your question completely, but I would imagine that the important thing is to have 2 different adapters for the outbound side - when *sending* JMS Messages. The inbound side could be a single adapter (or even some other process), since the prioritization happens at the broker.

                        Does that make sense? If not, maybe I didn't quite catch the intent of your question.

                        Comment


                        • #13
                          Hi Mark, yes you are correct. seems like me not good at pouring my thoughts in english very well.

                          Ok, this what I did to stamp JMSPriority on messages. I read the messages from the incoming queue and applied the rules to deetermine the priotity and set that in header and overriden the doSend method JmsTemplate as mentioned above and that worked for me.

                          Is there any issue with this approach? I will let all of you know if I end up in problems in my POC.

                          Comment


                          • #14
                            So, you are saying that you set the JMSPriority and then you are using that to drive the priority at the MessageProducer's send() method, right?

                            I believe that is what you are saying, because you are not able to access the Spring Integration Message at that send() call obviously.

                            I just want to clarify that first. It gets confusing sometimes with different "Message" instances being discussed in the same scenario

                            Thanks,
                            Mark

                            Comment


                            • #15
                              Yes, that is correct.

                              A separate question on poller--

                              1) Suppose I configure the poller to have max-messages-per-poll=5 and it runs in default thread( i would assume a single thread). Now suppose, in these 5 messages I have 3 higher priority( A, B, C ) and 2 low( D, E). When poller puts these messages on a channel then how are these messages processed like. I mean will it process like A,B,C, D, E or it will be random. Again Its single threaded. I know it will be different behavior for multi threaded scenario?

                              Comment

                              Working...
                              X