Веб-сервис, помещающий сообщение Soap в очередь с Spring Integration и Jms - PullRequest
1 голос
/ 14 апреля 2020

Я хочу использовать Spring Integration для предоставления простого веб-сервиса, который помещает входящее сообщение в ActiveMQ и немедленно отвечает. Моим решением go было MarshallingWebServiceInboundGateway, подключенный к Jms.outboundAdapter с IntegrationFlow. Ниже фрагментов шлюза и IntegrationFlow. Проблема в том, что Адаптер не обеспечивает ответ (дух), который ожидает шлюз. Ответ, который я получаю от сервиса, - пустой 202 с задержкой около 1500 мс Это вызвано таймаутом ответа, который я вижу в журналах TRACE:

"2020-04-14 17:17:50.101 TRACE 26524 --- [nio-8080-exec-6] o.s.integration.core.MessagingTemplate   : Failed to receive message from channel 'org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@518ffd27' within timeout: 1000" 

Никаких жестких исключений нигде нет. Другая проблема в том, что я не могу генерировать ответ сам. Я не могу ничего добавить в IntegrationFlow после .handle с адаптером.

  1. Любой другой способ попытаться выполнить сценарий?
  2. Как, если это вообще возможно, я могу генерировать и возвращать ответ в ситуации, когда нет лучшего подхода?

Скорее всего, правильным способом было бы использовать шлюзы на обоих концах, но это невозможно. Я не могу дождаться ответа, пока сообщение в очереди не будет использовано и обработано.

'' '

@Bean
public MarshallingWebServiceInboundGateway greetingWebServiceInboundGateway() {
    MarshallingWebServiceInboundGateway inboundGateway = new MarshallingWebServiceInboundGateway(
            jaxb2Marshaller()
    );
    inboundGateway.setRequestChannelName("greetingAsync.input");
    inboundGateway.setLoggingEnabled(true);
    return inboundGateway;
}

@Bean
public IntegrationFlow greetingAsync() {
    return f -> f
            .log(LoggingHandler.Level.INFO)
            .handle(Jms.outboundAdapter(this.jmsConnectionFactory)
                    .configureJmsTemplate(c -> {
                        c.jmsMessageConverter(new MarshallingMessageConverter(jaxb2Marshaller()));
                    })
                    .destination(JmsConfig.HELLO_WORLD_QUEUE));

}

' ''

1 Ответ

1 голос
/ 14 апреля 2020

Логика c и предположения полностью верны: вы не можете вернуться после одностороннего handle() и подобного этому Jms.outboundAdapter().

Но ваша проблема в том, что вы полностью пропустили одно из первоклассные граждане в весенней интеграции - это MessageChannel. Важно понимать, что даже в потоке, подобном вашему, существуют каналы между конечными точками (методы DSL) - неявные (DirectChannel), как в вашем случае, или явные: когда вы используете channel() между ними и можете разместить там любая возможная реализация: https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java -dsl-channel

Одной из важнейших реализаций канала является PublishSubscribeChannel (topic в спецификации JMS), когда вы можете отправить одно и то же сообщение к нескольким подписанным конечным точкам: https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/core.html#channel -implementations-publishsubscribechannel

В вашем случае подписчик кулаков должен быть вашим существующим, односторонним Jms.outboundAdapter(). И еще что-то, что будет генерировать ответ и отправлять его в заголовок replyChannel.

Для этой цели Java DSL обеспечивает удобный перехват через конфигурацию подпотоков: https://docs.spring.io/spring-integration/docs/5.3.0.M4/reference/html/dsl.html#java -dsl -subflows

Итак, некоторый пример publi sh -subscriber может выглядеть следующим образом:

.publishSubscribeChannel(c -> c
                        .subscribe(sf -> sf
                                  .handle(Jms.outboundAdapter(this.jmsConnectionFactory))))
.handle([PRODUCE_RESPONSE])
...