You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/01/11 14:59:47 UTC
[camel] branch main updated: CAMEL-17468: camel-core - Filter EIP - add option to turn on exchange property with filter status
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 23ae746 CAMEL-17468: camel-core - Filter EIP - add option to turn on exchange property with filter status
23ae746 is described below
commit 23ae7466c8acdca657041ef24aa1700f809f0a69
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Jan 11 15:58:52 2022 +0100
CAMEL-17468: camel-core - Filter EIP - add option to turn on exchange property with filter status
---
.../main/docs/modules/eips/pages/filter-eip.adoc | 32 ++++++++++++
.../resources/org/apache/camel/model/filter.json | 1 +
.../org/apache/camel/model/FilterDefinition.java | 22 ++++++++
.../apache/camel/processor/FilterProcessor.java | 12 +++++
.../org/apache/camel/reifier/FilterReifier.java | 7 ++-
.../camel/processor/FilterStatusPropertyTest.java | 61 ++++++++++++++++++++++
.../java/org/apache/camel/xml/in/ModelParser.java | 9 +++-
.../dsl/yaml/deserializers/ModelDeserializers.java | 6 +++
.../src/generated/resources/camel-yaml-dsl.json | 3 ++
9 files changed, 150 insertions(+), 3 deletions(-)
diff --git a/core/camel-core-engine/src/main/docs/modules/eips/pages/filter-eip.adoc b/core/camel-core-engine/src/main/docs/modules/eips/pages/filter-eip.adoc
index 9e05c29..15f2941 100644
--- a/core/camel-core-engine/src/main/docs/modules/eips/pages/filter-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/modules/eips/pages/filter-eip.adoc
@@ -116,6 +116,38 @@ of the bean as shown:
</route>
----
+=== Filtering with status property
+
+To know whether an `Exchange` was filtered or not, then you can choose to specify a name of a property
+to store on the exchange with the result (boolean), using `statusPropertyName` as shown below:
+
+[source,java]
+----
+from("direct:start")
+ .filter().method(MyBean.class, "isGoldCustomer").statusPropertyName("gold")
+ .to("mock:gold")
+ .end()
+ .to("mock:all");
+}
+----
+
+And in XML:
+
+[source,xml]
+----
+<route>
+ <from uri="direct:start"/>
+ <filter statusPropertyName="gold">
+ <method type="com.foo.MyBean" method="isGoldCustomer"/>
+ <to uri="mock:gold"/>
+ </filter>
+ <to uri="mock:all"/>
+</route>
+----
+
+In the example above then Camel will store an exchange property with key `gold` with the result of the filtering,
+whether it was `true` or `false`.
+
=== Filtering and stopping
When using the Message Filter EIP, then it only applies to its children.
diff --git a/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json b/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json
index 173a586..31cefd5 100644
--- a/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json
+++ b/core/camel-core-model/src/generated/resources/org/apache/camel/model/filter.json
@@ -13,6 +13,7 @@
},
"properties": {
"expression": { "kind": "expression", "displayName": "Expression", "required": true, "type": "object", "javaType": "org.apache.camel.model.language.ExpressionDefinition", "oneOf": [ "constant", "csimple", "datasonnet", "exchangeProperty", "groovy", "header", "hl7terser", "joor", "jsonpath", "language", "method", "mvel", "ognl", "ref", "simple", "spel", "tokenize", "xpath", "xquery", "xtokenize" ], "deprecated": false, "autowired": false, "secret": false, "asPredicate": true, "descrip [...]
+ "statusPropertyName": { "kind": "attribute", "displayName": "Status Property Name", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Name of exchange property to use for storing the status of the filtering. Setting this allows to know if the filter predicate evaluated as true or false." },
"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/main/java/org/apache/camel/model/FilterDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/FilterDefinition.java
index 8f770fc..244339d 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/FilterDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/FilterDefinition.java
@@ -18,6 +18,7 @@ package org.apache.camel.model;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.camel.Predicate;
@@ -34,6 +35,9 @@ import org.apache.camel.spi.Metadata;
@XmlAccessorType(XmlAccessType.FIELD)
public class FilterDefinition extends OutputExpressionNode {
+ @XmlAttribute
+ private String statusPropertyName;
+
public FilterDefinition() {
}
@@ -60,6 +64,14 @@ public class FilterDefinition extends OutputExpressionNode {
return "filter[" + getExpression() + "]";
}
+ public String getStatusPropertyName() {
+ return statusPropertyName;
+ }
+
+ public void setStatusPropertyName(String statusPropertyName) {
+ this.statusPropertyName = statusPropertyName;
+ }
+
/**
* Expression to determine if the message should be filtered or not. If the expression returns an empty value or
* <tt>false</tt> then the message is filtered (dropped), otherwise the message is continued being routed.
@@ -69,4 +81,14 @@ public class FilterDefinition extends OutputExpressionNode {
// override to include javadoc what the expression is used for
super.setExpression(expression);
}
+
+ /**
+ * Name of exchange property to use for storing the status of the filtering.
+ *
+ * Setting this allows to know if the filter predicate evaluated as true or false.
+ */
+ public FilterDefinition statusPropertyName(String statusPropertyName) {
+ this.statusPropertyName = statusPropertyName;
+ return this;
+ }
}
diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/FilterProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/FilterProcessor.java
index ae41e5b..5d66449 100644
--- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/FilterProcessor.java
+++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/FilterProcessor.java
@@ -42,6 +42,7 @@ public class FilterProcessor extends DelegateAsyncProcessor implements Traceable
private String routeId;
private final Predicate predicate;
private transient long filtered;
+ private String statusPropertyName;
public FilterProcessor(CamelContext context, Predicate predicate, Processor processor) {
super(processor);
@@ -49,6 +50,14 @@ public class FilterProcessor extends DelegateAsyncProcessor implements Traceable
this.predicate = predicate;
}
+ public String getStatusPropertyName() {
+ return statusPropertyName;
+ }
+
+ public void setStatusPropertyName(String statusPropertyName) {
+ this.statusPropertyName = statusPropertyName;
+ }
+
@Override
protected void doInit() throws Exception {
super.doInit();
@@ -61,6 +70,9 @@ public class FilterProcessor extends DelegateAsyncProcessor implements Traceable
try {
matches = matches(exchange);
+ if (statusPropertyName != null) {
+ exchange.setProperty(statusPropertyName, matches);
+ }
} catch (Exception e) {
exchange.setException(e);
}
diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FilterReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FilterReifier.java
index 239a82b..5436386 100644
--- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FilterReifier.java
+++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FilterReifier.java
@@ -35,9 +35,14 @@ public class FilterReifier extends ExpressionReifier<FilterDefinition> {
@Override
protected FilterProcessor createFilterProcessor() throws Exception {
+ String status = parseString(definition.getStatusPropertyName());
+
// filter EIP should have child outputs
Processor childProcessor = this.createChildProcessor(true);
- return new FilterProcessor(camelContext, createPredicate(), childProcessor);
+
+ FilterProcessor answer = new FilterProcessor(camelContext, createPredicate(), childProcessor);
+ answer.setStatusPropertyName(status);
+ return answer;
}
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/FilterStatusPropertyTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/FilterStatusPropertyTest.java
new file mode 100644
index 0000000..9b1c054
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/FilterStatusPropertyTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+public class FilterStatusPropertyTest extends ContextTestSupport {
+
+ @Test
+ public void testSendMatchingMessage() throws Exception {
+ getMockEndpoint("mock:bar").expectedMessageCount(1);
+ getMockEndpoint("mock:bar").message(0).exchangeProperty("myBar").isEqualTo(true);
+ getMockEndpoint("mock:result").expectedMessageCount(1);
+ getMockEndpoint("mock:result").message(0).exchangeProperty("myBar").isEqualTo(true);
+
+ template.sendBodyAndHeader("direct:start", "<matched/>", "foo", "bar");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Test
+ public void testSendNotMatchingMessage() throws Exception {
+ getMockEndpoint("mock:bar").expectedMessageCount(0);
+ getMockEndpoint("mock:result").expectedMessageCount(1);
+ getMockEndpoint("mock:result").message(0).exchangeProperty("myBar").isEqualTo(false);
+
+ template.sendBodyAndHeader("direct:start", "<notMatched/>", "foo", "notMatchedHeaderValue");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ public void configure() {
+ from("direct:start")
+ .filter(header("foo").isEqualTo("bar")).statusPropertyName("myBar")
+ .to("mock:bar")
+ .end()
+ .to("mock:result");
+ }
+ };
+ }
+
+}
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 bf04ce6..49fbc89 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
@@ -403,8 +403,13 @@ public class ModelParser extends BaseParser {
return doParse(new FaultToleranceConfigurationCommon(), faultToleranceConfigurationCommonAttributeHandler(), noElementHandler(), noValueHandler());
}
protected FilterDefinition doParseFilterDefinition() throws IOException, XmlPullParserException {
- return doParse(new FilterDefinition(),
- processorDefinitionAttributeHandler(), outputExpressionNodeElementHandler(), noValueHandler());
+ return doParse(new FilterDefinition(), (def, key, val) -> {
+ if ("statusPropertyName".equals(key)) {
+ def.setStatusPropertyName(val);
+ return true;
+ }
+ return processorDefinitionAttributeHandler().accept(def, key, val);
+ }, outputExpressionNodeElementHandler(), noValueHandler());
}
protected <T extends OutputExpressionNode> ElementHandler<T> outputExpressionNodeElementHandler() {
return (def, key) -> {
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 a3b978e..962193f 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
@@ -5142,6 +5142,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
@YamlProperty(name = "__extends", type = "object:org.apache.camel.model.language.ExpressionDefinition"),
@YamlProperty(name = "expression", type = "object:org.apache.camel.model.language.ExpressionDefinition"),
@YamlProperty(name = "inherit-error-handler", type = "boolean"),
+ @YamlProperty(name = "status-property-name", type = "string"),
@YamlProperty(name = "steps", type = "array:org.apache.camel.model.ProcessorDefinition")
}
)
@@ -5169,6 +5170,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport {
target.setInheritErrorHandler(java.lang.Boolean.valueOf(val));
break;
}
+ case "status-property-name": {
+ String val = asText(node);
+ target.setStatusPropertyName(val);
+ break;
+ }
case "id": {
String val = asText(node);
target.setId(val);
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 08075c1..67eead4 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
@@ -913,6 +913,9 @@
"inherit-error-handler" : {
"type" : "boolean"
},
+ "status-property-name" : {
+ "type" : "string"
+ },
"steps" : {
"type" : "array",
"items" : {