This is an automated email from the ASF dual-hosted git repository.
jamesnetherton 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 d7ca7e300c1 CAMEL-21357: Add ability to resolve JQ root scope from the
registry
d7ca7e300c1 is described below
commit d7ca7e300c1f5e6d3a01830fd7849a817590ba77
Author: James Netherton <[email protected]>
AuthorDate: Wed Oct 16 16:49:10 2024 +0100
CAMEL-21357: Add ability to resolve JQ root scope from the registry
---
.../org/apache/camel/language/jq/JqFunctions.java | 5 +-
.../org/apache/camel/language/jq/JqLanguage.java | 6 +-
.../camel/language/jq/JqCustomScopeTest.java | 116 +++++++++++++++++++++
3 files changed, 124 insertions(+), 3 deletions(-)
diff --git
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
index 8589ed7eeeb..2c28a795d38 100644
---
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
+++
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqFunctions.java
@@ -62,8 +62,6 @@ public final class JqFunctions {
Versions.JQ_1_6,
scope);
- Map<String, Function> fromRegistry =
camelContext.getRegistry().findByTypeWithName(Function.class);
-
if (fromServiceLoader != null) {
LOGGER.debug("Loading {} jq functions from ServiceLoader",
fromServiceLoader.size());
fromServiceLoader.forEach(scope::addFunction);
@@ -73,7 +71,10 @@ public final class JqFunctions {
LOGGER.debug("Loading {} jq functions from Json JQ",
fromJq.size());
fromJq.forEach(scope::addFunction);
}
+ }
+ public static void loadFromRegistry(CamelContext camelContext, Scope
scope) {
+ Map<String, Function> fromRegistry =
camelContext.getRegistry().findByTypeWithName(Function.class);
if (fromRegistry != null) {
LOGGER.debug("Loading {} jq functions from Registry",
fromRegistry.size());
fromRegistry.forEach(scope::addFunction);
diff --git
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
index 2686e84b437..4363ae94070 100644
---
a/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
+++
b/components/camel-jq/src/main/java/org/apache/camel/language/jq/JqLanguage.java
@@ -21,6 +21,7 @@ import
net.thisptr.jackson.jq.module.loaders.BuiltinModuleLoader;
import org.apache.camel.Expression;
import org.apache.camel.StaticService;
import org.apache.camel.spi.annotations.Language;
+import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.SingleInputTypedLanguageSupport;
import org.apache.camel.util.ObjectHelper;
@@ -33,12 +34,15 @@ public class JqLanguage extends
SingleInputTypedLanguageSupport implements Stati
public void init() {
ObjectHelper.notNull(getCamelContext(), "CamelContext", this);
+ this.rootScope =
CamelContextHelper.findSingleByType(getCamelContext(), Scope.class);
if (this.rootScope == null) {
this.rootScope = Scope.newEmptyScope();
this.rootScope.setModuleLoader(BuiltinModuleLoader.getInstance());
JqFunctions.load(getCamelContext(), rootScope);
- JqFunctions.loadLocal(rootScope);
}
+
+ JqFunctions.loadFromRegistry(getCamelContext(), rootScope);
+ JqFunctions.loadLocal(rootScope);
}
public Scope getRootScope() {
diff --git
a/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqCustomScopeTest.java
b/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqCustomScopeTest.java
new file mode 100644
index 00000000000..388b0c42972
--- /dev/null
+++
b/components/camel-jq/src/test/java/org/apache/camel/language/jq/JqCustomScopeTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.language.jq;
+
+import java.util.List;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.BooleanNode;
+import net.thisptr.jackson.jq.Expression;
+import net.thisptr.jackson.jq.Function;
+import net.thisptr.jackson.jq.PathOutput;
+import net.thisptr.jackson.jq.Scope;
+import net.thisptr.jackson.jq.Version;
+import net.thisptr.jackson.jq.exception.JsonQueryException;
+import net.thisptr.jackson.jq.path.Path;
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.jupiter.api.Test;
+
+public class JqCustomScopeTest extends JqTestSupport {
+
+ @Test
+ public void testCustomScopeFunction() throws Exception {
+
getMockEndpoint("mock:result").expectedBodiesReceived(MAPPER.createObjectNode().put("foo",
"camel bar"));
+
+ template.sendBody("direct:containsCamel",
MAPPER.createObjectNode().put("foo", "baz"));
+ template.sendBody("direct:containsCamel",
MAPPER.createObjectNode().put("foo", "camel bar"));
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testCustomScopeFunctionFromRegistry() throws Exception {
+
getMockEndpoint("mock:result").expectedBodiesReceived(MAPPER.createObjectNode().put("foo",
"beer"));
+
+ template.sendBody("direct:containsBeer",
MAPPER.createObjectNode().put("foo", "baz"));
+ template.sendBody("direct:containsBeer",
MAPPER.createObjectNode().put("foo", "beer"));
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testCustomScopeBuiltInFunction() throws Exception {
+
getMockEndpoint("mock:result").expectedBodiesReceived(MAPPER.createObjectNode().put("foo",
"123456"));
+
+ template.sendBody("direct:builtInFunction",
MAPPER.createObjectNode().put("foo", "12345"));
+ template.sendBody("direct:builtInFunction",
MAPPER.createObjectNode().put("foo", "123456"));
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @BindToRegistry
+ public Scope customScope() {
+ Scope scope = Scope.newEmptyScope();
+ JqFunctions.load(context, scope);
+ scope.addFunction("containsCamel", new Function() {
+ @Override
+ public void apply(Scope scope, List<Expression> args, JsonNode in,
Path path, PathOutput output, Version version)
+ throws JsonQueryException {
+ args.get(0).apply(scope, in, (value) -> {
+
output.emit(BooleanNode.valueOf(value.asText().contains("camel")), null);
+ });
+ }
+ });
+ return scope;
+ }
+
+ @BindToRegistry
+ public Function containsBeer() {
+ return new Function() {
+ @Override
+ public void apply(Scope scope, List<Expression> args, JsonNode in,
Path path, PathOutput output, Version version)
+ throws JsonQueryException {
+ args.get(0).apply(scope, in, (value) -> {
+
output.emit(BooleanNode.valueOf(value.asText().contains("beer")), null);
+ });
+ }
+ };
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:containsCamel")
+ .filter().jq("containsCamel(.foo)")
+ .to("mock:result");
+
+ from("direct:containsBeer")
+ .filter().jq("containsBeer(.foo)")
+ .to("mock:result");
+
+ from("direct:builtInFunction")
+ .filter().jq(".foo | length > 5")
+ .to("mock:result");
+
+ }
+ };
+ }
+}