You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Dirk Vanhaute (Jira)" <ji...@apache.org> on 2021/07/30 08:57:00 UTC

[jira] [Comment Edited] (CAMEL-16825) can not use endChoice() in nest choice DSL

    [ https://issues.apache.org/jira/browse/CAMEL-16825?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17390427#comment-17390427 ] 

Dirk Vanhaute edited comment on CAMEL-16825 at 7/30/21, 8:56 AM:
-----------------------------------------------------------------

Hi,

I happen to be investigating an identical problem (in 3.7.4) while migrating from 2.
 Using your testcase, it would probably look like this:

{{ProcessorDefinition<?> end = from("timer:foo?period=5000&synchronous=true")}}
{{ .transform(simple("${random(1000)}"))}}
{{ .choice()}}
{{   .when(simple("${body} > 500"))}}
{{      .log("High number ${body}")}}
{{      .choice()}}
{{         .when(simple("${body} > 750"))}}
{{            .log("High number >750 ${body}")}}
{{         .endChoice()}}

{{         .otherwise()}}
{{            .log("High number <750 ${body}")}}
{{         .endChoice()}}
{{      .end()}}
{{      .log(simple("extra log")}}
{{   .endChoice()}}
{{ .end()}}

it gives: org.apache.camel.model.RouteDefinition cannot be cast to class org.apache.camel.model.ChoiceDefinition

I don't understand the code completely, but I believe "choice" adds a new child to the OutputNode tree. While "when" and "otherwise" are pretty much treated like normal statements and are added to "blocks".  This causes all other non OutputNode statements like log to be placed in the same block.
 Because of that, you should never expect to find "WhenDefinition" in your tree, but still, ChoiceDefinition.endChoice has a check on it:

{{public ChoiceDefinition endChoice() {}}
{{ // are we nested choice?}}
{{ ProcessorDefinition<?> def = this;}}
{{ if (def.getParent() instanceof WhenDefinition)}}{{{ return (ChoiceDefinition) def.getParent().getParent(); }}}

 

 


was (Author: d.vanhaute):
Hi,

I happen to be investigating an identical problem (in 3.7.4) while migrating from 2.
Using your testcase, it would probably look like this:

ProcessorDefinition<?> end = from("timer:foo?period=5000&synchronous=true")
.transform(simple("${random(1000)}"))
.choice()
.when(simple("${body} > 500"))
.log("High number ${body}")
.choice()
.when(simple("${body} > 750"))
.log("High number >750 ${body}")
.endChoice()
.otherwise()
.log("High number <750 ${body}")
.endChoice()
.end()
.log(simple("extra log")
.endChoice()
.end()

it gives: org.apache.camel.model.RouteDefinition cannot be cast to class org.apache.camel.model.ChoiceDefinition 

I don't understand the code completely, but I believe "choice" adds a new child to the OutputNode tree. While "when" and "otherwise" are pretty much treated like normal statements and are added to "blocks".  This causes all other non OutputNode statements like log to be placed in the same block.
Because of that, you should never expect to find "WhenDefinition" in your tree, but still, ChoiceDefinition.endChoice has a check on it:
 
public ChoiceDefinition ProcessorDefinition.endChoice() {
 // are we nested choice?
 ProcessorDefinition<?> def = this;
 if (def.getParent() instanceof WhenDefinition) {
 return (ChoiceDefinition) def.getParent().getParent();
 } 



 

> can not use endChoice() in nest choice DSL
> ------------------------------------------
>
>                 Key: CAMEL-16825
>                 URL: https://issues.apache.org/jira/browse/CAMEL-16825
>             Project: Camel
>          Issue Type: Wish
>          Components: camel-core, eip
>    Affects Versions: 3.6.0, 3.11.0
>            Reporter: tang honggang
>            Priority: Minor
>             Fix For: 3.x
>
>
> I want to use nest choice DSL to finish some job, but it doesn't work well in my test case.  When I use endChoice() in the inner choice clause, it return back to the outer choice definition actually. 
> And this is the test case:
> ProcessorDefinition<?> end = from("timer:foo?period=5000&synchronous=true")
>  .transform(simple("${random(1000)}"))
>  .choice()
>  .when(simple("${body} > 500"))
>  .log("High number ${body}")
>  .choice()
>  .when(simple("${body} > 750"))
>  .log("High number >750 ${body}")
>  .endChoice()
>  .otherwise()
>  .log("High number <750 ${body}")
>  .endChoice()
>  .endChoice()
>  .otherwise()
>  .log("Low number ${body}")
>  .endChoice();
>  
> Though in this case, I can fix the problem by not use endChoice(), I see the code of endChoice(). I found that change the sequence of the two judgement below can fix my problem, but I am not sure the influence. So I hope you can give me an answer, thx!
> // are we nested choice?
> ProcessorDefinition<?> def = this;
> if (def.getParent() instanceof WhenDefinition) {
>  return (ChoiceDefinition) def.getParent().getParent();
> }
> // are we already a choice?
> if (def instanceof ChoiceDefinition) {
>  return (ChoiceDefinition) def;
> }
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)