Using Enterprise Integration Patterns as Your Camel Jockey

Post on 25-Jan-2015

3.575 views 1 download

description

 

Transcript of Using Enterprise Integration Patterns as Your Camel Jockey

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