2 Replies Latest reply on Feb 23, 2012 11:03 AM by Calle Andersson

    Problem using smooks to route message to correct JMS queue

    Calle Andersson Newbie



      I have tried to use a smooks-file for routing messages (XML) to different JMS queues based on content within the message.


      First I tried to use the following script:

      <?xml version='1.0' encoding='UTF-8'?>
      <smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd"
              <param name="stream.filter.type">SAX</param>
              <condition id="illegalValue"><!-- abc.xyz == "00000" --></condition>
              <condition id="legalValue"><!-- abc.xyz != "00000" --></condition>
          <!-- Capture some data from the message into the bean context... -->
          <jb:bean beanId="abc" class="java.util.Hashtable" createOnElement="abc">
              <jb:value property="xyz" data="abc/xyz"/>
          <!-- Create the split messages for the order items... -->
          <frag:serialize fragment="changeNotificationMessage" bindTo="changeNotificationMessageFrag" />
          <jms:router routeOnElement="changeNotificationMessage" beanId="changeNotificationMessageFrag" destination="queue/testQueueA_JMS_GW">
              <condition idRef="illegalValue" />
              <jms:highWaterMark mark="5" />
          <jms:router routeOnElement="changeNotificationMessage" beanId="changeNotificationMessageFrag" destination="queue/testQueueB_JMS_GW">
              <condition idRef="legalValue" />
              <jms:highWaterMark mark="5" />


      This seemed to work exactly as I wanted. However, since the <abc> element is optional within the message, an exception is thrown when it is missing. The log gives the following information:

      Caused by: org.milyn.expression.ExpressionEvaluationException: Error evaluating MVEL expression 'abc.xyz == "00000"' against object type 'org.milyn.javabean.repository.BeanRepository$RepositoryBeanMapAdapter'. Common issues include:

      1. Referencing a variable that is not bound into the context. In this case use the 'isdef' operator to check if the variable is bound in the context.

      2. Invalid expression reference to a List/Array based variable token. Example List/Array referencing expression token: 'order.orderItems[0].productId'.


      I tried to change the conditions by using 'isdef' in the following way:

          <conditions>        <condition id="illegalValue"><!-- isdef abc.xyz && abc.xyz == "00000" --></condition>
              <condition id="legalValue"><!-- !(isdef abc.xyz && abc.xyz == "00000") --></condition>


      With this change I didn't get any exception when the <abc> element was missing in a message. However, 'isdef abc.xyz' seems to evaluate to false all the time (which meens that all messages gets routed to the same JMS queue (queue/testQueueB_JMS_GW)).


      I have tried to google for information about MVEL and isdef but I havn't found something useful.


      Why does the isdef always result in false? Have I used it in the wrong way?


      Is there some other way to simply route messages to different JMS queues based on there content without having to write a custom action or using the ContentBasedRouter action (which only routes to different services unless I misunderstood)?

        • 1. Re: Problem using smooks to route message to correct JMS queue
          Tom Cunningham Master

          This is more of a straight Smooks question than an ESB one - and one you probably would have better luck at asking the guys over at the Smooks forum, but I do know that a MVEL shell exists.




          I don't know the answer to your question about isdef, but you should be able to use the interactive shell to figure out what's going on there and it should be pretty easy with the shell to figure out a working expression.

          1 of 1 people found this helpful
          • 2. Re: Problem using smooks to route message to correct JMS queue
            Calle Andersson Newbie

            Thanks for your answer!


            The way I have tried to solve the wanted behavior (routing messages to different JMS queues based on content within the message) is by using Smooks as described in my previous post. However, I wonder if there are some other ways (without using Smooks) to simple get the same behavior? (I am aware that it is possible to create a custom action to scan a message and manually put it on different queues but this is a little bit unconvenien. I also know that it is possible to use a ContentBasedRouter to get the same behavior but in that case I have to create some new services.)