Camel: How to go all "when" in "choice when"

8.1k views Asked by At

I need to ask a problem on the operator "choice when" in Apache Camel route. In the following example, if I have two soap-env:Order elements which have 1, 2 value, then I want to create two xml file named output_1.xml and output_2.xml. However, the code can only create one file output_1.xml. Can anyone give me any ideas or hints? Thanks for any help.

    public void configure() {
    ...  
    from("direct:a")
        .choice()
            .when(ns.xpath("//soap-env:Envelope//soap-env:Order='1'"))
                .to("file://data?fileName=output_1.xml")
            .when(ns.xpath("//soap-env:Envelope//soap-env:Order='2'"))
                .to("file://data?fileName=output_2.xml")
            .when(ns.xpath("//soap-env:Envelope//soap-env:Order='3'"))
                .to("file://data?fileName=output_3.xml")
}
3

There are 3 answers

3
Ralf On BEST ANSWER

My understanding is that the content based router implements "if - else if - else" semantics, meaning that as soon as one test evaluates to true, then the remaining tests are skipped. If you want to create files for every case that returns true then you'd have to change the route to something like this:

from("direct:a")
    .choice()
       .when(ns.xpath("//soap-env:Envelope//soap-env:Order='1'"))
           .to("file://data?fileName=output_1.xml")
    .end()
    .choice()
       .when(ns.xpath("//soap-env:Envelope//soap-env:Order='2'"))
           .to("file://data?fileName=output_2.xml")
    .end()
    .choice()
        .when(ns.xpath("//soap-env:Envelope//soap-env:Order='3'"))
           .to("file://data?fileName=output_3.xml")
    .end()
0
Robert Simmons Jr. On

There is nothing wrong with the DSL and you dontt need end blocks here. I would look at your data and trace through why all calls are ending up in the same when block. Put a couple of log lines in or enable the tracer and look at the exchanges going through.

0
Ramu On

In Camel root choice() if you have multiple when() cases you have to write otherwise(). Please refer below.

 from("direct:a")
          .choice()
              .when(header("foo").isEqualTo("bar"))
                   .to("direct:b")
              .when(header("foo").isEqualTo("cheese"))
                   .to("direct:c")
              .otherwise()
                   .to("direct:d")
         .end;

The above mentioned solution will check all three conditions even if first one pass.