Путь Spring Integration Outbound Gate для синхронных вызовов REST - PullRequest
0 голосов
/ 25 июня 2018

Ранее я мог разработать небольшую платформу с использованием Spring Integration, где разработчики могли указывать URL-адреса, методы HTTP и тело запроса и вызывать любой внешний REST API.

Это конфигурация для моей Spring Integration

<int:channel id='reply.channel'>
    <int:queue capacity='10' />
</int:channel>
<int:channel id='request.channel'/>

<int:channel id='outbound.Channel'/>

<int:gateway id="outboundGateway"
    service-interface="com.bst.pm.PostGateway"
    default-request-channel="outbound.Channel">
</int:gateway>

<int:object-to-json-transformer input-channel="outbound.Channel" output-channel="request.channel"/>



<int-http:outbound-gateway id="outbound.gateway"
    request-channel="request.channel" url-expression="headers.bstUrl"
    http-method-expression="headers.bstHttpMethod" expected-response-type-expression="headers.bstExpectedResponseType"
    charset="UTF-8" reply-timeout="5000" reply-channel="reply.channel"
    mapped-request-headers="bst*, HTTP_REQUEST_HEADERS">

</int-http:outbound-gateway>

Затем разработчики могут вызывать внешние API-вызовы rest, используя описанное выше инфраструк-троны, как показано ниже

@Autowired @Qualifier("reply.channel") PollableChannel receivedChannel;
@Autowired @Qualifier("request.channel") MessageChannel getRequestChannel;
@Autowired @Qualifier("outbound.Channel") MessageChannel httpOutboundGateway;

    Post post = new Post();
    post.setTitle("Spring INtegration Test");
    post.setBody("This is a sample request body to test Spring Integration HTTP Outbound gateway");
    post.setUserId(Long.valueOf(1));

    Message<?> message = MessageBuilder.withPayload(post)
                        .setHeader("bstUrl", "https://jsonplaceholder.typicode.com/posts")
                        .setHeader("bstHttpMethod", "POST")
                        .setHeader("bstExpectedResponseType", "com.bst.pages.crm.web.Post")
                         .build();

    httpOutboundGateway.send(message);
    Message<?> receivedMsg = receivedChannel.receive();

    Post post = (Post) receivedMsg.getPayload();
    System.out.println("############## ServerMsg ##############");
    System.out.println(o);
    System.out.println("############## Done! ##############");

Здесь я хочу сделать все REST-вызовы через эту инфраструктуру интеграции синхронными.Однако я использовал канал QUEUE в качестве канала ответа для http: outbound-gateway.Поэтому, насколько я понимаю, ответ может быть получен не тем отправителем, поскольку любой может объединить канал для сообщений.

Как мы можем быть уверены, что правильный отправитель всегда получит правильный ответ?

Спасибо, Кет

1 Ответ

0 голосов
/ 25 июня 2018

Вы правы. Реально имея глобальный канал ответа и несколько параллельных процессов, вы можете столкнуться с ситуацией кражи работы.

Чтобы решить вашу проблему, вам нужно избавиться от reply-channel на вашем HTTP-шлюзе и просто положиться на заголовок replyChannel, заполненный Messaging Gateway. Однако ваш метод Gateway действительно должен быть подписью запроса-ответа: он должен возвращать Object.

Подробнее о заголовке replyChannel см. В Справочном руководстве: https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#gateway

...