You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2020/10/30 17:47:50 UTC

[camel-spring-boot-examples] branch master updated: splitter-eip-example

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-spring-boot-examples.git


The following commit(s) were added to refs/heads/master by this push:
     new 3822b68  splitter-eip-example
3822b68 is described below

commit 3822b6864b66f2467ce5e3de94eca2f7351528ee
Author: Farid Guliyev <fg...@gmail.com>
AuthorDate: Fri Oct 30 10:03:34 2020 -0400

    splitter-eip-example
---
 README.adoc                                        |   4 +-
 camel-example-spring-boot-splitter-eip/README.adoc |  25 ++
 camel-example-spring-boot-splitter-eip/pom.xml     | 149 ++++++++
 .../spring/boot/AggregationStrategyPojo.java       |  30 ++
 .../camel/example/spring/boot/Application.java     |  34 ++
 .../example/spring/boot/MyMessageTransformer.java  |  40 ++
 .../camel/example/spring/boot/SplitterRouter.java  | 107 ++++++
 .../src/main/resources/application.properties      |  30 ++
 .../src/test/java/CamelSplitterEIPTests.java       | 136 +++++++
 pom.xml                                            | 424 +++++++++++----------
 10 files changed, 767 insertions(+), 212 deletions(-)

diff --git a/README.adoc b/README.adoc
index cb49d8a..f3cc342 100644
--- a/README.adoc
+++ b/README.adoc
@@ -27,7 +27,7 @@ readme's instructions.
 == Examples
 
 // examples: START
-Number of Examples: 47 (0 deprecated)
+Number of Examples: 48 (0 deprecated)
 
 [width="100%",cols="4,2,4",options="header"]
 |===
@@ -51,6 +51,8 @@ Number of Examples: 47 (0 deprecated)
 
 | link:camel-example-spring-boot-rest-swagger-simple/README.adoc[REST Swagger] (camel-example-spring-boot-rest-swagger-simple) | Beginner | This example shows how to call a Rest service defined using Swagger specification
 
+| link:camel-example-spring-boot-splitter-eip/README.adoc[Spring Boot Splitter Eip] (camel-example-spring-boot-splitter-eip) | Beginner | An example showing Splitter EIP with Camel and Spring Boot
+
 | link:camel-example-spring-boot-type-converter/README.adoc[Spring Boot Type Converter] (camel-example-spring-boot-type-converter) | Beginner | An example showing how to create custom type converter with Camel and Spring Boot
 
 | link:camel-example-spring-boot-unit-testing/README.adoc[Spring Boot Unit Testing] (camel-example-spring-boot-unit-testing) | Beginner | An example showing how to write unit tests with Camel and Spring Boot
