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

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


The following commit(s) were added to refs/heads/master by this push:
     new cbe77ef  CAMEL-15120: camel-jslt - Use headers as variables in the 
jslt component (#3861)
cbe77ef is described below

commit cbe77efd081aa0775aa2985a0d5c7ef8427f3e95
Author: jflabatBCSS <65955832+jflabatb...@users.noreply.github.com>
AuthorDate: Thu May 28 16:24:33 2020 +0200

    CAMEL-15120: camel-jslt - Use headers as variables in the jslt component 
(#3861)
---
 .../apache/camel/component/jslt/JsltEndpoint.java  |  46 ++++++++-
 .../camel/component/jslt/JsltVariablesTest.java    | 112 +++++++++++++++++++++
 .../camel/component/jslt/withVariables/input.json  |   8 ++
 .../camel/component/jslt/withVariables/output.json |   1 +
 .../jslt/withVariables/outputWithProperties.json   |   1 +
 .../jslt/withVariables/transformation.json         |   5 +
 .../transformationWithProperties.json              |   6 ++
 7 files changed, 178 insertions(+), 1 deletion(-)

diff --git 
a/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
 
b/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
index a64bfae..536ad91 100644
--- 
a/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
+++ 
b/components/camel-jslt/src/main/java/org/apache/camel/component/jslt/JsltEndpoint.java
@@ -22,9 +22,12 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.schibsted.spt.data.jslt.Expression;
 import com.schibsted.spt.data.jslt.Function;
 import com.schibsted.spt.data.jslt.JsltException;
@@ -38,6 +41,7 @@ import org.apache.camel.ValidationException;
 import org.apache.camel.component.ResourceEndpoint;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
+import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
 
@@ -47,6 +51,7 @@ import org.apache.camel.util.ObjectHelper;
 @UriEndpoint(firstVersion = "3.1.0", scheme = "jslt", title = "JSLT", syntax = 
"jslt:resourceUri", producerOnly = true, category = {Category.TRANSFORMATION})
 public class JsltEndpoint extends ResourceEndpoint {
 
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
     private Expression transform;
 
     @UriParam(defaultValue = "false")
@@ -146,13 +151,52 @@ public class JsltEndpoint extends ResourceEndpoint {
             throw new ValidationException(exchange, "Allowed body types are 
String or InputStream.");
         }
 
-        JsonNode output = getTransform(exchange.getMessage()).apply(input);
+        Map<String, JsonNode> variables = extractVariables(exchange);
+
+        JsonNode output = getTransform(exchange.getMessage()).apply(variables, 
input);
+
         Message out = exchange.getMessage();
         out.setBody(isPrettyPrint() ? output.toPrettyString() : 
output.toString());
         out.setHeaders(exchange.getIn().getHeaders());
     }
 
     /**
+     * Extract the variables from the headers in the message.
+     */
+    private Map<String, JsonNode> extractVariables(Exchange exchange) {
+        Map<String, Object> variableMap = 
ExchangeHelper.createVariableMap(exchange, isAllowContextMapAll());
+        Map<String, JsonNode> serializedVariableMap = new HashMap<>();
+        if (variableMap.containsKey("headers")) {
+            serializedVariableMap.put("headers", 
serializeMapToJsonNode((Map<String, Object>) variableMap.get("headers")));
+        }
+        if (variableMap.containsKey("exchange")) {
+            Exchange ex = (Exchange) variableMap.get("exchange");
+            ObjectNode exchangeNode = OBJECT_MAPPER.createObjectNode();
+            if (ex.getProperties() != null) {
+                exchangeNode.set("properties", 
serializeMapToJsonNode(ex.getProperties()));
+            }
+            serializedVariableMap.put("exchange", exchangeNode);
+        }
+        return serializedVariableMap;
+    }
+
+    private ObjectNode serializeMapToJsonNode(Map<String, Object> map) {
+        ObjectNode mapNode = OBJECT_MAPPER.createObjectNode();
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            if (entry.getValue() != null) {
+                try {
+                    // Use Jackson to convert value to JsonNode
+                    mapNode.set(entry.getKey(), 
OBJECT_MAPPER.valueToTree(entry.getValue()));
+                } catch (IllegalArgumentException e) {
+                    //If Jackson cannot convert the value to json (e.g. 
infinite recursion in the value to serialize)
+                    log.debug("Value could not be converted to JsonNode", e);
+                }
+            }
+        }
+        return mapNode;
+    }
+
+    /**
      * If true, JSON in output message is pretty printed.
      */
     public boolean isPrettyPrint() {
diff --git 
a/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltVariablesTest.java
 
b/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltVariablesTest.java
new file mode 100644
index 0000000..bf51bce
--- /dev/null
+++ 
b/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltVariablesTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.jslt;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.util.IOHelper;
+import org.junit.Test;
+
+/**
+ * Tests using variables used in headers
+ */
+public class JsltVariablesTest extends CamelTestSupport {
+
+    @Test
+    public void testWithVariables() throws Exception {
+        getMockEndpoint("mock:result").expectedMinimumMessageCount(1);
+        getMockEndpoint("mock:result").expectedBodiesReceived(
+                IOHelper.loadText(
+                        ResourceHelper.resolveMandatoryResourceAsInputStream(
+                                context, 
"org/apache/camel/component/jslt/withVariables/output.json"))
+                        .trim() // Remove the last newline added by 
IOHelper.loadText()
+        );
+
+        Map<String, Object> headers = new HashMap<>();
+        headers.put("published", "2020-05-26T16:00:00+02:00");
+        headers.put("type", "Controller");
+        //add an infinite recursion value, cannot be serialized with Jackson
+        headers.put("infinite", createInfiniteRecursionObject());
+        sendBody("direct://start",
+                ResourceHelper.resolveMandatoryResourceAsInputStream(
+                        context, 
"org/apache/camel/component/jslt/withVariables/input.json"),
+                headers);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testWithVariablesAndProperties() throws Exception {
+        getMockEndpoint("mock:result").expectedMinimumMessageCount(1);
+        getMockEndpoint("mock:result").expectedBodiesReceived(
+                IOHelper.loadText(
+                        ResourceHelper.resolveMandatoryResourceAsInputStream(
+                                context, 
"org/apache/camel/component/jslt/withVariables/outputWithProperties.json"))
+                        .trim() // Remove the last newline added by 
IOHelper.loadText()
+        );
+
+        InputStream body = 
ResourceHelper.resolveMandatoryResourceAsInputStream(
+                context, 
"org/apache/camel/component/jslt/withVariables/input.json");
+
+        template.send("direct://startWithProperties", exchange -> {
+            exchange.getIn().setBody(body);
+            exchange.getIn().setHeader("published", 
"2020-05-26T16:00:00+02:00");
+            exchange.getIn().setHeader("type", "Controller");
+            // add an infinite recursion value, cannot be serialized with 
Jackson
+            exchange.setProperty("infinite", createInfiniteRecursionObject());
+            exchange.setProperty("instance", 
"559e934f-b32b-47ab-8327-bd50e2bdc029");
+        });
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                from("direct://start")
+                        
.to("jslt:org/apache/camel/component/jslt/withVariables/transformation.json")
+                        .to("mock:result");
+
+                from("direct://startWithProperties")
+                        
.to("jslt:org/apache/camel/component/jslt/withVariables/transformationWithProperties.json?allowContextMapAll=true")
+                        .to("mock:result");
+            }
+        };
+    }
+
+    private static Master createInfiniteRecursionObject() {
+        Master master = new Master();
+        Slave slave = new Slave();
+        master.slave = slave;
+        slave.master = master;
+        return master;
+    }
+
+    private static class Master {
+        private Slave slave;
+    }
+
+    private static class Slave {
+        private Master master;
+    }
+}
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/input.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/input.json
new file mode 100644
index 0000000..e332d40e
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/input.json
@@ -0,0 +1,8 @@
+{
+  "schema": "http://schemas.schibsted.io/thing/pulse-simple.json#1.json";,
+  "id": "w23q7ca1-8729-24923-922b-1c0517ddffjf1",
+  "published": "2017-05-04T09:13:29+02:00",
+  "type": "View",
+  "environmentId": "urn:schibsted.com:environment:uuid",
+  "url": "http://www.aftenposten.no/";
+}
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/output.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/output.json
new file mode 100644
index 0000000..46b8e27
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/output.json
@@ -0,0 +1 @@
+{"published":"2020-05-26T16:00:00+02:00","type":"Controller","schema":"http://schemas.schibsted.io/thing/pulse-simple.json#1.json","id":"w23q7ca1-8729-24923-922b-1c0517ddffjf1","environmentId":"urn:schibsted.com:environment:uuid","url":"http://www.aftenposten.no/"}
\ No newline at end of file
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/outputWithProperties.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/outputWithProperties.json
new file mode 100644
index 0000000..45418ed
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/outputWithProperties.json
@@ -0,0 +1 @@
+{"published":"2020-05-26T16:00:00+02:00","type":"Controller","id":"559e934f-b32b-47ab-8327-bd50e2bdc029","schema":"http://schemas.schibsted.io/thing/pulse-simple.json#1.json","environmentId":"urn:schibsted.com:environment:uuid","url":"http://www.aftenposten.no/"}
\ No newline at end of file
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/transformation.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/transformation.json
new file mode 100644
index 0000000..26e101f
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/transformation.json
@@ -0,0 +1,5 @@
+{
+  "published": $headers.published,
+  "type": $headers.type,
+  * : .
+}
\ No newline at end of file
diff --git 
a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/transformationWithProperties.json
 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/transformationWithProperties.json
new file mode 100644
index 0000000..f3c65fb
--- /dev/null
+++ 
b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/withVariables/transformationWithProperties.json
@@ -0,0 +1,6 @@
+{
+  "published": $headers.published,
+  "type": $headers.type,
+  "id": $exchange.properties.instance,
+  * : .
+}
\ No newline at end of file

Reply via email to