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 2024/10/31 09:17:21 UTC
(camel) branch main updated: Allow Smooks execution context to be overridden via header (#16129)
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 10d0f5c6e37 Allow Smooks execution context to be overridden via header (#16129)
10d0f5c6e37 is described below
commit 10d0f5c6e37621805d9e305f09b93526a96b5e98
Author: cjmamo <82...@users.noreply.github.com>
AuthorDate: Thu Oct 31 10:17:15 2024 +0100
Allow Smooks execution context to be overridden via header (#16129)
* feat: allow Smooks execution context to be overridden via header
doc: document SmooksExecutionContext header
remove tabs from smooks-dataformat.adoc
* docs: change to advanced
* chore: regenerate
---
.../apache/camel/catalog/components/smooks.json | 3 ++
.../org/apache/camel/component/smooks/smooks.json | 3 ++
.../src/main/docs/smooks-component.adoc | 4 ++
.../src/main/docs/smooks-dataformat.adoc | 6 +--
.../camel/component/smooks/SmooksConstants.java | 29 ++++++++++++++
.../camel/component/smooks/SmooksEndpoint.java | 2 +-
.../camel/component/smooks/SmooksProcessor.java | 29 +++++++-------
.../component/smooks/SmooksProcessorTest.java | 45 ++++++++++++++++++++++
.../endpoint/dsl/SmooksEndpointBuilderFactory.java | 37 ++++++++++++++++++
9 files changed, 140 insertions(+), 18 deletions(-)
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
index 3eeb420617c..4525d223b10 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json
@@ -28,6 +28,9 @@
"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 [...]
"smooksFactory": { "index": 2, "kind": "property", "displayName": "Smooks Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.smooks.SmooksFactory", "deprecated": false, "autowired": true, "secret": false, "description": "To use a custom factory for creating Smooks." }
},
+ "headers": {
+ "CamelSmooksExecutionContext": { "index": 0, "kind": "header", "displayName": "", "group": "advanced", "label": "advanced", "required": false, "javaType": "org.smooks.api.ExecutionContext", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Smooks execution context.", "constantName": "org.apache.camel.component.smooks.SmooksConstants#SMOOKS_EXECUTION_CONTEXT" }
+ },
"properties": {
"smooksConfig": { "index": 0, "kind": "path", "displayName": "Smooks Config", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "description": "Path to the Smooks configuration file" },
"reportPath": { "index": 1, "kind": "parameter", "displayName": "Report Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "File path to place the generated HTML execution report. The report is a useful tool in the developers arsenal for diagnosing issues or comprehending a transformation. Do not set in production since this is a major performance drain" },
diff --git a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
index 3eeb420617c..4525d223b10 100644
--- a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
+++ b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json
@@ -28,6 +28,9 @@
"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 [...]
"smooksFactory": { "index": 2, "kind": "property", "displayName": "Smooks Factory", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.smooks.SmooksFactory", "deprecated": false, "autowired": true, "secret": false, "description": "To use a custom factory for creating Smooks." }
},
+ "headers": {
+ "CamelSmooksExecutionContext": { "index": 0, "kind": "header", "displayName": "", "group": "advanced", "label": "advanced", "required": false, "javaType": "org.smooks.api.ExecutionContext", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Smooks execution context.", "constantName": "org.apache.camel.component.smooks.SmooksConstants#SMOOKS_EXECUTION_CONTEXT" }
+ },
"properties": {
"smooksConfig": { "index": 0, "kind": "path", "displayName": "Smooks Config", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "description": "Path to the Smooks configuration file" },
"reportPath": { "index": 1, "kind": "parameter", "displayName": "Report Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "File path to place the generated HTML execution report. The report is a useful tool in the developers arsenal for diagnosing issues or comprehending a transformation. Do not set in production since this is a major performance drain" },
diff --git a/components/camel-smooks/src/main/docs/smooks-component.adoc b/components/camel-smooks/src/main/docs/smooks-component.adoc
index 93f917a6e85..722216baf5b 100644
--- a/components/camel-smooks/src/main/docs/smooks-component.adoc
+++ b/components/camel-smooks/src/main/docs/smooks-component.adoc
@@ -56,6 +56,10 @@ include::partial$component-endpoint-options.adoc[]
// endpoint options: END
+// component headers: START
+include::partial$component-endpoint-headers.adoc[]
+// component headers: END
+
== Usage
Using the Smooks component lets you leverage all the features of Smooks, such as transformation and fragment-driven routing, from within Camel. You can take an existing Smooks configuration and use this in your Camel routes as shown below:
diff --git a/components/camel-smooks/src/main/docs/smooks-dataformat.adoc b/components/camel-smooks/src/main/docs/smooks-dataformat.adoc
index 667bee73142..6b83b71002a 100644
--- a/components/camel-smooks/src/main/docs/smooks-dataformat.adoc
+++ b/components/camel-smooks/src/main/docs/smooks-dataformat.adoc
@@ -66,9 +66,9 @@ The Smooks configuration in `csv-smooks-unmarshal-config.xml` is as follows:
<core:result type="org.smooks.io.sink.JavaSink" extract="result"/>
</core:exports>
- <csv:reader fields="firstName,lastName,gender,age,country">
- <csv:listBinding beanId="result" class="org.smooks.example.Customer"/>
- </csv:reader>
+ <csv:reader fields="firstName,lastName,gender,age,country">
+ <csv:listBinding beanId="result" class="org.smooks.example.Customer"/>
+ </csv:reader>
</smooks-resource-list>
----
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksConstants.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksConstants.java
new file mode 100644
index 00000000000..1c7e6622dea
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksConstants.java
@@ -0,0 +1,29 @@
+/*
+ * 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.smooks;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Smooks constants
+ */
+public final class SmooksConstants {
+
+ @Metadata(label = "advanced", description = "The Smooks execution context.",
+ javaType = "org.smooks.api.ExecutionContext")
+ public static final String SMOOKS_EXECUTION_CONTEXT = "CamelSmooksExecutionContext";
+}
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
index f001a506774..1091f79d9cb 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java
@@ -33,7 +33,7 @@ import org.apache.camel.support.service.ServiceHelper;
*/
@UriEndpoint(firstVersion = "4.7.0", scheme = "smooks", title = "Smooks", syntax = "smooks:smooksConfig",
producerOnly = true,
- category = { Category.TRANSFORMATION })
+ category = { Category.TRANSFORMATION }, headersClass = SmooksConstants.class)
public class SmooksEndpoint extends DefaultEndpoint {
@UriPath(description = "Path to the Smooks configuration file")
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
index 1a318ac6f17..5f1ab2492c6 100644
--- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksProcessor.java
@@ -73,8 +73,6 @@ import org.smooks.io.source.URLSource;
*/
public class SmooksProcessor extends ServiceSupport implements Processor, CamelContextAware {
- public static final String SMOOKS_EXECUTION_CONTEXT = "CamelSmooksExecutionContext";
-
private static final TypedKey<Exchange> EXCHANGE_TYPED_KEY = TypedKey.of();
private static final Logger LOG = LoggerFactory.getLogger(SmooksProcessor.class);
@@ -110,16 +108,20 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
}
public void process(final Exchange exchange) {
- final ExecutionContext executionContext = smooks.createExecutionContext();
- try {
- executionContext.put(EXCHANGE_TYPED_KEY, exchange);
+ ExecutionContext executionContext
+ = exchange.getIn().getHeader(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, ExecutionContext.class);
+ if (executionContext == null) {
+ executionContext = smooks.createExecutionContext();
Charset charset = ExchangeHelper.getCharset(exchange, false);
if (charset != null) {
- // if provided use the came character encoding
+ // if provided use the same character encoding
executionContext.setContentEncoding(charset.name());
}
- exchange.getIn().setHeader(SMOOKS_EXECUTION_CONTEXT, executionContext);
- setupSmooksReporting(executionContext);
+ }
+ try {
+ executionContext.put(EXCHANGE_TYPED_KEY, exchange);
+ exchange.getIn().setHeader(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, executionContext);
+ setUpSmooksReporting(executionContext);
final Exports exports = smooks.getApplicationContext().getRegistry().lookup(new ExportsLookup());
if (exports.hasExports()) {
@@ -150,15 +152,14 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
}
}
- private void setupSmooksReporting(final ExecutionContext executionContext) {
+ private void setUpSmooksReporting(final ExecutionContext executionContext) {
if (reportPath != null) {
try {
executionContext.getContentDeliveryRuntime().addExecutionEventListener(
new HtmlReportGenerator(reportPath, executionContext.getApplicationContext()));
} catch (final IOException e) {
- LOG.warn("Cannot generate Smooks Report. The reportPath specified was [" + reportPath
- + "]. This exception is ignored.",
- e);
+ LOG.warn("Cannot generate Smooks Report. The reportPath specified was [{}]. This exception is ignored.",
+ reportPath, e);
}
}
}
@@ -258,7 +259,7 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
}
@Override
- protected void doStart() throws Exception {
+ protected void doStart() {
try {
if (smooks == null) {
smooks = createSmooks();
@@ -278,7 +279,7 @@ public class SmooksProcessor extends ServiceSupport implements Processor, CamelC
}
@Override
- protected void doStop() throws Exception {
+ protected void doStop() {
if (smooks != null) {
IOHelper.close(smooks);
smooks = null;
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
index 0be3e26f2cd..9ac2752fc71 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/SmooksProcessorTest.java
@@ -38,6 +38,8 @@ import org.apache.camel.support.DefaultExchange;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;
import org.smooks.Smooks;
+import org.smooks.SmooksFactory;
+import org.smooks.api.ExecutionContext;
import org.smooks.cartridges.javabean.Bean;
import org.smooks.cartridges.javabean.Value;
import org.smooks.io.payload.Exports;
@@ -58,6 +60,7 @@ import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SmooksProcessorTest extends CamelTestSupport {
@@ -78,6 +81,7 @@ public class SmooksProcessorTest extends CamelTestSupport {
assertIsSatisfied();
Exchange exchange = result.assertExchangeReceived(0);
+ assertNotNull(exchange.getMessage().getHeader(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, ExecutionContext.class));
assertIsInstanceOf(InputStreamCache.class, exchange.getIn().getBody());
assertFalse(DiffBuilder.compare(getExpectedOrderXml()).withTest(exchange.getIn().getBody(String.class)).ignoreComments()
.ignoreWhitespace().build().hasDifferences());
@@ -90,6 +94,47 @@ public class SmooksProcessorTest extends CamelTestSupport {
assertOneProcessedMessage();
}
+ @Test
+ public void testProcessUsesExistingExecutionContextWhenExecutionContextIsInHeader() throws Exception {
+ Smooks smooks = new Smooks();
+ SmooksProcessor processor = new SmooksProcessor("edi-to-xml-smooks-config.xml", context);
+ processor.setSmooksFactory(new SmooksFactory() {
+ @Override
+ public Smooks createInstance() {
+ return smooks;
+ }
+
+ @Override
+ public Smooks createInstance(InputStream config) {
+ return null;
+ }
+
+ @Override
+ public Smooks createInstance(String config) {
+ return null;
+ }
+ });
+
+ final ExecutionContext[] executionContext = new ExecutionContext[1];
+ context.addRoutes(new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:input")
+ .setHeader(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, () -> {
+ executionContext[0] = smooks.createExecutionContext();
+ return executionContext[0];
+ })
+ .process(processor).to("mock:result");
+ }
+
+ });
+ context.start();
+ template.sendBody("direct://input", getOrderEdi());
+
+ Exchange exchange = result.assertExchangeReceived(0);
+ assertEquals(executionContext[0], exchange.getMessage().getHeader(SmooksConstants.SMOOKS_EXECUTION_CONTEXT));
+ }
+
@Test
public void testProcessGivenAttachment() throws Exception {
context.addRoutes(createEdiToXmlRouteBuilder());
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
index 3d31dcefdcd..e5be1f84cf4 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/SmooksEndpointBuilderFactory.java
@@ -123,6 +123,20 @@ public interface SmooksEndpointBuilderFactory {
}
public interface SmooksBuilders {
+ /**
+ * Smooks (camel-smooks)
+ * Use Smooks to transform, route, and bind both XML and non-XML data,
+ * including EDI, CSV, JSON, and YAML.
+ *
+ * Category: transformation
+ * Since: 4.7
+ * Maven coordinates: org.apache.camel:camel-smooks
+ *
+ * @return the dsl builder for the headers' name.
+ */
+ default SmooksHeaderNameBuilder smooks() {
+ return SmooksHeaderNameBuilder.INSTANCE;
+ }
/**
* Smooks (camel-smooks)
* Use Smooks to transform, route, and bind both XML and non-XML data,
@@ -171,6 +185,29 @@ public interface SmooksEndpointBuilderFactory {
}
}
+ /**
+ * The builder of headers' name for the Smooks component.
+ */
+ public static class SmooksHeaderNameBuilder {
+ /**
+ * The internal instance of the builder used to access to all the
+ * methods representing the name of headers.
+ */
+ private static final SmooksHeaderNameBuilder INSTANCE = new SmooksHeaderNameBuilder();
+
+ /**
+ * The Smooks execution context.
+ *
+ * The option is a: {@code org.smooks.api.ExecutionContext} type.
+ *
+ * Group: advanced
+ *
+ * @return the name of the header {@code SmooksExecutionContext}.
+ */
+ public String smooksExecutionContext() {
+ return "CamelSmooksExecutionContext";
+ }
+ }
static SmooksEndpointBuilder endpointBuilder(String componentName, String path) {
class SmooksEndpointBuilderImpl extends AbstractEndpointBuilder implements SmooksEndpointBuilder, AdvancedSmooksEndpointBuilder {
public SmooksEndpointBuilderImpl(String path) {