This short tutorial will show you how to create a simple Camel with Spring Boot example application with a minimal test case in no time.
The simplest way to bootstrap a Camel application is to use one of its Maven archetypes. When using Spring Boot application, the recommended archetype is camel-archetype-spring-boot:
mvn archetype:generate \
-DarchetypeGroupId=org.apache.camel.archetypes \
-DarchetypeArtifactId=camel-archetype-spring-boot \
-DarchetypeVersion=3.7.0 \
-DgroupId=com.sample \
-DartifactId=camel-spring-boot
The following Spring Boot project tree will be created:
src ├── main │ ├── java │ │ └── com │ │ └── sample │ │ ├── MySpringBean.java │ │ ├── MySpringBootApplication.java │ │ └── MySpringBootRouter.java │ └── resources │ ├── application.properties │ └── META-INF │ ├── LICENSE.txt │ └── NOTICE.txt └── test ├── java │ └── com │ └── sample │ └── MySpringBootApplicationTest.java └── resources
You can also import the Spring Boot project in your favourite IDE, for example in IntelliJ by choosing "Import Project" and pointing to the Camel Spring Boot project.
Let's check out project class. The Spring Boot Main class is MySpringBootApplication which simply starts our application:
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
Next, the Router class MySpringBootRouter. Please note this class contains the @Component annotation to make Camel auto detect this route when starting:
@Component
public class MySpringBootRouter extends RouteBuilder {
@Override
public void configure() {
from("timer:hello?period={{timer.period}}").routeId("hello")
.transform().method("myBean", "saySomething")
.filter(simple("${body} contains 'foo'"))
.to("log:foo")
.end()
.to("stream:out");
}
}
This Route has a Timer component in it which fires according to the "timer.period" (defined in application.properties). Each time the Timer is fired, the Bean registered under the context "myBean" will be invoked through its method "saySomething". A Sample filter is included to fetch and log messages whose body contains 'foo'.
Let's check the Transformation done by the Bean "myBean":
@Component("myBean")
public class MySpringBean {
@Value("${greeting}")
private String say;
public String saySomething() {
return say.toUpperCase();
}
}
In the method saySomething we have changed the default example to transform the text to uppercase.
The Test class included in the project is in charge to intercept the Camel Route and replace the consumer with a direct consumer.
@SpringBootTest
@CamelSpringBootTest
public class MySpringBootApplicationTest {
@Autowired
private CamelContext camelContext;
@Autowired
private ProducerTemplate producerTemplate;
@Test
public void test() throws Exception {
MockEndpoint mock = camelContext.getEndpoint("mock:stream:out", MockEndpoint.class);
AdviceWith.adviceWith(camelContext, "hello",
// intercepting an exchange on route
r -> {
// replacing consumer with direct component
r.replaceFromWith("direct:start");
// mocking producer
r.mockEndpoints("stream*");
}
);
// setting expectations
mock.expectedMessageCount(1);
mock.expectedBodiesReceived("HELLO WORLD");
// invoking consumer
producerTemplate.sendBody("direct:start", null);
// asserting mock is satisfied
mock.assertIsSatisfied();
}
}
Please note we have set to upper case the expected value of the "Hello World" message.
Within the application.properties there are several default message properties. For the scope of this example, the following properties can be adjusted:
# what to say greeting = Hello World # how often to trigger the timer timer.period = 2000
You can run the application with:
mvn install spring-boot:run
You should see that the "HELLO WORLD" message is printed on the Camel spring Boot console:
2021-02-21 18:12:28.138 INFO 6030 --- [ main] com.sample.MySpringBootApplication : Started MySpringBootApplication in 1.991 seconds (JVM running for 2.311) HELLO WORLD HELLO WORLD
Making the Hello World Camel Spring Boot interactive
Let's spice a bit our example using some cool features of Spring Boot. As an example, we will add a REST Controller to produce the greeting message:
@RestController
public class MyRestController {
@Autowired
private ProducerTemplate template;
@RequestMapping("/hello")
public String sayHello(@RequestParam(defaultValue = "frank") String name) {
return template.requestBody("direct:sayHello", name).toString();
}
}
As you can see, we are using the direct Component which is the abstract way to initialize a Route from a ProducerTemplate object. In a nutshell, the ProducerTemplate will fire the synchronous call to "direct:sayHello" passing as parameter the value for "name" contained in the HTTP request. If no request object has been added, the default value of 'frank' will be used.
In order to use this example, we will replace the timer component with "direct:sayHello":
@Component
public class MySpringBootRouter extends RouteBuilder {
@Override
public void configure() {
from("direct:sayHello").routeId("hello")
.transform().method("myBean", "saySomething")
.filter(simple("${body} contains 'foo'"))
.to("log:foo")
.end()
.to("stream:out");
}
}
That's it. Adjust the Test class accordingly. (You can check the full source code below).
You can run the application with:
mvn install spring-boot:run
You can test it as follows:
curl http://localhost:8080/hello?name=Jack
JACK
We have just covered two basic examples of Camel applications built using Spring Boot.
Source code for the Camel Spring Boot demo: https://github.com/fmarchioni/masterspringboot/tree/master/camel/camel-helloworld-spring
FREE WildFly Application Server - JBoss - Quarkus - Drools Tutorials