This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch re
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 376f0c52c4bb1f8d6efae8817f2983e9ea8d72a6
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jun 26 10:23:36 2025 +0200

    CAMEL-22200: components that are resource endpoint based should have 
content cache true as default and make it configurable on component level.
---
 .../component/jsonpatch/JsonPatchEndpoint.java     |  2 +-
 .../jsonata/JsonataComponentConfigurer.java        | 12 +++++
 .../apache/camel/component/jsonata/jsonata.json    |  8 +--
 .../camel/component/jsonata/JsonataComponent.java  | 33 +++++++++++-
 .../camel/component/jsonata/JsonataRefTest.java    | 63 ++++++++++++++++++++++
 5 files changed, 113 insertions(+), 5 deletions(-)

diff --git 
a/components/camel-json-patch/src/main/java/org/apache/camel/component/jsonpatch/JsonPatchEndpoint.java
 
b/components/camel-json-patch/src/main/java/org/apache/camel/component/jsonpatch/JsonPatchEndpoint.java
index 985c139d941..e0c07825345 100644
--- 
a/components/camel-json-patch/src/main/java/org/apache/camel/component/jsonpatch/JsonPatchEndpoint.java
+++ 
b/components/camel-json-patch/src/main/java/org/apache/camel/component/jsonpatch/JsonPatchEndpoint.java
@@ -33,7 +33,7 @@ import org.apache.camel.spi.UriParam;
              category = { Category.TRANSFORMATION }, headersClass = 
