From 90812f01eefd213b14f615faa64906b869b15990 Mon Sep 17 00:00:00 2001 From: Jonathan Cook Date: Thu, 3 Nov 2022 17:40:26 +0100 Subject: [PATCH] BAEL-5236 - Apache Camel Exception Handling (#12973) * BAEL-4706 - Spring Boot with Spring Batch * BAEL-3948 - Fix test(s) in spring-batch which leaves repository.sqlite changed * BAEL-4736 - Convert JSONArray to List of Object using camel-jackson * BAEL-4756 - Mockito MockSettings * BAEL-4756 - Mockito MockSettings - fix spelling * BAEL-2674 - Upgrade the Okhttp article * BAEL-4204 - Adding Interceptors in OkHTTP * BAEL-4836 - Mocking Static Methods with Mockito * BAEL-4205 - A Guide to Events in OkHTTP * BAEL-5408 - Update Camel version in spring-boot-camel module * BAEL-5234 - Apache Camel Routes Testing in Spring Boot * BAEL-5234 - Apache Camel Routes Testing in Spring Boot * BAEL-5237 - Apache Camel Conditional Routing * BAEL-5236 - Apache Camel Exception Handling Co-authored-by: Jonathan Cook --- .../ExceptionHandlingSpringApplication.java | 13 +++++++ .../ExceptionHandlingWithDoTryRoute.java | 26 ++++++++++++++ ...ptionHandlingWithExceptionClauseRoute.java | 24 +++++++++++++ .../exception/ExceptionLoggingProcessor.java | 30 ++++++++++++++++ .../exception/ExceptionThrowingRoute.java | 30 ++++++++++++++++ ...galArgumentExceptionThrowingProcessor.java | 20 +++++++++++ ...ceptionHandlingWithDoTryRouteUnitTest.java | 30 ++++++++++++++++ ...dlingWithExceptionClauseRouteUnitTest.java | 30 ++++++++++++++++ .../ExceptionThrowingRouteUnitTest.java | 36 +++++++++++++++++++ ...entExceptionThrowingProcessorUnitTest.java | 16 +++++++++ 10 files changed, 255 insertions(+) create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingSpringApplication.java create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRoute.java create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRoute.java create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionLoggingProcessor.java create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionThrowingRoute.java create mode 100644 spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessor.java create mode 100644 spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRouteUnitTest.java create mode 100644 spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRouteUnitTest.java create mode 100644 spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionThrowingRouteUnitTest.java create mode 100644 spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessorUnitTest.java diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingSpringApplication.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingSpringApplication.java new file mode 100644 index 0000000000..df4550d9d5 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingSpringApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.camel.exception; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class ExceptionHandlingSpringApplication { + + public static void main(String[] args) { + SpringApplication.run(ExceptionHandlingSpringApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRoute.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRoute.java new file mode 100644 index 0000000000..ce3cfc129b --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRoute.java @@ -0,0 +1,26 @@ +package com.baeldung.camel.exception; + +import java.io.IOException; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.stereotype.Component; + +@Component +public class ExceptionHandlingWithDoTryRoute extends RouteBuilder { + + @Override + public void configure() throws Exception { + + from("direct:start-handling-exception") + .routeId("exception-handling-route") + .doTry() + .process(new IllegalArgumentExceptionThrowingProcessor()) + .to("mock:received") + .doCatch(IOException.class, IllegalArgumentException.class) + .to("mock:caught") + .doFinally() + .to("mock:finally") + .end(); + + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRoute.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRoute.java new file mode 100644 index 0000000000..3a438e2402 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRoute.java @@ -0,0 +1,24 @@ +package com.baeldung.camel.exception; + +import org.apache.camel.builder.RouteBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class ExceptionHandlingWithExceptionClauseRoute extends RouteBuilder { + + @Autowired + private ExceptionLoggingProcessor exceptionLogger; + + @Override + public void configure() throws Exception { + onException(IllegalArgumentException.class).process(exceptionLogger) + .handled(true) + .to("mock:handled"); + + from("direct:start-exception-clause") + .routeId("exception-clause-route") + .process(new IllegalArgumentExceptionThrowingProcessor()) + .to("mock:received"); + } +} diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionLoggingProcessor.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionLoggingProcessor.java new file mode 100644 index 0000000000..84e4072888 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionLoggingProcessor.java @@ -0,0 +1,30 @@ +package com.baeldung.camel.exception; + +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class ExceptionLoggingProcessor implements Processor { + + private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionLoggingProcessor.class); + + @Override + public void process(Exchange exchange) throws Exception { + Map headersMap = exchange.getIn().getHeaders(); + + if (!headersMap.isEmpty()) { + headersMap.entrySet() + .stream() + .forEach(e -> LOGGER.info("Header key [{}] -||- Header value [{}]", e.getKey(), e.getValue())); + } else { + LOGGER.info("Empty header"); + } + + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionThrowingRoute.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionThrowingRoute.java new file mode 100644 index 0000000000..752aabaf1a --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/ExceptionThrowingRoute.java @@ -0,0 +1,30 @@ +package com.baeldung.camel.exception; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class ExceptionThrowingRoute extends RouteBuilder { + + private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionThrowingRoute.class); + + @Override + public void configure() throws Exception { + + from("direct:start-exception") + .routeId("exception-throwing-route") + .process(new Processor() { + + @Override + public void process(Exchange exchange) throws Exception { + LOGGER.error("Exception Thrown"); + throw new IllegalArgumentException("An exception happened on purpose"); + + } + }).to("mock:received"); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessor.java b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessor.java new file mode 100644 index 0000000000..461a4e6553 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/main/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessor.java @@ -0,0 +1,20 @@ +package com.baeldung.camel.exception; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +public class IllegalArgumentExceptionThrowingProcessor implements Processor { + + private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionLoggingProcessor.class); + + @Override + public void process(Exchange exchange) throws Exception { + LOGGER.error("Exception Thrown"); + throw new IllegalArgumentException("An exception happened on purpose"); + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRouteUnitTest.java b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRouteUnitTest.java new file mode 100644 index 0000000000..23d3b1a392 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithDoTryRouteUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.camel.exception; + +import org.apache.camel.EndpointInject; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@CamelSpringBootTest +class ExceptionHandlingWithDoTryRouteUnitTest { + + @Autowired + private ProducerTemplate template; + + @EndpointInject("mock:caught") + private MockEndpoint mock; + + @Test + void whenSendHeaders_thenExceptionRaisedAndHandledSuccessfully() throws Exception { + mock.expectedMessageCount(1); + + template.sendBodyAndHeader("direct:start-handling-exception", null, "fruit", "Banana"); + + mock.assertIsSatisfied(); + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRouteUnitTest.java b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRouteUnitTest.java new file mode 100644 index 0000000000..28d672bd64 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionHandlingWithExceptionClauseRouteUnitTest.java @@ -0,0 +1,30 @@ +package com.baeldung.camel.exception; + +import org.apache.camel.EndpointInject; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@CamelSpringBootTest +class ExceptionHandlingWithExceptionClauseRouteUnitTest { + + @Autowired + private ProducerTemplate template; + + @EndpointInject("mock:handled") + private MockEndpoint mock; + + @Test + void whenSendHeaders_thenExceptionRaisedAndHandledSuccessfully() throws Exception { + mock.expectedMessageCount(1); + + template.sendBodyAndHeader("direct:start-exception-clause", null, "fruit", "Banana"); + + mock.assertIsSatisfied(); + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionThrowingRouteUnitTest.java b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionThrowingRouteUnitTest.java new file mode 100644 index 0000000000..6e6944fce8 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/ExceptionThrowingRouteUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.camel.exception; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.ExchangePattern; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.test.spring.junit5.CamelSpringBootTest; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +@CamelSpringBootTest +class ExceptionThrowingRouteUnitTest { + + @Autowired + private ProducerTemplate template; + + @Test + void whenSendBody_thenExceptionRaisedSuccessfully() { + CamelContext context = template.getCamelContext(); + Exchange exchange = context.getEndpoint("direct:start-exception") + .createExchange(ExchangePattern.InOut); + + exchange.getIn().setBody("Hello Baeldung"); + Exchange out = template.send("direct:start-exception", exchange); + + assertTrue(out.isFailed(), "Should be failed"); + assertTrue(out.getException() instanceof IllegalArgumentException, "Should be IllegalArgumentException"); + assertEquals("An exception happened on purpose", out.getException().getMessage()); + } + +} diff --git a/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessorUnitTest.java b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessorUnitTest.java new file mode 100644 index 0000000000..a95abdfd27 --- /dev/null +++ b/spring-boot-modules/spring-boot-camel/src/test/java/com/baeldung/camel/exception/IllegalArgumentExceptionThrowingProcessorUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.camel.exception; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class IllegalArgumentExceptionThrowingProcessorUnitTest { + + @Test + void whenProcessed_thenIllegalArgumentExceptionRaisedSuccessfully() { + assertThrows(IllegalArgumentException.class, () -> { + new IllegalArgumentExceptionThrowingProcessor().process(null); + }); + } + +}