Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Camel end vs endChoice - not the usual query

First, yes, I have searched and, yes, I have read the same Apache document every one points to. :-) I think there is a bit of confusion and I think I know an answer, so let me lay out an example of what I thought was correct, follow it with what I think the answer is. Thanks. Oh, and I do know that some of the endChoice() lines are not strictly necessary and that Camel will figure it out, but I like the blocks to be cleanly delineated, unless there is some reason not to use them.

.choice()
    .when(X1)
        // do stuff
        .choice()
            .when(Y)
                //do more stuff
            .endChoice()  // close inner when block
        .end() // close inner choice block
    .endChoice()  // close first outer when
    .when(X2)
        // do other stuff
    .endChoice()  // close second outer when
.end() // close outer choice

So, my original look at the API, I thought that end() was for closing things like choice and split and that endChoice() was for closing choice options like when and otherwise. It looks more like the latter is actually an end() that returns a ChoiceDefinition. Which makes the name a little better.

But, if I take out the end() labeled 'close inner choice block', this means I carry on to the next line, an endChoice(). Does this then close the inner choice block? Given that, the when(X2) is still within the the when(X1) block. So, I think that I need to replace the end() with an endChoice() rather than removing it. So the result would look like:

.choice()
    .when(X1)
        // do stuff
        .choice()
            .when(Y)
                //do more stuff
            .endChoice()  // close inner when block
        .endChoice() // close inner choice block
    .endChoice()  // close first outer when
    .when(X2)
        // do other stuff
    .endChoice()  // close second outer when
.end() // close outer choice

So is this the way to handle this in Camel? Or is there a simpler way that I am just missing? Thanks for your time.

like image 255
Scott Law Avatar asked Sep 03 '15 17:09

Scott Law


People also ask

How do you end camel choice?

. end() --> to close the entire "choice" block.

What problem does Apache Camel solve?

Purpose of 'Apache Camel' is to route 'messages' from one 'system' to another one in the world. Apache camel uses different transport mechanisms for message routing. Apache Camel picks up messages using 'Camel based Component' of the 'from' system and drops them using the 'Camel based Component' of the 'to' system.

What is RouteBuilder in camel?

The RouteBuilder is a base class which is derived from to create routing rules using the DSL. Instances of RouteBuilder are then added to the CamelContext .

What is stop in camel?

The stop/start approach will do a cold restart of Camel, where all internal state is reset. End users are advised to use suspend/resume. Using stop is for shutting down Camel and it's not guaranteed that when it's being started again using the start method that Camel will operate consistently.


2 Answers

SHORT ANSWER: I will call myself on this so no one else has to, the answer is that you are doing it wrong and should not have nested choices.

LONG ANSWER: I inherited a complicated route builder and was trying to clean it up to make it clearer. But straightening and putting in either end() or endChoice() just broke things. And, yes, the above fix still broke things. I did not understand how Camel knew which block to go to. Research and trying to find good examples of nesting eventually drove home the fact that Camel is not really designed for nesting choices. It allows it, but due to limitations in Java, it does not do it well. So I tried removing my nested choices. While this would have been possible, it would have meant ugly redundant conditionals, like:

choice()
  .when(x and a)
    //do stuff xa
  .when(x not a)
    // do other x stuff
  .when(y and a)
    // do y stuff

Only mine would have had at least another level. Further thought and recalling things that I had read brought about the second bit of enlightenment. The whole point of Camel is directing routes. Each choice's when block should just be pointing the process to a route. It should not be thinking, processing, or anything. In the end, our group is going to be refactoring to remove most of the logic from the route builder to a bean. The design we will be working towards will be something simple:

   from(uri)
     .bean(class, method)  // do any processing
     .choice()
       .when(header("result").isEqualTo("A")
          .to(routeA)
       .endChoice()
       .when(header("result").isEqualTo("B")
          .to(routeB)
       .endChoice()
       .when(header("result").isEqualTo("C")
          .to(route)
       .endChoice()
      .end()

My advice to you is to avoid nesting choices. Particularly complicated ones. You might get it to work, but you will not be able to trust it when you have to make changes later. If you find yourself tempted to use nested choices, examine what you are trying to accomplish and decide if it really belongs in a route builder.

like image 193
Scott Law Avatar answered Oct 16 '22 17:10

Scott Law


Coming late in the game, but might help.

Nested choice definitions work just fine with Camel. Only your terminators are wrong:

  • .endChoice() --> to close a "when" predicate
  • .end() --> to close the entire "choice" block

I know, the syntax is a bit confusing.

So in your case:

.choice()
    .when(X1)
        // do stuff

        .choice()
            .when(Y)
                //do more stuff
            .endChoice() // close Y condition

        .end() // close inner choice block

    .endChoice() // close X1 condition

    .when(X2)
        // do other stuff
    .endChoice() // close X2 condition

    .otherwise()
        // default case
    .endChoice() // close default condition

.end()

In practice, you don't have to close all when predicates, only for multiple child routings. In my humble opinion, being super meticulous with the indentation helps a lot.

like image 40
Alexis Avatar answered Oct 16 '22 17:10

Alexis