You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/05/24 04:25:49 UTC
[camel] branch main updated: CAMEL-19383: camel-jslt allowTemplateFromHeader bug (#10194)
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 114d62daf17 CAMEL-19383: camel-jslt allowTemplateFromHeader bug (#10194)
114d62daf17 is described below
commit 114d62daf1792265dac90430646449343849f00f
Author: jacekszymanski <ja...@gmail.com>
AuthorDate: Wed May 24 06:25:11 2023 +0200
CAMEL-19383: camel-jslt allowTemplateFromHeader bug (#10194)
* test case for CAMEL-19383
* two more test cases for the bug
* fix JsltEndpoint
---
.../apache/camel/component/jslt/JsltEndpoint.java | 84 ++++++++++++--------
.../component/jslt/JsltTemplateFromHeaderTest.java | 89 ++++++++++++++++++++++
.../component/jslt/simple/transformation.jslt | 1 +
3 files changed, 143 insertions(+), 31 deletions(-)
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 f95d1d6ca1c..11e3cbb4246 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
@@ -16,16 +16,18 @@
*/
package org.apache.camel.component.jslt;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
-import java.io.StringReader;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.DeserializationFeature;
@@ -40,6 +42,7 @@ import com.schibsted.spt.data.jslt.Expression;
import com.schibsted.spt.data.jslt.Function;
import com.schibsted.spt.data.jslt.JsltException;
import com.schibsted.spt.data.jslt.Parser;
+import com.schibsted.spt.data.jslt.filters.DefaultJsonFilter;
import com.schibsted.spt.data.jslt.filters.JsonFilter;
import org.apache.camel.Category;
import org.apache.camel.Exchange;
@@ -63,6 +66,7 @@ import org.apache.camel.util.ObjectHelper;
public class JsltEndpoint extends ResourceEndpoint {
private static final ObjectMapper OBJECT_MAPPER;
+ private static final JsonFilter DEFAULT_JSON_FILTER = new DefaultJsonFilter();
static {
OBJECT_MAPPER = new ObjectMapper();
@@ -99,41 +103,59 @@ public class JsltEndpoint extends ResourceEndpoint {
}
private synchronized Expression getTransform(Message msg) throws Exception {
- if (transform == null) {
+ final String jsltStringFromHeader
+ = allowTemplateFromHeader ? msg.getHeader(JsltConstants.HEADER_JSLT_STRING, String.class) : null;
+
+ final boolean useTemplateFromUri = jsltStringFromHeader == null;
+
+ if (useTemplateFromUri && transform != null) {
+ return transform;
+ }
+
+ final Collection<Function> functions = Objects.requireNonNullElse(
+ ((JsltComponent) getComponent()).getFunctions(),
+ Collections.emptyList());
+
+ final JsonFilter objectFilter = Objects.requireNonNullElse(
+ ((JsltComponent) getComponent()).getObjectFilter(),
+ DEFAULT_JSON_FILTER);
+
+ final String transformSource;
+ final InputStream stream;
+
+ if (useTemplateFromUri) {
+ transformSource = getResourceUri();
+
if (log.isDebugEnabled()) {
- String path = getResourceUri();
- log.debug("Jslt content read from resource {} with resourceUri: {} for endpoint {}", getResourceUri(), path,
+ log.debug("Jslt content read from resource {} with resourceUri: {} for endpoint {}",
+ transformSource,
+ transformSource,
getEndpointUri());
}
- String jsltStringFromHeader
- = allowTemplateFromHeader ? msg.getHeader(JsltConstants.HEADER_JSLT_STRING, String.class) : null;
- Collection<Function> functions = ((JsltComponent) getComponent()).getFunctions();
- JsonFilter objectFilter = ((JsltComponent) getComponent()).getObjectFilter();
-
- Parser parser;
- InputStream stream = null;
- try {
- if (jsltStringFromHeader != null) {
- parser = new Parser(new StringReader(jsltStringFromHeader)).withSource("<inline>");
- } else {
- stream = ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), getResourceUri());
- if (stream == null) {
- throw new JsltException("Cannot load resource '" + getResourceUri() + "': not found");
- }
- Reader reader = new InputStreamReader(stream, StandardCharsets.UTF_8);
- parser = new Parser(reader).withSource(getResourceUri());
- }
- if (functions != null) {
- parser = parser.withFunctions(functions);
- }
- if (objectFilter != null) {
- parser = parser.withObjectFilter(objectFilter);
- }
- this.transform = parser.compile();
- } finally {
- IOHelper.close(stream);
+ stream = ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), transformSource);
+ if (stream == null) {
+ throw new JsltException("Cannot load resource '" + transformSource + "': not found");
}
+ } else { // use template from header
+ stream = new ByteArrayInputStream(jsltStringFromHeader.getBytes(StandardCharsets.UTF_8));
+ transformSource = "<inline>";
+ }
+
+ final Expression transform;
+ try {
+ transform = new Parser(new InputStreamReader(stream))
+ .withFunctions(functions)
+ .withObjectFilter(objectFilter)
+ .withSource(transformSource)
+ .compile();
+ } finally {
+ // the stream is consumed only on .compile(), cannot be closed before
+ IOHelper.close(stream);
+ }
+
+ if (useTemplateFromUri) {
+ this.transform = transform;
}
return transform;
}
diff --git a/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltTemplateFromHeaderTest.java b/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltTemplateFromHeaderTest.java
new file mode 100644
index 00000000000..80dc4ab2e56
--- /dev/null
+++ b/components/camel-jslt/src/test/java/org/apache/camel/component/jslt/JsltTemplateFromHeaderTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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 org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+public class JsltTemplateFromHeaderTest extends CamelTestSupport {
+
+ private static final String TEST_BODY = "{ \"foo\": \"foo\", \"bar\": \"bar\" }";
+
+ @Test
+ public void testTemplateInHeaderOnMoreExchanges() throws Exception {
+ getMockEndpoint("mock:result").expectedMinimumMessageCount(2);
+ getMockEndpoint("mock:result").expectedBodiesReceived(
+ "\"foo\"",
+ "\"bar\"");
+
+ template.sendBodyAndHeader("direct:start", TEST_BODY,
+ JsltConstants.HEADER_JSLT_STRING, ".foo");
+
+ template.sendBodyAndHeader("direct:start", TEST_BODY,
+ JsltConstants.HEADER_JSLT_STRING, ".bar");
+
+ MockEndpoint.assertIsSatisfied(context);
+
+ }
+
+ @Test
+ public void testTemplateInHeaderOverrideUri() throws Exception {
+ getMockEndpoint("mock:result").expectedMinimumMessageCount(2);
+ getMockEndpoint("mock:result").expectedBodiesReceived(
+ "\"foo\"",
+ "\"bar\"");
+
+ template.sendBody("direct:start", TEST_BODY);
+
+ template.sendBodyAndHeader("direct:start", TEST_BODY,
+ JsltConstants.HEADER_JSLT_STRING, ".bar");
+
+ MockEndpoint.assertIsSatisfied(context);
+
+ }
+
+ @Test
+ public void testTemplateInHeaderOverrideUriOnlyWhenSet() throws Exception {
+ getMockEndpoint("mock:result").expectedMinimumMessageCount(2);
+ getMockEndpoint("mock:result").expectedBodiesReceived(
+ "\"bar\"",
+ "\"foo\"");
+
+ template.sendBodyAndHeader("direct:start", TEST_BODY,
+ JsltConstants.HEADER_JSLT_STRING, ".bar");
+
+ template.sendBody("direct:start", TEST_BODY);
+
+ MockEndpoint.assertIsSatisfied(context);
+
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct://start")
+ .to("jslt:org/apache/camel/component/jslt/simple/transformation.jslt?allowTemplateFromHeader=true")
+ .to("mock:result");
+ }
+ };
+ }
+
+}
diff --git a/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/simple/transformation.jslt b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/simple/transformation.jslt
new file mode 100644
index 00000000000..1e8ea91de53
--- /dev/null
+++ b/components/camel-jslt/src/test/resources/org/apache/camel/component/jslt/simple/transformation.jslt
@@ -0,0 +1 @@
+.foo