This is an automated email from the ASF dual-hosted git repository.
acosentino 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 86210fc3015 Add Jsonata frame binding functionality (#14995)
86210fc3015 is described below
commit 86210fc3015933d5dd4ec724f9a97ba894721db6
Author: Darren Vine <[email protected]>
AuthorDate: Fri Aug 2 11:39:44 2024 +0200
Add Jsonata frame binding functionality (#14995)
* feat: Add framebindings
* feat: Custom jsonata frame bindings
* Show sample with reversed string
* Formated
* Generated code
* chore: update generated
---
.../apache/camel/catalog/components/jsonata.json | 6 +-
.../jsonata/JsonataComponentConfigurer.java | 6 ++
.../jsonata/JsonataEndpointConfigurer.java | 6 ++
.../jsonata/JsonataEndpointUriFactory.java | 3 +-
.../apache/camel/component/jsonata/jsonata.json | 6 +-
.../src/main/docs/jsonata-component.adoc | 26 ++++++++
.../camel/component/jsonata/JsonataComponent.java | 24 ++++++-
.../camel/component/jsonata/JsonataEndpoint.java | 23 ++++++-
.../component/jsonata/JsonataFrameBinding.java | 23 +++++++
.../component/jsonata/JsonataFrameBindingTest.java | 74 ++++++++++++++++++++++
.../jsonata/frameBinding/expressions.spec | 6 ++
.../component/jsonata/frameBinding/input.json | 53 ++++++++++++++++
.../component/jsonata/frameBinding/output.json | 1 +
.../dsl/JsonataComponentBuilderFactory.java | 17 +++++
.../dsl/JsonataEndpointBuilderFactory.java | 34 ++++++++++
.../camel/kotlin/components/JsonataUriDsl.kt | 7 ++
16 files changed, 307 insertions(+), 8 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jsonata.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jsonata.json
index 49067676cea..6ab63b7f9a5 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jsonata.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jsonata.json
@@ -24,7 +24,8 @@
},
"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 [...]
+ "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." }
},
"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 [...]
@@ -32,6 +33,7 @@
"contentCache": { "index": 2, "kind": "parameter", "displayName": "Content
Cache", "group": "producer", "label": "", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "description": "Sets whether to use resource
content cache or not" },
"inputType": { "index": 3, "kind": "parameter", "displayName": "Input
Type", "group": "producer", "label": "", "required": false, "type": "object",
"javaType": "org.apache.camel.component.jsonata.JsonataInputOutputType",
"enum": [ "Jackson", "JsonString" ], "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "Jackson", "description": "Specifies if the
input should be Jackson JsonNode or a JSON String." },
"outputType": { "index": 4, "kind": "parameter", "displayName": "Output
Type", "group": "producer", "label": "", "required": false, "type": "object",
"javaType": "org.apache.camel.component.jsonata.JsonataInputOutputType",
"enum": [ "Jackson", "JsonString" ], "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "Jackson", "description": "Specifies if the
output should be Jackson JsonNode or a JSON String." },
- "lazyStartProducer": { "index": 5, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "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 produc [...]
+ "lazyStartProducer": { "index": 5, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "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 produc [...]
+ "frameBinding": { "index": 6, "kind": "parameter", "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 the Jsonata frame binding. Allows custom functions to be added." }
}
}
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 b89852dce29..86bb0ad4957 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
@@ -25,6 +25,8 @@ public class JsonataComponentConfigurer extends
PropertyConfigurerSupport implem
switch (ignoreCase ? name.toLowerCase() : name) {
case "autowiredenabled":
case "autowiredEnabled":
target.setAutowiredEnabled(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":
case "lazyStartProducer":
target.setLazyStartProducer(property(camelContext, boolean.class, value));
return true;
default: return false;
@@ -36,6 +38,8 @@ public class JsonataComponentConfigurer extends
PropertyConfigurerSupport implem
switch (ignoreCase ? name.toLowerCase() : name) {
case "autowiredenabled":
case "autowiredEnabled": return boolean.class;
+ case "framebinding":
+ case "frameBinding": return
org.apache.camel.component.jsonata.JsonataFrameBinding.class;
case "lazystartproducer":
case "lazyStartProducer": return boolean.class;
default: return null;
@@ -48,6 +52,8 @@ public class JsonataComponentConfigurer extends
PropertyConfigurerSupport implem
switch (ignoreCase ? name.toLowerCase() : name) {
case "autowiredenabled":
case "autowiredEnabled": return target.isAutowiredEnabled();
+ case "framebinding":
+ case "frameBinding": return target.getFrameBinding();
case "lazystartproducer":
case "lazyStartProducer": return target.isLazyStartProducer();
default: return null;
diff --git
a/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointConfigurer.java
b/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointConfigurer.java
index 57ebcc77b57..351bf6d73de 100644
---
a/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointConfigurer.java
+++
b/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointConfigurer.java
@@ -27,6 +27,8 @@ public class JsonataEndpointConfigurer extends
PropertyConfigurerSupport impleme
case "allowContextMapAll":
target.setAllowContextMapAll(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 "inputtype":
case "inputType": target.setInputType(property(camelContext,
org.apache.camel.component.jsonata.JsonataInputOutputType.class, value));
return true;
case "lazystartproducer":
@@ -44,6 +46,8 @@ public class JsonataEndpointConfigurer extends
PropertyConfigurerSupport impleme
case "allowContextMapAll": return boolean.class;
case "contentcache":
case "contentCache": return boolean.class;
+ case "framebinding":
+ case "frameBinding": return
org.apache.camel.component.jsonata.JsonataFrameBinding.class;
case "inputtype":
case "inputType": return
org.apache.camel.component.jsonata.JsonataInputOutputType.class;
case "lazystartproducer":
@@ -62,6 +66,8 @@ public class JsonataEndpointConfigurer extends
PropertyConfigurerSupport impleme
case "allowContextMapAll": return target.isAllowContextMapAll();
case "contentcache":
case "contentCache": return target.isContentCache();
+ case "framebinding":
+ case "frameBinding": return target.getFrameBinding();
case "inputtype":
case "inputType": return target.getInputType();
case "lazystartproducer":
diff --git
a/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointUriFactory.java
b/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointUriFactory.java
index 1cb289ac00b..d4708c6e769 100644
---
a/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointUriFactory.java
+++
b/components/camel-jsonata/src/generated/java/org/apache/camel/component/jsonata/JsonataEndpointUriFactory.java
@@ -23,9 +23,10 @@ public class JsonataEndpointUriFactory extends
org.apache.camel.support.componen
private static final Set<String> SECRET_PROPERTY_NAMES;
private static final Set<String> MULTI_VALUE_PREFIXES;
static {
- Set<String> props = new HashSet<>(6);
+ Set<String> props = new HashSet<>(7);
props.add("allowContextMapAll");
props.add("contentCache");
+ props.add("frameBinding");
props.add("inputType");
props.add("lazyStartProducer");
props.add("outputType");
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 49067676cea..6ab63b7f9a5 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,7 +24,8 @@
},
"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 [...]
+ "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." }
},
"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 [...]
@@ -32,6 +33,7 @@
"contentCache": { "index": 2, "kind": "parameter", "displayName": "Content
Cache", "group": "producer", "label": "", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "description": "Sets whether to use resource
content cache or not" },
"inputType": { "index": 3, "kind": "parameter", "displayName": "Input
Type", "group": "producer", "label": "", "required": false, "type": "object",
"javaType": "org.apache.camel.component.jsonata.JsonataInputOutputType",
"enum": [ "Jackson", "JsonString" ], "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "Jackson", "description": "Specifies if the
input should be Jackson JsonNode or a JSON String." },
"outputType": { "index": 4, "kind": "parameter", "displayName": "Output
Type", "group": "producer", "label": "", "required": false, "type": "object",
"javaType": "org.apache.camel.component.jsonata.JsonataInputOutputType",
"enum": [ "Jackson", "JsonString" ], "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "Jackson", "description": "Specifies if the
output should be Jackson JsonNode or a JSON String." },
- "lazyStartProducer": { "index": 5, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "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 produc [...]
+ "lazyStartProducer": { "index": 5, "kind": "parameter", "displayName":
"Lazy Start Producer", "group": "producer (advanced)", "label":
"producer,advanced", "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 produc [...]
+ "frameBinding": { "index": 6, "kind": "parameter", "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 the Jsonata frame binding. Allows custom functions to be added." }
}
}
diff --git a/components/camel-jsonata/src/main/docs/jsonata-component.adoc
b/components/camel-jsonata/src/main/docs/jsonata-component.adoc
index 7ba453635d9..10af5b7b474 100644
--- a/components/camel-jsonata/src/main/docs/jsonata-component.adoc
+++ b/components/camel-jsonata/src/main/docs/jsonata-component.adoc
@@ -58,6 +58,8 @@ include::partial$component-endpoint-options.adoc[]
== Samples
+=== Basic
+
For example, you could use something like:
[source,java]
@@ -75,5 +77,29 @@ from("activemq:My.Queue").
to("activemq:Another.Queue");
---------------------------------------------------------------
+=== Frame bindings
+
+It is possible to configure custom functions that can be called from Jsonata.
For example you might want to be able to
+inject environment variables:
+
+[source,java]
+---------------------------------------------------------------
+from("activemq:My.Queue").
+
to("jsonata:file://myfolder/MyResponse.json?contentCache=true&frameBinding=#customBindings").
+ to("activemq:Another.Queue");
+---------------------------------------------------------------
+
+A custom binding might look like the following:
+
+[source,java]
+---------------------------------------------------------------
+@NoArgsConstructor
+public class CustomJsonataFrameBinding implements JsonataFrameBinding {
+ @Override
+ public void bindToFrame(Jsonata.Frame frame) {
+ frame.bind("env", (String s) -> System.getenv(s));
+ }
+}
+---------------------------------------------------------------
include::spring-boot:partial$starter.adoc[]
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 a2523cd1ee6..e799c01a4de 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
@@ -19,12 +19,16 @@ package org.apache.camel.component.jsonata;
import java.util.Map;
import org.apache.camel.Endpoint;
+import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.annotations.Component;
import org.apache.camel.support.DefaultComponent;
import org.apache.camel.support.ResourceHelper;
@Component("jsonata")
public class JsonataComponent extends DefaultComponent {
+ @Metadata(label = "advanced",
+ description = "To configure custom frame bindings and inject
user functions.")
+ protected JsonataFrameBinding frameBinding;
public JsonataComponent() {
}
@@ -33,7 +37,14 @@ public class JsonataComponent extends DefaultComponent {
protected Endpoint createEndpoint(String uri, String remaining,
Map<String, Object> parameters) throws Exception {
boolean cache = getAndRemoveParameter(parameters, "contentCache",
Boolean.class, Boolean.TRUE);
- JsonataEndpoint answer = new JsonataEndpoint(uri, this, remaining);
+ JsonataFrameBinding frameBinding
+ = resolveAndRemoveReferenceParameter(parameters,
"frameBinding", JsonataFrameBinding.class);
+ if (frameBinding == null) {
+ // fallback to component configured
+ frameBinding = getFrameBinding();
+ }
+
+ JsonataEndpoint answer = new JsonataEndpoint(uri, this, remaining,
frameBinding);
answer.setContentCache(cache);
// if its a http resource then append any remaining parameters and
update the resource uri
@@ -44,4 +55,15 @@ public class JsonataComponent extends DefaultComponent {
return answer;
}
+
+ /**
+ * To use the custom JsonataFrameBinding to perform configuration of
custom functions that will be used.
+ */
+ public void setFrameBinding(JsonataFrameBinding frameBinding) {
+ this.frameBinding = frameBinding;
+ }
+
+ public JsonataFrameBinding getFrameBinding() {
+ return frameBinding;
+ }
}
diff --git
a/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataEndpoint.java
b/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataEndpoint.java
index 6fb1647217c..a641906eced 100644
---
a/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataEndpoint.java
+++
b/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataEndpoint.java
@@ -53,11 +53,15 @@ public class JsonataEndpoint extends ResourceEndpoint {
@UriParam(defaultValue = "Jackson")
private JsonataInputOutputType inputType;
+ @UriParam(label = "advanced", description = "To configure the Jsonata
frame binding. Allows custom functions to be added.")
+ private JsonataFrameBinding frameBinding;
+
public JsonataEndpoint() {
}
- public JsonataEndpoint(String uri, JsonataComponent component, String
resourceUri) {
+ public JsonataEndpoint(String uri, JsonataComponent component, String
resourceUri, JsonataFrameBinding frameBinding) {
super(uri, component, resourceUri);
+ this.frameBinding = frameBinding;
}
@Override
@@ -97,6 +101,17 @@ public class JsonataEndpoint extends ResourceEndpoint {
this.inputType = inputType;
}
+ /**
+ * Specifies the custom framebinding.
+ */
+ public void setFrameBinding(JsonataFrameBinding frameBinding) {
+ this.frameBinding = frameBinding;
+ }
+
+ public JsonataFrameBinding getFrameBinding() {
+ return frameBinding;
+ }
+
@Override
protected void onExchange(Exchange exchange) throws Exception {
String path = getResourceUri();
@@ -122,7 +137,11 @@ public class JsonataEndpoint extends ResourceEndpoint {
.collect(Collectors.joining("\n"));
expression = jsonata(spec);
}
- output = expression.evaluate(input);
+
+ Jsonata.Frame frame = expression.createFrame();
+ if (frameBinding != null)
+ frameBinding.bindToFrame(frame);
+ output = expression.evaluate(input, frame);
// now lets output the results to the exchange
Object body = output;
diff --git
a/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataFrameBinding.java
b/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataFrameBinding.java
new file mode 100644
index 00000000000..1ccfb23f013
--- /dev/null
+++
b/components/camel-jsonata/src/main/java/org/apache/camel/component/jsonata/JsonataFrameBinding.java
@@ -0,0 +1,23 @@
+/*
+ * 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 com.dashjoin.jsonata.Jsonata;
+
+public interface JsonataFrameBinding {
+ void bindToFrame(Jsonata.Frame clientBuilder);
+}
diff --git
a/components/camel-jsonata/src/test/java/org/apache/camel/component/jsonata/JsonataFrameBindingTest.java
b/components/camel-jsonata/src/test/java/org/apache/camel/component/jsonata/JsonataFrameBindingTest.java
new file mode 100644
index 00000000000..0680aeded4c
--- /dev/null
+++
b/components/camel-jsonata/src/test/java/org/apache/camel/component/jsonata/JsonataFrameBindingTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.dashjoin.jsonata.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;
+
+/**
+ * Unit test based on the first sample test from the JSONata project.
+ */
+class JsonataFrameBindingTest extends CamelTestSupport {
+
+ private JsonataFrameBinding frameBinding = new JsonataFrameBinding() {
+ @Override
+ public void bindToFrame(Jsonata.Frame clientBuilder) {
+ clientBuilder.bind("reverse", (String originalStr) -> {
+ String reversedStr = "";
+
+ for (int i = 0; i < originalStr.length(); i++) {
+ reversedStr = originalStr.charAt(i) + reversedStr;
+ }
+
+ return reversedStr;
+ });
+ }
+ };
+
+ @Test
+ void testFrameBindingJsonata() throws Exception {
+ getMockEndpoint("mock:result").expectedBodiesReceived(
+ IOHelper.loadText(
+ ResourceHelper.resolveMandatoryResourceAsInputStream(
+ context,
"org/apache/camel/component/jsonata/frameBinding/output.json"))
+ .trim() // Remove the last newline added by
IOHelper.loadText()
+ );
+
+ sendBody("direct://start",
+ ResourceHelper.resolveMandatoryResourceAsInputStream(
+ context,
"org/apache/camel/component/jsonata/frameBinding/input.json"));
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ context.getComponent("jsonata",
JsonataComponent.class).setFrameBinding(frameBinding);
+ return new RouteBuilder() {
+ public void configure() {
+ from("direct://start")
+
.to("jsonata:org/apache/camel/component/jsonata/frameBinding/expressions.spec?inputType=JsonString&outputType=JsonString")
+ .to("mock:result");
+ }
+ };
+ }
+}
diff --git
a/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/expressions.spec
b/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/expressions.spec
new file mode 100644
index 00000000000..3d993390c9d
--- /dev/null
+++
b/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/expressions.spec
@@ -0,0 +1,6 @@
+{
+ "name": FirstName & " " & Surname,
+ "mobile": Phone[type = "mobile"].number,
+ "emails": Email#$i[$i>0],
+ "binding": $reverse(FirstName)
+}
\ No newline at end of file
diff --git
a/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/input.json
b/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/input.json
new file mode 100644
index 00000000000..bceae29355c
--- /dev/null
+++
b/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/input.json
@@ -0,0 +1,53 @@
+{
+ "FirstName": "Fred",
+ "Surname": "Smith",
+ "Age": 28,
+ "Address": {
+ "Street": "Hursley Park",
+ "City": "Winchester",
+ "Postcode": "SO21 2JN"
+ },
+ "Phone": [
+ {
+ "type": "home",
+ "number": "0203 544 1234"
+ },
+ {
+ "type": "office",
+ "number": "01962 001234"
+ },
+ {
+ "type": "office",
+ "number": "01962 001235"
+ },
+ {
+ "type": "mobile",
+ "number": "077 7700 1234"
+ }
+ ],
+ "Email": [
+ {
+ "type": "office",
+ "address": [
+ "[email protected]",
+ "[email protected]"
+ ]
+ },
+ {
+ "type": "home",
+ "address": [
+ "[email protected]",
+ "[email protected]"
+ ]
+ }
+ ],
+ "Other": {
+ "Over 18 ?": true,
+ "Misc": null,
+ "Alternative.Address": {
+ "Street": "Brick Lane",
+ "City": "London",
+ "Postcode": "E1 6RF"
+ }
+ }
+ }
\ No newline at end of file
diff --git
a/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/output.json
b/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/output.json
new file mode 100644
index 00000000000..ec84e86c5f6
--- /dev/null
+++
b/components/camel-jsonata/src/test/resources/org/apache/camel/component/jsonata/frameBinding/output.json
@@ -0,0 +1 @@
+{"name":"Fred Smith","mobile":"077 7700
1234","emails":{"type":"home","address":["[email protected]","[email protected]"]},"binding":"derF"}
\ No newline at end of file
diff --git
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JsonataComponentBuilderFactory.java
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JsonataComponentBuilderFactory.java
index 2d5d280e822..4d5c3985b2e 100644
---
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JsonataComponentBuilderFactory.java
+++
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/JsonataComponentBuilderFactory.java
@@ -96,6 +96,22 @@ public interface JsonataComponentBuilderFactory {
doSetProperty("autowiredEnabled", autowiredEnabled);
return this;
}
+
+ /**
+ * To configure custom frame bindings and inject user functions.
+ *
+ * The option is a:
+ *
<code>org.apache.camel.component.jsonata.JsonataFrameBinding</code>
type.
+ *
+ * Group: advanced
+ *
+ * @param frameBinding the value to set
+ * @return the dsl builder
+ */
+ default JsonataComponentBuilder
frameBinding(org.apache.camel.component.jsonata.JsonataFrameBinding
frameBinding) {
+ doSetProperty("frameBinding", frameBinding);
+ return this;
+ }
}
class JsonataComponentBuilderImpl
@@ -113,6 +129,7 @@ public interface JsonataComponentBuilderFactory {
switch (name) {
case "lazyStartProducer": ((JsonataComponent)
component).setLazyStartProducer((boolean) value); return true;
case "autowiredEnabled": ((JsonataComponent)
component).setAutowiredEnabled((boolean) value); return true;
+ case "frameBinding": ((JsonataComponent)
component).setFrameBinding((org.apache.camel.component.jsonata.JsonataFrameBinding)
value); return true;
default: return false;
}
}
diff --git
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JsonataEndpointBuilderFactory.java
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JsonataEndpointBuilderFactory.java
index fe29224470a..f32e6b07f00 100644
---
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JsonataEndpointBuilderFactory.java
+++
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/JsonataEndpointBuilderFactory.java
@@ -234,6 +234,40 @@ public interface JsonataEndpointBuilderFactory {
doSetProperty("lazyStartProducer", lazyStartProducer);
return this;
}
+ /**
+ * To configure the Jsonata frame binding. Allows custom functions to
be
+ * added.
+ *
+ * The option is a:
+ * <code>org.apache.camel.component.jsonata.JsonataFrameBinding</code>
+ * type.
+ *
+ * Group: advanced
+ *
+ * @param frameBinding the value to set
+ * @return the dsl builder
+ */
+ default AdvancedJsonataEndpointBuilder
frameBinding(org.apache.camel.component.jsonata.JsonataFrameBinding
frameBinding) {
+ doSetProperty("frameBinding", frameBinding);
+ return this;
+ }
+ /**
+ * To configure the Jsonata frame binding. Allows custom functions to
be
+ * added.
+ *
+ * The option will be converted to a
+ * <code>org.apache.camel.component.jsonata.JsonataFrameBinding</code>
+ * type.
+ *
+ * Group: advanced
+ *
+ * @param frameBinding the value to set
+ * @return the dsl builder
+ */
+ default AdvancedJsonataEndpointBuilder frameBinding(String
frameBinding) {
+ doSetProperty("frameBinding", frameBinding);
+ return this;
+ }
}
public interface JsonataBuilders {
diff --git
a/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JsonataUriDsl.kt
b/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JsonataUriDsl.kt
index 3f84fd15b48..9b9a5228acf 100644
---
a/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JsonataUriDsl.kt
+++
b/dsl/camel-kotlin-api/src/generated/kotlin/org/apache/camel/kotlin/components/JsonataUriDsl.kt
@@ -124,4 +124,11 @@ public class JsonataUriDsl(
public fun lazyStartProducer(lazyStartProducer: Boolean) {
it.property("lazyStartProducer", lazyStartProducer.toString())
}
+
+ /**
+ * To configure the Jsonata frame binding. Allows custom functions to be
added.
+ */
+ public fun frameBinding(frameBinding: String) {
+ it.property("frameBinding", frameBinding)
+ }
}