异步拆分/聚合网关流

时间:2018-09-27 21:55:27

标签: spring-integration

我正在尝试使用Spring集成网关(入站和出站)为异步编排构建配方。看完示例here之后,我尝试使用分散采集,如下所示:

@Configuration
public class IntegrationComponents {

    @Value("${rest.endpoint.base}")
    private String endpointBase;

    @Bean
    public HttpRequestHandlingMessagingGateway inboundGateway() {
        return Http.inboundGateway("/test-inbound-gateway-resource")
            .requestMapping(mapping -> mapping.methods(HttpMethod.POST))
            .requestTimeout(3000)
            .replyTimeout(3000)
            .get();
    }

    @Bean
    public HttpRequestExecutingMessageHandler outboundGateway1() {
        return Http.outboundGateway(endpointBase + "/test-resource-1")
            .httpMethod(HttpMethod.POST)
            .expectedResponseType(String.class)
            .get();
    }

    @Bean
    public HttpRequestExecutingMessageHandler outboundGateway2() {
        return Http.outboundGateway(endpointBase + "/test-resource-2")
            .httpMethod(HttpMethod.POST)
            .expectedResponseType(String.class)
            .get();
    }

    @Bean
    public StandardIntegrationFlow integrationFlow() {
        ExecutorService executor = Executors.newCachedThreadPool();

        IntegrationFlow flow1 = IntegrationFlows.from(MessageChannels.executor(executor))
            .handle(outboundGateway1())
            .get();

        IntegrationFlow flow2 = IntegrationFlows.from(MessageChannels.executor(executor))
            .handle(outboundGateway2())
            .get();

        return IntegrationFlows
            .from(inboundGateway())
            .transform(String.class, String::toUpperCase)
            .channel(MessageChannels.executor(executor))
            .scatterGather(
                    scatterer -> scatterer
                        .applySequence(true)
                        .recipientFlow(flow1)
                        .recipientFlow(flow2),
                    gatherer -> gatherer
                        .outputProcessor(messageGroup -> {
                            List<Message<?>> list = new ArrayList<>(messageGroup.getMessages());

                            String payload1 = (String) list.get(0).getPayload();
                            String payload2 = (String) list.get(1).getPayload();

                            return MessageBuilder.withPayload(payload1 + "+" + payload2).build();
                        }))
            .get();
    }
}

这会执行,但是我的有效负载会被交换,因为在这种情况下,outboundGateway1的执行时间比outboundGateway2更长。有效负载2首先出现,然后是有效负载1。

当发送到输出处理器时,是否有一种方法可以告诉散点图收集者定义/维护订单?

类似地,也许在这里分割/聚合和/或使用路由器是更好的模式?但是,如果是这样,那会是什么样?

我尝试了以下拆分/路由/聚合,但失败了:“'currentComponent'(org.springframework.integration.router.RecipientListRouter@b016b4e)是单向的'MessageHandler',不适合配置'outputChannel'。这是集成流程的结束。”:

@Configuration
public class IntegrationComponents {

    @Value("${rest.endpoint.base}")
    private String endpointBase;

    @Bean
    public HttpRequestHandlingMessagingGateway inboundGateway() {
        return Http.inboundGateway("/test-inbound-gateway-resource")
            .requestMapping(mapping -> mapping.methods(HttpMethod.POST))
            .requestTimeout(3000)
            .replyTimeout(3000)
            .get();
    }

    @Bean
    public HttpRequestExecutingMessageHandler outboundGateway1() {
        return Http.outboundGateway(endpointBase + "/test-resource-1")
            .httpMethod(HttpMethod.POST)
            .expectedResponseType(String.class)
            .get();
    }

    @Bean
    public HttpRequestExecutingMessageHandler outboundGateway2() {
        return Http.outboundGateway(endpointBase + "/test-resource-2")
            .httpMethod(HttpMethod.POST)
            .expectedResponseType(String.class)
            .get();
    }

    @Bean
    public StandardIntegrationFlow integrationFlow() {
        ExecutorService executor = Executors.newCachedThreadPool();

        IntegrationFlow flow1 = IntegrationFlows.from(MessageChannels.executor(executor))
            .handle(outboundGateway1())
            .get();

        IntegrationFlow flow2 = IntegrationFlows.from(MessageChannels.executor(executor))
            .handle(outboundGateway2())
            .get();

        return IntegrationFlows
            .from(inboundGateway())
            .transform(String.class, String::toUpperCase)
            .split()
            .channel(MessageChannels.executor(executor))
            .routeToRecipients(r -> r
                .recipientFlow(flow1)
                .recipientFlow(flow2))
            .aggregate()
            .get();
    }
}

1 个答案:

答案 0 :(得分:0)

您是否可以简单地Collections.sort()在输出处理器中使用列表?由于您设置了IntegrationMessageHeaderAccessor.SEQUENCE_NUMBER,因此每封邮件都会有一个applySequence标头。