【问题标题】:Spring integration validation in split & aggregate flow拆分和聚合流中的 Spring 集成验证
【发布时间】:2018-07-31 20:19:42
【问题描述】:

我正在尝试添加过滤器以丢弃流程并在失败后继续执行主要流程并聚合拆分器。错误和成功的预期类型相同。没有特定的聚合器逻辑。

@Bean
public IntegrationFlow flow() {
     return f -> f
         .split(Orders.class, Orders::getItems)
         .enrich(e -> e.requestChannel("enrichChannel"))
         .filter(Order.class, c -> c.getId() > 10 ? true : false,
             e -> e.discardChannel(validationError()))
         .handle(new MyHandler())
         .transform(new MapToObjectTransformer(Order.class))
         .enrich(e -> e.requestChannel("transformChannel"))
         .filter(Order.class, c -> c.getTotal() > 100 ? true : false,
             e -> e.discardChannel(validationError())).handle( new transformer())
         .aggregate();
 }
            
@Bean
public IntegrationFlow validationErrorFlow() {
 return IntegrationFlows.from(validationError())
         .handle(new ValidationHandler())
         .get();
}

丢弃通道未加入主流程以执行拆分中的下一项。

我可以编写路由和子流映射,但它会变得过于嵌套在路由 -> 子流 -> 路由 -> 子流中,试图通过使用过滤器来解决这个问题。是否有更好的方法来执行验证并仍然继续拆分流程中的所有项目。

更新 1:

.handle(request.class, (p, h) -> validator.validate(p)
.gateway("filterFlow.input")
.handle(new MyHandler())
.enrich(...)
.handle(...)
.enrich(...)
.handle(...)
.enrich(...)
.handle(...)
.aggregate();



@Bean
    public IntegrationFlow filterFlow() {
        return f -> f
                .filter(response.class, c -> c.isValidationStatus(), df -> df.discardFlow
                        (flow -> flow.handle(Message.class, (p, h) -> p.getPayload())));
    }

网关能够拦截请求,但流程执行.handle(new MyHandler())而不是split()中的下一项

更新 2:来自 Artem 的(答案)

.handle(request.class, (p, h) -> validator.validate(p))
    .filter(response.class,p -> p.isValidationStatus(), f -> f.discardChannel("aggregatorChannel"))
    .handle(new MyHandler())
    .enrich(...)
    .handle(...)
    .enrich(...)
    .handle(...)
    .enrich(...)
    .handle(...)
    .channel("aggregatorChannel")
    .aggregate();

这将有条件地跳过并继续流程。

【问题讨论】:

    标签: spring-integration spring-integration-dsl


    【解决方案1】:

    丢弃通道未加入主流程以执行拆分中的下一个项目。

    确实如此。它就是这样设计的。在大多数情况下,丢弃流程类似于 JMS 中的死信队列。所以,这是一个简短的单向分支。

    如果你真的想回到主流,你应该考虑在流定义中使用命名通道。我的意思是在你想在补偿(丢弃)流程之后回来的地方:

    .filter(Order.class, c -> c.getId() > 10 ? true : false,
                        e -> e.discardFlow(sf -> sf
                                .gateway(validationError())
                                .channel("myHandleChannel")))
                .channel("myHandleChannel")
                .handle(new MyHandler())
    

    我使用gateway(),因为我们需要丢弃流的回复才能继续处理。我们需要 .channel("myHandleChannel") 在子流的末尾,因为丢弃流是一个分支。

    另一种方法可以通过主流程上的.gateway() 来实现:

    .gateway("filterFlow.input")
    .handle(new MyHandler())
    
    ...
    
    @Bean
    public IntegrationFlow filterFlow() {
        return f -> f
                .filter(Order.class, c -> c.getId() > 10 ? true : false,
                        e -> e.discardChannel(validationError()));
    }
    

    我们向discardChannel 发送相同的请求消息,因此上述网关的正确replyChannel 标头仍然存在。您只需要确保从.handle(new ValidationHandler()) 产生正确的回复。

    【讨论】:

    • 你看。它不可读。请考虑使用格式正确的代码编辑您的问题。请尊重人们为您提供的帮助。
    • 更新问题,键盘一按错,格式乱了。
    • rather than the next item in split()。听起来像是一个不同的问题,它与您的其他句子不平行:the discard channel is not joining back to the main flow。我已经回答了这个问题。否则,您的问题不清楚您希望看到什么。您最后建议的是默认行为:过滤器丢弃并将控制权返回给下一个拆分项的主流,除非您使用throwExceptionOnRejection,但这看起来不像。
    • 是的,最初的问题已得到回答,但正在寻找不同的行为,流程不应在 gateway 之后执行,并在拆分中查找下一项并在末尾查找 aggregate()。我在丢弃通道中尝试了 throwExceptionOnRejection/ 异常,在这种情况下,整个流程完全暂停,拆分中的剩余项目被丢弃。遵循对话路线和子流程是这种行为的唯一选择,而不是依赖过滤器
    • 好吧,也许您的想法是绕过所有这些处理步骤,直接在丢弃流程中进入聚合器?关键是当我们使用具有标准行为的过滤器时,标准聚合器将无法工作,因为没有足够的拆分项进行分组。因此,您肯定需要以某种方式从丢弃子流返回主流,然后再返回聚合器端点。为此,命名频道再次为您提供解决方案。
    猜你喜欢
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2016-09-12
    相关资源
    最近更新 更多