4

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?

2 Answers 2

5

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

Sign up to request clarification or add additional context in comments.

Comments

3

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.