Announcement Announcement Module
Collapse
No announcement yet.
JMS Adapter: Content Based Filtering Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • 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:

    Code:
        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?

    Comment


    • #3
      Mark,

      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.

      Comment


      • #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.

        Comment


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

          Message selectors cannot reference message body values.

          Comment


          • #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": http://docs.oracle.com/javaee/1.3/ap...s/Message.html

            Comment


            • #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:
              Code:
                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:

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

              Thank you.

              Comment


              • #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.

                http://publib.boulder.ibm.com/infoce...c/ac24876_.htm

                and

                http://docs.oracle.com/javaee/1.4/tu...4.html#wp79281

                (Scroll down the Message Headers and Message Properties).

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

                https://jira.springsource.org/browse/INT

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

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

                Comment


                • #9
                  Gary,

                  Sure: https://jira.springsource.org/browse/INT-2448

                  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.

                  Comment


                  • #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/>...

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

                    Comment


                    • #11
                      Gary,

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

                      Thank you.

                      Comment

                      Working...
                      X