This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch eh in repository https://gitbox.apache.org/repos/asf/camel.git
commit e32c96ed9b8756dd769656ad1f3cd60e654f69da Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Tue Jul 2 07:45:18 2024 +0200 CAMEL-20932: camel-core - Route templates parameters should be supported in error handler configuration --- .../org/apache/camel/reifier/AbstractReifier.java | 4 ++ .../errorhandler/DeadLetterChannelReifier.java | 8 +-- .../errorhandler/DefaultErrorHandlerReifier.java | 4 ++ .../errorhandler/ErrorHandlerRefReifier.java | 3 +- .../reifier/errorhandler/ErrorHandlerReifier.java | 28 +++++++---- .../camel/builder/RouteTemplateRedeliveryTest.java | 58 ++++++++++++++++++++++ .../OnExceptionRedeliveryPlaceholderTest.java | 58 ++++++++++++++++++++++ 7 files changed, 148 insertions(+), 15 deletions(-) diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractReifier.java index 21d87d2e026..f0c9da843ba 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/AbstractReifier.java @@ -144,6 +144,8 @@ public abstract class AbstractReifier implements BeanRepository { } public <T> T mandatoryLookup(String name, Class<T> type) { + name = parseString(name); + Object obj = lookupByNameAndType(name, type); if (obj == null) { throw new NoSuchBeanException(name, type.getName()); @@ -156,6 +158,7 @@ public abstract class AbstractReifier implements BeanRepository { if (name == null) { return null; } + name = parseString(name); if (EndpointHelper.isReferenceParameter(name)) { return EndpointHelper.resolveReferenceParameter(camelContext, name, Object.class, false); @@ -168,6 +171,7 @@ public abstract class AbstractReifier implements BeanRepository { if (name == null) { return null; } + name = parseString(name); if (EndpointHelper.isReferenceParameter(name)) { return EndpointHelper.resolveReferenceParameter(camelContext, name, type, false); diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java index 31becf55359..cda1f50a235 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java @@ -45,19 +45,19 @@ public class DeadLetterChannelReifier extends ErrorHandlerReifier<DeadLetterChan @Override public Processor createErrorHandler(Processor processor) throws Exception { - ObjectHelper.notNull(definition.getDeadLetterUri(), "deadLetterUri", this); + String uri = parseString(definition.getDeadLetterUri()); + ObjectHelper.notNull(uri, "deadLetterUri", this); // optimize to use shared default instance if using out of the box settings RedeliveryPolicy redeliveryPolicy = resolveRedeliveryPolicy(definition, camelContext); CamelLogger logger = resolveLogger(definition); - Processor deadLetterProcessor = createDeadLetterChannelProcessor(definition.getDeadLetterUri()); + Processor deadLetterProcessor = createDeadLetterChannelProcessor(uri); DeadLetterChannel answer = new DeadLetterChannel( camelContext, processor, logger, getProcessor(definition.getOnRedeliveryProcessor(), definition.getOnRedeliveryRef()), - redeliveryPolicy, deadLetterProcessor, - definition.getDeadLetterUri(), + redeliveryPolicy, deadLetterProcessor, uri, parseBoolean(definition.getDeadLetterHandleNewException(), true), parseBoolean(definition.getUseOriginalMessage(), false), parseBoolean(definition.getUseOriginalBody(), false), diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java index 699b41307e1..c60a7294a51 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java @@ -63,6 +63,7 @@ public class DefaultErrorHandlerReifier extends ErrorHandlerReifier<DefaultError return answer; } + @Deprecated private Predicate resolveRetryWhilePolicy(DeadLetterChannelDefinition definition, CamelContext camelContext) { Predicate answer = definition.getRetryWhilePredicate(); @@ -90,6 +91,7 @@ public class DefaultErrorHandlerReifier extends ErrorHandlerReifier<DefaultError return answer; } + @Deprecated private Processor createDeadLetterChannelProcessor(String uri) { // wrap in our special safe fallback error handler if sending to // dead letter channel fails @@ -121,6 +123,8 @@ public class DefaultErrorHandlerReifier extends ErrorHandlerReifier<DefaultError protected synchronized ScheduledExecutorService getExecutorService( ScheduledExecutorService executorService, String executorServiceRef) { + + executorServiceRef = parseString(executorServiceRef); if (executorService == null || executorService.isShutdown()) { // camel context will shutdown the executor when it shutdown so no // need to shut it down when stopping diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java index adf296b8154..2aaab3ef8af 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java @@ -38,7 +38,8 @@ public class ErrorHandlerRefReifier extends ErrorHandlerReifier<RefErrorHandlerD } private ErrorHandlerFactory lookupErrorHandler(Route route) { - ErrorHandlerFactory handler = ErrorHandlerHelper.lookupErrorHandlerFactory(route, definition.getRef(), true); + ErrorHandlerFactory handler + = ErrorHandlerHelper.lookupErrorHandlerFactory(route, parseString(definition.getRef()), true); ObjectHelper.notNull(handler, "error handler '" + definition.getRef() + "'"); route.addErrorHandlerFactoryReference(definition, handler); return handler; diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java index b9d691fd712..6a4a8e50214 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java @@ -117,21 +117,23 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends Processor onRedelivery = getProcessor(def.getOnRedelivery(), def.getOnRedeliveryRef()); Processor onExceptionOccurred = getProcessor(def.getOnExceptionOccurred(), def.getOnExceptionOccurredRef()); return new ExceptionPolicy( - def.getId(), CamelContextHelper.getRouteId(def), + parseString(def.getId()), CamelContextHelper.getRouteId(def), parseBoolean(def.getUseOriginalMessage(), false), parseBoolean(def.getUseOriginalBody(), false), ObjectHelper.isNotEmpty(def.getOutputs()), handled, continued, retryWhile, onRedelivery, - onExceptionOccurred, def.getRedeliveryPolicyRef(), + onExceptionOccurred, parseString(def.getRedeliveryPolicyRef()), createRedeliveryPolicyOptions(def.getRedeliveryPolicyType()), def.getExceptions()); } - public static RedeliveryPolicy createRedeliveryPolicy(RedeliveryPolicyDefinition definition, CamelContext context) { + @Deprecated + public RedeliveryPolicy createRedeliveryPolicy(RedeliveryPolicyDefinition definition, CamelContext context) { Map<RedeliveryOption, String> options = createRedeliveryPolicyOptions(definition); return createRedeliveryPolicy(options, context, null); } - private static RedeliveryPolicy createRedeliveryPolicy( + @Deprecated + private RedeliveryPolicy createRedeliveryPolicy( Map<RedeliveryOption, String> definition, CamelContext context, RedeliveryPolicy parentPolicy) { RedeliveryPolicy answer; if (parentPolicy != null) { @@ -240,7 +242,7 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends return answer; } - private static Map<RedeliveryOption, String> createRedeliveryPolicyOptions(RedeliveryPolicyDefinition definition) { + private Map<RedeliveryOption, String> createRedeliveryPolicyOptions(RedeliveryPolicyDefinition definition) { if (definition == null) { return null; } @@ -272,16 +274,16 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends return policy; } - private static void setOption(Map<RedeliveryOption, String> policy, RedeliveryOption option, Object value) { + private void setOption(Map<RedeliveryOption, String> policy, RedeliveryOption option, String value) { setOption(policy, option, value, null); } - private static void setOption( - Map<RedeliveryOption, String> policy, RedeliveryOption option, Object value, Object defaultValue) { + private void setOption( + Map<RedeliveryOption, String> policy, RedeliveryOption option, String value, String defaultValue) { if (value != null) { - policy.put(option, value.toString()); + policy.put(option, parseString(value)); } else if (defaultValue != null) { - policy.put(option, defaultValue.toString()); + policy.put(option, defaultValue); } } @@ -455,6 +457,8 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends } protected Predicate getPredicate(Predicate pred, String ref) { + ref = parseString(ref); + if (pred == null && ref != null) { // its a bean expression Language bean = camelContext.resolveLanguage("bean"); @@ -464,6 +468,8 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends } protected <U> U getBean(Class<U> clazz, U bean, String ref) { + ref = parseString(ref); + if (bean == null && ref != null) { bean = lookupByNameAndType(ref, clazz); } @@ -471,6 +477,8 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerFactory> extends } protected Processor getProcessor(Processor processor, String ref) { + ref = parseString(ref); + if (processor == null) { processor = getBean(Processor.class, null, ref); } diff --git a/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateRedeliveryTest.java b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateRedeliveryTest.java new file mode 100644 index 00000000000..ad62cd60804 --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/builder/RouteTemplateRedeliveryTest.java @@ -0,0 +1,58 @@ +/* + * 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.builder; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class RouteTemplateRedeliveryTest extends ContextTestSupport { + + @Test + public void testCreateRouteFromRouteTemplate() throws Exception { + assertEquals(1, context.getRouteTemplateDefinitions().size()); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("myCount", "3"); + parameters.put("myFac", "1"); + context.addRouteFromTemplate("first", "myTemplate", parameters); + + String out = template.requestBody("direct:start", "Hello World", String.class); + assertEquals("3", out); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + routeTemplate("myTemplate").templateParameter("myCount").templateParameter("myFac") + .from("direct:start") + .onException(Exception.class).maximumRedeliveryDelay(1).maximumRedeliveries("{{myCount}}") + .collisionAvoidanceFactor("{{myFac}}").onRedelivery(e -> { + e.getMessage().setBody(e.getMessage().getHeader(Exchange.REDELIVERY_COUNTER)); + }).handled(true).end() + .throwException(new IllegalArgumentException("Forced")); + } + }; + } +} diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/OnExceptionRedeliveryPlaceholderTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/OnExceptionRedeliveryPlaceholderTest.java new file mode 100644 index 00000000000..0c085b5e41b --- /dev/null +++ b/core/camel-core/src/test/java/org/apache/camel/processor/OnExceptionRedeliveryPlaceholderTest.java @@ -0,0 +1,58 @@ +/* + * 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.processor; + +import org.apache.camel.ContextTestSupport; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class OnExceptionRedeliveryPlaceholderTest extends ContextTestSupport { + + private static String counter = ""; + + @Test + public void testRedeliveryPlaceholder() throws Exception { + getMockEndpoint("mock:error").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + + assertEquals("123", counter); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + context.getPropertiesComponent().addInitialProperty("myCount", "3"); + context.getPropertiesComponent().addInitialProperty("myFac", "1"); + + from("direct:start") + .onException(Exception.class).maximumRedeliveryDelay(1).maximumRedeliveries("{{myCount}}") + .collisionAvoidanceFactor("{{myFac}}").onRedelivery(e -> { + counter += e.getMessage().getHeader(Exchange.REDELIVERY_COUNTER); + }).handled(true).to("mock:error").end() + .throwException(new IllegalArgumentException("Forced")); + } + }; + } +}