diff --git a/camel-example-spring-boot-splitter-eip/README.adoc b/camel-example-spring-boot-splitter-eip/README.adoc
new file mode 100644
index 0000000..e050011
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/README.adoc
@@ -0,0 +1,25 @@
+== Spring Boot and ServiceCall EIP Example
+
+This example show how to use Camel with Splitter EIP with Spring Boot.
+
+Examples
+
+ - Example 1 : Simple splitter.
+ - Example 2 : Splitter with subsequent aggregation.
+ - Example 3 : Splitter with subsequent aggregation using POJO bean instead of AggregationStrategy implementation
+ - Example 4 : Splitter with subsequent aggregation failing on exception.
+ - Example 5: Splitter with subsequent aggregation on failing on aggregation exception.
+
+=== How to run
+
+    mvn clean test
+     
+=== Help and contributions
+
+If you hit any problem using Camel or have some feedback, then please
+https://camel.apache.org/support.html[let us know].
+
+We also love contributors, so
+https://camel.apache.org/contributing.html[get involved] :-)
+
+The Camel riders!
diff --git a/camel-example-spring-boot-splitter-eip/pom.xml b/camel-example-spring-boot-splitter-eip/pom.xml
new file mode 100644
index 0000000..d30f548
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/pom.xml
@@ -0,0 +1,149 @@
+<?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.
+  ~  */
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<parent>
+		<artifactId>examples</artifactId>
+		<groupId>org.apache.camel.springboot.example</groupId>
+		<version>3.7.0-SNAPSHOT</version>
+	</parent>
+	<modelVersion>4.0.0</modelVersion>
+
+	<artifactId>camel-example-spring-boot-splitter-eip</artifactId>
+	<name>Camel SB Examples :: Camel Splitter EIP</name>
+	<description>An example showing Splitter EIP with Camel and Spring Boot</description>
+
+	<properties>
+		<category>Beginner</category>
+
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+		<spring.boot-version>${spring-boot-version}</spring.boot-version>
+	</properties>
+
+	<dependencyManagement>
+		<dependencies>
+			<!-- Spring Boot BOM -->
+			<dependency>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-dependencies</artifactId>
+				<version>${spring.boot-version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+			<!-- Camel BOM -->
+			<dependency>
+				<groupId>org.apache.camel.springboot</groupId>
+				<artifactId>camel-spring-boot-bom</artifactId>
+				<version>${camel-version}</version>
+				<type>pom</type>
+				<scope>import</scope>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+	<dependencies>
+
+		<!-- Spring Boot -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter</artifactId>
+		</dependency>
+		<!-- Camel -->
+		<dependency>
+			<groupId>org.apache.camel.springboot</groupId>
+			<artifactId>camel-spring-boot-starter</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.camel.springboot</groupId>
+			<artifactId>camel-stream-starter</artifactId>
+		</dependency>
+
+		<!-- test -->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-test-spring-junit5</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.springframework.boot</groupId>
+				<artifactId>spring-boot-maven-plugin</artifactId>
+				<version>${spring-boot-version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>repackage</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<!-- Camel Maven Package Plugin to generate Type Converter Loader source code - Camel 3.x way -->
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>build-helper-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<phase>initialize</phase>
+						<goals>
+							<goal>add-source</goal>
+							<goal>add-resource</goal>
+						</goals>
+						<configuration>
+							<sources>
+								<source>src/generated/java</source>
+							</sources>
+							<resources>
+								<resource>
+									<directory>src/generated/resources</directory>
+								</resource>
+							</resources>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+			<!-- Adds mgenerated Type Converter Loader source in src/generated to the source path - Camel 3.x way -->
+			<plugin>
+				<groupId>org.apache.camel</groupId>
+				<artifactId>camel-package-maven-plugin</artifactId>
+				<version>${camel-version}</version>
+				<executions>
+					<execution>
+						<id>generate</id>
+						<goals>
+							<goal>generate-component</goal>
+						</goals>
+						<phase>process-classes</phase>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
\ No newline at end of file
diff --git a/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/AggregationStrategyPojo.java b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/AggregationStrategyPojo.java
new file mode 100644
index 0000000..95922b0
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/AggregationStrategyPojo.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.example.spring.boot;
+
+public class AggregationStrategyPojo {
+
+	public String aggregate(String oldBody, String newBody) {
+		if (newBody != null) {
+			return oldBody + "+" + newBody;
+		} else {
+			return oldBody;
+		}
+	}
+}
diff --git a/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/Application.java b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/Application.java
new file mode 100644
index 0000000..ecfefd9
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/Application.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.example.spring.boot;
+
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+
+}
+
diff --git a/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/MyMessageTransformer.java b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/MyMessageTransformer.java
new file mode 100644
index 0000000..8ca6986
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/MyMessageTransformer.java
@@ -0,0 +1,40 @@
+/*
+ *
+ *  * 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.example.spring.boot;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MyMessageTransformer {
+
+	private final Map<String, String> messagesDictionary = new HashMap<>();
+
+	public MyMessageTransformer() {
+		messagesDictionary.put("A", "Alpha");
+		messagesDictionary.put("B", "Beta");
+		messagesDictionary.put("C", "Charlie");
+	}
+
+	public String transform(String key){
+		if (!messagesDictionary.containsKey(key)){
+			throw new IllegalArgumentException("Unknown key " + key);
+		}
+		return messagesDictionary.get(key);
+	}
+}
diff --git a/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/SplitterRouter.java b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/SplitterRouter.java
new file mode 100644
index 0000000..eb03995
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/src/main/java/org/apache/camel/example/spring/boot/SplitterRouter.java
@@ -0,0 +1,107 @@
+/*
+ *
+ *  * 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.example.spring.boot;
+
+import org.apache.camel.builder.AggregationStrategies;
+import org.apache.camel.builder.RouteBuilder;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class SplitterRouter extends RouteBuilder {
+	@Override
+	public void configure() throws Exception {
+
+		// @formatter:off
+		// Example 1 : Simple splitter
+		from("direct:splitter")
+				// body is of type java.lang.Iterable, java.lang.String or Array
+				.split(body())
+				.to("mock:a");
+
+		// Example 2 : Splitter with subsequent aggregation
+		from("direct:split-aggregate")
+					.split(body(), ((oldExchange, newExchange) -> {
+						if (oldExchange == null) {
+							// this is the first time so no existing aggregated exchange
+							return newExchange;
+						}
+
+						String body = newExchange.getIn().getBody(String.class);
+						String existing = oldExchange.getIn().getBody(String.class);
+
+						oldExchange.getIn().setBody(existing + "+" + body);
+						return oldExchange;
+					}))
+				// Transform after aggregation
+				.bean(MyMessageTransformer.class)
+				.to("mock:b")
+				.end()
+			.to("mock:c");
+
+		// Example 3 : Splitter with subsequent aggregation using POJO bean instead of AggregationStrategy implementation
+		from("direct:split-aggregate-bean")
+				// Aggregation with POJO, no tight coupling to Camel API - better for unit testing
+					.split(body(), AggregationStrategies.bean(AggregationStrategyPojo.class))
+					// Transformation after aggregation
+					.bean(MyMessageTransformer.class)
+					.to("mock:d")
+				.end()
+			.to("mock:e");
+
+		// Example 4 : Splitter with subsequent aggregation failing on exception
+		from("direct:split-aggregate-stop-on-exception")
+				.split(body(), AggregationStrategies.bean(AggregationStrategyPojo.class))
+						// stop processing if exception occured durring process of splitting
+						.stopOnException()
+						.bean(MyMessageTransformer.class)
+					.to("mock:f")
+				.end()
+			.to("mock:g");
+
+		// Example 5: Splitter with subsequent aggregation on failing on aggregation exception
+		from("direct:split-aggregate-stop-on-aggregation-exception")
+				// Continuing route processing on exception
+				.onException(IllegalArgumentException.class).continued(true).end()
+				.split(body(), ((oldExchange, newExchange) -> {
+						if (oldExchange == null) {
+							// this is the first time so no existing aggregated exchange
+							return newExchange;
+						}
+
+						String body = newExchange.getIn().getBody(String.class);
+						String existing = oldExchange.getIn().getBody(String.class);
+						if (body.equals("E")){
+							throw new IllegalArgumentException("Error occurred during aggregation");
+						}
+						oldExchange.getIn().setBody(existing + "+" + body);
+						return oldExchange;
+					}))
+					// stop processing if exception occurs during aggregation
+					.stopOnAggregateException(true)
+//					.bean(MyMessageTransformer.class)
+				.to("mock:h")
+				.end()
+			.to("mock:j");
+		// @formatter:on
+
+	}
+}
+
diff --git a/camel-example-spring-boot-splitter-eip/src/main/resources/application.properties b/camel-example-spring-boot-splitter-eip/src/main/resources/application.properties
new file mode 100644
index 0000000..def0862
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/src/main/resources/application.properties
@@ -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.
+## ---------------------------------------------------------------------------
+
+# the name of Camel
+camel.springboot.name = CamelSpringBootSplitter
+
+# required for generated Type Converter Loader - Camel 3.x way
+camel.springboot.load-type-converters=true
+
+# to configure logging levels
+logging.level.org.springframework = INFO
+logging.level.org.apache.camel.spring.boot = INFO
+logging.level.org.apache.camel.impl = INFO
+logging.level.org.apache.camel = INFO
+logging.level.sample.camel = INFO
+#logging.level.sample.camel = DEBUG
diff --git a/camel-example-spring-boot-splitter-eip/src/test/java/CamelSplitterEIPTests.java b/camel-example-spring-boot-splitter-eip/src/test/java/CamelSplitterEIPTests.java
new file mode 100644
index 0000000..3566679
--- /dev/null
+++ b/camel-example-spring-boot-splitter-eip/src/test/java/CamelSplitterEIPTests.java
@@ -0,0 +1,136 @@
+/*
+ *
+ *  * 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.
+ *
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelExchangeException;
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.example.spring.boot.Application;
+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;
+
+import static org.apache.camel.test.junit5.TestSupport.assertIsInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+@CamelSpringBootTest
+@SpringBootTest(classes = {Application.class})
+public class CamelSplitterEIPTests {
+
+	@Autowired
+	private CamelContext camelContext;
+
+	@Autowired
+	private ProducerTemplate producerTemplate;
+
+	@Test
+	public void testSplit() throws InterruptedException {
+		MockEndpoint mockA = camelContext.getEndpoint("mock:a", MockEndpoint.class);
+
+		mockA.expectedBodiesReceived("A", "B", "C");
+
+		producerTemplate.sendBody("direct:splitter", new ArrayList<>(Arrays.asList("A", "B", "C")));
+
+		mockA.assertIsSatisfied();
+	}
+
+	@Test
+	public void testSplitAggregate() throws InterruptedException {
+		MockEndpoint mockB = camelContext.getEndpoint("mock:b", MockEndpoint.class);
+		MockEndpoint mockC = camelContext.getEndpoint("mock:c", MockEndpoint.class);
+
+		mockB.expectedBodiesReceived("Alpha", "Beta", "Charlie");
+		mockC.expectedBodiesReceived("Alpha+Beta+Charlie");
+
+		producerTemplate.sendBody("direct:split-aggregate", "A,B,C");
+
+		mockB.assertIsSatisfied();
+		mockC.assertIsSatisfied();
+	}
+
+	@Test
+	public void testSplitAggregatePojo() throws InterruptedException {
+		MockEndpoint mockD = camelContext.getEndpoint("mock:d", MockEndpoint.class);
+		MockEndpoint mockE = camelContext.getEndpoint("mock:e", MockEndpoint.class);
+
+		mockD.expectedBodiesReceived("Alpha", "Beta", "Charlie");
+		mockE.expectedBodiesReceived("Alpha+Beta+Charlie");
+
+		producerTemplate.sendBody("direct:split-aggregate-bean", "A,B,C");
+
+		mockD.assertIsSatisfied();
+		mockE.assertIsSatisfied();
+	}
+
+	@Test
+	public void testSplitAggregateStopOnException() throws InterruptedException {
+		MockEndpoint mockF = camelContext.getEndpoint("mock:f", MockEndpoint.class);
+		MockEndpoint mockG = camelContext.getEndpoint("mock:g", MockEndpoint.class);
+
+		mockF.expectedBodiesReceived("Alpha");
+		mockG.expectedMessageCount(0);
+
+		final CamelExecutionException ex = assertThrows(CamelExecutionException.class,
+				() -> producerTemplate.sendBody("direct:split-aggregate-stop-on-exception", "A,E,C"));
+
+		CamelExchangeException cee = assertIsInstanceOf(CamelExchangeException.class, ex.getCause());
+		IllegalArgumentException iae = assertIsInstanceOf(IllegalArgumentException.class, cee.getCause());
+		assertEquals("Unknown key E", ex.getCause().getCause().getMessage());
+
+		mockF.assertIsSatisfied();
+		mockG.assertIsSatisfied();
+	}
+
+	@Test
+	public void testSplitAggregateStopOnAggregationException() throws InterruptedException {
+		MockEndpoint mockH = camelContext.getEndpoint("mock:h", MockEndpoint.class);
+		MockEndpoint mockJ = camelContext.getEndpoint("mock:j", MockEndpoint.class);
+
+		// without error aggregation is done as usual
+		mockH.expectedBodiesReceived("A", "B", "C");
+		mockJ.expectedBodiesReceived("A+B+C");
+
+		producerTemplate.sendBody("direct:split-aggregate-stop-on-aggregation-exception", "A,B,C");
+
+		mockH.assertIsSatisfied();
+		mockJ.assertIsSatisfied();
+
+		mockH.reset();
+		mockJ.reset();
+
+		// 'E' is poison message which will lead to an error during aggregation
+		producerTemplate.sendBody("direct:split-aggregate-stop-on-aggregation-exception", "A,B,E,C,D");
+
+		// TODO : THOSE TESTS ARE NOT CORRECT, ANY VALUE WOULD PASS
+		// Received all messages that went into aggregation, including corrupted one
+		mockH.expectedBodiesReceived("A", "B", "E");
+		// Since aggregation stopped, receiving all original messages
+		mockJ.expectedBodiesReceived("A,B,E,C,D");
+
+		mockH.assertIsSatisfied();
+		mockJ.assertIsSatisfied();
+	}
+}
diff --git a/pom.xml b/pom.xml
index d34b302..f9c6a90 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,219 +17,221 @@
     limitations under the License.
 
 -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.camel.springboot</groupId>
-        <artifactId>spring-boot</artifactId>
-        <version>3.7.0-SNAPSHOT</version>
-    </parent>
-
-    <groupId>org.apache.camel.springboot.example</groupId>
-    <artifactId>examples</artifactId>
-    <name>Camel SB :: Examples</name>
-    <description>Camel Examples</description>
-    <packaging>pom</packaging>
-
-    <modules>
-        <module>camel-example-spring-boot</module>
-        <module>camel-example-spring-boot-activemq</module>
-        <module>camel-example-spring-boot-actuator-http-metrics</module>
-        <module>camel-example-spring-boot-amqp</module>
-        <module>camel-example-spring-boot-apm-opentracing</module>
-        <module>camel-example-spring-boot-arangodb</module>
-        <module>camel-example-spring-boot-aws2-s3</module>
-        <module>camel-example-spring-boot-clustered-route-controller</module>
-        <module>camel-example-spring-boot-fhir</module>
-        <module>camel-example-spring-boot-fhir-auth-tx</module>
-        <module>camel-example-spring-boot-geocoder</module>
-        <module>camel-example-spring-boot-grpc</module>
-        <module>camel-example-spring-boot-grpc-kubernetes</module>
-        <module>camel-example-spring-boot-health-checks</module>
-        <module>camel-example-spring-boot-hystrix</module>
-        <module>camel-example-spring-boot-infinispan</module>
-        <module>camel-example-spring-boot-jira</module>
-        <module>camel-example-spring-boot-kafka-avro</module>
-        <module>camel-example-spring-boot-kafka-offsetrepository</module>
-        <module>camel-example-spring-boot-load-balancer-eip</module>
-        <module>camel-example-spring-boot-master</module>
-        <module>camel-example-spring-boot-metrics</module>
-        <module>camel-example-spring-boot-opentracing</module>
-        <module>camel-example-spring-boot-pojo</module>
-        <module>camel-example-spring-boot-rabbitmq</module>
-        <module>camel-example-spring-boot-reactive-streams</module>
-        <module>camel-example-spring-boot-resilience4j</module>
-        <module>camel-example-spring-boot-rest-jpa</module>
-        <module>camel-example-spring-boot-rest-producer</module>
-        <module>camel-example-spring-boot-rest-swagger</module>
-        <module>camel-example-spring-boot-rest-swagger-simple</module>
-        <module>camel-example-spring-boot-rest-openapi</module>
-        <module>camel-example-spring-boot-rest-openapi-simple</module>
-        <module>camel-example-spring-boot-servicecall</module>
-        <module>camel-example-spring-boot-supervising-route-controller</module>
-        <module>camel-example-spring-boot-twitter-salesforce</module>
-        <module>camel-example-spring-boot-type-converter</module>
-        <module>camel-example-spring-boot-undertow-spring-security</module>
-        <module>camel-example-spring-boot-validator</module>
-        <module>camel-example-spring-boot-webhook</module>
-        <module>camel-example-spring-boot-xml</module>
-        <module>camel-example-spring-boot-zipkin</module>
-        <module>camel-example-spring-boot-strimzi</module>
-        <module>camel-example-spring-cloud-servicecall</module>
-        <module>camel-example-spring-cloud-serviceregistry</module>
-        <module>camel-example-spring-boot-widget-gadget</module>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+	<modelVersion>4.0.0</modelVersion>
+
+	<parent>
+		<groupId>org.apache.camel.springboot</groupId>
+		<artifactId>spring-boot</artifactId>
+		<version>3.7.0-SNAPSHOT</version>
+	</parent>
+
+	<groupId>org.apache.camel.springboot.example</groupId>
+	<artifactId>examples</artifactId>
+	<name>Camel SB :: Examples</name>
+	<description>Camel Examples</description>
+	<packaging>pom</packaging>
+
+	<modules>
+		<module>camel-example-spring-boot</module>
+		<module>camel-example-spring-boot-activemq</module>
+		<module>camel-example-spring-boot-actuator-http-metrics</module>
+		<module>camel-example-spring-boot-amqp</module>
+		<module>camel-example-spring-boot-apm-opentracing</module>
+		<module>camel-example-spring-boot-arangodb</module>
+		<module>camel-example-spring-boot-aws2-s3</module>
+		<module>camel-example-spring-boot-clustered-route-controller</module>
+		<module>camel-example-spring-boot-fhir</module>
+		<module>camel-example-spring-boot-fhir-auth-tx</module>
+		<module>camel-example-spring-boot-geocoder</module>
+		<module>camel-example-spring-boot-grpc</module>
+		<module>camel-example-spring-boot-grpc-kubernetes</module>
+		<module>camel-example-spring-boot-health-checks</module>
+		<module>camel-example-spring-boot-hystrix</module>
+		<module>camel-example-spring-boot-infinispan</module>
+		<module>camel-example-spring-boot-jira</module>
+		<module>camel-example-spring-boot-kafka-avro</module>
+		<module>camel-example-spring-boot-kafka-offsetrepository</module>
+		<module>camel-example-spring-boot-load-balancer-eip</module>
+		<module>camel-example-spring-boot-master</module>
+		<module>camel-example-spring-boot-metrics</module>
+		<module>camel-example-spring-boot-opentracing</module>
+		<module>camel-example-spring-boot-pojo</module>
+		<module>camel-example-spring-boot-rabbitmq</module>
+		<module>camel-example-spring-boot-reactive-streams</module>
+		<module>camel-example-spring-boot-resilience4j</module>
+		<module>camel-example-spring-boot-rest-jpa</module>
+		<module>camel-example-spring-boot-rest-producer</module>
+		<module>camel-example-spring-boot-rest-swagger</module>
+		<module>camel-example-spring-boot-rest-swagger-simple</module>
+		<module>camel-example-spring-boot-rest-openapi</module>
+		<module>camel-example-spring-boot-rest-openapi-simple</module>
+		<module>camel-example-spring-boot-servicecall</module>
+		<module>camel-example-spring-boot-supervising-route-controller</module>
+		<module>camel-example-spring-boot-twitter-salesforce</module>
+		<module>camel-example-spring-boot-type-converter</module>
+		<module>camel-example-spring-boot-undertow-spring-security</module>
+		<module>camel-example-spring-boot-validator</module>
+		<module>camel-example-spring-boot-webhook</module>
+		<module>camel-example-spring-boot-xml</module>
+		<module>camel-example-spring-boot-zipkin</module>
+		<module>camel-example-spring-boot-strimzi</module>
+		<module>camel-example-spring-cloud-servicecall</module>
+		<module>camel-example-spring-cloud-serviceregistry</module>
+		<module>camel-example-spring-boot-splitter-eip</module>
+		<module>camel-example-spring-boot-widget-gadget</module>
 		<module>camel-example-spring-boot-unit-testing</module>
 	</modules>
 
-    <properties>
-        <!-- for symbolicName in OSGi examples we only want the artifactId, eg camel-example-sql -->
-        <!-- as having org.apache.camel as prefix is not needed and makes the name very long -->
-        <camel.osgi.symbolic.name>${project.artifactId}</camel.osgi.symbolic.name>
-        <camel-version>3.7.0-SNAPSHOT</camel-version>
-        <skip.starting.camel.context>false</skip.starting.camel.context>
-        <javax.servlet.api.version>4.0.1</javax.servlet.api.version>
-        <camel.osgi.export.pkg />
-        <fabric8-maven-plugin-version>4.4.1</fabric8-maven-plugin-version>
-        <kafka-avro-serializer-version>5.2.2</kafka-avro-serializer-version>
-        <reactor-version>3.2.16.RELEASE</reactor-version>
-        <testcontainers-version>1.14.3</testcontainers-version>
-        <tomcat-version>9.0.31</tomcat-version>
-    </properties>
-
-    <repositories>
-        <repository>
-            <id>apache.snapshots</id>
-            <url>https://repository.apache.org/snapshots/</url>
-            <name>Apache Snapshot Repo</name>
-            <snapshots>
-                <enabled>true</enabled>
-            </snapshots>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-        </repository>
-    </repositories>
-    <pluginRepositories>
-        <pluginRepository>
-            <id>apache.snapshots</id>
-            <url>https://repository.apache.org/snapshots/</url>
-            <snapshots>
-                <enabled>true</enabled>
-            </snapshots>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-        </pluginRepository>
-    </pluginRepositories>
-
-    <dependencyManagement>
-        <dependencies>
-            <!--
-              CAMEL-13084 Fix the spring-boot examples start up error by overriding servlet API version from camel-parent
-              Wqe need to clean it up once camel-parent upgrade the servlet api version.
-            -->
-            <dependency>
-                <groupId>javax.servlet</groupId>
-                <artifactId>javax.servlet-api</artifactId>
-                <version>${javax.servlet.api.version}</version>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <build>
-        <!--<resources>-->
-        <!--<resource>-->
-        <!--<directory>src/main/resources</directory>-->
-        <!--<filtering>true</filtering>-->
-        <!--</resource>-->
-        <!--</resources>-->
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-deploy-plugin</artifactId>
-                <configuration>
-                    <skip>true</skip>
-                </configuration>
-            </plugin>
-
-            <!-- update readme file -->
-            <plugin>
-                <groupId>org.apache.camel</groupId>
-                <artifactId>camel-package-maven-plugin</artifactId>
-                <version>${camel-version}</version>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>prepare-example</goal>
-                        </goals>
-                        <phase>process-resources</phase>
-                    </execution>
-                </executions>
-            </plugin>
-
-            <!-- to validate Camel endpoints: mvn camel-report:validate -->
-            <plugin>
-                <groupId>org.apache.camel</groupId>
-                <artifactId>camel-report-maven-plugin</artifactId>
-                <version>${camel-version}</version>
-                <configuration>
-                    <failOnError>false</failOnError>
-                    <includeTest>true</includeTest>
-                    <includeXml>true</includeXml>
-                    <ignoreLenientProperties>false</ignoreLenientProperties>
-                </configuration>
-            </plugin>
-
-            <plugin>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <forkCount>1</forkCount>
-                    <reuseForks>false</reuseForks>
-                    <systemPropertyVariables>
-                        <skipStartingCamelContext>${skip.starting.camel.context}</skipStartingCamelContext>
-                    </systemPropertyVariables>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>container-test</id>
-            <properties>
-                <skip.starting.camel.context>true</skip.starting.camel.context>
-            </properties>
-        </profile>
-        <!--
-          This profile allows you to add a repository to the repo list so that
-          you can test the examples out against a staged version of the camel distribution
-        -->
-        <profile>
-            <id>add-remote-repo</id>
-            <activation>
-                <property>
-                    <name>remoteRepo</name>
-                </property>
-            </activation>
-
-            <repositories>
-                <repository>
-                    <id>dynamic.repo</id>
-                    <name>Repository Dynamically Added Via the Command Line</name>
-                    <url>$remoteRepo</url>
-                </repository>
-            </repositories>
-            <pluginRepositories>
-                <pluginRepository>
-                    <id>dynamic.repo</id>
-                    <name>Repository Dynamically Added Via the Command Line</name>
-                    <url>$remoteRepo</url>
-                </pluginRepository>
-            </pluginRepositories>
-
-        </profile>
-    </profiles>
+	<properties>
+		<!-- for symbolicName in OSGi examples we only want the artifactId, eg camel-example-sql -->
+		<!-- as having org.apache.camel as prefix is not needed and makes the name very long -->
+		<camel.osgi.symbolic.name>${project.artifactId}</camel.osgi.symbolic.name>
+		<camel-version>3.7.0-SNAPSHOT</camel-version>
+		<skip.starting.camel.context>false</skip.starting.camel.context>
+		<javax.servlet.api.version>4.0.1</javax.servlet.api.version>
+		<camel.osgi.export.pkg/>
+		<fabric8-maven-plugin-version>4.4.1</fabric8-maven-plugin-version>
+		<kafka-avro-serializer-version>5.2.2</kafka-avro-serializer-version>
+		<reactor-version>3.2.16.RELEASE</reactor-version>
+		<testcontainers-version>1.14.3</testcontainers-version>
+		<tomcat-version>9.0.31</tomcat-version>
+	</properties>
+
+	<repositories>
+		<repository>
+			<id>apache.snapshots</id>
+			<url>https://repository.apache.org/snapshots/</url>
+			<name>Apache Snapshot Repo</name>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+		</repository>
+	</repositories>
+	<pluginRepositories>
+		<pluginRepository>
+			<id>apache.snapshots</id>
+			<url>https://repository.apache.org/snapshots/</url>
+			<snapshots>
+				<enabled>true</enabled>
+			</snapshots>
+			<releases>
+				<enabled>false</enabled>
+			</releases>
+		</pluginRepository>
+	</pluginRepositories>
+
+	<dependencyManagement>
+		<dependencies>
+			<!--
+			  CAMEL-13084 Fix the spring-boot examples start up error by overriding servlet API version from camel-parent
+			  Wqe need to clean it up once camel-parent upgrade the servlet api version.
+			-->
+			<dependency>
+				<groupId>javax.servlet</groupId>
+				<artifactId>javax.servlet-api</artifactId>
+				<version>${javax.servlet.api.version}</version>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+	<build>
+		<!--<resources>-->
+		<!--<resource>-->
+		<!--<directory>src/main/resources</directory>-->
+		<!--<filtering>true</filtering>-->
+		<!--</resource>-->
+		<!--</resources>-->
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-deploy-plugin</artifactId>
+				<configuration>
+					<skip>true</skip>
+				</configuration>
+			</plugin>
+
+			<!-- update readme file -->
+			<plugin>
+				<groupId>org.apache.camel</groupId>
+				<artifactId>camel-package-maven-plugin</artifactId>
+				<version>${camel-version}</version>
+				<executions>
+					<execution>
+						<goals>
+							<goal>prepare-example</goal>
+						</goals>
+						<phase>process-resources</phase>
+					</execution>
+				</executions>
+			</plugin>
+
+			<!-- to validate Camel endpoints: mvn camel-report:validate -->
+			<plugin>
+				<groupId>org.apache.camel</groupId>
+				<artifactId>camel-report-maven-plugin</artifactId>
+				<version>${camel-version}</version>
+				<configuration>
+					<failOnError>false</failOnError>
+					<includeTest>true</includeTest>
+					<includeXml>true</includeXml>
+					<ignoreLenientProperties>false</ignoreLenientProperties>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<configuration>
+					<forkCount>1</forkCount>
+					<reuseForks>false</reuseForks>
+					<systemPropertyVariables>
+						<skipStartingCamelContext>${skip.starting.camel.context}</skipStartingCamelContext>
+					</systemPropertyVariables>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<profiles>
+		<profile>
+			<id>container-test</id>
+			<properties>
+				<skip.starting.camel.context>true</skip.starting.camel.context>
+			</properties>
+		</profile>
+		<!--
+		  This profile allows you to add a repository to the repo list so that
+		  you can test the examples out against a staged version of the camel distribution
+		-->
+		<profile>
+			<id>add-remote-repo</id>
+			<activation>
+				<property>
+					<name>remoteRepo</name>
+				</property>
+			</activation>
+
+			<repositories>
+				<repository>
+					<id>dynamic.repo</id>
+					<name>Repository Dynamically Added Via the Command Line</name>
+					<url>$remoteRepo</url>
+				</repository>
+			</repositories>
+			<pluginRepositories>
+				<pluginRepository>
+					<id>dynamic.repo</id>
+					<name>Repository Dynamically Added Via the Command Line</name>
+					<url>$remoteRepo</url>
+				</pluginRepository>
+			</pluginRepositories>
+
+		</profile>
+	</profiles>
 
 </project>