This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch bf in repository https://gitbox.apache.org/repos/asf/camel.git
commit b3ae34d488a847ad972cb130bee0ba1e8ed73cb2 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Feb 5 15:40:06 2026 +0100 CAMEL-22958: camel-core - Add properties function for boolean to give more flexibility --- .../properties/BooleanPropertiesFunction.java | 79 ++++++++++++++++++++++ .../DefaultPropertiesFunctionResolver.java | 2 + .../properties/PropertiesComponentBooleanTest.java | 76 +++++++++++++++++++++ .../ROOT/pages/using-propertyplaceholder.adoc | 29 ++++++++ 4 files changed, 186 insertions(+) diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/BooleanPropertiesFunction.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/BooleanPropertiesFunction.java new file mode 100644 index 000000000000..c30640461fbe --- /dev/null +++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/BooleanPropertiesFunction.java @@ -0,0 +1,79 @@ +/* + * 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.component.properties; + +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.Exchange; +import org.apache.camel.Expression; +import org.apache.camel.Predicate; +import org.apache.camel.spi.Language; +import org.apache.camel.spi.PropertiesFunction; +import org.apache.camel.support.DefaultExchange; +import org.apache.camel.support.service.ServiceSupport; +import org.apache.camel.util.StringHelper; + +/** + * A {@link PropertiesFunction} that evaluates whether a property placeholder matches a given condition + */ +public class BooleanPropertiesFunction extends ServiceSupport implements PropertiesFunction, CamelContextAware { + + private CamelContext camelContext; + private Language lan; + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public String getName() { + return "boolean"; + } + + @Override + public String apply(String remainder) { + String key = StringHelper.before(remainder, " ", remainder); + String bool = StringHelper.after(remainder, " "); + if (bool != null) { + bool = bool.trim(); + } + + // key is property placeholder key + String simple = "${properties:" + key + "}"; + if (bool != null) { + simple += " " + bool; + } + + Predicate pred = lan.createPredicate(simple); + Exchange dummy = new DefaultExchange(camelContext); + boolean matches = pred.matches(dummy); + + return matches ? "true" : "false"; + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + lan = camelContext.resolveLanguage("simple"); + } +} diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesFunctionResolver.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesFunctionResolver.java index 334414aaa18c..a88f42816b02 100644 --- a/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesFunctionResolver.java +++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/DefaultPropertiesFunctionResolver.java @@ -49,6 +49,7 @@ public class DefaultPropertiesFunctionResolver extends ServiceSupport addPropertiesFunction(new ServicePropertiesFunction()); addPropertiesFunction(new ServiceHostPropertiesFunction()); addPropertiesFunction(new ServicePortPropertiesFunction()); + addPropertiesFunction(new BooleanPropertiesFunction()); } @Override @@ -123,6 +124,7 @@ public class DefaultPropertiesFunctionResolver extends ServiceSupport @Override protected void doInit() throws Exception { + functions.values().forEach(f -> CamelContextAware.trySetCamelContext(f, camelContext)); ServiceHelper.initService(functions.values()); } diff --git a/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentBooleanTest.java b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentBooleanTest.java new file mode 100644 index 000000000000..2b3a723a5a1c --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/component/properties/PropertiesComponentBooleanTest.java @@ -0,0 +1,76 @@ +/* + * 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.component.properties; + +import org.apache.camel.ContextTestSupport;` +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Test; + +public class PropertiesComponentBooleanTest extends ContextTestSupport { + + @Override + public boolean isUseRouteBuilder() { + return false; + } + + @Test + public void testFunctionTrue() throws Exception { + context.getPropertiesComponent().addInitialProperty("customer", "A"); + + context.addRoutes(new RouteBuilder() { + @Override + public void configure() { + from("direct:start") + .to("mock:foo") + .transform().constant("Customer A is here").disabled("{{boolean:customer != 'A'}}") + .to("mock:bar"); + } + }); + context.start(); + + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:bar").expectedBodiesReceived("Customer A is here"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testFunctionFalse() throws Exception { + context.getPropertiesComponent().addInitialProperty("customer", "B"); + + context.addRoutes(new RouteBuilder() { + @Override + public void configure() { + from("direct:start") + .to("mock:foo") + .transform().constant("Customer A is here").disabled("{{boolean:customer != 'A'}}") + .to("mock:bar"); + } + }); + context.start(); + + getMockEndpoint("mock:foo").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:bar").expectedBodiesReceived("Hello World"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + +} diff --git a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc index c3b4ec227f81..ae7b806d6995 100644 --- a/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc +++ b/docs/user-manual/modules/ROOT/pages/using-propertyplaceholder.adoc @@ -459,6 +459,7 @@ The xref:components::properties-component.adoc[Properties] component includes th * `env` - A function to lookup the property from OS environment variables * `sys` - A function to lookup the property from Java JVM system properties * `bean` - A function to lookup the property from the return value of bean's method (requires `camel-bean` JAR) +* `boolean` - A function to evaluate if a property key matches a condition and returns either `true` or `false` * `service` - A function to lookup the property from OS environment variables using the service naming idiom * `service.name` - A function to lookup the property from OS environment variables using the service naming idiom returning the hostname part only * `service.port` - A function to lookup the property from OS environment variables using the service naming idiom returning the port part only @@ -489,6 +490,34 @@ You can use default values as well, so if the property does not exist, you can d </camelContext> ---- +The boolean function is intended for more flexibility when enabling or disabling EIP options. + +For example given we have a property with key `region` that has the value `EMEA`: + +[source,properties] +---- +region = EMEA +---- + +We can then configure EIPs whether they are disabled based on this condition as follows: + +[source,yaml] +---- + - choice: + disabled: "{{boolean:region == 'EMEA`}}" + when: + - simple: "${header.RetryAttempts} == null" + steps: + - setProperty: + name: "HttpMessageMethod" + constant: "SET" + - process: + ref: "SetOriginalMessageProcessor" + ... +---- + +TIP: The boolean function uses the xref:components:languages:simple-language.adoc[Simple] language which has many functions and operators to build the condition. + The service function is for looking up a service which is defined using OS environment variables using the service naming idiom, to refer to a service location using `hostname : port` * __NAME__**_SERVICE_HOST**
