Page 3 of 3 FirstFirst 123
Results 21 to 26 of 26

Thread: TCP client Gateway - but need to handle unsolicited TCP server responses

  1. #21

    Default

    Here is the current set up if it helps :

    Code:
                 <int:gateway id="barxServerGateway"	 service-interface="MyServerGateway"
                         default-request-channel="toErrorCatchingGw"/>
    	<int:service-activator input-channel="toErrorCatchingGw" ref="errorCatchingGw"/>
    	<int:gateway id="errorCatchingGw" error-channel="errorObject"
    				 default-request-channel="requestObject"/>
    
    	<!-- Channels -->
    	<int:publish-subscribe-channel id="requestTcp"/>
    
                 <int-ip:tcp-connection-factory id="clientConnectionFactory" type="client" single-use="false" using-nio="true"/>
    
    	<!-- Outbound adapter - Send requests -->
    	<int-ip:tcp-outbound-channel-adapter channel="requestTcp" connection-factory="clientConnectionFactory" order="2"/>
    
    	<!-- Inbound adapter - Receive asynchronous replies -->
    	<int-ip:tcp-inbound-channel-adapter channel="responseTcp" connection-factory="clientConnectionFactory"/>
    
    	<!-- Use bridge to also send all requests to the aggregator where they will stay blocked,
    		 waiting for a response -->
    	<int:bridge input-channel="requestTcp" output-channel="toAggregator" order="1"/>
    
    	<!-- Aggregator matches incoming responses to the blocked requests and releases them -->
    	<int:aggregator input-channel="toAggregator" output-channel="aggregatedResponseObject"
    					expire-groups-upon-completion="true" release-strategy="customCorrelator"
    					correlation-strategy="customCorrelator"/>
    
    	<!-- Extract the second object - the response -->
    	<int:transformer input-channel="aggregatedResponseObject" expression="payload.get(1)"/>
    
    	<int:filter input-channel="errorObject" ref="connectionManager" method="filterException"
    				discard-channel="nonResponseException"/>
    
    	<!-- Handle any not yet handled exceptions -->
    	<int:transformer input-channel="nonResponseException" ref="connectionManager"
    					 method="handleException"/>
    It is based on the collaborative adapter example...

    And here are the request / response processing chains :
    Code:
                  <int:chain input-channel="requestObject" output-channel="requestTcp">
    
    		<!-- populate some headers, so that we can use them during further transformation -->
    		<int:header-enricher>
    			<int:header name="messageId" ref="requestHeaderEnricher"
    						method="readIncrementedMessageId"/>
    		</int:header-enricher>
    
    		<!-- Convert request object into XML via JAXB -->
    		<int-xml:marshalling-transformer marshaller="jaxbMarshaller" result-type="StringResult"/>
    
    		<!-- Convert JAXB DOM into a string -->
    		<int:object-to-string-transformer/>
    
    		<!-- Transform XML string via XSLT - add a Message envelope -->
    		<int-xml:xslt-transformer xsl-resource="request.xsl" xslt-param-headers="messageId"/>
    
    		<!-- Add a binary message envelope -->
    		<int:transformer ref="binaryTransformer" method="marshall"/>
    	</int:chain>
    
              <int:chain input-channel="responseTcp" output-channel="toAggregator">
    
    		<!-- Convert response object from byte array into a String -->
    		<int:transformer expression="new String(payload)"/>
    
    		<!-- Enrich some headers -->
    		<int-xml:xpath-header-enricher>
    			<int-xml:header name="messageId" evaluation-type="STRING_RESULT"
    							xpath-expression="Message/Header/@msgid"/>
    		</int-xml:xpath-header-enricher>
    
    		<!-- Transform XML string via XSLT - strip the Message envelope -->
    		<int-xml:xslt-transformer xsl-resource="response.xsl"/>
    
    		<!-- Convert response XML into objects via JAXB -->
    		<int-xml:unmarshalling-transformer unmarshaller="jaxbMarshaller"/>
    
    		<!-- Filter out incoming heartbeats/pings -->
    		<int:filter ref="connectionManager" method="filterPing"/>
    
    		<!-- Transform any errors into exceptions, and mark them as handled -->
    		<int:transformer ref="connectionManager" method="transformPotentialError"/>
    
    	</int:chain>
    Last edited by matt_koss; Jan 25th, 2013 at 04:51 AM.

  2. #22
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,016

    Default

    I am not sure why you had to post this 4 times - the first 3 went into "moderation" mode (I have now deleted them), but this one didn't need moderation for some reason; go figure.

    Anyway - you have changed your error flow from what it was back in your post #12 (in which it looked correct - the errorObject channel connected to a transformer, and thence to the aggregator).

    Now, your errorObject channel connects to a filter, which either returns the message to the gateway (it has no output-channel), or sends it to nonResponseException which is connected to a transformer which, again, has no output-channel, so its result goes back to the gateway.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  3. #23
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,016

    Default

    By the way, we arrived at all this complexity in response to your question #12 - how to get the error message to the aggregator to release the group.

    Rather than walking you though how to do what you asked, I should have offered you an alternative - that's simpler.

    You can simply configure a MessageGroupStoreReaper to "clean up" the uncorrelated messages that are hanging in the aggregator waiting for a response that won't come because of the connection problem. In that case, you wouldn't need the "double gateway" technique to handle the error.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  4. #24
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,016

    Default

    Yet another alternative would be to reverse the "order" attributes on the adapter/bridge. That way, the request won't go to the aggregator if the send over TCP fails. However, this would make the transformer after the aggregator more complicated - because it will have to deal with the condition that the reply might arrive at the aggregator before the request.

    Finally, it's probably a good idea to configure a reaper, regardless of which solution you end up with - you could possibly still have a hanging request if the send was successful, but the server crashes before the reply is received.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

  5. #25

    Default

    Quote Originally Posted by Gary Russell View Post
    I am not sure why you had to post this 4 times - the first 3 went into "moderation" mode (I have now deleted them), but this one didn't need moderation for some reason; go figure.

    Anyway - you have changed your error flow from what it was back in your post #12 (in which it looked correct - the errorObject channel connected to a transformer, and thence to the aggregator).

    Now, your errorObject channel connects to a filter, which either returns the message to the gateway (it has no output-channel), or sends it to nonResponseException which is connected to a transformer which, again, has no output-channel, so its result goes back to the gateway.
    I thought something went wrong with the sending
    Didn't realize that you have a "moderation" mode... good to know now.

  6. #26
    Join Date
    Mar 2010
    Location
    Gtr Philadelphia, PA
    Posts
    2,016

    Default

    Yeah - we seem to have more posts that need approval these days - maybe some words trigger it, I don't know - I'll check with the admins.
    Gary P. Russell
    Spring Integration Team
    SpringSource, a division of VMware

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •