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" xmlns:ftl="http://www.milyn.org/xsd/smooks/freemarker-1.1.xsd" xmlns:frag="http://www.milyn.org/xsd/smooks/fragment-routing-1.2.xsd" xmlns:jms="http://www.milyn.org/xsd/smooks/jms-routing-1.1.xsd" xmlns:jb="http://www.milyn.org/xsd/smooks/javabean-1.2.xsd"> <params> <param name="stream.filter.type">SAX</param> </params> <conditions> <condition id="illegalValue"><!-- abc.xyz == "00000" --></condition> <condition id="legalValue"><!-- abc.xyz != "00000" --></condition> </conditions> <!-- 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"/> </jb:bean> <!-- 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> <jms:router routeOnElement="changeNotificationMessage" beanId="changeNotificationMessageFrag" destination="queue/testQueueB_JMS_GW"> <condition idRef="legalValue" /> <jms:highWaterMark mark="5" /> </jms:router> </smooks-resource-list>
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.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> </conditions>
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)?