jeudi 26 février 2015

Spring Integration: individual timeouts settings for connections in the same pool

We've got an application written in Java that uses Spring Integration. The application sends requests to 3d-party service, each request is represented as byte array and is sent via plain TCP. Connections to the 3d-party are stored in a pool (CachingClientConnectionFactory is used).


There are several types of requests that we can send to the 3d-party, and now there is a need to have different timeout values for each type of requests. However, right now this looks problematic, as far as connection timeout settings are set for Gateway and ConnectionFactory components, and there is no way to setup connection timeout for a particular single request.


We would like to avoid introducing multiple gateways and connection factories just to support different connection timeouts.


Channel & Gateway configuration



<int:channel id="myInput" />

<int:gateway id="myGateway"
service-interface="com.mypackage.TcpGateway"
default-request-channel="myInput"/>

<int-ip:tcp-outbound-gateway id="myOutGateway"
request-channel="mybInput"
reply-channel="clientBytesChannel"
connection-factory="myConnectionFactory"
request-timeout="${conn.timeout}"
remote-timeout="${conn.timeout}"/>


TcpGateway.java



package com.mypackage.TcpGateway;

public interface TcpGateway {
byte[] send(byte[] message);
}


RequestProcessor.java



public class RequestProcessors {
@Autowired
private TcpGateway myGateway;

public MyResponse process(MyRequest requestMessage) {
byte[] binaryMessage = transformRequest(requestMessage);
byte[] response = myGateway.send(binaryMessage);
return transformResponse(response);
}

// rest of business logic here
}


Looking at the source code above, it seems that the simplest way could be to extend native component TcpOutboundGateway and replace property remoteTimeout with a singleton bean that holds timeout settings as a ThreadLocal variable. Then it will be possible to set necessary value based on the request type in RequestProcessors.process() method just before the request is passed to myGateway.send().


However, I was not able to find an elegant way to redefine TcpOutboundGateway component using my custom class. After analyzing source code of Spring Integration, it seems that TcpOutboundGateway doesn't know anything about input request, but is registered in a chain of message processors and is called whenever it is required. So, right now this doesn't look like a simple solution.


If you have any ideas how to change the class that is used by tag <int-ip:tcp-outbound-gateway>, or if you have any ideas how the main timeout problem could be resolved in a completely different way, please advise.


Thank you.


Aucun commentaire:

Enregistrer un commentaire