Announcement Announcement Module
Collapse
No announcement yet.
Problems with Gateways Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems with Gateways

    I am using the 2.0.0.BUILD-SNAPSHOT version of Spring Integration. (but it does not work with 2.0.0.M4 either)

    After inserting two connectionFactories into one XML configuration I reconfigured my application and its JMS gateways so that they don't interfere and use the right factory.

    My remote calls are made through a gateway implementing a given interface named "ServiceGateway".

    Code:
    protected SendGateway sendGateway; //see Gateway-Def. in XML
    ...
    public Long getDBiNumber() {
    	Message m = MessageBuilder.withPayload("")
    		.setHeader("serviceMethod", "getDBiNumber").build();
    	return (Long) sendGateway.toRemoteGateway(m).valueMap.get("result");
    }
    The following code shows the part of my XML configuraiton dealing with outbound JMS-Messages and the described Gateway.
    Code:
    <!-- needed Channels -->
    <int:channel id="dbmasterToJmsChannel">
    	<int:queue capacity="20"/>
    </int:channel>
    <int:channel id="dbmasterJmsReplyChannel">
    	<int:queue capacity="20"/>
    </int:channel>
    <int:channel id="dbmasterJmsReplyChannelUnfiltered">
    	<int:queue capacity="20"/>
    </int:channel>
    
    <!-- Outbound JMS-Gateway -->
    <int-jms:outbound-gateway id="dbmasterJmsout"
      request-channel="dbmasterToJmsChannel"
      reply-channel="dbmasterJmsReplyChannelUnfiltered"
      request-destination="dbmasterRequestQueue"
      reply-destination="dbmasterDbEndpointQueue"
      connection-factory="dbmasterConnectionFactory"/>
    
    <!-- Gateway for remote actions -->
    <int:gateway id="dbmasterRemotingSendGateway" service-interface="de.mpg.mis.neuesbibliothekssystem.dbmaster.remote.messaging.SendGateway">
    	<int:method name="toRemoteGatewayNative" request-channel="dbmasterToJmsChannel" reply-channel="dbmasterJmsReplyChannel"/>
    	<int:method name="toRemoteGateway" request-channel="dbmasterToJmsChannel" reply-channel="dbmasterJmsReplyChannel"/>
    	<int:method name="toRemote" request-channel="dbmasterToDirectJmsChannel"/>
    </int:gateway>
    
    <!-- Routing of the Exceptions -->
    <int:payload-type-router input-channel="dbmasterJmsReplyChannelUnfiltered" default-output-channel="dbmasterJmsReplyChannel">
    	<int:mapping type="java.lang.Exception" channel="errorChannel"/>
    	<int:mapping type="org.springframework.integration.message.MessageHandlingException" channel="errorChannel"/>
    </int:payload-type-router>
    ...
    After calling the mentioned method I get this ERROR message:
    Code:
    2010-08-25 16:31:46,194 [taskScheduler-3] DEBUG org.springframework.integration.channel.DirectChannel - postSend (sent=true) on channel 'logger', message: [Payload=result: (java.lang.Long) 0
    ][Headers={$jms_redelivered=false, serviceMethod=getDBiNumber, $timestamp=1282746705709, $history=[channel:dbmasterJmsReplyChannelUnfiltered, channel:logger, logging-channel-adapter:logger.adapter, channel:dbmasterJmsReplyChannel, channel:logger, logging-channel-adapter:logger.adapter], $jms_correlationId=ID:bibdev-4793-1282746704038-0:0:2:1:1, $jms_messageId=ID:bibdev-4772-1282746646864-0:0:1:1:1, $jms_replyTo=queue://qBdbmaster, $id=51674114-a3da-457e-872c-1f09ed8640ad}]
    2010-08-25 16:31:46,194 [taskScheduler-3] DEBUG org.springframework.integration.channel.QueueChannel - postSend (sent=true) on channel 'dbmasterJmsReplyChannel', message: [Payload=result: (java.lang.Long) 0
    ][Headers={$jms_redelivered=false, serviceMethod=getDBiNumber, $timestamp=1282746705709, $history=[channel:dbmasterJmsReplyChannelUnfiltered, channel:logger, logging-channel-adapter:logger.adapter, channel:dbmasterJmsReplyChannel, channel:logger, logging-channel-adapter:logger.adapter], $jms_correlationId=ID:bibdev-4793-1282746704038-0:0:2:1:1, $jms_messageId=ID:bibdev-4772-1282746646864-0:0:1:1:1, $jms_replyTo=queue://qBdbmaster, $id=51674114-a3da-457e-872c-1f09ed8640ad}]
    2010-08-25 16:31:46,194 [taskScheduler-5] DEBUG org.springframework.integration.channel.QueueChannel - postReceive on channel 'dbmasterJmsReplyChannel', message: [Payload=result: (java.lang.Long) 0
    ][Headers={$jms_redelivered=false, serviceMethod=getDBiNumber, $timestamp=1282746705709, $history=[channel:dbmasterJmsReplyChannelUnfiltered, channel:logger, logging-channel-adapter:logger.adapter, channel:dbmasterJmsReplyChannel, channel:logger, logging-channel-adapter:logger.adapter], $jms_correlationId=ID:bibdev-4793-1282746704038-0:0:2:1:1, $jms_messageId=ID:bibdev-4772-1282746646864-0:0:1:1:1, $jms_replyTo=queue://qBdbmaster, $id=51674114-a3da-457e-872c-1f09ed8640ad}]
    2010-08-25 16:31:46,194 [taskScheduler-5] DEBUG org.springframework.integration.handler.BridgeHandler - org.springframework.integration.handler.BridgeHandler@e265d0 received message: [Payload=result: (java.lang.Long) 0
    ][Headers={$jms_redelivered=false, serviceMethod=getDBiNumber, $timestamp=1282746705709, $history=[channel:dbmasterJmsReplyChannelUnfiltered, channel:logger, logging-channel-adapter:logger.adapter, channel:dbmasterJmsReplyChannel, channel:logger, logging-channel-adapter:logger.adapter], $jms_correlationId=ID:bibdev-4793-1282746704038-0:0:2:1:1, $jms_messageId=ID:bibdev-4772-1282746646864-0:0:1:1:1, $jms_replyTo=queue://qBdbmaster, $id=51674114-a3da-457e-872c-1f09ed8640ad}]
    2010-08-25 16:31:46,194 [taskScheduler-5] ERROR org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task.
    org.springframework.integration.message.MessageHandlingException: error occurred in message handler [org.springframework.integration.handler.BridgeHandler@e265d0]
    	at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:69)
    	at org.springframework.integration.endpoint.HandlerInvocationChain.handleMessage(HandlerInvocationChain.java:58)
    ...
    Caused by: java.lang.IllegalStateException: Bridge handler requires an output channel
    	at org.springframework.util.Assert.state(Assert.java:384)
    ...
    Does someone know how I can fix this?

  • #2
    Remove reply-channel="dbmasterJmsReplyChannelUnfiltered" from your JMS gateway config

    Comment


    • #3
      thank you for the quick reply, Oleg.
      The only question is on which channel the reply from the server will arrive. I thought I need the reply-channel for that.
      Sry, maybe I just do not get it ... actually I suppose it is like that

      Tobias

      Comment


      • #4
        First did it work?


        Here is what's happening:
        In your config JmsOutboundGateway upon receiving the reply will forward it to 'dbmasterJmsReplyChannelUnfiltered' channel. Your Gateway expects a reply on 'dbmasterJmsReplyChannel' so there is a disconnect.

        Over all you rarely have to specify reply channels on the Gateways since it auto-creates the reply channel and sets it as $replyChannel header. This means that JmsOutboundGateway upon receiving of the message will forward reply to that channel.
        The only time you really need a reply channel configured explicitly is when you want to make it a pub-sub channel and have additional subscriber to it.

        So you can actually remove reply-channel from both Gateway and JmsOutboundGateway

        IO hope that explains

        Comment


        • #5
          I was not able to test it so far but I will tell you immediately

          I thought I could use te reply-channel for filtering. That's why I put the payload-type-router in my configuration. It is aimed to simply log exceptions and to keep them away from my gateway.
          I thought I could link the gateway and the jms-gateway through this step. (and, to my opinion, the log is telling me that the message reached the dbmasterJmsReply channel).
          Is there a better way of redirecting the exception messages?
          Tobias

          Comment


          • #6
            The main issue with using Gateway is that the entire message exchange is hidden behind the simple method call and as a developer whenever you execute a method you don't expect it to hang. So in a way Gateways are good when you can always guarantee that for each request there will be a response. And if some error happened along the way, such error will be re-thrown back to the user as runtime exception, thus guaranteeing a response (good or bad).
            In your configuration that guarantee is broken since if payloads are of type exception they will be rerouted to different channels therefore reply will never get back to the gateway and your gateway method call will hang until it times out.
            Of course you can use your approach of filtering messages, there is nothing wrong with it and there is nothing wrong with the two statements you made in your last reply.

            So in a way i am questioning if using Gateway as an entry point is the right solution for you considering asynchronous and multidirectional nature of your message exchange as per your configuration.

            We also have a new attribute on the gateway we just implemented and since you are using snapshot build you should be able to try it.
            The attribute is exception-mapper
            See https://src.springsource.org/svn/spr...dlerTests.java
            and
            https://src.springsource.org/svn/spr...ts-context.xml
            The purpose of this attribute is to allow user to intercept the exception and convert it to a Message so it could return successfully. This way you always have some meaningful result.

            Comment


            • #7
              You are definitely right and I used this way of channeling the exceptions for debugging purposes. I wanted to know, where the exceptions come from and this was a quick but dirty way to do so (and it worked at some stage ... )
              I tried your advise and it worked for me. Thank you for that. I really appreciate your work at this forum and I am so glad that the Spring Team is so dedicated to the user and really cares about his or her problems. You are great!
              I still think that my code should work, as well, but maybe it is better to use the time to check out this exception-mapper and find a way to use it for my purposes.

              Thanks again.
              Tobias

              *big sigh*

              Comment

              Working...
              X