This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 4ecc9a7 CAMEL-17755: Propose precondition mode to Choice as
replacement for DoSwitch (#7166)
4ecc9a7 is described below
commit 4ecc9a752baf70b53e977197ddeb8e577181288e
Author: Nicolas Filotto <[email protected]>
AuthorDate: Wed Mar 9 07:03:57 2022 +0100
CAMEL-17755: Propose precondition mode to Choice as replacement for
DoSwitch (#7166)
---
.../org/apache/camel/catalog/models.properties | 1 -
.../org/apache/camel/catalog/models/choice.json | 1 +
.../org/apache/camel/catalog/models/doSwitch.json | 20 ----
.../apache/camel/catalog/schemas/camel-spring.xsd | 52 ++---------
.../docs/modules/eips/examples/json/doSwitch.json | 1 -
.../src/main/docs/modules/eips/nav.adoc | 1 -
.../main/docs/modules/eips/pages/choice-eip.adoc | 80 +++++++++++++++-
.../main/docs/modules/eips/pages/switch-eip.adoc | 95 -------------------
.../services/org/apache/camel/model.properties | 1 -
.../resources/org/apache/camel/model/choice.json | 1 +
.../resources/org/apache/camel/model/doSwitch.json | 20 ----
.../resources/org/apache/camel/model/jaxb.index | 1 -
.../org/apache/camel/model/ChoiceDefinition.java | 38 ++++++++
.../apache/camel/model/ProcessorDefinition.java | 12 ---
.../org/apache/camel/model/SwitchDefinition.java | 44 ---------
.../org/apache/camel/reifier/ChoiceReifier.java | 102 +++++++++++++++------
.../org/apache/camel/reifier/ProcessorReifier.java | 8 +-
.../org/apache/camel/reifier/SwitchReifier.java | 96 -------------------
...RouteTemplateChoiceInPreconditionModeTest.java} | 12 +--
...Test.java => ChoiceInPreconditionModeTest.java} | 14 +--
.../java/org/apache/camel/xml/in/ModelParser.java | 21 ++---
.../ROOT/pages/camel-3x-upgrade-guide-3_16.adoc | 22 +++++
.../dsl/yaml/deserializers/ModelDeserializers.java | 74 ++-------------
.../deserializers/ModelDeserializersResolver.java | 3 -
.../src/generated/resources/camel-yaml-dsl.json | 38 +-------
.../src/generated/resources/camelYamlDsl.json | 35 +------
.../org/apache/camel/dsl/yaml/ChoiceTest.groovy | 43 +++++++++
.../org/apache/camel/dsl/yaml/SwitchTest.groovy | 67 --------------
28 files changed, 303 insertions(+), 600 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
index 9ba8efe..0b9030c 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models.properties
@@ -41,7 +41,6 @@ description
dnsServiceDiscovery
doCatch
doFinally
-doSwitch
doTry
dynamicRouter
endpoint
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/choice.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/choice.json
index eca6131..f666212 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/choice.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/choice.json
@@ -14,6 +14,7 @@
"properties": {
"when": { "kind": "element", "displayName": "When", "required": false,
"type": "array", "javaType":
"java.util.List<org.apache.camel.model.WhenDefinition>", "oneOf": [ "when" ],
"deprecated": false, "autowired": false, "secret": false, "asPredicate": true,
"description": "Sets the when nodes" },
"otherwise": { "kind": "element", "displayName": "Otherwise", "required":
false, "type": "object", "javaType":
"org.apache.camel.model.OtherwiseDefinition", "oneOf": [ "otherwise" ],
"deprecated": false, "autowired": false, "secret": false, "description": "Sets
the otherwise node" },
+ "precondition": { "kind": "attribute", "displayName": "Precondition",
"label": "advanced", "required": false, "type": "boolean", "javaType":
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "description": "Indicates whether this Choice EIP is in
precondition mode or not. If so its branches (when\/otherwise) are evaluated
during startup to keep at runtime only the branch that matched." },
"id": { "kind": "attribute", "displayName": "Id", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the id of this node"
},
"description": { "kind": "element", "displayName": "Description",
"required": false, "type": "object", "javaType":
"org.apache.camel.model.DescriptionDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the description of
this node" }
}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doSwitch.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doSwitch.json
deleted file mode 100644
index a15cc5a..0000000
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/doSwitch.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "model": {
- "kind": "model",
- "name": "doSwitch",
- "title": "Do Switch",
- "description": "Route messages based on a series of predicates (optimized
during startup to select one predicate that will always be used)",
- "deprecated": false,
- "label": "eip,routing",
- "javaType": "org.apache.camel.model.SwitchDefinition",
- "abstract": false,
- "input": true,
- "output": false
- },
- "properties": {
- "when": { "kind": "element", "displayName": "When", "required": false,
"type": "array", "javaType":
"java.util.List<org.apache.camel.model.WhenDefinition>", "oneOf": [ "when" ],
"deprecated": false, "autowired": false, "secret": false, "asPredicate": true,
"description": "Sets the when nodes" },
- "otherwise": { "kind": "element", "displayName": "Otherwise", "required":
false, "type": "object", "javaType":
"org.apache.camel.model.OtherwiseDefinition", "oneOf": [ "otherwise" ],
"deprecated": false, "autowired": false, "secret": false, "description": "Sets
the otherwise node" },
- "id": { "kind": "attribute", "displayName": "Id", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the id of this node"
},
- "description": { "kind": "element", "displayName": "Description",
"required": false, "type": "object", "javaType":
"org.apache.camel.model.DescriptionDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the description of
this node" }
- }
-}
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index d06f7df..8c54a85 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -350,15 +350,6 @@ Path traversed when a try, catch, finally block exits
</xs:annotation>
</xs:element>
- <xs:element name="doSwitch" type="tns:switchDefinition">
- <xs:annotation>
- <xs:documentation xml:lang="en"><![CDATA[
-Route messages based on a series of predicates (optimized during startup to
-select one predicate that will always be used)
- ]]></xs:documentation>
- </xs:annotation>
- </xs:element>
-
<xs:element name="doTry" type="tns:tryDefinition">
<xs:annotation>
<xs:documentation xml:lang="en"><![CDATA[
@@ -3053,7 +3044,6 @@ will fallback to use the fixed value if the Expression
result was null or 0.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -3558,7 +3548,6 @@ should be intercepted by this exception type or not.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -3659,7 +3648,6 @@ should be intercepted by this exception type or not.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -3685,6 +3673,15 @@ should be intercepted by this exception type or not.
<xs:element maxOccurs="unbounded" minOccurs="0" ref="tns:when"/>
<xs:element minOccurs="0" ref="tns:otherwise"/>
</xs:sequence>
+ <xs:attribute name="precondition" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en"><![CDATA[
+Indicates whether this Choice EIP is in precondition mode or not. If so its
+branches (when/otherwise) are evaluated during startup to keep at runtime only
+the branch that matched. Default value: false
+ ]]></xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -3748,7 +3745,6 @@ should be intercepted by this exception type or not.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -3829,7 +3825,6 @@ should be intercepted by this exception type or not.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -4876,7 +4871,6 @@ org.apache.camel.spi.SendDynamicAware . Default value:
true
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -4962,7 +4956,6 @@ Setting this allows to know if the filter predicate
evaluated as true or false.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -5102,7 +5095,6 @@ Global option value.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -5282,7 +5274,6 @@ Whether if validation is required for this input type.
Default value: false
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -5376,7 +5367,6 @@ configured, then all incoming messages is intercepted.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -5477,7 +5467,6 @@ process its result.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -5572,7 +5561,6 @@ specified using uri syntax, eg mynamecount=4&type=gold.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -5867,7 +5855,6 @@ To refer to a custom logger instance to lookup from the
registry.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -8902,7 +8889,6 @@ decompressed size. Default value: 1073741824
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -9104,7 +9090,6 @@ should be invoked or not.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -9273,7 +9258,6 @@ failure. If this option is enabled then its considered
handled as well.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -9636,7 +9620,6 @@ generate the log message from exchange.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -9774,7 +9757,6 @@ Include finding route builder from these java package
names.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -9852,7 +9834,6 @@ Include finding route builder from these java package
names.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -10397,7 +10378,6 @@ Name of property to remove.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -10703,7 +10683,6 @@ Reference to the routes in the xml dsl.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -11062,7 +11041,6 @@ compensation/completion exchange.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -11414,7 +11392,6 @@ Sets the comparator to use for sorting.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -11624,7 +11601,6 @@ individual unit of work. Default value: false
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -11651,14 +11627,6 @@ individual unit of work. Default value: false
</xs:complexContent>
</xs:complexType>
- <xs:complexType name="switchDefinition">
- <xs:complexContent>
- <xs:extension base="tns:choiceDefinition">
- <xs:sequence/>
- </xs:extension>
- </xs:complexContent>
- </xs:complexType>
-
<xs:complexType name="templatedRouteBeanDefinition">
<xs:complexContent>
<xs:extension base="tns:beanFactoryDefinition">
@@ -12126,7 +12094,6 @@ Whether to auto startup components when toD is starting
up. Default value: true
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
@@ -12241,7 +12208,6 @@ Sets a reference to use for lookup the policy in the
registry.
<xs:element ref="tns:split"/>
<xs:element ref="tns:step"/>
<xs:element ref="tns:stop"/>
- <xs:element ref="tns:doSwitch"/>
<xs:element ref="tns:threads"/>
<xs:element ref="tns:throttle"/>
<xs:element ref="tns:throwException"/>
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/examples/json/doSwitch.json
b/core/camel-core-engine/src/main/docs/modules/eips/examples/json/doSwitch.json
deleted file mode 120000
index b0512c4..0000000
---
a/core/camel-core-engine/src/main/docs/modules/eips/examples/json/doSwitch.json
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../../../../camel-core-model/src/generated/resources/org/apache/camel/model/doSwitch.json
\ No newline at end of file
diff --git a/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
index 54c5822..67a091a 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/nav.adoc
@@ -82,7 +82,6 @@
** xref:eips:split-eip.adoc[Split]
** xref:eips:step-eip.adoc[Step]
** xref:eips:stop-eip.adoc[Stop]
- ** xref:eips:switch-eip.adoc[Switch]
** xref:eips:threads-eip.adoc[Threads]
** xref:eips:throttle-eip.adoc[Throttle]
** xref:eips:to-eip.adoc[To]
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
index 0428e9b..550200a 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/choice-eip.adoc
@@ -144,6 +144,82 @@ There can be some combinations of
xref:eips:enterprise-integration-patterns.adoc
that can hit limits in how far we can take the fluent builder DSL with
generics you can do in Java programming language.
-== See Also
+== Precondition Mode
-See xref:switch-eip.adoc[Switch EIP].
\ No newline at end of file
+In precondition mode, the Choice EIP is an optimized
http://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html[Content
+Based Router] which selects a single branch (when/otherwise) during startup,
and
+always executes the same branch. This allows to optimize the runtime Camel to
avoid
+this evaluation process for every message; because they are supposed
+to always be routed on the same branch.
+
+NOTE: Because the Choice EIP in precondition mode evaluates the predicates
during startup, then the predicates
+cannot be based on the content of the message. Therefore, the predicates would
often
+be based on property placeholders, JVM system properties, or OS Environment
variables.
+
+The Choice EIP in precondition mode combined with
xref:manual:ROOT:route-template.adoc[Route Templates] allows
+for more flexible templates, as the template parameters can be used as the
predicates in the Choice EIP;
+meaning that the Choice EIP in precondition mode is fully parameterized, but
is optimized for best runtime performance.
+
+=== Example
+
+The Camel xref:languages:simple-language.adoc[Simple] language
+is great to use with the Choice EIP in precondition mode to select a specific
branch based
+on xref:manual:ROOT:using-propertyplaceholder.adoc[property placeholders].
+
+Here we select from the Switch the first predicate that matches. So if there is
+a property placeholder with the key `foo` then its select, and so on.
+Notice how we can use `{{?foo}}` to mark the property placeholder as optional.
+
+[source,java]
+----
+from("direct:a")
+ .choice().precondition()
+ .when(simple("{{?foo}}")).to("direct:foo")
+ .when(simple("{{?bar}}")).to("direct:bar")
+ .otherwise().to("direct:other");
+----
+
+And the same example using XML DSL:
+
+[source,xml]
+----
+<route>
+ <from uri="direct:a"/>
+ <choice precondition="true">
+ <when>
+ <simple>{{?foo}}</simple>
+ <to uri="direct:foo"/>
+ </when>
+ <when>
+ <simple>{{?bar}}</simple>
+ <to uri="direct:bar"/>
+ </when>
+ <otherwise>
+ <to uri="direct:other"/>
+ </otherwise>
+ </choice>
+</route>
+----
+
+And in YAML DS:
+
+[source,yaml]
+----
+- from:
+ uri: "direct:a"
+ steps:
+ - choice:
+ precondition: true
+ when:
+ - simple: "{{?foo}}"
+ steps:
+ - to: "direct:foo"
+ - simple: "{{?bar}}"
+ steps:
+ - to: "direct:bar"
+ otherwise:
+ steps:
+ - to: "direct:other"
+----
+
+TIP: Otherwise, is optional, and if none of the predicates would match, then
no branches is selected.
\ No newline at end of file
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/pages/switch-eip.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/pages/switch-eip.adoc
deleted file mode 100644
index f7ce625..0000000
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/switch-eip.adoc
+++ /dev/null
@@ -1,95 +0,0 @@
-= Switch EIP
-:doctitle: Switch
-:shortname: doSwitch
-:description: Route messages based on a series of predicates
-:since:
-:supportlevel: Stable
-
-The Switch EIP is an optimized
http://www.enterpriseintegrationpatterns.com/ContentBasedRouter.html[Content
-Based Router] which selects a single branch (when/otherwise) during startup,
and
-always executes the same branch. This allows to optimize the runtime Camel to
avoid
-this evaluation process for every message; because they are supposed
-to always be routed on the same branch.
-
-NOTE: Because the Switch EIP evaluates the predicates during startup, then the
predicates
-cannot be based on the content of the message. Therefore, the predicates would
often
-be based on property placeholders, JVM system properties, or OS Environment
variables.
-
-The Switch EIP combined with xref:manual:ROOT:route-template.adoc[Route
Templates] allows
-for more flexible templates, as the template parameters can be used as the
predicates in the Switch EIP;
-meaning that the Switch EIP is fully parameterized, but is optimized for best
runtime performance.
-
-image::eip/ContentBasedRouter.gif[image]
-
-== Switch options
-
-// eip options: START
-include::partial$eip-options.adoc[]
-// eip options: END
-
-== Example
-
-The Camel xref:languages:simple-language.adoc[Simple] language
-is great to use with the Switch EIP to select a specific branch based
-on xref:manual:ROOT:using-propertyplaceholder.adoc[property placeholders].
-
-Here we select from the Switch the first predicate that matches. So if there is
-a property placeholder with the key `foo` then its select, and so on.
-Notice how we can use `{{?foo}}` to mark the property placeholder as optional.
-
-[source,java]
-----
-from("direct:a")
- .doSwitch()
- .when(simple("{{?foo}}")).to("direct:foo")
- .when(simple("{{?bar}}")).to("direct:bar")
- .otherwise().to("direct:other");
-----
-
-And the same example using XML DSL:
-
-[source,xml]
-----
-<route>
- <from uri="direct:a"/>
- <doSwitch>
- <when>
- <simple>{{?foo}}</simple>
- <to uri="direct:foo"/>
- </when>
- <when>
- <simple>{{?bar}}</simple>
- <to uri="direct:bar"/>
- </when>
- <otherwise>
- <to uri="direct:other"/>
- </otherwise>
- </doSwitch>
-</route>
-----
-
-And in YAML DS:
-
-[source,yaml]
-----
-- from:
- uri: "direct:a"
- steps:
- - doSwitch:
- when:
- - simple: "{{?foo}}"
- steps:
- - to: "direct:foo"
- - simple: "{{?bar}}"
- steps:
- - to: "direct:bar"
- otherwise:
- steps:
- - to: "direct:other"
-----
-
-TIP: Otherwise, is optional, and if none of the predicates would match, then
no branches is selected.
-
-=== Why can I not use otherwise in Java DSL
-
-See the same section at xref:choice-eip.adoc[Choice EIP].
diff --git
a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
index acf74d0..812a961 100644
---
a/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
+++
b/core/camel-core-model/src/generated/resources/META-INF/services/org/apache/camel/model.properties
@@ -39,7 +39,6 @@ description
dnsServiceDiscovery
doCatch
doFinally
-doSwitch
doTry
dynamicRouter
enrich
diff --git
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/choice.json
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/choice.json
index eca6131..f666212 100644
---
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/choice.json
+++
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/choice.json
@@ -14,6 +14,7 @@
"properties": {
"when": { "kind": "element", "displayName": "When", "required": false,
"type": "array", "javaType":
"java.util.List<org.apache.camel.model.WhenDefinition>", "oneOf": [ "when" ],
"deprecated": false, "autowired": false, "secret": false, "asPredicate": true,
"description": "Sets the when nodes" },
"otherwise": { "kind": "element", "displayName": "Otherwise", "required":
false, "type": "object", "javaType":
"org.apache.camel.model.OtherwiseDefinition", "oneOf": [ "otherwise" ],
"deprecated": false, "autowired": false, "secret": false, "description": "Sets
the otherwise node" },
+ "precondition": { "kind": "attribute", "displayName": "Precondition",
"label": "advanced", "required": false, "type": "boolean", "javaType":
"java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": false, "description": "Indicates whether this Choice EIP is in
precondition mode or not. If so its branches (when\/otherwise) are evaluated
during startup to keep at runtime only the branch that matched." },
"id": { "kind": "attribute", "displayName": "Id", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the id of this node"
},
"description": { "kind": "element", "displayName": "Description",
"required": false, "type": "object", "javaType":
"org.apache.camel.model.DescriptionDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the description of
this node" }
}
diff --git
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doSwitch.json
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/doSwitch.json
deleted file mode 100644
index a15cc5a..0000000
---
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/doSwitch.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "model": {
- "kind": "model",
- "name": "doSwitch",
- "title": "Do Switch",
- "description": "Route messages based on a series of predicates (optimized
during startup to select one predicate that will always be used)",
- "deprecated": false,
- "label": "eip,routing",
- "javaType": "org.apache.camel.model.SwitchDefinition",
- "abstract": false,
- "input": true,
- "output": false
- },
- "properties": {
- "when": { "kind": "element", "displayName": "When", "required": false,
"type": "array", "javaType":
"java.util.List<org.apache.camel.model.WhenDefinition>", "oneOf": [ "when" ],
"deprecated": false, "autowired": false, "secret": false, "asPredicate": true,
"description": "Sets the when nodes" },
- "otherwise": { "kind": "element", "displayName": "Otherwise", "required":
false, "type": "object", "javaType":
"org.apache.camel.model.OtherwiseDefinition", "oneOf": [ "otherwise" ],
"deprecated": false, "autowired": false, "secret": false, "description": "Sets
the otherwise node" },
- "id": { "kind": "attribute", "displayName": "Id", "required": false,
"type": "string", "javaType": "java.lang.String", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the id of this node"
},
- "description": { "kind": "element", "displayName": "Description",
"required": false, "type": "object", "javaType":
"org.apache.camel.model.DescriptionDefinition", "deprecated": false,
"autowired": false, "secret": false, "description": "Sets the description of
this node" }
- }
-}
diff --git
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
index 6b088ff..592cf1a 100644
---
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
+++
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/jaxb.index
@@ -89,7 +89,6 @@ SortDefinition
SplitDefinition
StepDefinition
StopDefinition
-SwitchDefinition
TemplatedRouteBeanDefinition
TemplatedRouteDefinition
TemplatedRouteParameterDefinition
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
index 73801a5..38a9452 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/ChoiceDefinition.java
@@ -23,6 +23,7 @@ import java.util.stream.Collectors;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
@@ -52,6 +53,9 @@ public class ChoiceDefinition extends
ProcessorDefinition<ChoiceDefinition> impl
@XmlElement
@Metadata(description = "Sets the otherwise node")
private OtherwiseDefinition otherwise;
+ @XmlAttribute
+ @Metadata(label = "advanced", javaType = "java.lang.Boolean", defaultValue
= "false")
+ private String precondition;
public ChoiceDefinition() {
}
@@ -147,6 +151,18 @@ public class ChoiceDefinition extends
ProcessorDefinition<ChoiceDefinition> impl
super.addOutput(output);
}
+ public String getPrecondition() {
+ return precondition;
+ }
+
+ /**
+ * Indicates whether this Choice EIP is in precondition mode or not. If so
its branches (when/otherwise) are
+ * evaluated during startup to keep at runtime only the branch that
matched.
+ */
+ public void setPrecondition(String precondition) {
+ this.precondition = precondition;
+ }
+
@Override
public ProcessorDefinition<?> end() {
// we end a block so only when or otherwise is supported
@@ -165,6 +181,28 @@ public class ChoiceDefinition extends
ProcessorDefinition<ChoiceDefinition> impl
//
-------------------------------------------------------------------------
/**
+ * Indicates that this Choice EIP is in precondition mode, its branches
(when/otherwise) are then evaluated during
+ * startup to keep at runtime only the branch that matched.
+ *
+ * @return the builder
+ */
+ public ChoiceDefinition precondition() {
+ return precondition(true);
+ }
+
+ /**
+ * Indicates whether this Choice EIP is in precondition mode or not. If so
its branches (when/otherwise) are
+ * evaluated during startup to keep at runtime only the branch that
matched.
+ *
+ * @param precondition the flag indicating if it is in precondition mode
or not.
+ * @return the builder
+ */
+ public ChoiceDefinition precondition(boolean precondition) {
+ setPrecondition(Boolean.toString(precondition));
+ return this;
+ }
+
+ /**
* Sets the predicate for the when node
*
* @param predicate the predicate
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
index e61d2ce..68ba1c1 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/ProcessorDefinition.java
@@ -1451,18 +1451,6 @@ public abstract class ProcessorDefinition<Type extends
ProcessorDefinition<Type>
}
/**
- * An optimized <a
href="http://camel.apache.org/content-based-router.html">Content Based Router
EIP:</a> Optimized
- * during startup to select one predicate that will always be used.
- *
- * @return the builder for a switch expression
- */
- public SwitchDefinition doSwitch() {
- SwitchDefinition answer = new SwitchDefinition();
- addOutput(answer);
- return answer;
- }
-
- /**
* Creates a try/catch block
*
* @return the builder for a tryBlock expression
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/SwitchDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/SwitchDefinition.java
deleted file mode 100644
index 541a241..0000000
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/SwitchDefinition.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.model;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.apache.camel.spi.Metadata;
-
-/**
- * Route messages based on a series of predicates (optimized during startup to
select one predicate that will always be
- * used)
- */
-@Metadata(label = "eip,routing")
-@XmlRootElement(name = "doSwitch")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class SwitchDefinition extends ChoiceDefinition {
-
- @Override
- public String toString() {
- return "Switch[" + getWhenClauses() + (getOtherwise() != null ? " " +
getOtherwise() : "") + "]";
- }
-
- @Override
- public String getShortName() {
- return "switch";
- }
-
-}
diff --git
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
index dc99340..1be5abf 100644
---
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
+++
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ChoiceReifier.java
@@ -19,6 +19,7 @@ package org.apache.camel.reifier;
import java.util.ArrayList;
import java.util.List;
+import org.apache.camel.Exchange;
import org.apache.camel.ExpressionFactory;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
@@ -30,43 +31,33 @@ import org.apache.camel.model.language.ExpressionDefinition;
import org.apache.camel.processor.ChoiceProcessor;
import org.apache.camel.processor.FilterProcessor;
import org.apache.camel.spi.ExpressionFactoryAware;
+import org.apache.camel.support.DefaultExchange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ChoiceReifier extends ProcessorReifier<ChoiceDefinition> {
+ /**
+ * The logger.
+ */
+ private static final Logger LOG =
LoggerFactory.getLogger(ChoiceReifier.class);
+
public ChoiceReifier(Route route, ProcessorDefinition<?> definition) {
super(route, ChoiceDefinition.class.cast(definition));
}
@Override
public Processor createProcessor() throws Exception {
- List<FilterProcessor> filters = new ArrayList<>();
+ final boolean isPrecondition = Boolean.TRUE ==
parseBoolean(definition.getPrecondition());
+ final List<FilterProcessor> filters = isPrecondition ? null : new
ArrayList<>();
for (WhenDefinition whenClause : definition.getWhenClauses()) {
- ExpressionDefinition exp = whenClause.getExpression();
- if (exp.getExpressionType() != null) {
- exp = exp.getExpressionType();
- }
- Predicate pre = exp.getPredicate();
- if (pre instanceof ExpressionFactoryAware) {
- ExpressionFactoryAware aware = (ExpressionFactoryAware) pre;
- if (aware.getExpressionFactory() != null) {
- // if using the Java DSL then the expression may have been
- // set using the
- // ExpressionClause (implements ExpressionFactoryAware)
- // which is a fancy builder to define
- // expressions and predicates
- // using fluent builders in the DSL. However we need
- // afterwards a callback to
- // reset the expression to the expression type the
- // ExpressionClause did build for us
- ExpressionFactory model = aware.getExpressionFactory();
- if (model instanceof ExpressionDefinition) {
- whenClause.setExpression((ExpressionDefinition) model);
- }
- }
+ initBranch(whenClause);
+ if (filters != null) {
+ filters.add((FilterProcessor) createProcessor(whenClause));
}
-
- FilterProcessor filter = (FilterProcessor)
createProcessor(whenClause);
- filters.add(filter);
+ }
+ if (isPrecondition) {
+ return getMatchingBranchProcessor();
}
Processor otherwiseProcessor = null;
if (definition.getOtherwise() != null) {
@@ -75,4 +66,63 @@ public class ChoiceReifier extends
ProcessorReifier<ChoiceDefinition> {
return new ChoiceProcessor(filters, otherwiseProcessor);
}
+ /**
+ * Initialize the given branch if needed.
+ */
+ private void initBranch(WhenDefinition whenClause) {
+ ExpressionDefinition exp = whenClause.getExpression();
+ if (exp.getExpressionType() != null) {
+ exp = exp.getExpressionType();
+ }
+ Predicate pre = exp.getPredicate();
+ if (pre instanceof ExpressionFactoryAware) {
+ ExpressionFactoryAware aware = (ExpressionFactoryAware) pre;
+ if (aware.getExpressionFactory() != null) {
+ // if using the Java DSL then the expression may have been
+ // set using the
+ // ExpressionClause (implements ExpressionFactoryAware)
+ // which is a fancy builder to define
+ // expressions and predicates
+ // using fluent builders in the DSL. However we need
+ // afterwards a callback to
+ // reset the expression to the expression type the
+ // ExpressionClause did build for us
+ ExpressionFactory model = aware.getExpressionFactory();
+ if (model instanceof ExpressionDefinition) {
+ whenClause.setExpression((ExpressionDefinition) model);
+ }
+ }
+ }
+ }
+
+ /**
+ * @return the processor corresponding to the matching branch if any,
{@code null} otherwise.
+ */
+ private Processor getMatchingBranchProcessor() throws Exception {
+ // evaluate when predicates to optimize
+ Exchange dummy = new DefaultExchange(camelContext);
+ for (WhenDefinition whenClause : definition.getWhenClauses()) {
+ ExpressionDefinition exp = whenClause.getExpression();
+ exp.initPredicate(camelContext);
+
+ Predicate predicate = exp.getPredicate();
+ predicate.initPredicate(camelContext);
+
+ boolean matches = predicate.matches(dummy);
+ if (matches) {
+ LOG.debug("doSwitch selected: {}", whenClause.getLabel());
+ return createOutputsProcessor(whenClause.getOutputs());
+ }
+ }
+
+ if (definition.getOtherwise() != null) {
+ LOG.debug("doSwitch selected: otherwise");
+ return createProcessor(definition.getOtherwise());
+ }
+
+ // no cases were selected
+ LOG.debug("doSwitch no when or otherwise selected");
+ return null;
+ }
+
}
diff --git
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
index 42695ca..1f6a3fe 100644
---
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
+++
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
@@ -94,7 +94,6 @@ import org.apache.camel.model.SortDefinition;
import org.apache.camel.model.SplitDefinition;
import org.apache.camel.model.StepDefinition;
import org.apache.camel.model.StopDefinition;
-import org.apache.camel.model.SwitchDefinition;
import org.apache.camel.model.ThreadsDefinition;
import org.apache.camel.model.ThrottleDefinition;
import org.apache.camel.model.ThrowExceptionDefinition;
@@ -186,12 +185,7 @@ public abstract class ProcessorReifier<T extends
ProcessorDefinition<?>> extends
} else if (definition instanceof CatchDefinition) {
return new CatchReifier(route, definition);
} else if (definition instanceof ChoiceDefinition) {
- if (definition instanceof SwitchDefinition) {
- // switch is an optimized choice
- return new SwitchReifier(route, definition);
- } else {
- return new ChoiceReifier(route, definition);
- }
+ return new ChoiceReifier(route, definition);
} else if (definition instanceof CircuitBreakerDefinition) {
return new CircuitBreakerReifier(route, definition);
} else if (definition instanceof ClaimCheckDefinition) {
diff --git
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SwitchReifier.java
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SwitchReifier.java
deleted file mode 100644
index b160867..0000000
---
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/SwitchReifier.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.reifier;
-
-import org.apache.camel.Exchange;
-import org.apache.camel.ExpressionFactory;
-import org.apache.camel.Predicate;
-import org.apache.camel.Processor;
-import org.apache.camel.Route;
-import org.apache.camel.model.ProcessorDefinition;
-import org.apache.camel.model.SwitchDefinition;
-import org.apache.camel.model.WhenDefinition;
-import org.apache.camel.model.language.ExpressionDefinition;
-import org.apache.camel.spi.ExpressionFactoryAware;
-import org.apache.camel.support.DefaultExchange;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SwitchReifier extends ProcessorReifier<SwitchDefinition> {
-
- private static final Logger LOG =
LoggerFactory.getLogger(SwitchReifier.class);
-
- public SwitchReifier(Route route, ProcessorDefinition<?> definition) {
- super(route, SwitchDefinition.class.cast(definition));
- }
-
- @Override
- public Processor createProcessor() throws Exception {
- // prepare when predicates
- for (WhenDefinition whenClause : definition.getWhenClauses()) {
- ExpressionDefinition exp = whenClause.getExpression();
- if (exp.getExpressionType() != null) {
- exp = exp.getExpressionType();
- }
- Predicate pre = exp.getPredicate();
- if (pre instanceof ExpressionFactoryAware) {
- ExpressionFactoryAware aware = (ExpressionFactoryAware) pre;
- if (aware.getExpressionFactory() != null) {
- // if using the Java DSL then the expression may have been
- // set using the
- // ExpressionClause (implements ExpressionFactoryAware)
- // which is a fancy builder to define
- // expressions and predicates
- // using fluent builders in the DSL. However we need
- // afterwards a callback to
- // reset the expression to the expression type the
- // ExpressionClause did build for us
- ExpressionFactory model = aware.getExpressionFactory();
- if (model instanceof ExpressionDefinition) {
- whenClause.setExpression((ExpressionDefinition) model);
- }
- }
- }
- }
-
- // evaluate when predicates to optimize
- Exchange dummy = new DefaultExchange(camelContext);
- for (WhenDefinition whenClause : definition.getWhenClauses()) {
- ExpressionDefinition exp = whenClause.getExpression();
- exp.initPredicate(camelContext);
-
- Predicate predicate = exp.getPredicate();
- predicate.initPredicate(camelContext);
-
- boolean matches = predicate.matches(dummy);
- if (matches) {
- LOG.debug("doSwitch selected: {}", whenClause.getLabel());
- return createOutputsProcessor(whenClause.getOutputs());
- }
- }
-
- if (definition.getOtherwise() != null) {
- LOG.debug("doSwitch selected: otherwise");
- return createProcessor(definition.getOtherwise());
- }
-
- // no cases were selected
- LOG.debug("doSwitch no when or otherwise selected");
- return null;
- }
-
-}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateSwitchTest.java
b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateChoiceInPreconditionModeTest.java
similarity index 91%
rename from
core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateSwitchTest.java
rename to
core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateChoiceInPreconditionModeTest.java
index aef3a0a..557620f 100644
---
a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateSwitchTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateChoiceInPreconditionModeTest.java
@@ -19,10 +19,10 @@ package org.apache.camel.builder;
import org.apache.camel.ContextTestSupport;
import org.junit.jupiter.api.Test;
-public class RouteTemplateSwitchTest extends ContextTestSupport {
+class RouteTemplateChoiceInPreconditionModeTest extends ContextTestSupport {
@Test
- public void testRed() throws Exception {
+ void testRed() throws Exception {
TemplatedRouteBuilder.builder(context, "myTemplate")
.parameter("red", "true")
.parameter("blue", "false")
@@ -38,7 +38,7 @@ public class RouteTemplateSwitchTest extends
ContextTestSupport {
}
@Test
- public void testBlue() throws Exception {
+ void testBlue() throws Exception {
TemplatedRouteBuilder.builder(context, "myTemplate")
.parameter("red", "false")
.parameter("blue", "true")
@@ -54,7 +54,7 @@ public class RouteTemplateSwitchTest extends
ContextTestSupport {
}
@Test
- public void testNotProvidedBlue() throws Exception {
+ void testNotProvidedBlue() throws Exception {
TemplatedRouteBuilder.builder(context, "myTemplate")
.parameter("blue", "true")
.routeId("myRoute")
@@ -69,7 +69,7 @@ public class RouteTemplateSwitchTest extends
ContextTestSupport {
}
@Test
- public void testNotProvided() throws Exception {
+ void testNotProvided() throws Exception {
TemplatedRouteBuilder.builder(context, "myTemplate")
.routeId("myRoute")
.add();
@@ -92,7 +92,7 @@ public class RouteTemplateSwitchTest extends
ContextTestSupport {
.templateOptionalParameter("red")
.templateOptionalParameter("blue")
.from("direct:start")
- .doSwitch()
+ .choice().precondition()
.when(simple("{{?red}}")).to("mock:red")
.when(simple("{{?blue}}")).to("mock:blue")
.end()
diff --git
a/core/camel-core/src/test/java/org/apache/camel/processor/DoSwitchTest.java
b/core/camel-core/src/test/java/org/apache/camel/processor/ChoiceInPreconditionModeTest.java
similarity index 93%
rename from
core/camel-core/src/test/java/org/apache/camel/processor/DoSwitchTest.java
rename to
core/camel-core/src/test/java/org/apache/camel/processor/ChoiceInPreconditionModeTest.java
index f007e03..d6f3a8c 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/DoSwitchTest.java
+++
b/core/camel-core/src/test/java/org/apache/camel/processor/ChoiceInPreconditionModeTest.java
@@ -23,7 +23,7 @@ import org.apache.camel.builder.RouteBuilder;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-public class DoSwitchTest extends ContextTestSupport {
+class ChoiceInPreconditionModeTest extends ContextTestSupport {
@Override
public boolean isUseRouteBuilder() {
@@ -31,7 +31,7 @@ public class DoSwitchTest extends ContextTestSupport {
}
@Test
- public void testRed() throws Exception {
+ void testRed() throws Exception {
Properties init = new Properties();
init.setProperty("red", "true");
init.setProperty("blue", "false");
@@ -54,7 +54,7 @@ public class DoSwitchTest extends ContextTestSupport {
}
@Test
- public void testBlue() throws Exception {
+ void testBlue() throws Exception {
Properties init = new Properties();
init.setProperty("red", "false");
init.setProperty("blue", "true");
@@ -77,7 +77,7 @@ public class DoSwitchTest extends ContextTestSupport {
}
@Test
- public void testYellow() throws Exception {
+ void testYellow() throws Exception {
Properties init = new Properties();
init.setProperty("red", "false");
init.setProperty("blue", "false");
@@ -100,12 +100,12 @@ public class DoSwitchTest extends ContextTestSupport {
}
@Test
- public void testNone() throws Exception {
+ void testNone() throws Exception {
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").routeId("myRoute")
- .doSwitch().id("mySwitch")
+ .choice().precondition().id("mySwitch")
.when(simple("{{?red}}")).to("mock:red").id("myRed")
.when(simple("{{?blue}}")).to("mock:blue").id("myBlue")
.end()
@@ -132,7 +132,7 @@ public class DoSwitchTest extends ContextTestSupport {
return new RouteBuilder() {
public void configure() {
from("direct:start").routeId("myRoute")
- .doSwitch().id("mySwitch")
+ .choice().precondition(true).id("mySwitch")
.when(simple("{{red}}")).to("mock:red").id("myRed")
.when(simple("{{blue}}")).to("mock:blue").id("myBlue")
.otherwise().to("mock:yellow").id("myYellow");
diff --git
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 4aaca5f..94bdffd 100644
---
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -219,19 +219,21 @@ public class ModelParser extends BaseParser {
return doParse(new WhenDefinition(),
processorDefinitionAttributeHandler(),
outputExpressionNodeElementHandler(), noValueHandler());
}
- protected <T extends ChoiceDefinition> ElementHandler<T>
choiceDefinitionElementHandler() {
- return (def, key) -> {
+ protected ChoiceDefinition doParseChoiceDefinition() throws IOException,
XmlPullParserException {
+ return doParse(new ChoiceDefinition(), (def, key, val) -> {
+ if ("precondition".equals(key)) {
+ def.setPrecondition(val);
+ return true;
+ }
+ return processorDefinitionAttributeHandler().accept(def, key, val);
+ }, (def, key) -> {
switch (key) {
case "when": doAdd(doParseWhenDefinition(),
def.getWhenClauses(), def::setWhenClauses); break;
case "otherwise":
def.setOtherwise(doParseOtherwiseDefinition()); break;
default: return
optionalIdentifiedDefinitionElementHandler().accept(def, key);
}
return true;
- };
- }
- protected ChoiceDefinition doParseChoiceDefinition() throws IOException,
XmlPullParserException {
- return doParse(new ChoiceDefinition(),
- processorDefinitionAttributeHandler(),
choiceDefinitionElementHandler(), noValueHandler());
+ }, noValueHandler());
}
protected OtherwiseDefinition doParseOtherwiseDefinition() throws
IOException, XmlPullParserException {
return doParse(new OtherwiseDefinition(),
@@ -1365,10 +1367,6 @@ public class ModelParser extends BaseParser {
return doParse(new StopDefinition(),
processorDefinitionAttributeHandler(),
optionalIdentifiedDefinitionElementHandler(), noValueHandler());
}
- protected SwitchDefinition doParseSwitchDefinition() throws IOException,
XmlPullParserException {
- return doParse(new SwitchDefinition(),
- processorDefinitionAttributeHandler(),
choiceDefinitionElementHandler(), noValueHandler());
- }
protected TemplatedRouteBeanDefinition
doParseTemplatedRouteBeanDefinition() throws IOException,
XmlPullParserException {
return doParse(new TemplatedRouteBeanDefinition(),
beanFactoryDefinitionAttributeHandler(),
beanFactoryDefinitionElementHandler(), noValueHandler());
@@ -3266,7 +3264,6 @@ public class ModelParser extends BaseParser {
case "split": return doParseSplitDefinition();
case "step": return doParseStepDefinition();
case "stop": return doParseStopDefinition();
- case "doSwitch": return doParseSwitchDefinition();
case "threads": return doParseThreadsDefinition();
case "throttle": return doParseThrottleDefinition();
case "throwException": return doParseThrowExceptionDefinition();
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_16.adoc
b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_16.adoc
index e6cde7c..c235b8f 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_16.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_16.adoc
@@ -180,6 +180,28 @@ Removed some unnecessary methods in Java DSL.
Renamed `executorServiceRef` to `executorService`.
+=== DoSwitch EIP
+
+Replaced by Choice EIP in precondition mode.
+
+Before it was:
+[source,java]
+----
+.doSwitch()
+ .when(simple("{{?red}}")).to("mock:red")
+ .when(simple("{{?blue}}")).to("mock:blue")
+.end()
+----
+
+Now it is:
+[source,java]
+----
+.choice().precondition()
+ .when(simple("{{?red}}")).to("mock:red")
+ .when(simple("{{?blue}}")).to("mock:blue")
+.end()
+----
+
=== Enrich & Poll Enrich EIPs
Renamed `strategyRef` to `aggregationStrategy`, and marked this option as
required.
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index 34eb592..ab3c1f5 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -87,7 +87,6 @@ import org.apache.camel.model.SortDefinition;
import org.apache.camel.model.SplitDefinition;
import org.apache.camel.model.StepDefinition;
import org.apache.camel.model.StopDefinition;
-import org.apache.camel.model.SwitchDefinition;
import org.apache.camel.model.TemplatedRouteParameterDefinition;
import org.apache.camel.model.ThreadPoolProfileDefinition;
import org.apache.camel.model.ThreadsDefinition;
@@ -1674,6 +1673,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "id", type = "string"),
@YamlProperty(name = "inherit-error-handler", type =
"boolean"),
@YamlProperty(name = "otherwise", type =
"object:org.apache.camel.model.OtherwiseDefinition"),
+ @YamlProperty(name = "precondition", type = "boolean"),
@YamlProperty(name = "steps", type =
"array:org.apache.camel.model.ProcessorDefinition"),
@YamlProperty(name = "when", type =
"array:org.apache.camel.model.WhenDefinition")
}
@@ -1702,6 +1702,11 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
target.setOtherwise(val);
break;
}
+ case "precondition": {
+ String val = asText(node);
+ target.setPrecondition(val);
+ break;
+ }
case "when": {
java.util.List<org.apache.camel.model.WhenDefinition> val
= asFlatList(node, org.apache.camel.model.WhenDefinition.class);
target.setWhenClauses(val);
@@ -15050,73 +15055,6 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
}
@YamlType(
- types = org.apache.camel.model.SwitchDefinition.class,
- order =
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
- nodes = {
- "do-switch",
- "doSwitch"
- },
- properties = {
- @YamlProperty(name = "description", type = "string"),
- @YamlProperty(name = "id", type = "string"),
- @YamlProperty(name = "inherit-error-handler", type =
"boolean"),
- @YamlProperty(name = "otherwise", type =
"object:org.apache.camel.model.OtherwiseDefinition"),
- @YamlProperty(name = "steps", type =
"array:org.apache.camel.model.ProcessorDefinition"),
- @YamlProperty(name = "when", type =
"array:org.apache.camel.model.WhenDefinition")
- }
- )
- public static class SwitchDefinitionDeserializer extends
YamlDeserializerBase<SwitchDefinition> {
- public SwitchDefinitionDeserializer() {
- super(SwitchDefinition.class);
- }
-
- @Override
- protected SwitchDefinition newInstance() {
- return new SwitchDefinition();
- }
-
- @Override
- protected boolean setProperty(SwitchDefinition target, String
propertyKey,
- String propertyName, Node node) {
- switch(propertyKey) {
- case "inherit-error-handler": {
- String val = asText(node);
-
target.setInheritErrorHandler(java.lang.Boolean.valueOf(val));
- break;
- }
- case "otherwise": {
- org.apache.camel.model.OtherwiseDefinition val =
asType(node, org.apache.camel.model.OtherwiseDefinition.class);
- target.setOtherwise(val);
- break;
- }
- case "when": {
- java.util.List<org.apache.camel.model.WhenDefinition> val
= asFlatList(node, org.apache.camel.model.WhenDefinition.class);
- target.setWhenClauses(val);
- break;
- }
- case "id": {
- String val = asText(node);
- target.setId(val);
- break;
- }
- case "description": {
- org.apache.camel.model.DescriptionDefinition val =
asType(node, org.apache.camel.model.DescriptionDefinition.class);
- target.setDescription(val);
- break;
- }
- case "steps": {
- setSteps(target, node);
- break;
- }
- default: {
- return false;
- }
- }
- return true;
- }
- }
-
- @YamlType(
types = org.apache.camel.model.dataformat.SyslogDataFormat.class,
order =
org.apache.camel.dsl.yaml.common.YamlDeserializerResolver.ORDER_LOWEST - 1,
nodes = "syslog",
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
index 24c2fa8..8011976 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializersResolver.java
@@ -445,9 +445,6 @@ public final class ModelDeserializersResolver implements
YamlDeserializerResolve
case "org.apache.camel.model.StopDefinition": return new
ModelDeserializers.StopDefinitionDeserializer();
case "stream-config": return new
ModelDeserializers.StreamResequencerConfigDeserializer();
case "org.apache.camel.model.config.StreamResequencerConfig":
return new ModelDeserializers.StreamResequencerConfigDeserializer();
- case "do-switch": return new
ModelDeserializers.SwitchDefinitionDeserializer();
- case "doSwitch": return new
ModelDeserializers.SwitchDefinitionDeserializer();
- case "org.apache.camel.model.SwitchDefinition": return new
ModelDeserializers.SwitchDefinitionDeserializer();
case "syslog": return new
ModelDeserializers.SyslogDataFormatDeserializer();
case "org.apache.camel.model.dataformat.SyslogDataFormat": return
new ModelDeserializers.SyslogDataFormatDeserializer();
case "tar-file": return new
ModelDeserializers.TarFileDataFormatDeserializer();
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
index e7ac7f4..cdf77b0 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camel-yaml-dsl.json
@@ -236,12 +236,6 @@
"stop" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.StopDefinition"
},
- "do-switch" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.SwitchDefinition"
- },
- "doSwitch" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.SwitchDefinition"
- },
"threads" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.ThreadsDefinition"
},
@@ -628,6 +622,9 @@
"otherwise" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.OtherwiseDefinition"
},
+ "precondition" : {
+ "type" : "boolean"
+ },
"steps" : {
"type" : "array",
"items" : {
@@ -2950,35 +2947,6 @@
}
}
},
- "org.apache.camel.model.SwitchDefinition" : {
- "type" : "object",
- "properties" : {
- "description" : {
- "type" : "string"
- },
- "id" : {
- "type" : "string"
- },
- "inherit-error-handler" : {
- "type" : "boolean"
- },
- "otherwise" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.OtherwiseDefinition"
- },
- "steps" : {
- "type" : "array",
- "items" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.ProcessorDefinition"
- }
- },
- "when" : {
- "type" : "array",
- "items" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.WhenDefinition"
- }
- }
- }
- },
"org.apache.camel.model.TemplatedRouteBeanDefinition" : {
"type" : "object",
"properties" : {
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camelYamlDsl.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camelYamlDsl.json
index 7179ecf..f0628b0 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camelYamlDsl.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/camelYamlDsl.json
@@ -161,9 +161,6 @@
"stop" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.StopDefinition"
},
- "doSwitch" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.SwitchDefinition"
- },
"threads" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.ThreadsDefinition"
},
@@ -532,6 +529,9 @@
"otherwise" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.OtherwiseDefinition"
},
+ "precondition" : {
+ "type" : "boolean"
+ },
"steps" : {
"type" : "array",
"items" : {
@@ -2851,35 +2851,6 @@
}
}
},
- "org.apache.camel.model.SwitchDefinition" : {
- "type" : "object",
- "properties" : {
- "description" : {
- "type" : "string"
- },
- "id" : {
- "type" : "string"
- },
- "inheritErrorHandler" : {
- "type" : "boolean"
- },
- "otherwise" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.OtherwiseDefinition"
- },
- "steps" : {
- "type" : "array",
- "items" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.ProcessorDefinition"
- }
- },
- "when" : {
- "type" : "array",
- "items" : {
- "$ref" :
"#/items/definitions/org.apache.camel.model.WhenDefinition"
- }
- }
- }
- },
"org.apache.camel.model.TemplatedRouteBeanDefinition" : {
"type" : "object",
"properties" : {
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ChoiceTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ChoiceTest.groovy
index 9595c5b..4ae8a5f 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ChoiceTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ChoiceTest.groovy
@@ -65,4 +65,47 @@ class ChoiceTest extends YamlTestSupport {
}
}
}
+
+ def "choice in precondition mode"() {
+ when:
+ loadRoutes '''
+ - from:
+ uri: "direct:start"
+ steps:
+ - choice:
+ precondition: true
+ when:
+ - simple: "{{?red}}"
+ steps:
+ - to: "mock:red"
+ - simple: "{{?blue}}"
+ steps:
+ - to: "mock:blue"
+ otherwise:
+ steps:
+ - to: "mock:other"
+ '''
+ then:
+ context.routeDefinitions.size() == 1
+
+ with(context.routeDefinitions[0].outputs[0], ChoiceDefinition) {
+ with(whenClauses[0], WhenDefinition) {
+ expression.language == 'simple'
+ expression.expression == '{{?red}}'
+ with(outputs[0], ToDefinition) {
+ endpointUri == 'mock:red'
+ }
+ }
+ with(whenClauses[1], WhenDefinition) {
+ expression.language == 'simple'
+ expression.expression == '{{?blue}}'
+ with(outputs[0], ToDefinition) {
+ endpointUri == 'mock:blue'
+ }
+ }
+ with(otherwise.outputs[0], ToDefinition) {
+ endpointUri == 'mock:other'
+ }
+ }
+ }
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SwitchTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SwitchTest.groovy
deleted file mode 100644
index 2d5730c..0000000
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/SwitchTest.groovy
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.dsl.yaml
-
-import org.apache.camel.dsl.yaml.support.YamlTestSupport
-import org.apache.camel.model.SwitchDefinition
-import org.apache.camel.model.ToDefinition
-import org.apache.camel.model.WhenDefinition
-
-class SwitchTest extends YamlTestSupport {
-
- def "switch definition"() {
- when:
- loadRoutes '''
- - from:
- uri: "direct:start"
- steps:
- - doSwitch:
- when:
- - simple: "{{?red}}"
- steps:
- - to: "mock:red"
- - simple: "{{?blue}}"
- steps:
- - to: "mock:blue"
- otherwise:
- steps:
- - to: "mock:other"
- '''
- then:
- context.routeDefinitions.size() == 1
-
- with(context.routeDefinitions[0].outputs[0], SwitchDefinition) {
- with(whenClauses[0], WhenDefinition) {
- expression.language == 'simple'
- expression.expression == '{{?red}}'
- with(outputs[0], ToDefinition) {
- endpointUri == 'mock:red'
- }
- }
- with(whenClauses[1], WhenDefinition) {
- expression.language == 'simple'
- expression.expression == '{{?blue}}'
- with(outputs[0], ToDefinition) {
- endpointUri == 'mock:blue'
- }
- }
- with(otherwise.outputs[0], ToDefinition) {
- endpointUri == 'mock:other'
- }
- }
- }
-}