I have a question regarding Gateways and multiple parameters:
The context: I would like a Gateway to have two methods:
search(Query query, FetchSpec fetchSpec);
search(int queryId, FetchSpec fetchSpec);
The first method should route directly to a service executing the query, while the second should route to another service to have the queryId resolved into a Query, and then on to the first Service to have the Query executed.
The Question: What would be best practice for having TWO (or more) parameters as arguments for a Gateway method? It seems that the entire pattern is targeted at having only one parameter corresponding the one Message. Should I use the message headers for adding extra parameters?
I guess that asking the question was forcing me to think about the problem.
The answer to my question is this:
The Gateway takes exactly ONE parameter as Payload - the rest goes to headerfields with custom names. So in my case I would do like this:
@Gateway (requestChannel = "incomingAdhocQuery")
public ResultSet search(@Payload Query query, @Header("fetchSpec") FetchSpec fetchSpec);
@Gateway (requestChannel = "incomingPersistedQuery")
public ResultSet search(@Payload int queryId, @Header("fetchSpec") FetchSpec fetchSpec);
I DEFINE which parameters are payload and which are headers.Then each method direct its messages to specific channels for service activation.
In the configuration I define my Gateway like this:
<int:gateway service-interface="my.company.search.Search" />
And then I activate the search service with one specific configuration for each gateway method:
<bean id="myManager" class="my.company.search.MyManager"/>
<int:service-activator input-channel="incomingAdhocQuery" expression="@myManager.fetchByQuery(payload, headers['fetchSpec'])"/>
<int:service-activator input-channel="incomingPersistedQuery" expression="@myManager.fetchById(payload, headers['fetchSpec'])"/>
In this way, I design my Manager like this:
public ResultSet fetchById(int queryId, FetchSpec fetchSpec) {...}
public ResultSet fetchByQuery(Query query, FetchSpec fetchSpec) {...}
I find this solution very elegant because I do not have to have any dependencies to Spring in my Service. Only the Gateway need have this dependency. The wiring is all done in the spring configuration. I think I'm in love with spring-integration :-D
You can use following on the gateway side:
@Payload("T(java.util.Arrays).asList(#args[0],#args[1])")
search(Query query, FetchSpec fetchSpec);
while on service activator if assuming it's same signature:
@ServiceActivator(inputChannel = "request", outputChannel = "reply")
search(@Payload("#this[0]") Query query, @Payload("#this[1]") FetchSpec fetchSpec)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With