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/12/16 09:48:05 UTC
(camel) branch main updated: CAMEL-21547: Migrate bean routing functionality from Smooks Cartridge to Smooks Component (#16563)
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 3c0dbfafab8 CAMEL-21547: Migrate bean routing functionality from Smooks Cartridge to Smooks Component (#16563)
3c0dbfafab8 is described below
commit 3c0dbfafab8c61a753dc013ca0a49a9ecf3e7217
Author: cjmamo <82...@users.noreply.github.com>
AuthorDate: Mon Dec 16 10:47:59 2024 +0100
CAMEL-21547: Migrate bean routing functionality from Smooks Cartridge to Smooks Component (#16563)
* CAMEL-21547: migrate bean routing functionality from Smooks Cartridge to Smooks Component
* docs: remove author comments
---
components/camel-smooks/pom.xml | 9 +-
.../src/main/docs/smooks-component.adoc | 55 ++++-
.../camel/component/smooks/routing/BeanRouter.java | 238 +++++++++++++++++++++
.../smooks/routing/BeanRouterObserver.java | 87 ++++++++
.../resources/META-INF/xsd/smooks/camel-1.5.xsd | 104 +++++++++
.../META-INF/xsd/smooks/camel-1.5.xsd-smooks.xml | 80 +++++++
.../smooks/routing/BeanRouterFunctionalTest.java | 48 +++++
.../smooks/routing/BeanRouterObserverTest.java | 69 ++++++
.../component/smooks/routing/BeanRouterTest.java | 173 +++++++++++++++
.../component/smooks/routing/gender/Gender.java | 22 ++
.../routing/gender/GenderTypeConverterFactory.java | 34 +++
.../dataformat/smooks/SmooksDataFormatTest.java | 2 +-
.../org.smooks.api.converter.TypeConverterFactory | 1 +
.../test/resources/bean-routing-smooks-config.xml | 38 ++++
.../src/test/resources/xml/customer.xml | 2 +-
.../src/test/resources/xml/expected-customer.xml | 2 +-
16 files changed, 955 insertions(+), 9 deletions(-)
diff --git a/components/camel-smooks/pom.xml b/components/camel-smooks/pom.xml
index 79eabd666e7..ac7ed60f571 100644
--- a/components/camel-smooks/pom.xml
+++ b/components/camel-smooks/pom.xml
@@ -55,15 +55,18 @@
<groupId>org.smooks</groupId>
<artifactId>smooks-core</artifactId>
</dependency>
-
+ <dependency>
+ <groupId>org.smooks.cartridges</groupId>
+ <artifactId>smooks-javabean-cartridge</artifactId>
+ </dependency>
<dependency>
<groupId>org.smooks.cartridges.edi</groupId>
<artifactId>smooks-edi-cartridge</artifactId>
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.smooks.cartridges</groupId>
- <artifactId>smooks-javabean-cartridge</artifactId>
+ <groupId>org.smooks</groupId>
+ <artifactId>smooks-test-kit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/components/camel-smooks/src/main/docs/smooks-component.adoc b/components/camel-smooks/src/main/docs/smooks-component.adoc
index 722216baf5b..8e6d214f437 100644
--- a/components/camel-smooks/src/main/docs/smooks-component.adoc
+++ b/components/camel-smooks/src/main/docs/smooks-component.adoc
@@ -62,7 +62,7 @@ include::partial$component-endpoint-headers.adoc[]
== 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:
+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 reference it from your Camel routes as shown below:
[tabs]
====
@@ -87,7 +87,7 @@ YAML::
----
====
-The Smooks component is configured with a mandatory configuration file, which is `smooks-config.xml` in the example above. It is not clear what type of output the component is producing from looking at the above route. By default, the message body output is a stream but the type of output can be changed by configuring `{https://www.smooks.org/xsd/smooks/smooks-core-1.6.xsd}exports` in `smooks-config.xml` as shown in this Smooks configuration:
+The Smooks component is configured with a mandatory configuration file, which is `smooks-config.xml` in the example above. It is not clear what type of output the component is producing from looking at the above route. By default, the message body output is a stream but the type of output can be changed by configuring `{https://www.smooks.org/xsd/smooks/smooks-core-1.6.xsd}exports` in the Smooks configuration as shown next:
.smooks-config.xml
[source,xml]
@@ -106,4 +106,53 @@ The Smooks component is configured with a mandatory configuration file, which is
</smooks-resource-list>
----
-The example `<core:exports>` configures Smooks to export the execution result to Camel as a string. Keep in mind that exporting the result as string means that the whole result will be kept in-memory which could cause unexpected performance issues for large payloads.
+The `{https://www.smooks.org/xsd/smooks/smooks-core-1.6.xsd}exports` element in this example configures Smooks to export the execution result to Camel as a string. Keep in mind that exporting the result as string means that the whole result will be kept in-memory which could cause unexpected performance issues for large payloads.
+
+=== Bean routing
+
+Smooks is capable of routing fragments to Camel endpoints using the `{https://www.smooks.org/xsd/smooks/camel-1.5.xsd}route` element from the Smooks configuration. As an example, you can route to an endpoint by declaring the following in your Smooks configuration:
+
+.smooks-config.xml
+[source,xml]
+----
+<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
+ xmlns:jb="https://www.smooks.org/xsd/smooks/javabean-1.6.xsd"
+ xmlns:camel="https://www.smooks.org/xsd/smooks/camel-1.5.xsd">
+
+ <!-- Create some bean instances from the input source... -->
+ <jb:bean beanId="orderItem" ...>
+ <!-- etc... See Smooks Java Binding docs -->
+ </jb:bean>
+
+ <!-- Route bean to camel endpoints... -->
+ <camel:route beanId="orderItem">
+ <camel:to endpoint="direct:slow" if="orderItem.priority == 'Normal'"/>
+ <camel:to endpoint="direct:express" if="orderItem.priority == 'High'"/>
+ </camel:route>
+
+</smooks-resource-list>
+----
+
+The above file configures Smooks to route the Java bean `orderItem` in the https://www.smooks.org/documentation/#bean_context[bean context] to the endpoints `direct:slow` and `direct:express`, depending on whether the `priority` field of the `orderItem` instance is equal to `Normal` or `High`. It is possible to route based on an event selector rather than a condition thanks to the `routeOnElement` XML attribute:
+
+.smooks-config.xml
+[source,xml]
+----
+<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
+ xmlns:jb="https://www.smooks.org/xsd/smooks/javabean-1.6.xsd"
+ xmlns:camel="https://www.smooks.org/xsd/smooks/camel-1.5.xsd">
+
+ <!-- Create some bean instances from the input source... -->
+ <jb:bean beanId="orderItem" ...>
+ <!-- etc... See Smooks Java Binding docs -->
+ </jb:bean>
+
+ <!-- Route bean to camel endpoints... -->
+ <camel:route beanId="orderItem" routeOnElement="order">
+ <camel:to endpoint="direct:all"/>
+ </camel:route>
+
+</smooks-resource-list>
+----
+
+NOTE: instead of routing complex objects to Camel, a https://www.smooks.org/documentation/#pipeline[pipeline] allows you to have a template (e.g., FreeMarker) reference the beans and then route the evaluated template as string (e.g., XML, CSV, etc...) to Camel.
\ No newline at end of file
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/routing/BeanRouter.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/routing/BeanRouter.java
new file mode 100644
index 00000000000..e07a344ca47
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/routing/BeanRouter.java
@@ -0,0 +1,238 @@
+/*
+ * 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.routing;
+
+import java.util.Map;
+import java.util.Optional;
+
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.PreDestroy;
+
+import javax.inject.Inject;
+
+import org.w3c.dom.Element;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.smooks.SmooksConstants;
+import org.smooks.api.ApplicationContext;
+import org.smooks.api.ExecutionContext;
+import org.smooks.api.SmooksConfigException;
+import org.smooks.api.SmooksException;
+import org.smooks.api.delivery.ordering.Consumer;
+import org.smooks.api.lifecycle.PostExecutionLifecycle;
+import org.smooks.api.lifecycle.PreExecutionLifecycle;
+import org.smooks.api.resource.config.ResourceConfig;
+import org.smooks.api.resource.visitor.sax.ng.AfterVisitor;
+import org.smooks.assertion.AssertArgument;
+import org.smooks.cartridges.javabean.BeanMapExpressionEvaluator;
+import org.smooks.engine.resource.config.DefaultResourceConfig;
+import org.smooks.support.FreeMarkerTemplate;
+import org.smooks.support.FreeMarkerUtils;
+
+/**
+ * Camel bean routing visitor.
+ *
+ */
+public class BeanRouter implements AfterVisitor, Consumer, PreExecutionLifecycle, PostExecutionLifecycle {
+
+ @Inject
+ protected String beanId;
+
+ @Inject
+ protected String toEndpoint;
+
+ @Inject
+ protected Optional<String> condition;
+
+ @Inject
+ protected Optional<String> correlationIdName;
+
+ @Inject
+ protected Optional<FreeMarkerTemplate> correlationIdPattern;
+
+ @Inject
+ protected ApplicationContext applicationContext;
+
+ @Inject
+ protected ResourceConfig resourceConfig;
+
+ protected ProducerTemplate producerTemplate;
+ protected BeanRouterObserver camelRouterObservable;
+ protected CamelContext camelContext;
+
+ public BeanRouter() {
+ }
+
+ public BeanRouter(final CamelContext camelContext) {
+ this.camelContext = camelContext;
+ }
+
+ @PostConstruct
+ public void postConstruct() {
+ if (resourceConfig == null) {
+ resourceConfig = new DefaultResourceConfig();
+ }
+
+ producerTemplate = getCamelContext().createProducerTemplate();
+ if (isBeanRoutingConfigured()) {
+ camelRouterObservable = new BeanRouterObserver(this, beanId);
+ if (condition != null && condition.isPresent()) {
+ camelRouterObservable.setConditionEvaluator(new BeanMapExpressionEvaluator(condition.get()));
+ }
+ }
+
+ if ((correlationIdName != null && correlationIdName.isPresent())
+ && (correlationIdPattern == null || correlationIdPattern.isEmpty())) {
+ throw new SmooksConfigException(
+ "Camel router component configured with a 'correlationIdName', but 'correlationIdPattern' is not configured.");
+ }
+ if ((correlationIdName == null || correlationIdName.isEmpty())
+ && (correlationIdPattern != null && correlationIdPattern.isPresent())) {
+ throw new SmooksConfigException(
+ "Camel router component configured with a 'correlationIdPattern', but 'correlationIdName' is not configured.");
+ }
+ }
+
+ /**
+ * Set the beanId of the bean to be routed.
+ *
+ * @param beanId the beanId to set
+ * @return This router instance.
+ */
+ public BeanRouter setBeanId(final String beanId) {
+ this.beanId = beanId;
+ return this;
+ }
+
+ /**
+ * Set the Camel endpoint to which the bean is to be routed.
+ *
+ * @param toEndpoint the toEndpoint to set
+ * @return This router instance.
+ */
+ public BeanRouter setToEndpoint(final String toEndpoint) {
+ this.toEndpoint = toEndpoint;
+ return this;
+ }
+
+ /**
+ * Set the correlationId header name.
+ *
+ * @return This router instance.
+ */
+ public BeanRouter setCorrelationIdName(String correlationIdName) {
+ AssertArgument.isNotNullAndNotEmpty(correlationIdName, "correlationIdName");
+ this.correlationIdName = Optional.of(correlationIdName);
+ return this;
+ }
+
+ /**
+ * Set the correlationId pattern used to generate correlationIds.
+ *
+ * @param correlationIdPattern The pattern generator template.
+ * @return This router instance.
+ */
+ public BeanRouter setCorrelationIdPattern(final String correlationIdPattern) {
+ this.correlationIdPattern = Optional.of(new FreeMarkerTemplate(correlationIdPattern));
+ return this;
+ }
+
+ @Override
+ public void visitAfter(final Element element, final ExecutionContext executionContext) throws SmooksException {
+ final Object bean = getBeanFromExecutionContext(executionContext, beanId);
+ sendBean(bean, executionContext);
+ }
+
+ /**
+ * Send the bean to the target endpoint.
+ *
+ * @param bean The bean to be sent.
+ * @param executionContext The execution context.
+ */
+ protected void sendBean(final Object bean, final ExecutionContext executionContext) {
+ try {
+ if (correlationIdPattern != null && correlationIdPattern.isPresent()) {
+ Processor processor = exchange -> {
+ Message in = exchange.getIn();
+ in.setBody(bean);
+ in.setHeader(correlationIdName.orElse(null),
+ correlationIdPattern.get().apply(FreeMarkerUtils.getMergedModel(executionContext)));
+ };
+ producerTemplate.send(toEndpoint, processor);
+ } else {
+ producerTemplate.sendBodyAndHeaders(toEndpoint, bean,
+ Map.of(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, executionContext));
+ }
+ } catch (final Exception e) {
+ throw new SmooksException(String.format("Exception routing beanId [%s] to endpoint [%s]", beanId, toEndpoint), e);
+ }
+ }
+
+ protected Object getBeanFromExecutionContext(final ExecutionContext executionContext, final String beanId) {
+ final Object bean = executionContext.getBeanContext().getBean(beanId);
+ if (bean == null) {
+ throw new SmooksException(
+ String.format("Exception routing beanId [%s]. The bean was not found in the Smooks execution context",
+ beanId));
+ }
+
+ return bean;
+ }
+
+ protected CamelContext getCamelContext() {
+ if (camelContext == null) {
+ return applicationContext.getRegistry().lookup(CamelContext.class);
+ } else {
+ return camelContext;
+ }
+ }
+
+ protected boolean isBeanRoutingConfigured() {
+ return "none".equals(resourceConfig.getSelectorPath().getSelector());
+ }
+
+ @PreDestroy
+ public void preDestroy() {
+ try {
+ producerTemplate.stop();
+ } catch (final Exception e) {
+ throw new SmooksException(e.getMessage(), e);
+ }
+ }
+
+ @Override
+ public boolean consumes(final Object object) {
+ return beanId.equals(object);
+ }
+
+ @Override
+ public void onPostExecution(ExecutionContext executionContext) {
+ if (isBeanRoutingConfigured()) {
+ executionContext.getBeanContext().removeObserver(camelRouterObservable);
+ }
+ }
+
+ @Override
+ public void onPreExecution(ExecutionContext executionContext) {
+ if (isBeanRoutingConfigured()) {
+ executionContext.getBeanContext().addObserver(camelRouterObservable);
+ }
+ }
+}
diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/routing/BeanRouterObserver.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/routing/BeanRouterObserver.java
new file mode 100644
index 00000000000..8663731ee40
--- /dev/null
+++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/routing/BeanRouterObserver.java
@@ -0,0 +1,87 @@
+/*
+ * 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.routing;
+
+import org.smooks.api.bean.context.BeanContext;
+import org.smooks.api.bean.lifecycle.BeanContextLifecycleEvent;
+import org.smooks.api.bean.lifecycle.BeanContextLifecycleObserver;
+import org.smooks.api.bean.lifecycle.BeanLifecycle;
+import org.smooks.api.expression.ExecutionContextExpressionEvaluator;
+import org.smooks.assertion.AssertArgument;
+
+/**
+ * BeanRouterObserver is a {@link BeanContextLifecycleObserver} that will route a specified bean to the configured
+ * endpoint.
+ * </p>
+ *
+ */
+public class BeanRouterObserver implements BeanContextLifecycleObserver {
+ private final BeanRouter beanRouter;
+ private final String beanId;
+ private ExecutionContextExpressionEvaluator conditionEvaluator;
+
+ /**
+ * Sole contructor.
+ *
+ * @param beanRouter The bean router instance to be used for routing beans.
+ * @param beanId The beanId which is the beanId in the Smooks {@link BeanContext}.
+ */
+ public BeanRouterObserver(final BeanRouter beanRouter, final String beanId) {
+ AssertArgument.isNotNull(beanRouter, "beanRouter");
+ AssertArgument.isNotNull(beanId, "beanId");
+
+ this.beanRouter = beanRouter;
+ this.beanId = beanId;
+ }
+
+ /**
+ * Set the condition evaluator for performing the routing.
+ * <p/>
+ * Used to test if the routing is to be performed based on the user configured condition.
+ *
+ * @param conditionEvaluator The routing condition evaluator.
+ */
+ public void setConditionEvaluator(ExecutionContextExpressionEvaluator conditionEvaluator) {
+ this.conditionEvaluator = conditionEvaluator;
+ }
+
+ /**
+ * Will route to the endpoint if the BeanLifecycle is of type BeanLifecycle.REMOVE and the beanId is equals to the
+ * beanId that was configured for this instance.
+ */
+ public void onBeanLifecycleEvent(final BeanContextLifecycleEvent event) {
+ if (endEventAndBeanIdMatch(event) && conditionsMatch(event)) {
+ beanRouter.sendBean(event.getBean(), event.getExecutionContext());
+ }
+ }
+
+ private boolean endEventAndBeanIdMatch(final BeanContextLifecycleEvent event) {
+ return event.getLifecycle() == BeanLifecycle.END_FRAGMENT && event.getBeanId().getName().equals(beanId);
+ }
+
+ public boolean conditionsMatch(BeanContextLifecycleEvent event) {
+ if (conditionEvaluator == null) {
+ return true;
+ }
+
+ try {
+ return conditionEvaluator.eval(event.getExecutionContext());
+ } catch (Exception e) {
+ return false;
+ }
+ }
+}
diff --git a/components/camel-smooks/src/main/resources/META-INF/xsd/smooks/camel-1.5.xsd b/components/camel-smooks/src/main/resources/META-INF/xsd/smooks/camel-1.5.xsd
new file mode 100644
index 00000000000..33d32c90b3f
--- /dev/null
+++ b/components/camel-smooks/src/main/resources/META-INF/xsd/smooks/camel-1.5.xsd
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<xs:schema elementFormDefault="qualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="https://www.smooks.org/xsd/smooks/camel-1.5.xsd"
+ xmlns:camel="https://www.smooks.org/xsd/smooks/camel-1.5.xsd"
+ xmlns:smooks="https://www.smooks.org/xsd/smooks-2.0.xsd">
+
+ <xs:import namespace="https://www.smooks.org/xsd/smooks-2.0.xsd" />
+
+ <xs:annotation>
+ <xs:documentation xml:lang="en">Smooks Camel Integration Configuration</xs:documentation>
+ </xs:annotation>
+
+ <xs:element name="route" substitutionGroup="smooks:abstract-resource-config" type="camel:route" />
+ <xs:complexType name="route">
+ <xs:complexContent>
+ <xs:extension base="smooks:abstract-resource-config">
+ <xs:sequence>
+ <xs:element name="to" type="camel:to" minOccurs="1" maxOccurs="unbounded" />
+ </xs:sequence>
+ <xs:attribute name="beanId" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The beanId of the bean to be routed.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="correlationIdName" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Default correlation ID header name e.g. "JMSCorrelationID" when working
+ with JMS components.
+ <p/>
+ This configuration property can be overridden on the "to" child element.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="correlationIdPattern" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Correlation ID value pattern. This is a FreeMarker template, allowing
+ construction of correlation IDs from BeanContext data.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="routeOnElement" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The source element event on which to trigger routing of the bean.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:complexType name="to">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="endpoint" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ The Camel endpoint to which the bean is to be routed.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="if" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ If condition. Also supports adding of the condition on the child element.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute name="correlationIdName" type="xs:string">
+ <xs:annotation>
+ <xs:documentation xml:lang="en">
+ Endpoint specific correlation ID header name e.g. "JMSCorrelationID" when working
+ with JMS components. Allows override of the default correlationIdName set on the
+ parent "route" element.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/components/camel-smooks/src/main/resources/META-INF/xsd/smooks/camel-1.5.xsd-smooks.xml b/components/camel-smooks/src/main/resources/META-INF/xsd/smooks/camel-1.5.xsd-smooks.xml
new file mode 100644
index 00000000000..8d2ad52e58c
--- /dev/null
+++ b/components/camel-smooks/src/main/resources/META-INF/xsd/smooks/camel-1.5.xsd-smooks.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<smooks-resource-list xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
+ xmlns:camel="https://www.smooks.org/xsd/smooks/camel-1.5.xsd">
+
+ <resource-config selector="camel:route">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.NewResourceConfig</resource>
+ <param name="resource">org.apache.camel.component.smooks.routing.BeanRouter</param>
+ <param name="isTemplate">true</param>
+ </resource-config>
+
+ <resource-config selector="camel:route">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">beanId</param>
+ </resource-config>
+
+ <resource-config selector="camel:route">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">routeOnElement</param>
+ <param name="mapTo">selector</param>
+ </resource-config>
+
+ <resource-config selector="camel:route">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">correlationIdName</param>
+ <param name="mapTo">correlationIdName</param>
+ </resource-config>
+
+ <resource-config selector="camel:route">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">correlationIdPattern</param>
+ <param name="mapTo">correlationIdPattern</param>
+ </resource-config>
+
+ <resource-config selector="camel:route/to">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.CloneResourceConfig</resource>
+ </resource-config>
+
+ <resource-config selector="camel:route/to">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">endpoint</param>
+ <param name="mapTo">toEndpoint</param>
+ </resource-config>
+
+ <resource-config selector="camel:route/to">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">if</param>
+ <param name="mapTo">condition</param>
+ </resource-config>
+
+ <resource-config selector="camel:route/to">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromText</resource>
+ <param name="mapTo">condition</param>
+ </resource-config>
+
+ <resource-config selector="camel:route/to">
+ <resource>org.smooks.engine.resource.config.loader.xml.extension.MapToResourceConfigFromAttribute</resource>
+ <param name="attribute">correlationIdName</param>
+ <param name="mapTo">correlationIdName</param>
+ </resource-config>
+
+</smooks-resource-list>
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterFunctionalTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterFunctionalTest.java
new file mode 100644
index 00000000000..cfbe0af9454
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterFunctionalTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.routing;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dataformat.smooks.Customer;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+import org.smooks.Smooks;
+import org.smooks.io.source.StreamSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class BeanRouterFunctionalTest extends CamelTestSupport {
+ @Test
+ public void test() throws Exception {
+ MockEndpoint endpoint = createAndConfigureMockEndpoint("mock://beanRouterUnitTest");
+ endpoint.setExpectedMessageCount(1);
+
+ Smooks smooks = new Smooks("bean-routing-smooks-config.xml");
+ smooks.getApplicationContext().getRegistry().registerObject(CamelContext.class, endpoint.getCamelContext());
+ smooks.filterSource(new StreamSource<>(getClass().getResourceAsStream("/xml/customer.xml")));
+
+ endpoint.assertIsSatisfied();
+ Customer customer = endpoint.getReceivedExchanges().get(0).getMessage().getBody(Customer.class);
+ assertEquals("Wonderland", customer.getCountry());
+ }
+
+ private MockEndpoint createAndConfigureMockEndpoint(String endpointUri) throws Exception {
+ MockEndpoint mockEndpoint = getMockEndpoint(endpointUri);
+ return mockEndpoint;
+ }
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterObserverTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterObserverTest.java
new file mode 100644
index 00000000000..c96b307cfb8
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterObserverTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.routing;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.smooks.api.bean.lifecycle.BeanContextLifecycleEvent;
+import org.smooks.api.bean.lifecycle.BeanLifecycle;
+import org.smooks.engine.bean.repository.DefaultBeanId;
+import org.smooks.testkit.MockExecutionContext;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Unit test for {@link BeanRouterObserver}
+ *
+ */
+public class BeanRouterObserverTest extends CamelTestSupport {
+ private static final String ENDPOINT_URI = "mock://beanRouterUnitTest";
+ private MockEndpoint endpoint;
+
+ @BeforeEach
+ public void beforeEach() {
+ endpoint = getMockEndpoint(ENDPOINT_URI);
+ }
+
+ @Test
+ public void onBeanLifecycleEventCreated() throws Exception {
+ final String sampleBean = "testOrder";
+ final String beanId = "orderId";
+ final BeanRouter beanRouter = new BeanRouter(context);
+
+ beanRouter.setBeanId(beanId);
+ beanRouter.setToEndpoint(ENDPOINT_URI);
+ beanRouter.postConstruct();
+
+ final BeanRouterObserver beanRouterObserver = new BeanRouterObserver(beanRouter, beanId);
+ final MockExecutionContext smooksExecutionContext = new MockExecutionContext();
+ final BeanContextLifecycleEvent event = mock(BeanContextLifecycleEvent.class);
+
+ when(event.getBeanId()).thenReturn(new DefaultBeanId(null, 0, beanId));
+ when(event.getLifecycle()).thenReturn(BeanLifecycle.END_FRAGMENT);
+ when(event.getBean()).thenReturn(sampleBean);
+ when(event.getExecutionContext()).thenReturn(smooksExecutionContext);
+
+ endpoint.setExpectedMessageCount(1);
+ beanRouterObserver.onBeanLifecycleEvent(event);
+ endpoint.assertIsSatisfied();
+ endpoint.expectedBodiesReceived(sampleBean);
+ }
+
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterTest.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterTest.java
new file mode 100644
index 00000000000..fcf3c435b3d
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/BeanRouterTest.java
@@ -0,0 +1,173 @@
+/*
+ * 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.routing;
+
+import java.util.Properties;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.smooks.SmooksConstants;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.smooks.Smooks;
+import org.smooks.api.ExecutionContext;
+import org.smooks.api.SmooksException;
+import org.smooks.api.bean.context.BeanContext;
+import org.smooks.api.bean.lifecycle.BeanLifecycle;
+import org.smooks.api.resource.config.ResourceConfig;
+import org.smooks.engine.bean.lifecycle.DefaultBeanContextLifecycleEvent;
+import org.smooks.engine.injector.Scope;
+import org.smooks.engine.lifecycle.PostConstructLifecyclePhase;
+import org.smooks.engine.lookup.LifecycleManagerLookup;
+import org.smooks.engine.resource.config.DefaultResourceConfig;
+import org.smooks.testkit.MockApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * Unit test for {@link BeanRouter}.
+ *
+ */
+public class BeanRouterTest extends CamelTestSupport {
+ private static final String END_POINT_URI = "mock://beanRouterUnitTest";
+ private static final String BEAN_ID = "testBeanId";
+
+ private ExecutionContext smooksExecutionContext;
+ private MockEndpoint endpoint;
+ private MyBean myBean = new MyBean("bajja");
+ private BeanContext beanContext;
+
+ @Test
+ public void visitAfter() throws Exception {
+ endpoint.setExpectedMessageCount(1);
+ endpoint.expectedBodiesReceived(myBean);
+ createBeanRouter(BEAN_ID, END_POINT_URI).visitAfter(null, smooksExecutionContext);
+ endpoint.assertIsSatisfied();
+ }
+
+ @Test
+ public void testVisitAfterWithMissingBeanInSmookBeanContext() throws SmooksException {
+ when(beanContext.getBean(BEAN_ID)).thenReturn(null);
+ assertThrows(SmooksException.class,
+ () -> createBeanRouter(BEAN_ID, END_POINT_URI).visitAfter(null, smooksExecutionContext));
+ }
+
+ @Test
+ public void testBeanRouterUsingOnlyBeanId() throws Exception {
+ endpoint.setExpectedMessageCount(1);
+ endpoint.expectedBodiesReceived(myBean);
+
+ Smooks smooks = new Smooks();
+ ExecutionContext executionContext = smooks.createExecutionContext();
+
+ BeanRouter beanRouter = createBeanRouter(null, BEAN_ID, END_POINT_URI);
+ beanRouter.onPreExecution(executionContext);
+ executionContext.getBeanContext().addBean(BEAN_ID, myBean);
+
+ // Force an END event
+ executionContext.getBeanContext().notifyObservers(new DefaultBeanContextLifecycleEvent(
+ executionContext,
+ null, BeanLifecycle.END_FRAGMENT, executionContext.getBeanContext().getBeanId(BEAN_ID), myBean));
+
+ endpoint.assertIsSatisfied();
+ }
+
+ @Test
+ public void testBeanRouterAddsCamelSmooksExecutionContextHeader() throws Exception {
+ Smooks smooks = new Smooks();
+ ExecutionContext executionContext = smooks.createExecutionContext();
+
+ endpoint.setExpectedMessageCount(1);
+ endpoint.expectedHeaderReceived(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, executionContext);
+
+ BeanRouter beanRouter = createBeanRouter(null, BEAN_ID, END_POINT_URI);
+ beanRouter.onPreExecution(executionContext);
+ executionContext.getBeanContext().addBean(BEAN_ID, myBean);
+
+ // Force an END event
+ executionContext.getBeanContext().notifyObservers(new DefaultBeanContextLifecycleEvent(
+ executionContext,
+ null, BeanLifecycle.END_FRAGMENT, executionContext.getBeanContext().getBeanId(BEAN_ID), myBean));
+
+ endpoint.assertIsSatisfied();
+ assertNotNull(endpoint.getReceivedExchanges().get(0).getMessage()
+ .getHeader(SmooksConstants.SMOOKS_EXECUTION_CONTEXT, ExecutionContext.class).getBeanContext().getBean(BEAN_ID));
+ }
+
+ @BeforeEach
+ public void beforeEach() throws Exception {
+ endpoint = createAndConfigureMockEndpoint(END_POINT_URI);
+ Exchange exchange = createExchange(endpoint);
+ BeanContext beanContext = createBeanContextAndSetBeanInContext(BEAN_ID, myBean);
+
+ smooksExecutionContext = createExecutionContext();
+ makeExecutionContextReturnBeanContext(beanContext);
+ }
+
+ private MockEndpoint createAndConfigureMockEndpoint(String endpointUri) throws Exception {
+ MockEndpoint mockEndpoint = getMockEndpoint(endpointUri);
+ return mockEndpoint;
+ }
+
+ private Exchange createExchange(MockEndpoint endpoint) {
+ Exchange exchange = endpoint.createExchange();
+ return exchange;
+ }
+
+ private BeanContext createBeanContextAndSetBeanInContext(String beanId, Object bean) {
+ beanContext = mock(BeanContext.class);
+ when(beanContext.getBean(beanId)).thenReturn(bean);
+ return beanContext;
+ }
+
+ private ExecutionContext createExecutionContext() {
+ return mock(ExecutionContext.class);
+ }
+
+ private void makeExecutionContextReturnBeanContext(BeanContext beanContext) {
+ when(smooksExecutionContext.getBeanContext()).thenReturn(beanContext);
+ }
+
+ private BeanRouter createBeanRouter(String beanId, String endpointUri) {
+ return createBeanRouter("dummySelector", beanId, endpointUri);
+ }
+
+ private BeanRouter createBeanRouter(String selector, String beanId, String endpointUri) {
+ BeanRouter beanRouter = new BeanRouter();
+ ResourceConfig resourceConfig = new DefaultResourceConfig();
+ if (selector != null) {
+ resourceConfig.setSelector(selector, new Properties());
+ }
+ resourceConfig.setParameter("beanId", beanId);
+ resourceConfig.setParameter("toEndpoint", endpointUri);
+
+ MockApplicationContext appContext = new MockApplicationContext();
+ appContext.getRegistry().registerObject(CamelContext.class, context);
+ appContext.getRegistry().lookup(new LifecycleManagerLookup()).applyPhase(beanRouter,
+ new PostConstructLifecyclePhase(new Scope(appContext.getRegistry(), resourceConfig, beanId)));
+
+ return beanRouter;
+ }
+
+ public record MyBean(String name) {
+ }
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/gender/Gender.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/gender/Gender.java
new file mode 100644
index 00000000000..18b4b123a92
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/gender/Gender.java
@@ -0,0 +1,22 @@
+/*
+ * 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.routing.gender;
+
+public enum Gender {
+ Male,
+ Female
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/gender/GenderTypeConverterFactory.java b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/gender/GenderTypeConverterFactory.java
new file mode 100644
index 00000000000..03fff88cb4a
--- /dev/null
+++ b/components/camel-smooks/src/test/java/org/apache/camel/component/smooks/routing/gender/GenderTypeConverterFactory.java
@@ -0,0 +1,34 @@
+/*
+ * 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.routing.gender;
+
+import org.smooks.api.converter.TypeConverter;
+import org.smooks.api.converter.TypeConverterDescriptor;
+import org.smooks.api.converter.TypeConverterFactory;
+import org.smooks.engine.converter.DefaultTypeConverterDescriptor;
+
+public class GenderTypeConverterFactory implements TypeConverterFactory<String, Gender> {
+ @Override
+ public TypeConverter<String, Gender> createTypeConverter() {
+ return value -> Enum.valueOf(Gender.class, value);
+ }
+
+ @Override
+ public TypeConverterDescriptor<Class<String>, Class<Gender>> getTypeConverterDescriptor() {
+ return new DefaultTypeConverterDescriptor<>(String.class, Gender.class);
+ }
+}
diff --git a/components/camel-smooks/src/test/java/org/apache/camel/dataformat/smooks/SmooksDataFormatTest.java b/components/camel-smooks/src/test/java/org/apache/camel/dataformat/smooks/SmooksDataFormatTest.java
index 0c58650fcc4..c7b3b9ed320 100644
--- a/components/camel-smooks/src/test/java/org/apache/camel/dataformat/smooks/SmooksDataFormatTest.java
+++ b/components/camel-smooks/src/test/java/org/apache/camel/dataformat/smooks/SmooksDataFormatTest.java
@@ -84,7 +84,7 @@ public class SmooksDataFormatTest extends CamelTestSupport {
customer.setLastName("Cocktolstol");
customer.setGender(Gender.Male);
customer.setAge(35);
- customer.setCountry("USA");
+ customer.setCountry("Wonderland");
exchange.getIn().setBody(customer, JavaSource.class);
diff --git a/components/camel-smooks/src/test/resources/META-INF/services/org.smooks.api.converter.TypeConverterFactory b/components/camel-smooks/src/test/resources/META-INF/services/org.smooks.api.converter.TypeConverterFactory
new file mode 100644
index 00000000000..94a082822c7
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/META-INF/services/org.smooks.api.converter.TypeConverterFactory
@@ -0,0 +1 @@
+org.apache.camel.component.smooks.routing.gender.GenderTypeConverterFactory
\ No newline at end of file
diff --git a/components/camel-smooks/src/test/resources/bean-routing-smooks-config.xml b/components/camel-smooks/src/test/resources/bean-routing-smooks-config.xml
new file mode 100644
index 00000000000..274b5cf6dd8
--- /dev/null
+++ b/components/camel-smooks/src/test/resources/bean-routing-smooks-config.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+<smooks-resource-list
+ xmlns="https://www.smooks.org/xsd/smooks-2.0.xsd"
+ xmlns:jb="https://www.smooks.org/xsd/smooks/javabean-1.6.xsd"
+ xmlns:camel="https://www.smooks.org/xsd/smooks/camel-1.5.xsd">
+
+ <jb:bean beanId="cust" class="org.apache.camel.dataformat.smooks.Customer" createOnElement="customer">
+ <jb:value property="firstName" data="firstName"/>
+ <jb:value property="lastName" data="lastName"/>
+ <jb:value property="gender" data="gender"/>
+ <jb:value property="age" data="age"/>
+ <jb:value property="country" data="country"/>
+ </jb:bean>
+
+ <camel:route beanId="cust">
+ <camel:to endpoint="mock://beanRouterUnitTest" if="cust.country == 'Wonderland'"/>
+ <camel:to endpoint="mock://beanRouterUnitTest" if="cust.country == 'Narnia'"/>
+ </camel:route>
+
+</smooks-resource-list>
diff --git a/components/camel-smooks/src/test/resources/xml/customer.xml b/components/camel-smooks/src/test/resources/xml/customer.xml
index b4a3409d74c..007b19b0748 100644
--- a/components/camel-smooks/src/test/resources/xml/customer.xml
+++ b/components/camel-smooks/src/test/resources/xml/customer.xml
@@ -21,5 +21,5 @@
<lastName>Cocktolstol</lastName>
<gender>Male</gender>
<age>35</age>
- <country>USA</country>
+ <country>Wonderland</country>
</customer>
diff --git a/components/camel-smooks/src/test/resources/xml/expected-customer.xml b/components/camel-smooks/src/test/resources/xml/expected-customer.xml
index dd5f71af8b9..a7cfe0e81a0 100644
--- a/components/camel-smooks/src/test/resources/xml/expected-customer.xml
+++ b/components/camel-smooks/src/test/resources/xml/expected-customer.xml
@@ -21,5 +21,5 @@
<lastName>Cocktolstol</lastName>
<gender>Male</gender>
<age>35</age>
- <country>USA</country>
+ <country>Wonderland</country>
</org.apache.camel.dataformat.smooks.Customer>