Search code examples
javaspringspring-integrationadapter

How enricher adapts the service activator and gateway interfaces?


My question based on official samples: Spring Integration - Enricher Sample Let's consider following xml configuration:

<int:gateway id="userGateway" default-request-timeout="5000"
                 default-reply-timeout="5000"
                 service-interface="org.springframework.integration.samples.enricher.service.UserService">
        <int:method name="findUserWithUsernameInMap" request-channel="findUserWithMapEnricherChannel"/>
</int:gateway>
<int:enricher id="findUserWithMapEnricher"
                  input-channel="findUserWithMapEnricherChannel"
                  request-channel="findUserByUsernameServiceChannel"
                  request-payload-expression="payload.username">
        <int:property name="user"    expression="payload"/>
    </int:enricher>

<int:service-activator id="findUserByUsernameServiceActivator"
                           ref="systemService" method="findUserByUsername"
                           input-channel="findUserByUsernameServiceChannel"/>

SystemService is:

public class SystemService {

    public User findUserByUsername(String username) {
            ...    
    }

}

UserService is:

public interface UserService {

    Map<String, Object> findUserWithUsernameInMap(Map<String, Object> userdata);

}

So we have 3 components:

userGateway <---> enricher <---> findUserByUsernameServiceActivator

As you can see UserService#findUserWithUsernameInMap accepts Map<String, Object> but SystemService#findUserByUsername accepts the String. So we have to convert Map to string. Looks like:

<request-payload-expression="payload.username">

is responsible for that.

Moreover SystemService#findUserByUsername returns User but UserService#findUserWithUsernameInMap returns Map<String, Object> but I don't see any place where this tranformation is happen.

So my question is where the User -> Map transformations is defined ?


Solution

  • This configuration:

    <int:enricher id="findUserWithMapEnricher"
                  input-channel="findUserWithMapEnricherChannel"
                  request-channel="findUserByUsernameServiceChannel"
                  request-payload-expression="payload.username">
        <int:property name="user"    expression="payload"/>
    </int:enricher>
    

    Can be explained like:

    1. The findUserWithMapEnricherChannel brings messages to this component as Map.
    2. The request-payload-expression="payload.username" get a value from the map by username key.
    3. This plain username value is sent to the findUserByUsernameServiceChannel
    4. The service on that channel returns a User result
    5. The expression <int:property name="user" expression="payload"/> means: add a new user entry into the request Map and store there the whole result of service calling on the findUserByUsernameServiceChannel

    Therefore into the reply in sent an original Map, but already with a new user entry. That's the main point of enricher: add something new (or modify) in the incoming payload and return it back.