This document provides an overview of Apache Camel, an open source integration framework for connecting applications and integrating disparate systems. It discusses what Camel is, its key features like support for Enterprise Integration Patterns and Domain Specific Languages, components, architecture, platforms, testing, tooling, security, and hands-on examples.
1. Red Hat | Bryan Saunders
Camel from the Field
Bryan Saunders
Feb 16, 2015
2. Agenda
Introduction to Camel
What is Camel
Camel Features
Enterprise Integration Patterns
Key Components
Camel Architecture
Supported Platforms
Camel Hands On
Common EIPs
Camel on EAP
Using JMS
Web Services
Future of Camel
Q & A
4. What is Camel
Apache Camel ™ is a versatile open-source integration framework
based on known Enterprise Integration Patterns.
- Apache Camel Website
Apache Camel is an open source Java framework that focuses on
making integration easier and more accessible to developers. It does
this by providing: concrete implementations of all the widely used
EIPs, connectivity to a great variety of transports and APIs, and easy
to use Domain Specific Languages (DSLs) to wire EIPs and transports
together
- Jonathan Anstey
5. Why an Integration Framework
Integration is Critical for Business
Framework does the Heavy Lifting
Lets you Focus on the Problem
Prevents Re-inventing the Wheel
6. History of Camel
Started in March 2007
Founded by
James Strachan
Rob Davies
Hiram Chirino
Guillaume Nodet
First Release in June 2007
Spawned from Apache ServiceMix and Apache ActiveMQ
7. Camel Features
Very Leightweight , Consists of only a handful of JARs
Easy Configuration
No Heavy Specification
No Container Dependencies
Payload Agnostic
12. Components
191 Components and counting
Component for pretty much anything
Most commonley used components
CXF
CXFRS
JMS
ActiveMQ
AMQP
Infinispan
CDI
Drools
17. Error Handling
Try...Catch...Finally
Exception Clause in Java DSL
Error Handlers
Default Error Handler
Dead Letter Channel
Logging Error Handler
No Error Handler
Transaction Error Handler
Support for Exponential Backoff of Retries
19. Redelivery Delay Patterns
Allows for custom backoff of retries.
Syntax: limit:delay;limit2:delay2;limit3:delay3;...;limitN:delayN
If delayPattern=5:1000;10:5000;20:20000 then we get
Redelivery attempt number 1..4 = 0 sec (as the first group starts with 5)
Redelivery attempt number 5..9 = 1 sec (the first group)
Redelivery attempt number 10..19 = 5 sec (the second group)
Redelivery attempt number 20.. = 20 sec (the last group)
20. Security
Four Broad Categories of Security Offered
Route Security
Payload Security
Endpoint Security
Configuration Security
23. Endpoint Security
Some components can be secured, but not all
Jetty - HTTP Basic & SSL
CXF - HTTP Basic & WS-Security
Spring Web Services - HTTP Basic & WS-Security
Netty - SSL
MINA - SSL
Cometd - SSL
JMS - JAAS and SSL for client <--> broker communication
25. Scalable
Load Balancing Policies
Thread and Service Pools
Asynchronous API
Clustering
Same JVM & Context - Use direct or seda
Same JVM, Different Context - Use vm
Different JVM - Use jms, activemq, ftp, etc...
OSGi - Use Normalized Message Router (NMR)
26. HA & Failover
Not natively supported
Provided by the following components
Camel Fabric Master component
Camel ZooKeeper via a Route policy
Camel JGroups
27. Testable
Native test frameworks
Supports unit and integration Testing
Built in mock & stub support
Advanced testing with NotifyBuilder and AdviceWith
Works with 3rd party test frameworks
PaxExam
Arquillian
JUnit
TestNG
28. Available Test Harnesses
Name Component Description
Camel
Test
camel-test Standalone Java library to create Camel test cases using a single Java
class for all your configuration and routing without using Spring or
Guice
Spring
Testing
camel-test-
spring
Supports JUnit 4 tests that bootstrap a test environment using Spring
without needing to be familiar with Spring Test.
Blueprint
Testing
camel-test-
blueprint
Provides the ability to do unit testing on blueprint configurations
Guice camel-
guice
Uses Guice to dependency inject your test classes
Camel
TestNG
camel-
testng
Supports plain TestNG based tests with or without Spring or Guice
33. Enterprise Integration Patterns
Similar to Design Patterns
Focused specifically on Integration
Written by Gregor Hohpe & Bobby Wolf
65 Documented Patterns
Camel supports 53 of them
39. Route
Set of rules that define message flow
Consists of:
Endpoints
EIP Constructs
Processors
40. Endpoint
Implementation of the Message Endpoint pattern
Created by components
Referred to by uniue URI's in the DSL
Consumers receive messages
Producers send messages
41. Component
Essentially a factory for Endpoint instances
Adds functionality to Camel
Custom components extend DefaultComponent
46. Camel and Red Hat
Included in JBoss Fuse
Included in JBoss Fuse Service Works
Run as part of SwitchYard
Run outside of SwitchYard on EAP Container
Supported on EAP 6.1.1+
Requires JBoss Fuse & JBoss EAP Subscription
Must use Camel libraries from JBoss Fuse
49. Fuse or Service Works
Use Fuse if...
Dont use Java or JEE
Dont use EAP
Use OSGi or Karaf
Governance is not needed
No SCA requirement
Use Fuse Service Works if...
Use JEE
Want to use JEE in Services
Currently use EAP
Need Governance
Need SCA or already use SwitchYard
50. Camel Considerations
For Fuse...
Can use Blueprint/Spring/Java DSL for Routes
Most configuration is done via XML
Testing relies on PaxExam and Built in Camel Test Frameworks
For Fuse Service Works w/ SwitchYard...
SwitchYard limits amount of Components you can use
JEE Stack well Supported
No XML Configuration
Can make use of Arquillian
For Camel on EAP...
Can use CDI or Spring
JEE Stack not currently well supported
Most Components use Spring for configuration
Can make use of Arquillian
52. Camel on EAP
Use Camel without SwitchYard or Karaf
Supported on EAP 6.1.1 and up with Camel 2.12 Red Hat Libraries
Two ways to use Libraries
Packaged inside Application
Deployed as EAP Module
Camel Started with 3 methods
Spring ContextLoaderListener
ServletListener Component
CDI Component
53. Starting with Spring
Requires Spring
Best if already using Spring
Camel uses Spring's Bean Registry
Started using Spring ContextLoaderListener
Configuration very similar to Fuse with Spring or Blueprint
56. Starting with Spring Demo
https://github.com/bsaunder/camel/tree/master/eap_6/soap-
contract-first
57. Starting without Spring
Does not Require Spring
Best if using JEE, but do not need to access Camel with JEE Stack
Camel uses a Simple Map based Bean Registry (Can also use JNDI)
Started using CamelServletContextListener
Configuration XML Based
Route Builders defined in web.xml
60. Bootstrapping with CDI
Does not Require Spring or use Servlets
Best if using JEE, Especially CDI
Camel uses CDI Bean Manager
Started using an @Startup @Singleton Annotated Bean
All Configuration done in Java, No XML
61. Camel Bootstrap Class
Must be a Singleton, @Singleton
Must run at Startup. @Startup
Inject an instance of CdiCamelContext
Adds a CDI Bean Registry that allows lookup of CDI Beans when
Instantiated
@PostConstruct method should Configure/Start Context and Add
Routes
@PreDestroy should Stop Camel Context
63. Using the XML Based DSL
Spring and Blueprint XML routes can also be used
Routes loaded from XML file in Bootstrap Class
InputStream is = this.getClass().getClassLoader().getResourceAsStream("camelroutes.xml");
if (is != null) {
RoutesDefinition routes = this.camelCtx.loadRoutesDefinition(is);
this.camelCtx.addRouteDefinitions(routes.getRoutes());
}
65. Configuration with Camel CDI
No Spring Config or Context
With Camel CDI Components are Configured in Java
Configured on the Camel Context
All Components can be Configured
66. Configuring Components
Configred in your Bootstrap Class
Must be Configured Prior to Start of Camel Context
Lookup Existing Components with getComponent()
Lookup via Registered Name - jms, activemq, etc...
Most Core Components already Registered on Context
Lazily initialize Components that arent Registered
Add New Components with addComponent()
69. Camel & JBoss A-MQ
Camel has no JBoss A-MQ Component
Several ways to Connect to A-MQ from Camel
JMS Component
ActiveMQ Component
Bean using JMS API
70. Camel JMS vs ActiveMQ
JMS component
Based on Spring JMS
Uses Spring JmsTemplate for Sending
Uses Spring MessageListenerContainer for Consuming
ActiveMQ Component
Based on JMS Component
Optimized for ActiveMQ
Supports ActiveMQ Specific Features such as Destination Options
71. MDB vs Camel JMS
Using an MDB Generally offers Higher Performance
Use a Producer Template to send to a Direct Camel Route
MDB Uses Containers Pooled Resource Adapter
Camel JMS Component Built on Spring JMS
Uses the DefaultMessageListenerContainer
Shares a Single Connection for all Consumers
72. Attachments over JMS
Not Supported by Camel or any of its JMS based Components
Two Solutions
Move Attachment into Message Body with a Custom Object
Use the Claim Check EIP
73. Claim Check EIP
Replaces Message Data with a Unique ID for Future Retrieval
Data stored into Persistent Data Store
Data Retrieved later using Unique ID
74. Claim Check EIP Example
from("direct:start").to("bean:checkLuggage").to("jms:queue:SomeQueue");
from("jms:queue:SomeQueue").to("bean:dataEnricher").log("Do Stuff");
public static final class CheckLuggageBean {
public void checkLuggage(Exchange exchange, @Body String body, @XPath("/order/@custId") String custId) {
dataStore.put(custId, body);
exchange.getIn().setHeader("claimCheck", custId);
exchange.getIn().setBody(null);
}
}
public static final class DataEnricherBean {
public void addDataBackIn(Exchange exchange, @Header("claimCheck") String claimCheck) {
exchange.getIn().setBody(dataStore.get(claimCheck));
dataStore.remove(claimCheck);
exchange.getIn().removeHeader("claimCheck");
}
}
75. Web Services with Camel CDI
Web Services are common place in Integration
Camel has Several Web Service Related Components
CXF
CXFRS
Spring Web Services
Rest
Spark-Rest
76. Some of the Problems
Spring Web Services require Spring
Rest and Spark-Rest Components not Available
Part of Camel 2.14
Only Leaves CXF and CXFRS
Dependent on Spring for Configuration
Needs Servlet to Start
77. Using Camel CXF with Camel CDI
Configured via Camel Context
Endpoints created Programmatically
Requires Http Jetty Transport to Publish Service
CxfEndpoint orderEndpoint = new CxfEndpoint();
orderEndpoint.setAddress("http://localhost:9595/order");
orderEndpoint.setServiceClass("net.bryansaunders.camel.OrderEndpoint");
orderEndpoint.setWsdlURL("wsdl/order.wsdl");
orderEndpoint.setCamelContext(this.camelCtx);
camelCtx.addEndpoint("cxf:bean:orderEndpoint", orderEndpoint);
78. Alternate Solution
Use the Web Services Subsystem
Deploy Web Services using JAX-WS
Use Producer Template to Call Camel from Implementation
Use a Direct Route
Route is more Flexible, Can be Called without SOAP
Easier to Configure more Advanced Web Services
80. Camel & SwitchYard Test Support
Camel and SwitchYard both include Test Frameworks
Mocks created with Camel Test cannot replace SwitchYard Endpoints
Intercept Messages and Route to Mockable Endpoint
SwitchYard expects Route to Start with SwitchYard Endpoint
Define two Routes
First Route has SwitchYard Endpoint and Forwards to Second Route
Second Route starts with a Mockable Endpoint (Usually Direct)
81. Camel & SwitchYard Test Support
public class SomeTestClass extends CamelTestSupport {
private static final String MESSAGE = "...";
@Test
public void someTest() throws Exception {
MockEndpoint endpoint = getMockEndpoint("mock:switchyard:WebOutService");
endpoint.expectedBodiesReceived(MESSAGE);
template.sendBody("direct:WebInService", MESSAGE);
endpoint.assertIsSatisfied();
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new WebInServiceRoute() {
@Override
public void configure() throws Exception {
interceptSendToEndpoint("switchyard://WebOutService")
.skipSendToOriginalEndpoint().to(
"mock:switchyard:WebOutService");
super.configure();
}
};
}
}
from("switchyard://WebInService").to("direct:WebInService");
from("direct:WebInService").log("Doing something very clever").to("switchyard://WebInCanonicalSystem");
82. Testing with Pax Exam
In-Container Testing Framework for OSGi, Java EE, and CDI
Similar to Arquillian
Uses a Test Driver and a Test Container
Test Driver launches the OSGi framework and the system under test
Probe Builds Bundles from Test Cases and Injects into the Container
JUnit and TestNG Drivers
Drivers are Annotation Based
83. Pax Exam
Supports All Major OSGi Frameworks
Equinox, Felix, Knoplerfish, Karaf
Multiple Strategies for Restarting and Reusing the Running OSGi
Framework for each Test
Two Types of Containers
Native runs in the same VM as the Test Driver
Forked runs in a separate VM from the Test Driver
84. Pax Exam Karaf Container
Eases Integration Testing with Pax Exam and Karaf
Provides an Actual Karaf Container for Testing
Supports any Karaf Based Distribution (Fuse, Service Mix, Geronimo)
Maintained as Official Pax Exam modules
Adds Karaf Specific Support
85. Container Configuration
Controls the Host Container
Determines the Set of Bundles and Features provisioned to the Container
Builds and Configures the Container Environment
Multiple Methods of Specifying Configuration Options
One or more Methods Annotated with @Configuration that return Option[]
86. Probe
Artifact added to the Container for Testing
Created on the Fly by Pax TinyBundles
Contains the Current Test Classes and All Classes/Resources under the
Same Root
Can be Configured inside the Test Class if needed
87. Writing Testable Routes
Anything that needs to Change during a Test should be Externalized
All Endpoints
Configuration Values
Header Names
Etc...
Integrations with External Resources should be Mock able
Database Connections
Messaging Brokers
Etc...
88. Generating Dependency File
Generate using the Maven Plugin
<plugin>
<groupId>org.apache.servicemix.tooling</groupId>
<artifactId>dependsmavenplugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>generatedependsfile</id>
<goals>
<goal>generatedependsfile</goal>
</goals>
</execution>
</executions>
</plugin>
Should use the versionAsInProject() method in Container Configuration
89. Configuring the Container
Container Configuration is Done with the @Configuration Annotation
Method should Return Option[]
Used for
Specifying the Distribution
Setting Distribution Properties
Log Level, Unpack Directory, Start Method, Etc…
Loading Features / Bundles
Adding/Modifying Distribution Environment
Property Files, Etc…
91. Modifying the Probe
Modified Using the @ProbeBuilder Annotation
Uses the Following Method Signature
@ProbeBuilder
public TestProbeBuilder probeConfiguration(TestProbeBuilder probe) {
// Do Things
}
Method should return the probe Parameter after Modification
Sets Probe Specific Configurations via Headers
Dynamically Imports all Packages by Default
92. Using Provisional Packages
Provisional Packages are by Default NOT Imported
Probe must be Modified to Import Them
Add the Following Line to your ProbeBuilder Method
probe.setHeader(Constants.DYNAMICIMPORT_PACKAGE, "*;status=provisional");
93. Getting the Camel Context
There will potentially be Multiple Camel Contexts running in the
Container
Need to get the Correct Context for Our Tests
Best Done in doPreSetup() Method that can be Overridden from
CamelTestSupport
Camel Context should be Looked Up by it’s name in the BundleContext
@Override
protected void doPreSetup() throws Exception {
camelContext = PaxExamTestUtil.getOsgiService(CamelContext.class,
"(camel.context.name=" + CAMEL_CONTEXT_NAME + ")", 10000, bundleContext);
assertNotNull(camelContext);
}
94. Sending Messages
2 Steps
Create/Start Producer Template
Send Message using Template
// Set Headers To Be Sent
final Map<String, Object> headerMap = new HashMap<String, Object>();
headerMap.put("WM_MSG_ID", null);
headerMap.put("WM_HO_WMQ_QUEUE", null);
// Send the Message Body
ProducerTemplate template = camelContext.createProducerTemplate();
template.start();
template.send("direct:gateway_in", new Processor() {
public void process(Exchange exchange) {
Message in = exchange.getIn();
in.setBody("Hello from Camel");
in.setHeaders(headerMap);
}
});
95. Using Mock Queues
Get the Endpoint from the Camel Context and Cast to a MockEndpoint
MockEndpoint mockNoHomeOfficeDlq = (MockEndpoint)
CamelContext.getEndpoint("mock:gateway_noHomeOfficeDlq");
Set Mock Endpoint’s Expectations
mockNoHomeOfficeDlq.expectedMessageCount(1);
mockNoHomeOfficeDlq.expectedBodiesReceived("Hello from Camel");
Send Messages to Mock Endpoint
Assert Mock Endpoint is Satisfied
mockNoHomeOfficeDlq.assertIsSatisfied(2500);
96. Pax Exam on Karaf Demo
https://github.com/bsaunder/camel/tree/master/fuse/pax-exam
97. What About Arquillian?
Arquillian has OSGi support
Works like standard Arquillian
Supports Multiple Containers
JBoss (Embedded)
Felix (Embedded)
Equinox (Embedded)
Karak (Embedded/Managed/Remote)
Not as Feature Rich as Pax Exam
Evolving Quickly
99. Camel v3 Improvements
Improved Test Support
Support for testing indiviual components, processors, etc...
Persistent Message Store
Java 8 DSL
Split/Optimize Camel-CXF
100. Camel on EAP Subsystem
Full EAP Subsystem
Improved Integration with JEE Standards
Updated JEE Related Camel Components
camel-cdi
camel-cxf
camel-jaxb
camel-jms
camel-jmx
camel-jpa
Full Arquillian Support
Available now in Wildfly 8.1
Official Support in future Fuse Release
Targeted for Fuse 6.2
101. Questions?
Presentation is Available At
https://github.com/bsaunder/camel_from_the_field
All Demo Code is Available At
https://github.com/bsaunder/camel/