Post on 25-Jan-2015
description
Bruce Snyderbsnyder@apache.org
IASA DenverSeptember 2009
Using Enterprise Integration Patterns
as Your Camel Jockey
1
Integrationis
everywhere!2
Just Because You Can, Doesn’t Mean You Should
3
And Then There’s the Llama Car
4
Options For Integration
5
1 2
3
Option One - DIY
6
Do It Yourself
Option Two - Buy It
7
Buy It
Option Three - Adopt It
8
Adopt It
What Are Design Patterns?
A design pattern is a formal way of documenting a solution to a design problem in a particular field of expertise.
(Wikipedia)
9
Enterprise Integration Patterns
Got EIP?
Pattern Overview
11
Visualizing EIPs
::Stencils exist for Visio and OmniGraffle ::http://www.eaipatterns.com/downloads.html
12
What is Apache Camel?
A framework for simplifying integration through the use of the Enterprise Integration Patterns for message mediation, processing, routing and transformation
http://camel.apache.org/
13
Apache Camel is Focused on EIP
14
http://camel.apache.org/
=>
http://eaipatterns.com/
History of Apache Camel
15
Message Routing
16
from("A").to("B");
Simple Routing
17
from("file:///tmp/myFile.txt").to("jms:TEST.Q");
Slightly More Complex Routing
18
from("file:///tmp/myFile.txt").to("bean:MyBean?method=handleMessage").to("jms:TEST.Q");
Multicast Routing
19
from("file:///tmp/myFile.txt").choice().when(). method("MyBean", "matches"). to("Q").end().multicast("B", "C", "D");
Pipeline Routing
20
from("file:///tmp/myFile.txt").choice().when(). method("MyBean", "matches"). to("Q").end().pipeline("B", "C", "D");
Camel Components
21
:: 70+ components supported
Pattern Examples
22
Patterns Again
23
Content Based Router
RouteBuilder builder = new RouteBuilder() { public void configure() { from("activemq:NewOrders") .choice() .when(header("order-type").isEqualTo("widget")) .to("activemq:Orders.Widgets") .when(header("order-type").isEqualTo("gadget")) .to("activemq:Orders.Gadgets") .otherwise() .to("file:errors"); } };
24
Java DSL
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="activemq:NewOrders"/> <choice> <when> <xpath>/order/product = 'widget'</xpath> <to uri="activemq:Orders.Widgets"/> </when> <when> <xpath>/order/product = 'gadget'</xpath> <to uri="activemq:Orders.Gadgets"/> </when> <otherwise> <to uri="activemq:Orders.Bad"/> </otherwise> </choice> </route> </camelContext>
Content Based Router
25
Spring DSL
Message Filter
26
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("activemq:topic:Orders) .filter().xpath("/order/product = ʻwidgetʼ") .to("ftp://bsnyder@host:2223/widgets/orders"); }}
Java DSL
Message Filter
27
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="activemq:topic:Orders"/> <filter> <xpath>/order/product = ʻwidgetʼ</xpath> <to uri="ftp://bsnyder@host:2223/widgets/orders"/> </filter> </route> </camelContext>
Spring DSL
Splitter
28
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("file:///orders")
.splitter(body(String.class).tokenize("\n")) .to("activemq:Order.Items"); }}
Java DSL
Splitter
29
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file:///orders" /> <split> <tokenize token="\n" /> <to uri="activemq:Order.Items" /> </split> </route> </camelContext>
Spring DSL
Aggregator
30
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("activemq:STOCKS") .aggregator(header("symbol")) .batchSize(10) .to("activemq:MY.STOCKS"); }}
Java DSL
Aggregator
31
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file:///orders" /> <aggregate> <correlationExpression> <simple>header.symbol</simple> </correlationExpression> <batchSize>10</batchSize> <to uri="activemq:MY.STOCKS" /> </aggregate> </route> </camelContext>
Spring DSL
Throttler
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("seda:a”) .throttler(3).timePeriodMillis(30000) .to("seda:b"); }}
32
Java DSL
Delayer
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("seda:a”)
.delayer(header("JMSTimestamp", 3000) .to("seda:b"); }}
33
Java DSL
Load Balancer
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("file:/path/to/file") .loadBalance().roundRobin() .to("file:///one", "activemq:MY.Q", "http://host1:8181/fooApp"); }}
34
Policy DescriptionRound Robin Balance the exchange load across the available endpoints
Random Randomly choose an endpoint to send the exchange
Sticky Sticky load balancing of exchanges using an expression
Topic Send exchange to all endpoints (JMS topic semantics)
Java DSL
Multicast
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:a") .multicast() .to("direct:x", "mock:y", "file:///tmp/bar?fileName=test.txt");
}}
35
Java DSL
More Patterns
36
Wire Tap
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:a") .to("log:com.mycompany.messages?level=info") .to("mock:foo");
}}
37
Java DSL
Content Enricher
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("activemq:My.Queue") .to("velocity:com/acme/MyResponse.vm") .to("activemq:Another.Queue");
}}
38
Java DSL
More Content Enricher
39
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("activemq:My.Queue") .beanRef("myPojo", “methodName”) .to("activemq:Another.Queue"); }}
Java DSL
Content Filter
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:start").process(new Processor() { public void process(Exchange exchange) { Message in = exchange.getIn(); in.setBody(in.getBody(String.class) + " World!"); } }).to("mock:result"); }}
40
Java DSL
Combine Patterns
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("seda:a”). resequencer(header("JMSGroupSeq")).
delayer(3000). to("mock:x"); }}
41
Java DSL
Error Handling in Camel
::Global Error Handler:
::Local Error Handler:
42
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("file:errors")); from("bean:foo").to("seda:b"); }};
RouteBuilder builder = new RouteBuilder() { public void configure() { from("seda:a"). errorHandler(loggingErrorHandler("FOO.BAR")). to("seda:b"); from("seda:b").to("seda:c"); }};
Java DSL
Exception Policies in Camel
43
RouteBuilder builder = new RouteBuilder() { public void configure() { exception(IOException.class) .initialRedeliveryDelay(5000L) .maximumRedeliveries(3) .maximumRedeliveryDelay(30000L) .backOffMultiplier(1.0) .useExponentialBackOff() .setHeader(MESSAGE_INFO, constant("Damned IOException!")) .to("activemq:errors"); from("seda:a").to("seda:b"); }};
Java DSL
Make Context Discover Beans
44
package com.mycompany.beans;
public class MyBean {
public void someMethod(String name) { ... }}
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> <package>com.mycompany.beans</package></camelContext>
Bean as a Message Translator
45
public class MyRouteBuilder extends RouteBuilder { public void configure() {
from("activemq:Incoming”). beanRef("myBean"). to("activemq:Outgoing"); }}
Java DSL
Bean as a Message Translator
46
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("activemq:Incoming”). beanRef("myBean", "someMethod"). to("activemq:Outgoing"); }}
*With Method Name
Java DSL
Binding Beans to Camel Endpoints
47
public class Foo {
@MessageDriven(uri=”activemq:cheese”) public void onCheese(String name) { ... }}
Java DSL
Binding Method Arguments
48
public class Foo {
public void onCheese( @XPath(“/foo/bar/”) String name, @Header(“JMSCorrelationID”) String id) { ... }}
Java DSL
Injecting Endpoints Into Beans
49
public class Foo { @EndpointInject(uri= “activemq:foo.bar”) ProducerTemplate producer;
public void doSomething() { if (whatever) { producer.sendBody(“<hello>world</hello>”); } }}
Java DSL
Type Convertors
public class MyRouteBuilder extends RouteBuilder { public void configure() { from("direct:start").process(new Processor() { public void process(Exchange exchange) { Message in = exchange.getIn(); in.setBody(in.getBody(String.class) + " World!"); } }).to("mock:result"); }}
50
Support for the following types: • File• String• byte[] and ByteBuffer • InputStream and OutputStream • Reader and Writer • Document and Source
Type Conversion
51
@Converterpublic class IOConverter {
@Converter public static InputStream toInputStream(File file) throws FileNotFoundException { return new BufferedInputStream(
new FileInputStream(file)); }}
Business Activity Monitoring (BAM)
52
public class MyActivities extends ProcessBuilder {
public void configure() throws Exception {
// lets define some activities, correlating on an // XPath query of the message body ActivityBuilder purchaseOrder = activity("activemq:PurchaseOrders") .correlate(xpath("/purchaseOrder/@id").stringResult());
ActivityBuilder invoice = activity("activemq:Invoices") .correlate(xpath("/invoice/@purchaseOrderId").stringResult());
// now lets add some BAM rules invoice.starts().after(purchaseOrder.completes()) .expectWithin(seconds(1)) .errorIfOver(seconds(2)).to("activemq:FailedProcesses"); }}
The Camel Truck!
53
54
Ride the Camel!http://camel.apache.org/
bsnyder@apache.orghttp://twitter.com/brucesnyder