Announcement Announcement Module
No announcement yet.
JMS Adapter: Content Based Filtering Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • JMS Adapter: Content Based Filtering

    Environment: Websphere MQ 7.1 / Spring Integration 2.1.1-BUILD-SNAPSHOT

    Is there a way to configure a "jms:message-driven-channel-adapter" to enable content-based filtering with publish/subscribe?

    Without using Spring Integration / Websphere MQ, and relying on ZeroMQ, it is as easy as:

        byte [] messageType = { 10, 2, 81, 84 };
        subscriber.subscribe( messageType );
    Would appreciate a way to do it with SI's help.

    P.S. The idea is not to route messages based on the payload in the same process / JVM, but to have many processes / JVMs running listening to only their messages from a single queue.
    Last edited by spinter; Feb 21st, 2012, 03:36 PM. Reason: fixed the content based filtering link

  • #2
    You can add a MessageSelector via the "selector" attribute on a message-driven-channel-adapter element. Is that sufficient for your use-case?


    • #3

      Thanks for the idea. Doing that is not horrible, but it also means if a source has a million messages in a queue, every subscriber would receive a million messages, and then will filter them out.

      If a "message selector" is the only choice I have with SI, can I use it to inspect a JMS header as well? I have control over where publishers will place a "selection criteria", and it would be nice if I can use JMS header for that, so I don't have to peek inside the payload. (I would still like to strip out all the JMSsness from the message before it is passed down the line)

      Thank you.


      • #4
        I suppose it depends on your broker; a few googles for IBM MQ would indicate the selection is done on the broker. It's probably reasonable to expect that all enterprise-ready brokers will run the selection on the broker rather than the client.
        Last edited by Gary Russell; Feb 21st, 2012, 10:19 PM.


        • #5
          And, yes, the selection uses headers; in fact the JavaDoc for Message says...

          Message selectors cannot reference message body values.


          • #6
            I actually meant that you can use a JMS MessageSelector (not a Spring Integration filter), so that happens broker-side. In terms of the supported queries, scroll down to "Message Selectors":


            • #7
              Gary, Mark,

              Right, I thought you meant an SI MessageSelector at first, since it is not immediately obvious where a "selector" attribute of "jms:message-driven-channel-adapter" points to. I did a quick "Command + F" on docs, and this particular "selector" is not (yet) discussed there.

              Now as I looked at it a bit closer I can see it takes a selector, passes it to JmsTemplate and:
                protected Message doReceive(Session session, Destination destination, String messageSelector) throws JMSException {
                  return doReceive(session, createConsumer(session, destination, messageSelector));
              which goes directly to the broker.

              Just to confirm:

                  <jms:message-driven-channel-adapter destination="xyzQueue"
                                                      selector="someId = '75D938E89AF18C30'"/>
              Will only receive messages that have "someId" set to "75D938E89AF18C30" in JMS header?

              Thank you.


              • #8
                Almost; you can't add arbitrary 'headers', these are more properly called 'properties'. You can set arbitrary properties on messages that can be used in message selectors.




                (Scroll down the Message Headers and Message Properties).

                Please open up a documentation Improvement JIRA on the reference manual here...


                There *is* brief documentation in the XSD schema...

                <xsd:attribute name="selector" type="xsd:string">
                A JMS Message Selector expression.
                ...but we should explain it in the reference.


                • #9


                  Is there a way to test it with SI, e.g. create a JMS message with such custom property(ies) and publish it to xyzQueue, where "the real" thing is listening on this queue?

                  Thank you.


                  • #10
                    Yes, just implement a custom message converter and inject it into a JmsTemplate, and provide a reference to that to a <int-jms:outbound-channel-adapter/>...

                    public class MyMessageConverter extends SimpleMessageConverter {
                    	public Message toMessage(Object object, Session session)
                    			throws JMSException, MessageConversionException {
                    		Message message = super.toMessage(object, session);
                    		message.setStringProperty("foo", "bar");
                    		return message;


                    • #11

                      That + [ selector="someId = '75D938E89AF18C30'" ] did it.

                      Thank you.