Spring Integration - custom errorChannel - only first exception gets logged

偶尔善良 提交于 2019-12-13 04:36:01

问题


This is a follow up to the previous question (requirements given in original question).

Spring Integration - Filter - Send messages to a different end point

My issue is that if there is more than one error in the input file, only the first error is getting logged. The subsequent errors are not getting logged.

Modified code:

@Configuration
public class CreateUserConfiguration {
    @Bean
    public IntegrationFlow createUser() {
        return IntegrationFlows.from(Files.inboundAdapter(new File(INPUT_DIR)))
                .enrichHeaders(h -> h.header("errorChannel", "exceptionChannel", true))
                .transform(csvToUserBeanTransformer, "convertCsvToUserBean")
                .split(userBeanSplitter, "splitUserBeans")
                .wireTap(flow -> flow.<UserBean>filter(userBean -> !userBean.getStatus().equalsIgnoreCase("SUCCESS")).channel("errorSummaryReportGenerationChannel"))
                .transform(userBeanToJSONTransformer, "convertUserBeanToJSON")
                .handle(Files.outboundAdapter(new File(OUTPUT_SUCCESS_DIRECTORY)))
                .get();
    }

    @Bean
    public IntegrationFlow logErrorSummary() {
        return IntegrationFlows.from("errorSummaryReportGenerationChannel")
                .handle((p,h) -> {
                    return ((UserBean)(p)).getUserID() + "\t" + ((UserBean)(p)).getStatus();
                })
                .transform(Transformers.objectToString())
                .handle(Files.outboundAdapter(new File(OUTPUT_FAILED_REPORT_FILE_NAME)))
                .get();
    }

    @Bean
    public IntegrationFlow logError() {
        return IntegrationFlows.from("exceptionChannel")
                .enrichHeaders(h -> h.headerExpression("errorFileName", "payload.failedMessage.headers.fileName"))
                .wireTap(flow -> flow.handle(msg -> System.out.println("Received on exceptionChannel " + msg.getHeaders().get("errorFileName"))))
                .transform(Transformers.objectToString())
                .handle(Files.outboundAdapter(new File(generateOutputDirectory(OUTPUT_FAILED_DIRECTORY))).autoCreateDirectory(true).fileExistsMode(FileExistsMode.APPEND).fileNameExpression("getHeaders().get(\"errorFileName\")+'.json'"))
                .get();
    }

    @Bean(name = "exceptionChannel")
    MessageChannel exceptionChannel() {
        return MessageChannels.executor(new SimpleAsyncTaskExecutor()).get();
    }

    @Bean(name="errorSummaryReportGenerationChannel")
    MessageChannel errorSummaryReportGenerationChannel() {
        return DirectChannel();
    }
}

WHAT I EXPECT:

In errorSummaryReport -

B123  ERROR, FREQUENCY
C123  FREQUENCY_DETAIL

In OUTPUT_FAILED_DIRECTORY -

B123.json -> stacktrace of error
C123.json -> stacktrace of error

WHAT I SEE: (C123 information is missing)

In errorSummaryReport -

B123  ERROR, FREQUENCY

In OUTPUT_FAILED_DIRECTORY -

B123.json -> stacktrace of error

回答1:


The problem pops up from the .split(userBeanSplitter, "splitUserBeans").

I would say it is fully similar to what we do in plain Java with a for loop. So, if method in the loop throws an exception, you indeed go away from the loop and the next item is not going to be processed any more.

To fix your problem you need to add a .channel(c -> c.executor(myExecutor())) to process splitted items in parallel and have a error handling in the separate thread. This way the loop in the splitter is not going to be affected.



来源:https://stackoverflow.com/questions/58120142/spring-integration-custom-errorchannel-only-first-exception-gets-logged

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!