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 3447b838aa6 CAMEL-20897: Allow to use {xxx} inside RAW(xxx) for more
power (#14615)
3447b838aa6 is described below
commit 3447b838aa6bca1ad70eb4914609b46bda5ddf96
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jun 21 11:36:59 2024 +0200
CAMEL-20897: Allow to use {xxx} inside RAW(xxx) for more power (#14615)
---
.../impl/engine/PrototypeExchangeFactory.java | 7 ---
.../support/component/RawParameterHelperTest.java | 56 ++++++++++++++++++++++
.../org/apache/camel/support/DefaultComponent.java | 3 +-
.../support/component/RawParameterHelper.java | 51 ++++++++++++++++++++
.../support/component/SendDynamicAwareSupport.java | 5 +-
.../java/org/apache/camel/util/URISupport.java | 23 +++++++++
.../faq/pages/how-do-i-configure-endpoints.adoc | 13 +++++
7 files changed, 147 insertions(+), 11 deletions(-)
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PrototypeExchangeFactory.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PrototypeExchangeFactory.java
index be8a697c10a..dbb808092e7 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PrototypeExchangeFactory.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/PrototypeExchangeFactory.java
@@ -50,13 +50,6 @@ public class PrototypeExchangeFactory extends
PooledObjectFactorySupport<Exchang
protected void doBuild() throws Exception {
super.doBuild();
this.exchangeFactoryManager =
camelContext.getCamelContextExtension().getExchangeFactoryManager();
- // force creating and load the class during build time so the JVM does
not
- // load the class on first exchange to be created
- DefaultExchange dummy = new DefaultExchange(camelContext);
- // force message init to load classes
- dummy.getIn();
- dummy.getIn().getHeaders();
- LOG.trace("Warming up PrototypeExchangeFactory loaded class: {}",
dummy.getClass().getName());
}
@Override
diff --git
a/core/camel-core/src/test/java/org/apache/camel/support/component/RawParameterHelperTest.java
b/core/camel-core/src/test/java/org/apache/camel/support/component/RawParameterHelperTest.java
new file mode 100644
index 00000000000..6d8cc4c968f
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/support/component/RawParameterHelperTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.support.component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class RawParameterHelperTest extends ContextTestSupport {
+
+ @Override
+ public boolean isUseRouteBuilder() {
+ return false;
+ }
+
+ @Test
+ public void testResolveRawParameterValues() throws Exception {
+ Map<String, Object> map = new HashMap<>();
+ map.put("username", "abc");
+ map.put("password", "RAW(sec*ret)");
+
+ RawParameterHelper.resolveRawParameterValues(context, map);
+ Assertions.assertEquals("abc", map.get("username"));
+ Assertions.assertEquals("sec*ret", map.get("password"));
+
+ map.put("password", "RAW($simple{camelId})");
+ RawParameterHelper.resolveRawParameterValues(context, map);
+ Assertions.assertEquals("abc", map.get("username"));
+ Assertions.assertEquals(context.getName(), map.get("password"));
+
+ String usr = System.getenv("USER");
+ if (usr != null) {
+ map.put("password", "RAW($simple{env:USER})");
+ RawParameterHelper.resolveRawParameterValues(context, map);
+ Assertions.assertEquals("abc", map.get("username"));
+ Assertions.assertEquals(usr, map.get("password"));
+ }
+ }
+}
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
index dd9ad5e8d19..577b92bfe3d 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultComponent.java
@@ -37,6 +37,7 @@ import
org.apache.camel.component.extension.ComponentExtension;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.PropertyConfigurer;
import org.apache.camel.spi.PropertyConfigurerAware;
+import org.apache.camel.support.component.RawParameterHelper;
import org.apache.camel.support.service.ServiceSupport;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.PropertiesHelper;
@@ -132,7 +133,7 @@ public abstract class DefaultComponent extends
ServiceSupport implements Compone
// parameters using raw syntax: RAW(value)
// should have the token removed, so its only the value we have in
parameters, as we are about to create
// an endpoint and want to have the parameter values without the
RAW tokens
- URISupport.resolveRawParameterValues(parameters);
+ RawParameterHelper.resolveRawParameterValues(camelContext,
parameters);
}
// use encoded or raw uri?
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/component/RawParameterHelper.java
b/core/camel-support/src/main/java/org/apache/camel/support/component/RawParameterHelper.java
new file mode 100644
index 00000000000..1f5278c5ebb
--- /dev/null
+++
b/core/camel-support/src/main/java/org/apache/camel/support/component/RawParameterHelper.java
@@ -0,0 +1,51 @@
+/*
+ * 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.support.component;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.util.URISupport;
+
+public final class RawParameterHelper {
+
+ private RawParameterHelper() {
+ }
+
+ /**
+ * Traverses the given parameters, and resolve any parameter values which
uses the RAW token syntax:
+ * <tt>key=RAW(value)</tt>. This method will then remove the RAW tokens,
and replace the content of the value, with
+ * just the value.
+ *
+ * The value can refer to a simple expression using $simple{xxx} syntax
which allows to refer to passwords defined
+ * as ENV variables etc.
+ *
+ * @param camelContext the camel context
+ * @param parameters the uri parameters
+ */
+ public static void resolveRawParameterValues(CamelContext camelContext,
Map<String, Object> parameters) {
+ URISupport.resolveRawParameterValues(parameters, s -> {
+ if (s != null && s.contains("$simple{")) {
+ Exchange dummy = new DefaultExchange(camelContext);
+ s =
camelContext.resolveLanguage("simple").createExpression(s).evaluate(dummy,
String.class);
+ }
+ return s;
+ });
+ }
+}
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
b/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
index 0d09f8f776e..3655d799693 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/component/SendDynamicAwareSupport.java
@@ -85,7 +85,7 @@ public abstract class SendDynamicAwareSupport extends
ServiceSupport implements
// parameters using raw syntax: RAW(value)
// should have the token removed, so its only the value we
have in parameters, as we are about to create
// an endpoint and want to have the parameter values without
the RAW tokens
- URISupport.resolveRawParameterValues(map);
+
RawParameterHelper.resolveRawParameterValues(exchange.getContext(), map);
}
// okay so only add the known properties as they are the non
lenient properties
properties = new LinkedHashMap<>();
@@ -116,7 +116,7 @@ public abstract class SendDynamicAwareSupport extends
ServiceSupport implements
// parameters using raw syntax: RAW(value)
// should have the token removed, so its only the value we
have in parameters, as we are about to create
// an endpoint and want to have the parameter values without
the RAW tokens
- URISupport.resolveRawParameterValues(map);
+
RawParameterHelper.resolveRawParameterValues(exchange.getContext(), map);
}
properties = new LinkedHashMap<>();
map.forEach((k, v) -> {
@@ -138,7 +138,6 @@ public abstract class SendDynamicAwareSupport extends
ServiceSupport implements
public String asEndpointUri(Exchange exchange, String uri, Map<String,
Object> properties) throws Exception {
String query = URISupport.createQueryString(properties, false);
-
return StringHelper.before(uri, "?", uri) + "?" + query;
}
diff --git
a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
index c8afdcb6f12..cfb09f010a0 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
@@ -30,6 +30,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Function;
import java.util.regex.Pattern;
import static org.apache.camel.util.CamelURIParser.URI_ALREADY_NORMALIZED;
@@ -316,6 +317,22 @@ public final class URISupport {
* @see #RAW_TOKEN_END
*/
public static void resolveRawParameterValues(Map<String, Object>
parameters) {
+ resolveRawParameterValues(parameters, null);
+ }
+
+ /**
+ * Traverses the given parameters, and resolve any parameter values which
uses the RAW token syntax:
+ * <tt>key=RAW(value)</tt>. This method will then remove the RAW tokens,
and replace the content of the value, with
+ * just the value.
+ *
+ * @param parameters the uri parameters
+ * @param onReplace optional function executed when replace the raw value
+ * @see #parseQuery(String)
+ * @see #RAW_TOKEN_PREFIX
+ * @see #RAW_TOKEN_START
+ * @see #RAW_TOKEN_END
+ */
+ public static void resolveRawParameterValues(Map<String, Object>
parameters, Function<String, String> onReplace) {
for (Map.Entry<String, Object> entry : parameters.entrySet()) {
if (entry.getValue() == null) {
continue;
@@ -336,6 +353,9 @@ public final class URISupport {
// do not encode RAW parameters unless it has %
// need to reverse: replace % with %25 to avoid losing
"%" when decoding
String s = raw.replace("%25", "%");
+ if (onReplace != null) {
+ s = onReplace.apply(s);
+ }
list.set(i, s);
}
}
@@ -346,6 +366,9 @@ public final class URISupport {
// do not encode RAW parameters unless it has %
// need to reverse: replace % with %25 to avoid losing "%"
when decoding
String s = raw.replace("%25", "%");
+ if (onReplace != null) {
+ s = onReplace.apply(s);
+ }
entry.setValue(s);
}
}
diff --git
a/docs/user-manual/modules/faq/pages/how-do-i-configure-endpoints.adoc
b/docs/user-manual/modules/faq/pages/how-do-i-configure-endpoints.adoc
index da44e99e9bb..79ec4d547a0 100644
--- a/docs/user-manual/modules/faq/pages/how-do-i-configure-endpoints.adoc
+++ b/docs/user-manual/modules/faq/pages/how-do-i-configure-endpoints.adoc
@@ -136,6 +136,19 @@ actual password would be as typed, eg `se+re?t&23`.
NOTE: you may find a corner case when you use both `)` and `&` character as
part of your password (ie, `se+re)t&23`). The parser will interpret the `)` as
closing the `RAW` function and having a parameter started by `&`. In such case,
you can instead use the `RAW{}` notation to let you include the `)` character
and have it decoded as part of the password (ie, `RAW{se+re)t&23}`). As a safe
alternative you can also use `password=#property:myPass` and then have `myPass`
a xref:ROOT:property [...]
+==== Using ENV variables with raw values
+
+*Since Camel 4.7*
+
+If you need to use environment variables, for example as username or passwords
then this is now possible by inlining
+the xref:components:languages:simple-language.adoc[Simple] language
+using `+++$simple{xxx}+++` syntax in `RAW(...)` as shown below:
+
+[source,java]
+----
+.to("ftp:[email protected]?password=RAW($simple{env:MY_FTP_PASSWORD})&binary=true")
+----
+
[[HowdoIconfigureendpoints-Usingpropertyplaceholders]]
=== Using property placeholders