响应通过Rest Api在多个出站网关调用之间传递的消息

时间:2018-02-13 20:38:17

标签: spring-integration

我有一个入站网关,它通过Rest接收消息。收到的所有邮件都会进入内部网关。下面是入站网关xml文件。

 <bean name="testConfig" class="test.TestApiConfiguration"/>
    <context:annotation-config/>

    <int-http:inbound-gateway request-channel="requestChannel" supported-methods="POST" path="/data" reply-channel="replyChannel"
                              request-payload-type="com.test.model.CallFlow" header-mapper="cc20InBoundHeaders" error-channel="errorChannel" reply-timeout="9000">
        <int-http:request-mapping produces="application/json" consumes="application/json"/>
    </int-http:inbound-gateway>

    <bean id="cc20InBoundHeaders" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
        <property name="inboundHeaderNames" value="*"/>
    </bean>

    <bean id="cc20OutBoundHeaders" class="org.springframework.integration.http.support.DefaultHttpHeaderMapper">
        <property name="outboundHeaderNames" value="Content-Type, HTTP_REQUEST_HEADERS"/>
        <property name="userDefinedHeaderPrefix" value="" />
    </bean>

因此,入站网关消息正确地以Json形式到达,然后内部网关接受它们,并且消息按照配置传递到通道中。

@MessagingGateway(name="callFlowGateway", requestChannel = "callFlowRequestChannel")
public interface ICallFlow {

    /**
     * Process CallFlow Request
     * @param message SI Message covering APiCall payload and relevant headers for service
     */
    @Gateway
    void processCallFlowRequest(Message<CallFlow> message);

}

直到这里,它按预期工作。消息流向Filter,然后流向路由器。在Router中,如果一个json属性的类型是“drink”服务,则调用drink channel并调用相关的出站网关以通过REST请求外部API端点。

但是在调用该外部API的每个其他端点之前,您需要有一个有效的会话ID令牌来访问其他端点。它在其有效负载中返回会话ID以调用其他端点除此之外,它将application / x-www-form-urlencoded作为内容键入标头。 我创建了一个转换器来创建身份验证服务请求。

@MessageEndpoint               
public class AuthenticateTransformer {

    @Transformer(inputChannel = "splitterChannel", outputChannel = "authenticateRequestChannel")
    public Message<?> transform(CallFlow callFlow) {

        Map<String, Object> messagePayload = new HashMap<String, Object>();
        messagePayload.put("user", "test");
        messagePayload.put("password", "test");
        return MessageBuilder.withPayload(messagePayload).setHeader("Content-Type", "application/x-www-form-urlencoded").build();
        }
}

所以,理想情况下,呼叫进入入站网关 - Json被转换为内部对象。根据JSON中的一个属性值,我使用http出站网关调用不同的外部休息端点。

由于获取会话ID的身份验证调用不在收到的Json中,因此我必须在流程中创建一个订单。

  1. 我需要调用http出站网关进行身份验证才能获取该会话ID。如何从入站网关调用此出站,因为应该在每次调用其他端点之前执行该出站。

  2. 在我得到那个会话ID后,我希望其他端点超过Rest,在这个阶段,我希望调用ICallFlow网关,以便基于json中的值,以及来自步骤1的会话ID,i可以调用其他休息端点并获得回复。

  3. 那么,我被困在将第一次呼叫的会话ID令牌传递给第二次呼叫?我希望只在第一次身份验证请求完成后调用ICallFlow,并将该会话传递给其他后续请求。我读过,标题扩充器可以做到这一点,我可以将有效负载放入标题,但不知何故它不起作用。此外,我不知道如何以正确的顺序创建上述流程。

    任何帮助都将受到高度赞赏。

1 个答案:

答案 0 :(得分:0)

你在单个帖子中的信息太多,而且它有点令人困惑和误导。

我建议您使用ContentEnricherhttps://docs.spring.io/spring-integration/docs/5.0.1.RELEASE/reference/html/messaging-transformation-chapter.html#payload-enricher

因此,您将通过request-channel子流程调用该身份验证服务,获取会话ID,并且如果可能的话,将能够将其填充到标头或ICallFlow有效负载中。

您应该谨慎使用MessageBuilder用例中的@Transformer。那个之后不会合并请求标头,您将无法在开始时对<int-http:inbound-gateway>做出响应,只是因为replyChannel标头将丢失。

接收请求标头的方式就像在Message方法中接受transform()并在copyHeaders()上调用MessageBuilder