Search code examples
javaspring-bootapache-camelspring-camel

Need to end Apache camel split while processing


My intention is to send a list of messages one by one (messages are generate using values from db). What I do is query and get the message list attach it to the exchange and use split to slipt the messages and it sends

Below is my route

.process(this::analyseSettlement)
    .choice()
        .when()
            .simple("${header.error_reason} == 001")
            .log("Settlement Completed")
        .otherwise()
            .log("BatchUpload process")
            .split(body(), flexible().accumulateInCollection(ArrayList.class))
                .setHeader(Exchange.HTTP_METHOD).constant(HttpMethod.POST)
                .removeHeader(Exchange.HTTP_PATH)
                .marshal().json(JsonLibrary.Jackson)

                .to("http://localhost:8087/channel/tcp?bridgeEndpoint=true")
                // analyze response if success then update the table 
                // if not return error
                .unmarshal(new JacksonDataFormat(InternalTransactionBean.class))
                .process(this::analyseBatchUploadResponse)

                .end()
            .log("${body}")
            .process(this::processPostSettlement)

What I require is if I find an error in one of the response need to stop sending all un send messages and end the split and go to postProcesssettlement function

flow required->

 Message list->  

            send message 1 by one
            error occurred while processing one message 
            stop processing the rest of the messages and exit the route

How to achieve this or If my process of sending batch of messages is not correct please advice me regarding that.


Solution

  • One way to implement what you try to achieve in a Camel route is to use the EIPs doTry, doCatch and doFinally pretty much like the famous try-catch-finally blocks in Java associated with stopOnException to interrupt the execution of the split in case of error.

    In the example below, I simulate a per line validation of my file content which fails, I then execute something when the exception is caught in my doCatch block and finally execute something else whatever happened in my doFinally block

    from("file:src/data")
        .doTry()
            .split(body().tokenize("\n")).stopOnException()
                .log("In split ${body}")
                .throwException(new RuntimeException("Not good"))
            .end()
        .endDoTry()
        .doCatch(RuntimeException.class)
            .log("In catch: ${body}")
        .doFinally()
            .log("In finally: ${body}")
        .end();
    

    Assuming that the content of my file is:

    line 1
    line 2
    line 3
    

    The result of my route is then:

    In split line 1
    In catch: line 1
    line 2
    line 3
    In finally: line 1
    line 2
    line 3
    

    More details about the EIPs doTry, doCatch and doFinally.

    More details about the option stopOnException.