Announcement Announcement Module
Collapse
No announcement yet.
TCP client Gateway - but need to handle unsolicited TCP server responses Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Yes, I have done that now, thanks.
    I only spotted after my post that is was DEBUG level (got confused as the stack trace was was being logged too).

    I very much appreciate your quick responses.

    Comment


    • #17
      No problem - I opened a JIRA ticket... https://jira.springsource.org/browse/INT-2900

      Comment


      • #18
        BTW, in the error scenario above, with regard to the original request message that is in the aggregator... What happens to that ?
        Error seems to come back to the caller, so does the request message expire inside the aggregator independently ?

        Comment


        • #19
          The aggregator releases both messages in the released message (with the payload being a List<?>). Your transformer (get(1)) transforms the List<?> to the second payload and the first is simply discarded.

          This is true whether the second message is the response, or the ErrorMessage.

          Comment


          • #20
            That part I understand. However, in case of the above error, as it is not routed back into the aggregator, how can it "release" the group ?
            I can confirm, that during the debugging, in case of the connectivity error, the exception / ErrorMessage does not come into the aggregator and my release strategy does not get invoked :
            Code:
            	@ReleaseStrategy
            	public boolean isReadyToRelease(List<Message<?>> messages)
            	{
            		return messages.size() == 2;
            	}

            Comment


            • #21
              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, 04:51 AM.

              Comment


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

                Comment


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

                  Comment


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

                    Comment


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

                      Comment


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

                        Comment

                        Working...
                        X