问题
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