diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/CopyableProcessorDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/Copyable.java similarity index 96% rename from core/camel-core-model/src/main/java/org/apache/camel/model/CopyableProcessorDefinition.java rename to core/camel-core-model/src/main/java/org/apache/camel/model/Copyable.java index cf770d7515c5a..98ea9d58fc8c0 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/CopyableProcessorDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/Copyable.java @@ -20,6 +20,6 @@ * This interface is used to copy {@link ProcessorDefinition ProcessorDefinitions} during instantiation of a route * template. */ -interface CopyableProcessorDefinition { +interface Copyable { ProcessorDefinition copy(); } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java index 7b94d4e0bf29a..ba904e06f27a6 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/EnrichDefinition.java @@ -34,7 +34,8 @@ @Metadata(label = "eip,transformation") @XmlRootElement(name = "enrich") @XmlAccessorType(XmlAccessType.FIELD) -public class EnrichDefinition extends ExpressionNode implements AggregationStrategyAwareDefinition { +public class EnrichDefinition extends ExpressionNode + implements AggregationStrategyAwareDefinition, Copyable { @XmlTransient private AggregationStrategy aggregationStrategyBean; @@ -72,13 +73,28 @@ public class EnrichDefinition extends ExpressionNode implements AggregationStrat private String autoStartComponents; public EnrichDefinition() { - this(null); + this((AggregationStrategy) null); } public EnrichDefinition(AggregationStrategy aggregationStrategy) { this.aggregationStrategyBean = aggregationStrategy; } + protected EnrichDefinition(EnrichDefinition source) { + this.aggregationStrategyBean = source.aggregationStrategyBean; + this.variableSend = source.variableSend; + this.variableReceive = source.variableReceive; + this.aggregationStrategy = source.aggregationStrategy; + this.aggregationStrategyMethodName = source.aggregationStrategyMethodName; + this.aggregationStrategyMethodAllowNull = source.aggregationStrategyMethodAllowNull; + this.aggregateOnException = source.aggregateOnException; + this.shareUnitOfWork = source.shareUnitOfWork; + this.cacheSize = source.cacheSize; + this.ignoreInvalidEndpoint = source.ignoreInvalidEndpoint; + this.allowOptimisedComponents = source.allowOptimisedComponents; + this.autoStartComponents = source.autoStartComponents; + } + @Override public String toString() { return "Enrich[" + getExpression() + "]"; @@ -379,4 +395,9 @@ public String getAutoStartComponents() { public void setAutoStartComponents(String autoStartComponents) { this.autoStartComponents = autoStartComponents; } + + @Override + public EnrichDefinition copy() { + return new EnrichDefinition(this); + } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ExpressionNode.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ExpressionNode.java index d5e98a939abd3..5f5273c94258a 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/ExpressionNode.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ExpressionNode.java @@ -58,6 +58,11 @@ public ExpressionNode(Predicate predicate) { setPredicate(predicate); } + protected ExpressionNode(ExpressionNode source) { + super(source); + this.expression = source.expression; + } + public ExpressionDefinition getExpression() { return expression; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java index c471bdbb73d9a..87ff9cb4fe8e8 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/PollEnrichDefinition.java @@ -34,7 +34,8 @@ @Metadata(label = "eip,transformation") @XmlRootElement(name = "pollEnrich") @XmlAccessorType(XmlAccessType.FIELD) -public class PollEnrichDefinition extends ExpressionNode implements AggregationStrategyAwareDefinition { +public class PollEnrichDefinition extends ExpressionNode + implements AggregationStrategyAwareDefinition, Copyable { @XmlTransient private AggregationStrategy aggregationStrategyBean; @@ -74,6 +75,20 @@ public PollEnrichDefinition(AggregationStrategy aggregationStrategy, long timeou this.timeout = Long.toString(timeout); } + protected PollEnrichDefinition(PollEnrichDefinition source) { + super(source); + this.aggregationStrategyBean = source.aggregationStrategyBean; + this.variableReceive = source.variableReceive; + this.aggregationStrategy = source.aggregationStrategy; + this.aggregationStrategyMethodName = source.aggregationStrategyMethodName; + this.aggregationStrategyMethodAllowNull = source.aggregationStrategyMethodAllowNull; + this.aggregateOnException = source.aggregateOnException; + this.timeout = source.timeout; + this.cacheSize = source.cacheSize; + this.ignoreInvalidEndpoint = source.ignoreInvalidEndpoint; + this.autoStartComponents = source.autoStartComponents; + } + @Override public String toString() { return "PollEnrich[" + getExpression() + "]"; @@ -358,4 +373,9 @@ public String getAutoStartComponents() { public void setAutoStartComponents(String autoStartComponents) { this.autoStartComponents = autoStartComponents; } + + @Override + public PollEnrichDefinition copy() { + return new PollEnrichDefinition(this); + } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java index be367b589d2b8..5175d4b849949 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteTemplateDefinition.java @@ -449,8 +449,8 @@ private Map shallowCopy(Map map) { private List> copy(List> outputs) { var copy = new ArrayList>(); for (var definition : outputs) { - if (definition instanceof CopyableProcessorDefinition copyable) { - copy.add(copyable.copy()); + if (definition instanceof Copyable copyableDefinition) { + copy.add(copyableDefinition.copy()); } else { copy.add(definition); } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java index 469ab1ea8b977..d75b68e075393 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDefinition.java @@ -33,7 +33,7 @@ @Metadata(label = "eip,routing") @XmlRootElement(name = "to") @XmlAccessorType(XmlAccessType.FIELD) -public class ToDefinition extends SendDefinition implements CopyableProcessorDefinition { +public class ToDefinition extends SendDefinition implements Copyable { @XmlAttribute private String variableSend; diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java index b1495e9fa8c18..4c4ae7e2c5e6e 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/ToDynamicDefinition.java @@ -34,7 +34,7 @@ @Metadata(label = "eip,routing") @XmlRootElement(name = "toD") @XmlAccessorType(XmlAccessType.FIELD) -public class ToDynamicDefinition extends NoOutputDefinition implements CopyableProcessorDefinition { +public class ToDynamicDefinition extends NoOutputDefinition implements Copyable { @XmlTransient protected EndpointProducerBuilder endpointProducerBuilder; diff --git a/core/camel-core/src/test/java/org/apache/camel/model/RouteTemplateDefinitionTest.java b/core/camel-core/src/test/java/org/apache/camel/model/RouteTemplateDefinitionTest.java index 0c74b35a18140..4f63304cccc7f 100644 --- a/core/camel-core/src/test/java/org/apache/camel/model/RouteTemplateDefinitionTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/model/RouteTemplateDefinitionTest.java @@ -22,6 +22,8 @@ import org.apache.camel.support.RoutePolicySupport; import org.junit.jupiter.api.Test; +import static java.util.Collections.emptyList; +import static java.util.UUID.randomUUID; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotSame; @@ -37,12 +39,12 @@ void testDeepCopyMutableProperties() { route.setRoutePolicies(List.of(new RoutePolicySupport() { })); route.setInput(new FromDefinition("direct://fromEndpoint")); - route.setOutputs(List.of(new ToDefinition("direct://toEndpoint"), new SetHeaderDefinition("header", "headerValue"))); + route.setOutputs(List.of( + new CopyableProcessDefinition(), + new NonCopyableProcessDefinition())); RouteTemplateDefinition routeTemplate = new RouteTemplateDefinition(); routeTemplate.setRoute(route); - RouteDefinition routeCopy = routeTemplate.asRouteDefinition(); - assertNotSame(route.getTemplateParameters(), routeCopy.getTemplateParameters()); assertEquals(route.getTemplateParameters(), routeCopy.getTemplateParameters()); assertNotSame(route.getRouteProperties(), routeCopy.getRouteProperties()); @@ -53,11 +55,47 @@ void testDeepCopyMutableProperties() { assertEquals(route.getInput().getUri(), routeCopy.getInput().getUri()); assertNotSame(route.getOutputs(), routeCopy.getOutputs()); assertEquals(2, routeCopy.getOutputs().size()); + assertInstanceOf(CopyableProcessDefinition.class, routeCopy.getOutputs().get(0)); assertNotSame(route.getOutputs().get(0), routeCopy.getOutputs().get(0)); - assertInstanceOf(ToDefinition.class, route.getOutputs().get(0)); - assertInstanceOf(ToDefinition.class, routeCopy.getOutputs().get(0)); - assertEquals(((ToDefinition) route.getOutputs().get(0)).getUri(), - ((ToDefinition) routeCopy.getOutputs().get(0)).getUri()); + assertEquals(route.getOutputs().get(0).getId(), routeCopy.getOutputs().get(0).getId()); assertSame(route.getOutputs().get(1), routeCopy.getOutputs().get(1)); } + + private static final class CopyableProcessDefinition extends ProcessorDefinition + implements Copyable { + + public CopyableProcessDefinition() { + setId(randomUUID().toString()); + } + + @Override + public ProcessorDefinition copy() { + var copy = new CopyableProcessDefinition(); + copy.setId(getId()); + return copy; + } + + @Override + public String getShortName() { + return toString(); + } + + @Override + public List> getOutputs() { + return emptyList(); + } + } + + private static final class NonCopyableProcessDefinition extends ProcessorDefinition { + + @Override + public String getShortName() { + return toString(); + } + + @Override + public List> getOutputs() { + return emptyList(); + } + } }