Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring integration service activator not sending null reply

I have a very simple integration flow:

    <int:gateway id="integrationGateway"
                 service-interface="com.wheeler.fits.returns.messaging.MessagingGateway"
                 default-request-channel="transactionMatcher">
        <int:method name="publishReturnedTransaction" request-channel="transactionMatcher"/>
    </int:gateway>

    <int:channel id="transactionMatcher"/>
    <int:service-activator input-channel="transactionMatcher" requires-reply="true">
        <bean class="com.wheeler.fits.returns.domain.MatchTransactionToOriginal">
            <constructor-arg ref="achTransactionMapper"/>
            <constructor-arg ref="bankTransactionDao"/>
            <constructor-arg ref="clientMapper"/>
            <constructor-arg ref="oldAchTransactionMapper"/>
        </bean>
    </int:service-activator>

The method the service activator is calling attempts to match the data in the message with some data in the DB. If it does, it returned the matched data. If it does not, it will return null.

If I do not set required-reply=true, the null replies just seem to evaporate out of the integration flow, resulting in the service interface to never return causing the app to hang. If I do set required-reply=true, I at least get an exception, but the app still hangs because the service interface for the gateway never returns:

[org.springframework.integration.handler.ReplyRequiredException: No reply produced by handler 'org.springframework.integration.config.ServiceActivatorFactoryBean#0', and its 'requiresReply' property is set to true.,

It doesn't seem like this behavior is documented anywhere in spring integration reference material. I want my service activator to pass the null back to the gateway so the gateway can reply with a null.

This is my service interface for the gateway:

public interface MessagingGateway {

    RawMessageData publishReturnedTransaction(ReturnedTransactionData returnedTransactionData) throws ChannelPublishException;
}

How do I get it to handle the null like any other message?

like image 584
wheeler Avatar asked Apr 20 '17 16:04

wheeler


People also ask

What is ServiceActivator annotation?

The Service Activator is any POJO that defines the @ServiceActivator annotation on a given method. This allows us to execute any method on our POJO when a message is received from an inbound channel, and it allows us to write messages to an outward channel.

What is service activator in Spring Integration?

The service activator is the endpoint type for connecting any Spring-managed object to an input channel so that it may play the role of a service. If the service produces output, it may also be connected to an output channel.

Is Service Activator pattern addresses the integration layer?

The service activator design pattern is one of the Java EE patterns. It is an SI (spring integration) component. It is responsible for triggering or activating a service object or bean which is managed by the spring. A service activator searches through the message channel in order to look for messages.

What is Spring Integration message?

The Spring Integration Message is a generic container for data. Any object can be provided as the payload, and each Message instance includes headers containing user-extensible properties as key-value pairs.


1 Answers

There is some info on the matter in the Service Activator chapter:

The Service Activator is one of those components that is not required to produce a reply message. If your method returns null or has a void return type, the Service Activator exits after the method invocation, without any signals. This behavior can be controlled by the AbstractReplyProducingMessageHandler.requiresReply option, also exposed as requires-reply when configuring with the XML namespace. If the flag is set to true and the method returns null, a ReplyRequiredException is thrown.

You also can find some discussion in JIRA.

Generally speaking, the null payload does not make sense in the messaging and must be treated as terminal signal or error like in case of ReplyRequiredException.

For your use-case you should consider to return some RawMessageData instance from your service activator which you can treat as a null.

like image 141
Artem Bilan Avatar answered Sep 30 '22 02:09

Artem Bilan