Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
01 apache camel-intro
1. REDPILL LINPRO
SWAT
Competence Gathering #1 Apache Camel
April 2011 introduction
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
2. Agenda
Background
EIP
Architecture from 10,000 ft
Endpoints & components
Programming model
Hiding the integration API from your code
Error handling
Type converters
Deployment
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
3. Background
Started as a subproject to ActiveMQ
Now one of the top Apache projects
Implementation of the EIP patterns
Framework for declaring routing logic
NOT a fullblown runtime, such as an ESB.
… but has the same characteristics
Reuses Spring concepts such as Templates, DI, registries,
contexts etc..
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
4. Enterprise Integration Patterns
(EIP)
”Pipe and filter” stateless flows
The de facto bible when it comes to the messaging
integration style
EIP is the basis for all types of flow-based integration
frameworks (i.e. Camel, Spring Integration, Jboss ESB,
Mule)
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
6. A Camel EIP example
Queue
Papers
Split on each Route on body Queue
Queue
lineitem Pencils
purchaseOrder
File dir
/invalid
from("jms:queue:purchaseOrder?concurrentConsumers=5")
.split().xpath("//lineItem")
.choice()
.when(body().contains("Pen")) .to("jms:queue:Pencils")
.when(body().contains("Paper")).to("jms:queue:Papers")
.otherwise().to("file:target/messages/invalid");
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
7. 10,000 ft architecture
CamelContext - Runtime "engine", similar to a SpringContext
Routes - Your DSL/XML declared flows
Components - Physical connectivity factories to Endpoints, i.e to()/from()
Processors - Implements the Processor interface (process() method)
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
8. Components and endpoints
> 100 components jms:myQueue?concurrentConsumers=5&username=Billy
Component Path Options
Separate JAR's
The usual suspects...
File / JMS / RMI / WS / Http / DB
+ a lot more
SEDA, Direct, MINA, XMPP,
WebSockets, Twitter...
Components are bound to URI schemes
..which are then interpreted as Endpoints
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
9. Message Exchanges
Context for messages
Exchange ID – Unique id
MEP – InOnly/InOut Enum
Exception – Contains eventual runtime
exception
Properties – Meta-Data with a lifecycle
of the complete exchange
Message – In/Out used in processors
and request/reply
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
10. Programming model
Java "DSL" from("file:data/orders")
(chained methods) .split.xpath("//order")
.to("jms:queue:order");
Declarative XML <route>
(NS support) <from uri="file:data/orders"/>
<split>
<xpath>//order</xpath>
<to uri="jms:queue:order"/>
</split>
</route>
- Scala and Groovy alternatives...
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
11. Adding the routes, Java style
public class MyRoutes extends RouteBuilder{
@Override
public void configure() throws Exception {
from("file:/orders").to("jms:/orders");
from("file:/payments").to("jms/payments");
}
}
camelContext.addRoutes(new MyRoutes());
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
12. Adding the routes, Spring /
Blueprint style
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:/orders"/>
<to uri="jms:/orders"/>
</route>
<route>
<from uri="file:/payments"/>
<to uri="jms:/orders"/>
</route>
</camelContext>
Bootstraps the context as Spring starts
Main, servlet listener, camel included Main class etc
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
13. Loading Java Routes from XML
Mix'n match between XML/Java
Consistent concept throughout the framework
<camelContext xmlns="http://camel.apache.org/schema/spring">
<packageScan>
<package>com.rl.routes</package>
<excludes>**.*Excluded*</excludes>
<includes>**.*</includes>
</packageScan>
</camelContext>
Irrespective of the language choice, the routes will be
the same as it's only instructions to Camel
Means that cross-functionality such as visualization etc
works across the languages
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
14. Processors
Simple way to add custom logic in a route
Implements the Processor interface
Quick and dirty way, define your own anonymous impl inline
from("file:/payments")
.process(new Processor(){
public void process(Exchange exchng) throws Exception {
//business logic on exchange here
}
})
.to("jms:payments");
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
15. Service activator pattern
Instead of implementing the Processor intf
Reference service beans instead
Flexible, less Camel API smell
Camel can guess method based on message
type/parameters, annotations or method-ref
Can also reference by class type instead of registered
beans
from("file:/payments")
.beanRef("paymentService")
.to("jms/payments");
@Service
class PaymentService{
public PaymentAck conductPayment(String payment){...
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
16. The Registry
public interface Registry {
Object lookup(String name);
<T> T lookup(String name, Class<T> type);
<T> Map<String, T> lookupByType(Class<T> type);
}
Strategy interface for bean lookups
Used internally, i.e for finding a TransactionManager impl
As well as from your flows, using beanRef(”myBean”)
Impl delegates to SpringContext, CDI BeanManager, Guice,
OSGi etc...
camelContext.setRegistry(myRegistry)
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
17. Payload type conversion
from("file://inbox")
.convertBodyTo(String.class, "UTF-8")
.to("jms:inbox");
Camel often automatically tries to convert message payload to
method param based on registered converters
If not, use .convertBodyTo(clazz) from flow to invoke type
converter explicitly
Could be used where default type would not be the best fit
I.e. explicitly wanting JMS TextMessage over ByteMessage
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
18. Writing type converters
@Converter
public final class IOConverter {
@Converter
public static InputStream toInputStream(URL url) throws IOException {
return url.openStream();
}
}
META-INF/services/org/apache/camel/TypeConverter
com.rl.common.typeconverters.IOConverter
com.rl.<customer>.typeconverters.MyConverter
....
Or in runtime using..:
context.getTypeConverterRegistry().addTypeConverter(from, to, converter);
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
19. CamelProxy – Hiding Camel
from clients
Same concept as i.e. Spring Remoting
Camel automatically creates proxy implementations of a given
interface
DI-wire your proxy to the client
<camelContext xmlns="http://camel.apache.org/schema/spring">
<proxy id="paymentService" serviceInterface="se.rl.IPaymentService"
serviceUrl="direct:payments"/>
<route>
<from uri="direct:payments"/>
<to uri="...."/>
......
</route>
</camelContext>
<b:bean id="paymentClient" class="se.rl.banking.PaymentClient">
<b:property name="paymentSvc" ref="paymentService"/>
</b:bean>
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
20. Error handling
Thrown exceptions → Exchange.exception
Typically technical exceptions
Camel Error handling by default only kicks in when
exchange.getException() != null
Error handling is declarative and very flexible
But you should test your assumptions!
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
21. Error handlers
Default Error handling:
No redelivery
Exceptions are propagated back to the caller / incoming endpoint
DefaultErrorHandler Default if none specified
<retryable>
DeadLetterChannel Implements DLQ pattern. Redirect message.
<retryable> Also supports rolling back to original message
TransactionErrorHandler Only used for transactions
<retryable>
NoErrorHandler Dummy
LoggingErrorHandler Logging
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
22. Error handler features
errorHandler(defaultErrorHandler()
.maximumRedeliveries(2)
.redeliveryDelay(1000)
.retryAttemptedLogLevel(LoggingLevel.WARN));
from("seda:queue.inbox")
.beanRef("orderService", "validate")
.beanRef("orderService", "enrich")
.log("Received order ${body}")
.to("mock:queue.order");
Redelivery policies Specify retries, exponential backoff etc.
Redelivery will be on the exception origin,
NOT from the start of the route
Scope Context or on a route basis
Exception policies (onException(E)) Specific policies for particular exceptions
onWhen Even more fine-grained control. I.e check
status code on Http exceptions.
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
23. Exception policies
onException(JmsException.class)
.handled(true)
.beanRef("errorFormatter");
from("jetty:http://0.0.0.0:80/orderservice")
.beanRef("orderTransformer")
.to("jms:queue:incomingOrders")
.beanRef("orderAckTransformer");
onException lets you provide granularity to exception handling
handled(true) instructs the incoming endpoint to not throw
exception back at caller
Basically an alternative route for i.e constructing an error reply
message, without it the consumer would get the actual
exception
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
24. Deployment options
Camel is only a framework, not a deployment server
WAR, Java standalone, JMS Provider, ServiceMix OSGI, in-
application
Think about what Spring did for web app environment
independence, Camel does the same for integration
solutions
Does not impose restrictions on deployment
environment!
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
25. Proposed deployment path
Camel as stand-alone app or deployed into Jetty/Tomcat
Good for PoC and getting to know the framework
Another option is to bundle Jetty inside your application (as in
demo)
Tomcat/Jetty
OrderRoutes.war
camel- camel- camel-
core file cxf
P2pRoutes.war
camel- camel- camel-
core file cxf
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
26. For transactional use-cases and messaging, consider deploying
to your standard Java EE container (JBoss, Glassfish,
Weblogic, Websphere)
Java EE container
OrderRoutes.war
camel- camel- camel-
core jms jdbc
P2pRoutes.war
camel- camel- camel-
core jms jdbc
JMS / JPA /
JTA
JCA adapters DataSources
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
27. To scale – go full OSGI, deploying to Fuse ESB/ServiceMix
Removes need to bundle Camel in application
Makes multi-versions at runtime possible
Extra features for route management etc..
Fuse ESB/ServiceMix
camel-core
1.0
OrderRoutes.jar
camel-jms 1.0
camel-jdbc
1.0
P2pRoutes.jar
camel-... x.x
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING
28. More info at
Camel Official site
http://camel.apache.org/
FuseSource webinars
http://fusesource.com/resources/video-archived-webinars/
Open Source SOA with Fuse
http://www.parleys.com/#sl=2&st=5&id=1577
And of course, the Camel In Action book!
PRODUCTS • CONSULTING • APPLICATION MANAGEMENT • IT OPERATIONS • SUPPORT • TRAINING