You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/07/15 09:01:53 UTC
[camel] 01/04: CAMEL-19607: camel-core - Fix error handler redeliveryPolicyRef
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-3.20.x
in repository https://gitbox.apache.org/repos/asf/camel.git
commit a00f0c33d451e54f717d11e117f57466aa984ca4
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Jul 15 09:32:55 2023 +0200
CAMEL-19607: camel-core - Fix error handler redeliveryPolicyRef
---
...SpringDefaultErrorHandlerRedeliveryRefTest.java | 30 +++++++++
.../DefaultErrorHandlerRedeliveryRefTest.xml | 44 +++++++++++++
.../DefaultErrorHandlerDefinition.java | 17 ++++-
.../errorhandler/DeadLetterChannelReifier.java | 7 +-
.../errorhandler/DefaultErrorHandlerReifier.java | 7 +-
.../DefaultErrorHandlerRedeliveryRefTest.java | 74 ++++++++++++++++++++++
.../org/apache/camel/xml/in/ModelParserTest.java | 42 ++++++++++++
.../test/resources/errorHandlerConfiguration.xml | 29 +++++++++
...rrorHandlerConfigurationRedeliveryPolicyRef.xml | 26 ++++++++
.../apache/camel/dsl/yaml/ErrorHandlerTest.groovy | 33 ++++++++++
10 files changed, 306 insertions(+), 3 deletions(-)
diff --git a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringDefaultErrorHandlerRedeliveryRefTest.java b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringDefaultErrorHandlerRedeliveryRefTest.java
new file mode 100644
index 00000000000..fc5c21ff64b
--- /dev/null
+++ b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/processor/SpringDefaultErrorHandlerRedeliveryRefTest.java
@@ -0,0 +1,30 @@
+/*
+ * 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.spring.processor;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.processor.DefaultErrorHandlerRedeliveryRefTest;
+
+import static org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
+
+public class SpringDefaultErrorHandlerRedeliveryRefTest extends DefaultErrorHandlerRedeliveryRefTest {
+ @Override
+ protected CamelContext createCamelContext() throws Exception {
+ return createSpringCamelContext(this,
+ "org/apache/camel/spring/processor/DefaultErrorHandlerRedeliveryRefTest.xml");
+ }
+}
diff --git a/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/DefaultErrorHandlerRedeliveryRefTest.xml b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/DefaultErrorHandlerRedeliveryRefTest.xml
new file mode 100644
index 00000000000..a8dea3727dd
--- /dev/null
+++ b/components/camel-spring-xml/src/test/resources/org/apache/camel/spring/processor/DefaultErrorHandlerRedeliveryRefTest.xml
@@ -0,0 +1,44 @@
+<?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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
+ ">
+
+ <bean id="myPolicy" class="org.apache.camel.processor.errorhandler.RedeliveryPolicy">
+ <property name="maximumRedeliveries" value="2"/>
+ <property name="redeliveryDelay" value="0"/>
+ </bean>
+
+ <bean id="myProcessor" class="org.apache.camel.processor.DefaultErrorHandlerRedeliveryRefTest$MyProcessor"/>
+
+ <camelContext errorHandlerRef="eh" xmlns="http://camel.apache.org/schema/spring">
+
+ <errorHandler id="eh" redeliveryPolicyRef="myPolicy"/>
+
+ <route>
+ <from uri="direct:start"/>
+ <process ref="myProcessor"/>
+ </route>
+
+ </camelContext>
+</beans>
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java
index 2bfe1fef8fb..090f80b05f8 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/errorhandler/DefaultErrorHandlerDefinition.java
@@ -126,7 +126,7 @@ public class DefaultErrorHandlerDefinition extends BaseErrorHandlerDefinition {
other.setRetryWhileRef(getRetryWhileRef());
other.setUseOriginalBody(getUseOriginalBody());
other.setUseOriginalMessage(getUseOriginalMessage());
- if (getRedeliveryPolicy() != null) {
+ if (hasRedeliveryPolicy()) {
other.setRedeliveryPolicy(getRedeliveryPolicy().copy());
}
}
@@ -395,6 +395,10 @@ public class DefaultErrorHandlerDefinition extends BaseErrorHandlerDefinition {
return redeliveryPolicy;
}
+ public boolean hasRedeliveryPolicy() {
+ return redeliveryPolicy != null;
+ }
+
/**
* Sets the redelivery settings
*/
@@ -789,4 +793,15 @@ public class DefaultErrorHandlerDefinition extends BaseErrorHandlerDefinition {
return this;
}
+ /**
+ * Sets a reference to a {@link RedeliveryPolicy} to be used for redelivery settings.
+ *
+ * @param redeliveryPolicyRef the redelivrey policy reference
+ * @return the builder
+ */
+ public DefaultErrorHandlerDefinition redeliveryPolicyRef(String redeliveryPolicyRef) {
+ setRedeliveryPolicyRef(redeliveryPolicyRef);
+ return this;
+ }
+
}
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 072a3e58d5f..31becf55359 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
@@ -107,8 +107,13 @@ public class DeadLetterChannelReifier extends ErrorHandlerReifier<DeadLetterChan
}
private RedeliveryPolicy resolveRedeliveryPolicy(DeadLetterChannelDefinition definition, CamelContext camelContext) {
+ if (definition.hasRedeliveryPolicy() && definition.getRedeliveryPolicyRef() != null) {
+ throw new IllegalArgumentException(
+ "Cannot have both redeliveryPolicy and redeliveryPolicyRef set at the same time.");
+ }
+
RedeliveryPolicy answer = null;
- RedeliveryPolicyDefinition def = definition.getRedeliveryPolicy();
+ RedeliveryPolicyDefinition def = definition.hasRedeliveryPolicy() ? definition.getRedeliveryPolicy() : null;
if (def == null && definition.getRedeliveryPolicyRef() != null) {
// ref may point to a definition
def = lookupByNameAndType(definition.getRedeliveryPolicyRef(), RedeliveryPolicyDefinition.class);
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 013849b8719..699b41307e1 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
@@ -100,8 +100,13 @@ public class DefaultErrorHandlerReifier extends ErrorHandlerReifier<DefaultError
}
private RedeliveryPolicy resolveRedeliveryPolicy(DefaultErrorHandlerDefinition definition, CamelContext camelContext) {
+ if (definition.hasRedeliveryPolicy() && definition.getRedeliveryPolicyRef() != null) {
+ throw new IllegalArgumentException(
+ "Cannot have both redeliveryPolicy and redeliveryPolicyRef set at the same time.");
+ }
+
RedeliveryPolicy answer = null;
- RedeliveryPolicyDefinition def = definition.getRedeliveryPolicy();
+ RedeliveryPolicyDefinition def = definition.hasRedeliveryPolicy() ? definition.getRedeliveryPolicy() : null;
if (def != null) {
answer = ErrorHandlerReifier.createRedeliveryPolicy(def, camelContext, null);
}
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/DefaultErrorHandlerRedeliveryRefTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/DefaultErrorHandlerRedeliveryRefTest.java
new file mode 100644
index 00000000000..19da41520e2
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/DefaultErrorHandlerRedeliveryRefTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.Processor;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class DefaultErrorHandlerRedeliveryRefTest extends ContextTestSupport {
+
+ private static int counter;
+
+ @Test
+ public void testRedeliveryRefTest() throws Exception {
+ counter = 0;
+
+ try {
+ template.sendBody("direct:start", "Hello World");
+ fail("Should have thrown exception");
+ } catch (RuntimeCamelException e) {
+ // expected
+ }
+
+ // One call + 2 re-deliveries
+ assertEquals(3, counter);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ public void configure() throws Exception {
+ RedeliveryPolicy policy = new RedeliveryPolicy();
+ policy.maximumRedeliveries(2);
+ policy.redeliveryDelay(0);
+ getCamelContext().getRegistry().bind("myPolicy", policy);
+
+ errorHandler(defaultErrorHandler().redeliveryPolicyRef("myPolicy"));
+
+ from("direct:start").process(new MyProcessor());
+ }
+ };
+ }
+
+ public static class MyProcessor implements Processor {
+
+ @Override
+ public void process(Exchange exchange) throws Exception {
+ counter++;
+ throw new Exception("Forced exception by unit test");
+ }
+ }
+
+}
diff --git a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
index c90d0acfd1c..ff40a5c1fa1 100644
--- a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
+++ b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
@@ -29,11 +29,14 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.camel.model.PropertyDefinition;
+import org.apache.camel.model.RouteConfigurationDefinition;
+import org.apache.camel.model.RouteConfigurationsDefinition;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.RouteTemplatesDefinition;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.model.SetBodyDefinition;
import org.apache.camel.model.TemplatedRoutesDefinition;
+import org.apache.camel.model.errorhandler.DeadLetterChannelDefinition;
import org.apache.camel.model.language.XPathExpression;
import org.apache.camel.model.rest.ParamDefinition;
import org.apache.camel.model.rest.RestDefinition;
@@ -43,7 +46,10 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
public class ModelParserTest {
@@ -200,6 +206,42 @@ public class ModelParserTest {
Assertions.assertEquals(4, param.getAllowableValues().size());
}
+ @Test
+ public void testErrorHandler() throws Exception {
+ Path dir = getResourceFolder();
+ Path path = new File(dir.toFile(), "errorHandlerConfiguration.xml").toPath();
+ ModelParser parser = new ModelParser(Files.newInputStream(path), NAMESPACE);
+ RouteConfigurationsDefinition routes = parser.parseRouteConfigurationsDefinition().orElse(null);
+ assertNotNull(routes);
+ assertEquals(1, routes.getRouteConfigurations().size());
+
+ RouteConfigurationDefinition cfg = routes.getRouteConfigurations().get(0);
+ assertInstanceOf(DeadLetterChannelDefinition.class, cfg.getErrorHandler().getErrorHandlerType());
+ DeadLetterChannelDefinition dlc = (DeadLetterChannelDefinition) cfg.getErrorHandler().getErrorHandlerType();
+ assertEquals("mock:dead", dlc.getDeadLetterUri());
+ assertTrue(dlc.hasRedeliveryPolicy());
+ assertEquals("2", dlc.getRedeliveryPolicy().getMaximumRedeliveries());
+ assertEquals("123", dlc.getRedeliveryPolicy().getRedeliveryDelay());
+ assertEquals("false", dlc.getRedeliveryPolicy().getLogStackTrace());
+ }
+
+ @Test
+ public void testErrorHandlerRedeliveryPolicyRef() throws Exception {
+ Path dir = getResourceFolder();
+ Path path = new File(dir.toFile(), "errorHandlerConfigurationRedeliveryPolicyRef.xml").toPath();
+ ModelParser parser = new ModelParser(Files.newInputStream(path), NAMESPACE);
+ RouteConfigurationsDefinition routes = parser.parseRouteConfigurationsDefinition().orElse(null);
+ assertNotNull(routes);
+ assertEquals(1, routes.getRouteConfigurations().size());
+
+ RouteConfigurationDefinition cfg = routes.getRouteConfigurations().get(0);
+ assertInstanceOf(DeadLetterChannelDefinition.class, cfg.getErrorHandler().getErrorHandlerType());
+ DeadLetterChannelDefinition dlc = (DeadLetterChannelDefinition) cfg.getErrorHandler().getErrorHandlerType();
+ assertEquals("mock:dead", dlc.getDeadLetterUri());
+ assertFalse(dlc.hasRedeliveryPolicy());
+ assertEquals("myPolicy", dlc.getRedeliveryPolicyRef());
+ }
+
private Path getResourceFolder() {
String url = getClass().getClassLoader().getResource("barInterceptorRoute.xml").toString();
if (url.startsWith("file:")) {
diff --git a/core/camel-xml-io/src/test/resources/errorHandlerConfiguration.xml b/core/camel-xml-io/src/test/resources/errorHandlerConfiguration.xml
new file mode 100644
index 00000000000..81071092a93
--- /dev/null
+++ b/core/camel-xml-io/src/test/resources/errorHandlerConfiguration.xml
@@ -0,0 +1,29 @@
+<?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.
+
+-->
+<routeConfigurations xmlns="http://camel.apache.org/schema/spring">
+ <routeConfiguration>
+ <errorHandler>
+ <deadLetterChannel deadLetterUri="mock:dead">
+ <redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="123"
+ logStackTrace="false"/>
+ </deadLetterChannel>
+ </errorHandler>
+ </routeConfiguration>
+</routeConfigurations>
diff --git a/core/camel-xml-io/src/test/resources/errorHandlerConfigurationRedeliveryPolicyRef.xml b/core/camel-xml-io/src/test/resources/errorHandlerConfigurationRedeliveryPolicyRef.xml
new file mode 100644
index 00000000000..24b7aa36ddb
--- /dev/null
+++ b/core/camel-xml-io/src/test/resources/errorHandlerConfigurationRedeliveryPolicyRef.xml
@@ -0,0 +1,26 @@
+<?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.
+
+-->
+<routeConfigurations xmlns="http://camel.apache.org/schema/spring">
+ <routeConfiguration>
+ <errorHandler>
+ <deadLetterChannel deadLetterUri="mock:dead" redeliveryPolicyRef="myPolicy"/>
+ </errorHandler>
+ </routeConfiguration>
+</routeConfigurations>
diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
index b66d919020d..9e9bdb4f2ef 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
@@ -139,4 +139,37 @@ class ErrorHandlerTest extends YamlTestSupport {
context.getErrorHandlerFactory() instanceof NoErrorHandlerDefinition
}
+ def "error-handler (redelivery policy ref)"() {
+ setup:
+ loadRoutes """
+ - beans:
+ - name: myFailingProcessor
+ type: ${MyFailingProcessor.name}
+ - name: myPolicy
+ type: org.apache.camel.processor.errorhandler.RedeliveryPolicy
+ properties:
+ maximumRedeliveries: 3
+ logStackTrace: true
+ - error-handler:
+ default-error-handler:
+ useOriginalMessage: true
+ redelivery-policy-ref: myPolicy
+ - from:
+ uri: "direct:start"
+ steps:
+ - process:
+ ref: "myFailingProcessor"
+ """
+
+ when:
+ context.start()
+ then:
+ with(context.getCamelContextExtension().getErrorHandlerFactory(), DefaultErrorHandlerDefinition) {
+ useOriginalMessage == "true"
+ hasRedeliveryPolicy() == false
+ redeliveryPolicyRef == "myPolicy"
+ }
+ }
+
+
}