0
Get Cooking with
Apache Camel
Cookbook of Tips and Tricks
Scott Cranton
@scottcranton
•  Red Hat Middleware (technical) sales
•  Over 5 years working with Camel
–  Joined FuseSource Feb, 2009
• ...
Apache Camel Developer’s Cookbook
•  100+ Recipes
•  424 pages
•  Published Dec 2013
•  Camel 2.12.2
•  https://github.com...
Why a Camel Cookbook?
•  Help beginner to intermediate users get
productive by example with follow on references
•  Break ...
How Do I Control Route Startup Order?
•  Introduction
–  Sometimes order matters, and routes need to start and stop in a d...
Camel Cookbook Tasting Menu
•  Route Design
•  Routing messages (EIP)
•  Transactions
•  Unit Testing
•  Monitoring
•  Cal...
Interconnecting Routes
Camel supports breaking routes up into
re-usable sub-routes, and
synchronously or asynchronously
ca...
Interconnecting Routes
Within
CamelContext
Within
JVM
Synchronous direct: direct-vm:
Asynchronous seda: vm:
Interconnecting Routes
CamelContext-1
from("activemq:queue:one").to("direct:one");
from("direct:one").to("direct-vm:two");...
Interconnecting Routes
CamelContext-1
from("activemq:queue:one").to("seda:one");
from("seda:one").to("vm:two");
CamelConte...
Interconnecting Routes
from("activemq:queue:one").to("seda:one");
from("seda:one?multipleConsumers=true").log("here");
fro...
Wire Tap
To create an asynchronous path from
your main route. Useful for audit and
logging operations.
Wire Tap
from("direct:start")
.wiretap("direct:tap")
.to("direct:other");
from("direct:tap")
.log("something interesting h...
Wire Tap
from("direct:start")
.wiretap("direct:tap-mod")
.delay(constant(1000))
.log("Oops! Body changed unexpectedly");
f...
Wire Tap
from("direct:start")
.wiretap("direct:tap-mod").onPrepare(new DeepCloningProcessor())
.delay(constant(1000))
.log...
Throttler
For when you need to limit the number
of concurrent calls made a sequence of
actions. For example, limit calls t...
Throttler
from("direct:start")
.throttle(constant(5)) // max per period expression
.to("direct:throttled") // step(s) bein...
Throttler
from("direct:start")
.throttle(header("message-limit")) // expression
.to("direct:throttled")
.end()
.to("direct...
Throttler
from("direct:start")
.throttle(constant(5)).timePeriodMillis(2000) // value in milliseconds
.to("direct:throttle...
Throttler
from("direct:start")
.throttle(constant(5)).asyncDelayed()
.to("direct:throttled")
.end()
.to("direct:post-throt...
Transactions
For local transaction control within your
routes to commit data or rollback on
error. Includes fine grained su...
Transactions
Setup Transaction manager reference (requires Spring).
<bean id="sql" class="org.apache.camel.component.sql.S...
Transactions
Mark a route as transacted. Will commit local transaction at route completion or
automatically rollback if an...
Transactions
Can also explicitly scope transactions.
from("direct:policies")
.setHeader("message", body())
.policy("PROPAG...
XSLT
Camel supports many different ways to
transform data, for example using XSLT
to transform XML.
XSLT
from("direct:start")
.to("xslt:books.xslt");
–  Example uses books.xslt on classpath: (default)
–  Also supports file...
XSLT
from("direct:start")
.to("xslt:books.xslt?output=DOM");
–  output controls output data type
–  Supports: string (defa...
XSLT
from("direct:start").setHeader("myParamValue", constant("29.99")).to("xslt:books-with-param.xslt");
<xsl:stylesheet v...
Mock Endpoints
Camel provides some very powerful
Unit Testing capabilities. Its
MockEndpoint class supports complex
expres...
Mock Endpoints
from("direct:start")
.filter().simple("${body} contains 'Camel'")
.to("mock:camel")
.end();
public class Co...
Mock Endpoints
MockEndpoint mockCamel = getMockEndpoint("mock:camel");
mockCamel.expectedMessageCount(2);
mockCamel.messag...
Mock Endpoints
from("direct:start").inOut("mock:replying").to("mock:out");
getMockEndpoint("mock:replying")
.returnReplyBo...
Mock Endpoints
from("direct:start").to("activemq:out");
public class ContentBasedRouterTest extends CamelTestSupport {
@Ov...
Naming your Routes in JMX
Camel by default exposes your routes
through JMX. You should provide
explicit names for your rou...
Naming your Routes in JMX
from("direct:start")
.routeId("first-route")
.log("${body}")
.to("mock:result");
JMX Name
org.ap...
POJO Producing
Camel’s ProducerTemplate is seen
mostly in Unit Tests, and it provides a
great way to interact with Camel f...
POJO Producing
public class ProducePojo {
@Produce
private ProducerTemplate template;
public String sayHello(String name) ...
POJO Producing
public interface ProxyPojo {
String sayHello(String name);
}
public class ProxyProduce {
@Produce(uri = "ac...
Parameter Binding
Camel was designed to work well with
calling POJOs. Parameter Binding allows
you to, within the route, m...
Parameter Binding
public String myMethod(
@Header("JMSCorrelationID") String id,
@Body String message) {
...
}
public Stri...
Parameter Binding
public class MyBean {
public String sayHello(String name, boolean fanboy) {
return (fanboy) ? ("Hello iP...
Questions?
Apache Camel Developer’s Cookbook
•  100+ Recipes
•  424 pages
•  Published Dec 2013
•  Camel 2.12.2
•  https://github.com...
Cooking with Apache Camel: Tips and Tricks - DevNation 2014
Cooking with Apache Camel: Tips and Tricks - DevNation 2014
Upcoming SlideShare
Loading in...5
×

Cooking with Apache Camel: Tips and Tricks - DevNation 2014

1,499

Published on

Intermediate tips and tricks for using Apache Camel to solve complex integration challenges.

Published in: Software, Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,499
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
37
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Transcript of "Cooking with Apache Camel: Tips and Tricks - DevNation 2014"

  1. 1. Get Cooking with Apache Camel Cookbook of Tips and Tricks Scott Cranton
  2. 2. @scottcranton •  Red Hat Middleware (technical) sales •  Over 5 years working with Camel –  Joined FuseSource Feb, 2009 •  https://github.com/FuseByExample •  https://github.com/CamelCookbook
  3. 3. Apache Camel Developer’s Cookbook •  100+ Recipes •  424 pages •  Published Dec 2013 •  Camel 2.12.2 •  https://github.com/ CamelCookbook
  4. 4. Why a Camel Cookbook? •  Help beginner to intermediate users get productive by example with follow on references •  Break common Camel tasks into Recipes •  Each recipe contains: •  Introduction •  How to do it (task oriented) •  How it works •  There’s more
  5. 5. How Do I Control Route Startup Order? •  Introduction –  Sometimes order matters, and routes need to start and stop in a defined order •  How to do it –  Set route startupOrder attribute –  XML DSL: <route startupOrder="20" routeId="myRoute">...</route> –  Java DSL: from("direct:in").startupOrder(20).routeId("myRoute")...; •  How it works –  Routes started in ascending order, and stopped in descending order •  http://camel.apache.org/configuring-route-startup-ordering-and-autostartup.html •  There’s more –  You can programmatically startup and shutdown routes in response to events •  exchange.getContext().startRoute("myRoute");
  6. 6. Camel Cookbook Tasting Menu •  Route Design •  Routing messages (EIP) •  Transactions •  Unit Testing •  Monitoring •  Calling Camel Routes
  7. 7. Interconnecting Routes Camel supports breaking routes up into re-usable sub-routes, and synchronously or asynchronously calling those sub-routes.
  8. 8. Interconnecting Routes Within CamelContext Within JVM Synchronous direct: direct-vm: Asynchronous seda: vm:
  9. 9. Interconnecting Routes CamelContext-1 from("activemq:queue:one").to("direct:one"); from("direct:one").to("direct-vm:two"); CamelContext-2 from("direct-vm:two").log("Direct Excitement!"); –  Run on same thread as caller –  direct-vm within JVM, including other OSGi Bundles Direct and Direct-VM
  10. 10. Interconnecting Routes CamelContext-1 from("activemq:queue:one").to("seda:one"); from("seda:one").to("vm:two"); CamelContext-2 from("vm:two").log("Async Excitement!"); –  Run on different thread from caller –  concurrentConsumers=1 controls thread count –  vm within JVM, including other OSGi Bundles SEDA and VM
  11. 11. Interconnecting Routes from("activemq:queue:one").to("seda:one"); from("seda:one?multipleConsumers=true").log("here"); from("seda:one?multipleConsumers=true").log("and there"); –  Publish / Subscribe like capability –  Each route gets its own copy of the Exchange –  Multicast EIP better for known set of routes –  https://issues.apache.org/jira/browse/CAMEL-6451 SEDA and VM
  12. 12. Wire Tap To create an asynchronous path from your main route. Useful for audit and logging operations.
  13. 13. Wire Tap from("direct:start") .wiretap("direct:tap") .to("direct:other"); from("direct:tap") .log("something interesting happened"); from("direct:other") .wiretap("activemq:queue:tap") .to("direct:other"); –  Runs on different thread / thread pool –  Default Thread Pool - initial 10; grows to 20
  14. 14. Wire Tap from("direct:start") .wiretap("direct:tap-mod") .delay(constant(1000)) .log("Oops! Body changed unexpectedly"); from("direct:tap-mod") .bean(BodyModifier.class, "changeIt"); // Modifies message body –  Message, Header, and Properties passed by reference
  15. 15. Wire Tap from("direct:start") .wiretap("direct:tap-mod").onPrepare(new DeepCloningProcessor()) .delay(constant(1000)) .log("Yay! Body not changed."); from("direct:tap-mod") .bean(BodyModifier.class, "changeIt"); –  onPrepare calls Processor before wiretap endpoint
  16. 16. Throttler For when you need to limit the number of concurrent calls made a sequence of actions. For example, limit calls to a back-end ERP.
  17. 17. Throttler from("direct:start") .throttle(constant(5)) // max per period expression .to("direct:throttled") // step(s) being throttled .end() // end of step(s) .to("direct:post-throttle"); –  Example limits to 5 messages per 1,000 ms (default) –  Should use end() to delimit steps being throttled
  18. 18. Throttler from("direct:start") .throttle(header("message-limit")) // expression .to("direct:throttled") .end() .to("direct:post-throttle"); –  Example throttles to value in header "message-limit" –  Will use last value if Expression evaluates to null
  19. 19. Throttler from("direct:start") .throttle(constant(5)).timePeriodMillis(2000) // value in milliseconds .to("direct:throttled") .end() .to("direct:post-throttle"); –  Example limits to 5 messages per 2,000 ms
  20. 20. Throttler from("direct:start") .throttle(constant(5)).asyncDelayed() .to("direct:throttled") .end() .to("direct:post-throttle"); –  asyncDelayed() causes throttled requests to be queued for future processing, releasing calling thread (non-blocking)
  21. 21. Transactions For local transaction control within your routes to commit data or rollback on error. Includes fine grained support for scoping of transactions.
  22. 22. Transactions Setup Transaction manager reference (requires Spring). <bean id="sql" class="org.apache.camel.component.sql.SqlComponent"> <property name="dataSource" ref="auditDataSource"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="auditDataSource"/> </bean> <bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="transactionManager"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/> </bean>
  23. 23. Transactions Mark a route as transacted. Will commit local transaction at route completion or automatically rollback if an error is thrown and not handled. from("direct:transacted") .transacted() .setHeader("message", body()) .to("sql:insert into audit_log (message) values(:#message)") .to("mock:out");
  24. 24. Transactions Can also explicitly scope transactions. from("direct:policies") .setHeader("message", body()) .policy("PROPAGATION_REQUIRED") // Transaction 1 .to("sql:insert into audit_log (message) values (:#message)") .to("mock:out1") .end() .policy("PROPAGATION_REQUIRED") // Transaction 2 .to("sql:insert into messages (message) values (:#message)") .to("mock:out2") .end();
  25. 25. XSLT Camel supports many different ways to transform data, for example using XSLT to transform XML.
  26. 26. XSLT from("direct:start") .to("xslt:books.xslt"); –  Example uses books.xslt on classpath: (default) –  Also supports file: and http:
  27. 27. XSLT from("direct:start") .to("xslt:books.xslt?output=DOM"); –  output controls output data type –  Supports: string (default), bytes, DOM, and file –  output=file writes directly to disk; path must exist –  File name controlled by header "CamelXsltFileName"
  28. 28. XSLT from("direct:start").setHeader("myParamValue", constant("29.99")).to("xslt:books-with-param.xslt"); <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="myParamValue"/> <xsl:template match="/"> <books> <xsl:attribute name="value"> <xsl:value-of select="$myParamValue"/> </xsl:attribute> <xsl:apply-templates select="/bookstore/book/title[../price>$myParamValue]"> <xsl:sort select="."/> </xsl:apply-templates> </books> </xsl:template> </xsl:stylesheet>
  29. 29. Mock Endpoints Camel provides some very powerful Unit Testing capabilities. Its MockEndpoint class supports complex expressions to validate your routes.
  30. 30. Mock Endpoints from("direct:start") .filter().simple("${body} contains 'Camel'") .to("mock:camel") .end(); public class ContentBasedRouterTest extends CamelTestSupport { @Test public void testCamel() throws Exception { getMockEndpoint("mock:camel").expectedMessageCount(1); template.sendBody("direct:start", "Camel Rocks!"); assertMockEndpointsSatisfied(); } }
  31. 31. Mock Endpoints MockEndpoint mockCamel = getMockEndpoint("mock:camel"); mockCamel.expectedMessageCount(2); mockCamel.message(0).body().isEqualTo("Camel Rocks"); mockCamel.message(0).header("verified").isEqualTo(true); mockCamel.message(0).arrives().noLaterThan(50).millis().beforeNext(); mockCamel.allMessages().simple("${header.verified} == true"); template.sendBody("direct:start", "Camel Rocks"); template.sendBody("direct:start", "Loving the Camel"); mockCamel.assertIsSatisfied(); Exchange exchange0 = mockCamel.assertExchangeReceived(0); Exchange exchange1 = mockCamel.assertExchangeReceived(1); assertEquals(exchange0.getIn().getHeader("verified"), exchange1.getIn().getHeader("verified"));
  32. 32. Mock Endpoints from("direct:start").inOut("mock:replying").to("mock:out"); getMockEndpoint("mock:replying") .returnReplyBody(SimpleBuilder.simple("Hello ${body}")); getMockEndpoint("mock:out").expectedBodiesReceived("Hello Camel"); template.sendBody("direct:start", "Camel"); assertMockEndpointsSatisfied(); Mock Responding
  33. 33. Mock Endpoints from("direct:start").to("activemq:out"); public class ContentBasedRouterTest extends CamelTestSupport { @Override public String isMockEndpoints() { return "activemq:out"; } @Test public void testCamel() throws Exception { getMockEndpoint("mock:activemq:out").expectedMessageCount(1); template.sendBody("direct:start", "Camel Rocks!"); assertMockEndpointsSatisfied(); } } Auto Mocking
  34. 34. Naming your Routes in JMX Camel by default exposes your routes through JMX. You should provide explicit names for your routes to make it easier for yourself and others to monitor.
  35. 35. Naming your Routes in JMX from("direct:start") .routeId("first-route") .log("${body}") .to("mock:result"); JMX Name org.apache.camel:context=localhost/contextName,type=routes,name=first-route •  By default, Camel will name "route-N" •  It will use the route id if provided as part of the JMX name
  36. 36. POJO Producing Camel’s ProducerTemplate is seen mostly in Unit Tests, and it provides a great way to interact with Camel from your existing code.
  37. 37. POJO Producing public class ProducePojo { @Produce private ProducerTemplate template; public String sayHello(String name) { return template.requestBody("activemq:sayhello", name, String.class); } } –  Send (InOnly) or Request (InOut) to Endpoint or Route
  38. 38. POJO Producing public interface ProxyPojo { String sayHello(String name); } public class ProxyProduce { @Produce(uri = "activemq:queue:sayhello") ProxyPojo myProxy; public String doSomething(String name) { return myProxy.sayHello(name); } } –  Proxy template Java interface to make use clearer
  39. 39. Parameter Binding Camel was designed to work well with calling POJOs. Parameter Binding allows you to, within the route, map the message to the method parameters. This makes it even easier to call POJOs from Camel.
  40. 40. Parameter Binding public String myMethod( @Header("JMSCorrelationID") String id, @Body String message) { ... } public String myOtherMethod( @XPath("/myDate/people/@id") String id, @Body String message) { ... }
  41. 41. Parameter Binding public class MyBean { public String sayHello(String name, boolean fanboy) { return (fanboy) ? ("Hello iPhone") : ("Hello " + name); } } from("direct:fanboy").bean(MyBean.class, "sayHello(${body}, true)"); from("direct:undecided") .bean(MyBean.class, "sayHello(${body}, ${header.fanboy})"); –  Send (InOnly) or Request (InOut) to Endpoint or Route
  42. 42. Questions?
  43. 43. Apache Camel Developer’s Cookbook •  100+ Recipes •  424 pages •  Published Dec 2013 •  Camel 2.12.2 •  https://github.com/ CamelCookbook
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×