Какой хороший способ зарегистрировать смежные HTTP-запросы с помощью потока интеграции Spring

Каков хороший способ зарегистрировать смежные HTTP-запросы в потоке интеграции Spring?

Мое приложение:

Для каждого покупателя (есть свой поток, запуск которого назначает опросчик)

  • Операция GET 1 в исходном приложении, результат - JSON_1.
  • POST JSON_1 в удаленную систему, и результат будет JSON_1B
  • POST JSON_1B в исходное приложение, и результат будет JSON_1C
  • Операция GET 2 в исходном приложении, результат - JSON_2.
  • POST JSON_2 в удаленную систему, и результат будет JSON_2B
  • POST JSON_2B в исходное приложение, и результат будет JSON_2C

...

  • Операция GET n в исходном приложении, результат - JSON_N
  • POST JSON_N в удаленную систему, и результат будет JSON_NB
  • POST JSON_NB в исходное приложение, и результат будет JSON_NC

Операции 1, 2, ..., n должны быть в порядке

Вот мой пример программы (для простоты все вызовы REST относятся к одному и тому же классу)

@Configuration
public class ApplicationConfiguration {

@Autowired
private IntegrationFlowContext flowContext;

@Bean
public MethodInvokingMessageSource integerMessageSource() {
    final MethodInvokingMessageSource source = new MethodInvokingMessageSource();
    source.setObject(new AtomicInteger());
    source.setMethodName("getAndIncrement");
    return source;
}

@PostConstruct
public void createAndRegisterFlows() {
    IntegrationFlowBuilder integrationFlowBuilder = createFlowBuilder();
    for (int i = 1; i <= 2; i++) {
        integrationFlowBuilder = flowBuilder(integrationFlowBuilder, i);
    }
    integrationFlowBuilder.handle(CharacterStreamWritingMessageHandler.stdout());
    flowContext.registration(integrationFlowBuilder.get()).register();
}

private IntegrationFlowBuilder createFlowBuilder() {
    return IntegrationFlows.from(this.integerMessageSource(), c -> c.poller(Pollers.fixedRate(5000)));
}

private IntegrationFlowBuilder flowBuilder(final IntegrationFlowBuilder integrationFlowBuilder, final int number) {
    return integrationFlowBuilder
            .handle(Http.outboundGateway("http://localhost:8055/greeting" + number).httpMethod(HttpMethod.GET)
                    .expectedResponseType(String.class))
            .channel("getReceive" + number)
            .handle(Http.outboundGateway("http://localhost:8055/greeting" + number).httpMethod(HttpMethod.POST)
                    .expectedResponseType(String.class))
            .channel("postReceive" + number)
            .handle(Http.outboundGateway("http://localhost:8055/greeting-final" + number)
                    .httpMethod(HttpMethod.POST).expectedResponseType(String.class))
            .channel("postReceiveFinal" + number);
}
}

Эта программа запускает процесс интеграции

GET http://localhost:8055/greeting1
POST http://localhost:8055/greeting1 (previous result as an input)
POST http://localhost:8055/greeting-final1 (previous result as an input)
GET http://localhost:8055/greeting2
POST http://localhost:8055/greeting2 (previous result as an input)
POST http://localhost:8055/greeting-final2 (previous result as an input)

Это работает, как ожидалось. Но мне интересно, это хороший способ сделать это, потому что ответ от вызова POST http://localhost:8055/greeting-final1 не используется в вызове GET http://localhost:8055/greeting2. Я только хочу, чтобы эти звонки были в таком порядке.


person Mike    schedule 01.10.2018    source источник


Ответы (1)


На самом деле у вас есть все необходимое с этим циклом для создания вызовов подпотока к службам REST. Вам не хватает только payload в результате greeting-final1, который будет опубликован с сообщением для .channel("postReceiveFinal" + number). Вторая итерация подпишет greeting2" на этот канал, и payload будет доступен для обработки здесь. Не знаете, как переделать ваш flowBuilder() метод, но вам просто нужно использовать payload из сообщения для любых ваших требований, например вы можете использовать его как:

/**
 * Specify an {@link Expression} to evaluate a value for the uri template variable.
 * @param variable the uri template variable.
 * @param expression the expression to evaluate value for te uri template variable.
 * @return the current Spec.
 * @see AbstractHttpRequestExecutingMessageHandler#setUriVariableExpressions(Map)
 * @see ValueExpression
 * @see org.springframework.expression.common.LiteralExpression
 */
public S uriVariable(String variable, Expression expression) {

чтобы добавить полезную нагрузку в какой-либо параметр запроса, поскольку он всего лишь HttpMethod.GET:

handle(Http.outboundGateway("http://localhost:8055/greeting2?param1={param1}")
        .httpMethod(HttpMethod.GET)
        .uriVariable("param1", "payload")
        .expectedResponseType(String.class))
person Artem Bilan    schedule 01.10.2018
comment
Результат от POST до приветствия-final1 не требуется в GET welcome2. Я хочу, чтобы в заказе были только операции 1, 2 .. n. Эта технология для меня нова, и мне просто было интересно, есть ли у меня хорошее решение. - person Mike; 02.10.2018
comment
Нет, тогда решение не подходит. Вам нужно взглянуть на PublishSubscribeChannel или RecipientListRouter - person Artem Bilan; 02.10.2018
comment
Я так считаю, что эти занятия не решение. Я попытался выделить свое решение и отредактировал первоначальный вопрос. Я выполняю смежные операции, которые должны выполняться в определенном порядке. Но после завершения некоторого набора из трех операций вывод не используется в следующем наборе из трех операций. Например, JSON_1C не используется в операции GET operation 2. IntegrationFlowBuilder работает отлично, и в настоящее время у меня нет никаких проблем, но я думал, что мое решение хорошее. - person Mike; 02.10.2018
comment
Как я сказал вам: согласно вашей логике цикла результат последнего POST доступен для следующего GET. В этом цикле вы по-прежнему составляете тот же IntegrationFlow, и все идет последовательно. Не уверен, что вам не хватает, но вы просто не используете этот результат. Это все. Если вы беспокоитесь о заказе, то вам хорошо. - person Artem Bilan; 02.10.2018
comment
В моем примере GET operation 2 не требуется JSON_1C. Я так думаю, что все ок. GET, POST и POST внутри одной операции находятся в последовательности, а все операции 1, 2, 3 ... находятся в последовательности. Спасибо :-) - person Mike; 03.10.2018