JsonPatchConstants.class)
 public class JsonPatchEndpoint extends ResourceEndpoint {
 
-    @UriParam(defaultValue = "false")
+    @UriParam
     private boolean allowTemplateFromHeader;
 
     public JsonPatchEndpoint() {
diff --git 
a/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataComponentConfigurer.java
 
b/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataComponentConfigurer.java
index 86bb0ad4957..c6829e5994d 100644
--- 
a/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataComponentConfigurer.java
+++ 
b/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataComponentConfigurer.java
@@ -23,8 +23,12 @@ public class JsonataComponentConfigurer extends 
PropertyConfigurerSupport implem
     public boolean configure(CamelContext camelContext, Object obj, String 
name, Object value, boolean ignoreCase) {
         JsonataComponent target = (JsonataComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": 
target.setAllowTemplateFromHeader(property(camelContext, boolean.class, 
value)); return true;
         case "autowiredenabled":
         case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
+        case "contentcache":
+        case "contentCache": target.setContentCache(property(camelContext, 
boolean.class, value)); return true;
         case "framebinding":
         case "frameBinding": target.setFrameBinding(property(camelContext, 
org.apache.camel.component.jsonata.JsonataFrameBinding.class, value)); return 
true;
         case "lazystartproducer":
@@ -36,8 +40,12 @@ public class JsonataComponentConfigurer extends 
PropertyConfigurerSupport implem
     @Override
     public Class<?> getOptionType(String name, boolean ignoreCase) {
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return boolean.class;
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
+        case "contentcache":
+        case "contentCache": return boolean.class;
         case "framebinding":
         case "frameBinding": return 
org.apache.camel.component.jsonata.JsonataFrameBinding.class;
         case "lazystartproducer":
@@ -50,8 +58,12 @@ public class JsonataComponentConfigurer extends 
PropertyConfigurerSupport implem
     public Object getOptionValue(Object obj, String name, boolean ignoreCase) {
         JsonataComponent target = (JsonataComponent) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
+        case "allowtemplatefromheader":
+        case "allowTemplateFromHeader": return 
target.isAllowTemplateFromHeader();
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "contentcache":
+        case "contentCache": return target.isContentCache();
         case "framebinding":
         case "frameBinding": return target.getFrameBinding();
         case "lazystartproducer":
diff --git 
a/components/camel-jsonata/src/generated/resources/META-INF/org/apache/camel/component/jsonata/jsonata.json
 
b/components/camel-jsonata/src/generated/resources/META-INF/org/apache/camel/component/jsonata/jsonata.json
index ab46b61d8a8..af8b338bccf 100644
--- 
a/components/camel-jsonata/src/generated/resources/META-INF/org/apache/camel/component/jsonata/jsonata.json
+++ 
b/components/camel-jsonata/src/generated/resources/META-INF/org/apache/camel/component/jsonata/jsonata.json
@@ -24,9 +24,11 @@
     "remote": false
   },
   "componentProperties": {
-    "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
-    "frameBinding": { "index": 2, "kind": "property", "displayName": "Frame 
Binding", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.jsonata.JsonataFrameBinding", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
configure custom frame bindings and inject user functions." }
+    "allowTemplateFromHeader": { "index": 0, "kind": "property", 
"displayName": "Allow Template From Header", "group": "producer", "label": "", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Whether to allow to use resource template from header or not 
(default false). Enabling this allows to specify dynamic templates via message 
header. However this can be seen as a potential se [...]
+    "contentCache": { "index": 1, "kind": "property", "displayName": "Content 
Cache", "group": "producer", "label": "", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "autowired": false, "secret": 
false, "defaultValue": true, "description": "Sets whether to use resource 
content cache or not" },
+    "lazyStartProducer": { "index": 2, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
+    "autowiredEnabled": { "index": 3, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "frameBinding": { "index": 4, "kind": "property", "displayName": "Frame 
Binding", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "org.apache.camel.component.jsonata.JsonataFrameBinding", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
configure custom frame bindings and inject user functions." }
   },
   "properties": {
     "resourceUri": { "index": 0, "kind": "path", "displayName": "Resource 
Uri", "group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "supportFileReference": true, 
"description": "Path to the resource. You can prefix with: classpath, file, 
http, ref, or bean. classpath, file and http loads the resource using these 
protocols (classpath is default). ref will look [...]
diff --git 
a/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataComponent.java
 
b/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataComponent.java
index e799c01a4de..d3449fac41f 100644
--- 
a/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataComponent.java
+++ 
b/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataComponent.java
@@ -26,6 +26,11 @@ import org.apache.camel.support.ResourceHelper;
 
 @Component("jsonata")
 public class JsonataComponent extends DefaultComponent {
+
+    @Metadata(defaultValue = "true", description = "Sets whether to use 
resource content cache or not")
+    private boolean contentCache;
+    @Metadata(defaultValue = "false")
+    private boolean allowTemplateFromHeader;
     @Metadata(label = "advanced",
               description = "To configure custom frame bindings and inject 
user functions.")
     protected JsonataFrameBinding frameBinding;
@@ -35,7 +40,7 @@ public class JsonataComponent extends DefaultComponent {
 
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
-        boolean cache = getAndRemoveParameter(parameters, "contentCache", 
Boolean.class, Boolean.TRUE);
+        boolean cache = getAndRemoveParameter(parameters, "contentCache", 
Boolean.class, contentCache);
 
         JsonataFrameBinding frameBinding
                 = resolveAndRemoveReferenceParameter(parameters, 
"frameBinding", JsonataFrameBinding.class);
@@ -46,6 +51,7 @@ public class JsonataComponent extends DefaultComponent {
 
         JsonataEndpoint answer = new JsonataEndpoint(uri, this, remaining, 
frameBinding);
         answer.setContentCache(cache);
+        answer.setAllowTemplateFromHeader(allowTemplateFromHeader);
 
         // if its a http resource then append any remaining parameters and 
update the resource uri
         if (ResourceHelper.isHttpUri(remaining)) {
@@ -56,6 +62,31 @@ public class JsonataComponent extends DefaultComponent {
         return answer;
     }
 
+    public boolean isContentCache() {
+        return contentCache;
+    }
+
+    /**
+     * Sets whether to use resource content cache or not
+     */
+    public void setContentCache(boolean contentCache) {
+        this.contentCache = contentCache;
+    }
+
+    public boolean isAllowTemplateFromHeader() {
+        return allowTemplateFromHeader;
+    }
+
+    /**
+     * Whether to allow to use resource template from header or not (default 
false).
+     *
+     * Enabling this allows to specify dynamic templates via message header. 
However this can be seen as a potential
+     * security vulnerability if the header is coming from a malicious user, 
so use this with care.
+     */
+    public void setAllowTemplateFromHeader(boolean allowTemplateFromHeader) {
+        this.allowTemplateFromHeader = allowTemplateFromHeader;
+    }
+
     /**
      * To use the custom JsonataFrameBinding to perform configuration of 
custom functions that will be used.
      */
diff --git 
a/components/camel-jsonata/src/test/java/org/apache/camel/component/jsonata/JsonataRefTest.java
 
b/components/camel-jsonata/src/test/java/org/apache/camel/component/jsonata/JsonataRefTest.java
new file mode 100644
index 00000000000..d3bdc6f31b5
--- /dev/null
+++ 
b/components/camel-jsonata/src/test/java/org/apache/camel/component/jsonata/JsonataRefTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.jsonata;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.camel.util.IOHelper;
+import org.junit.jupiter.api.Test;
+
+class JsonataRefTest extends CamelTestSupport {
+
+    private static String TEMP = """
+            {
+                "name": Surname & " " & FirstName,
+                "mobile": Phone[type = "mobile"].number
+            }
+                        """;
+
+    @Test
+    void testRef() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived(
+                IOHelper.loadText(
+                        ResourceHelper.resolveMandatoryResourceAsInputStream(
+                                context, 
"org/apache/camel/component/jsonata/firstSample/output2.json"))
+                        .trim() // Remove the last newline added by 
IOHelper.loadText()
+        );
+
+        sendBody("direct://start",
+                ResourceHelper.resolveMandatoryResourceAsInputStream(
+                        context, 
"org/apache/camel/component/jsonata/firstSample/input.json"));
+
+        MockEndpoint.assertIsSatisfied(context);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                context.getRegistry().bind("mytemp", TEMP);
+
+                from("direct://start")
+                        
.to("jsonata:ref:mytemp?inputType=JsonString&outputType=JsonString")
+                        .to("mock:result");
+            }
+        };
+    }
+}

Reply via email to