Announcement Announcement Module
Collapse
No announcement yet.
jms inbound channel adapter + extract payload + payload type router? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • jms inbound channel adapter + extract payload + payload type router?

    I have a queue on which two kinds of messages arrive - javax.jms.BytesMessage and javax.jms.TextMessage.

    What will extract-payload do in this case? I presume BytesMessage gets extracted to a byte[] and TextMessage extracts to a String but will it try to send both to the same endpoint?

    Is there any way to use extract-payload along with payload type router to get SI to send to two different endpoints based on which of the above jms message types are received on the queue?

    I could write a router myself which checks message type manually and routes to two endpoints but was wondering if there is a way to do it already.

    Currently I have jms message driven channel adapter sending to the next endpoint which accepts GenericMessage and then subsequently does genericMessage.getPayload(). Based on the type of the payload it could route but I'd like to know if there is a way to do this already.

    Thanks.
    Last edited by Narada; Mar 9th, 2009, 08:43 AM.

  • #2
    You are right about the byte[] and String payloads. And, yes you could easily add a PayloadTypeRouter on the channel that the JMS endpoint is sending to. Then, just add 2 individual channels after that (for byte[] and String respectively). So, there should be no reason for you to implement your own router for this use-case.

    Hope that helps.

    Comment


    • #3
      Thanks. That does indeed help. However I must clarify a few things - possibly n00b questions

      I assume you mean that extract-payload will be true? In which case what will be the java.lang.Class<?> equivalent of byte[] to be supplied to the payload type router?

      Or alternatively if you meant that extract-payload will be false then the java.lang.Class<?> equivalences will be javax.jms.BytesMessage and javax.jms.TextMessage to be supplied to the payload type router.

      Update: Actually the last statement above is not right. It will be a GenericMessage sent to the channel so not sure how that would work subsequently.

      Update2: Mark on second thoughts I'd really appreciate a small dummy xml example of what you mean if possible.
      Last edited by Narada; Mar 9th, 2009, 10:19 AM.

      Comment


      • #4
        Mark,

        I'd like to ask once more if I may.

        In the following example of a payload type router taken from the manual:

        Code:
        <bean id="payloadTypeRouter" class="org.springframework.integration.router.PayloadTypeRouter">
            <property name="payloadTypeChannelMap">
                <map>
                    <entry key="java.lang.String" value-ref="stringChannel"/>
                    <entry key="java.lang.Integer" value-ref="integerChannel"/>
                </map>
            </property>
        </bean>
        how would I define something like this for byte[] and String? What would be the class equivalent of a byte[]?

        If the above way is not a possible solution how else can I get SI to interpret a jms bytesmessage and textmessage and extract their payloads automatically?

        What about having an endpoint after the jms message driven channel adapter that has two public methods one that takes a String and another that takes a byte[]? Will SI pick the right method based on the jms message type?

        I would really appreciate your feedback.

        Many thanks.
        Last edited by Narada; Mar 24th, 2009, 11:18 AM.

        Comment


        • #5
          That's an interesting question about the byte[] class. It is possible to use 'java.lang.byte[].class' programmatically, but I believe only "java.lang.Byte[]" would work as a value in the configuration.

          However, I don't think you need a PayloadTypeRouter. As you mention, you can use 2 different methods (one for byte[] and one for String).

          To clarify "extract-payload"... if true, the message payload will be byte[]/String, but if "false", the payload will be the JMS TextMessage/ObjectMessage.

          Comment


          • #6
            Hi Narada,

            The following is my inbound gateway code:

            Code:
            <jms:inbound-gateway id="jmsin"
            	                     request-destination="requestQueue"
            	                     request-channel="demoChannel"/>
            	                    
            	<!-- <jms:message-driven-channel-adapter id="jmsIn" destination="requestQueue" channel="demoChannel"/>                    
            --> 
            	 <channel id="demoChannel"/> 
            	 
            	<service-activator input-channel="demoChannel"
            	                   ref="test"
            	                   method="checkOutput"/>
            
            	<beans:bean id="test" class="com.springintegration.TestOutput"/>
            and my outboundGateway code is:

            Code:
            <jms:outbound-gateway id="jmsout" request-channel="order"
            						  request-destination="requestQueue"
            						  reply-channel="jmsReplyToStdoutChannel"/>						  
            
            
            
            	<channel id="jmsReplyToStdoutChannel"/>
            
            	<stream:stdout-channel-adapter channel="jmsReplyToStdoutChannel" append-newline="true"/>
            This is a standalone java application to just write a message to JMS queue and read it using SpringIntegration gateways.

            Now i am able to write to JMS queue using outboundGateway, but i am unable to read it from inboundGateway.

            Is my configuration is correct?... i am also getting the following exception each time i run the application:

            Code:
            org.springframework.integration.message.MessageTimeoutException: failed to receive JMS response within timeout of: 5000ms
            	at org.springframework.integration.jms.JmsOutboundGateway.handleRequestMessage(JmsOutboundGateway.java:296)
            	at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:90)
            	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:48)
            	at org.springframework.integration.dispatcher.AbstractDispatcher.sendMessageToHandler(AbstractDispatcher.java:75)
            	at org.springframework.integration.dispatcher.SimpleDispatcher.dispatch(SimpleDispatcher.java:45)
            	at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:56)
            	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:116)
            	at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:94)
            	at org.springframework.integration.channel.MessageChannelTemplate.doSend(MessageChannelTemplate.java:222)
            	at org.springframework.integration.channel.MessageChannelTemplate.send(MessageChannelTemplate.java:179)
            	at org.springframework.integration.gateway.AbstractMessagingGateway.send(AbstractMessagingGateway.java:128)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.invokeGatewayMethod(GatewayProxyFactoryBean.java:206)
            	at org.springframework.integration.gateway.GatewayProxyFactoryBean.invoke(GatewayProxyFactoryBean.java:172)
            	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
            	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
            	at $Proxy5.placeOrder(Unknown Source)
            	at com.springintegration.Client.main(Client.java:37)

            What is the cause for this exception?...how do i change JMS response time?

            Request you to help me in this regard and also please do share if you have any sample code to implement jms gateway support.

            Awaiting response....thanks in advance.

            Comment


            • #7
              Originally posted by Mark Fisher View Post
              That's an interesting question about the byte[] class. It is possible to use 'java.lang.byte[].class' programmatically, but I believe only "java.lang.Byte[]" would work as a value in the configuration.

              However, I don't think you need a PayloadTypeRouter. As you mention, you can use 2 different methods (one for byte[] and one for String).

              To clarify "extract-payload"... if true, the message payload will be byte[]/String, but if "false", the payload will be the JMS TextMessage/ObjectMessage.
              Thanks Mark. The two different methods approach worked perfectly.

              Comment

              Working...
              X