Beruflich Dokumente
Kultur Dokumente
UniversittStuttgart
Universittsstrae38
70569Stuttgart
StudienarbeitNr.2127
RealizationofEAIPatterns
withApacheCamel
PascalKolb
Studiengang:
Informatik
Prfer:
Prof.Dr.FrankLeymann
Betreuer:
Dipl.Inf.ThorstenScheibler
begonnenam:
26.10.2007
beendetam:
26.04.2008
CRKlassifikation
D.2.11,D.3,H.4.1
Table of Contents
TableofListings.............................................................................................................vii
1 Introduction.............................................................................................................1
1.1
TaskDescription.................................................................................................................................1
1.2
Structureofthisthesis.......................................................................................................................2
2 ApacheCamelFundamentals...................................................................................3
2.1
IntroductionintoApacheCamel........................................................................................................3
2.2 ApacheCamelsArchitecture.............................................................................................................4
2.2.1
CamelComponentsandEndpoints............................................................................................4
2.2.2
CamelExchangeandMessage...................................................................................................6
2.2.3
CamelTypeConverter...............................................................................................................6
2.2.4
CamelProcessor........................................................................................................................7
2.2.5
CamelContext...........................................................................................................................7
2.2.6
CamelDomainSpecificLanguage/FluentAPI..........................................................................8
2.2.7
CamelRoutes.............................................................................................................................8
2.3
AsimpleCamelexample....................................................................................................................9
3 EAIPatternsinApacheCamel.................................................................................11
3.1 MessagingChannels........................................................................................................................12
3.1.1
PointtoPointChannel............................................................................................................12
3.1.2
PublishSubscribeChannel......................................................................................................13
3.1.3
DatatypeChannel....................................................................................................................13
3.1.4
InvalidMessageChannel.........................................................................................................13
3.1.5
DeadLetterChannel................................................................................................................13
3.1.6
GuaranteedDelivery................................................................................................................14
3.1.7
ChannelAdapter......................................................................................................................14
3.1.8
MessagingBridge.....................................................................................................................15
3.1.9
MessageBus............................................................................................................................15
3.2 MessageConstruction.....................................................................................................................15
3.2.1
Command/Document/EventMessage.................................................................................16
3.2.2
RequestReply..........................................................................................................................16
3.2.3
ReturnAddress........................................................................................................................17
3.2.4
MessageExpiration..................................................................................................................17
3.2.5
CorrelationIdentifier/MessageSequence/FormatIndicator...............................................18
3.3
PipesandFilters...............................................................................................................................18
iii
TABLEOFCONTENTS
3.4 MessageRouting..............................................................................................................................20
3.4.1
ContentBasedRouter..............................................................................................................20
3.4.2
MessageFilter..........................................................................................................................21
3.4.3
DynamicRouter........................................................................................................................21
3.4.4
RecipientList............................................................................................................................22
3.4.5
Splitter......................................................................................................................................23
3.4.6
Aggregator................................................................................................................................24
3.4.7
ComposedMessageProcessor/ScatterGather......................................................................27
3.5 MessageTransformation..................................................................................................................27
3.5.1
EnvelopeWrapper....................................................................................................................27
3.5.2
ContentEnricher......................................................................................................................28
3.5.3
ContentFilter...........................................................................................................................28
3.5.4
ClaimCheck..............................................................................................................................29
3.5.5
Normalizer................................................................................................................................30
3.6 MessagingEndpoint.........................................................................................................................30
3.6.1
MessagingGateway..................................................................................................................30
3.6.2
MessagingMapper...................................................................................................................31
3.6.3
PollingConsumer.....................................................................................................................31
3.6.4
EventDrivenConsumer............................................................................................................32
3.6.5
CompetingConsumers.............................................................................................................32
3.6.6
MessageDispatcher.................................................................................................................33
3.6.7
SelectiveConsumer..................................................................................................................34
3.6.8
DurableSubscriber...................................................................................................................34
3.6.9
IdempotentReceiver................................................................................................................35
3.6.10 ServiceActivator.......................................................................................................................35
4 Implementation......................................................................................................37
4.1
Concept............................................................................................................................................37
4.2
Technologiesused.............................................................................................................................38
4.3 TheEAI2CamelFramework............................................................................................................39
4.3.1
HelperClasses..........................................................................................................................40
4.3.2
MessageProducerTemplate....................................................................................................41
4.3.3
WebServiceEndpoint..............................................................................................................41
4.3.4
WebServiceProvider...............................................................................................................42
4.3.5
MessageTranslator..................................................................................................................43
4.3.6
ContentEnricher......................................................................................................................43
4.3.7
RecipientList............................................................................................................................44
4.3.8
Aggregator................................................................................................................................45
4.4 GenerationofApacheCamelbasedJavacode.................................................................................47
4.4.1
ParameterizationoftheEAIpatterns.......................................................................................47
4.4.2
IntegrationintotheEclipsebasedEditor.................................................................................48
4.4.3
GenerationoftheCode............................................................................................................48
4.4.4
RequiredLibraries.....................................................................................................................49
4.5
iv
ExampleMessagingSystem.............................................................................................................49
Bibliography.................................................................................................................51
Appendix......................................................................................................................55
A.1 CamelexampleusingbuiltinPipeline.............................................................................................55
A.1.1
JavaCode.................................................................................................................................55
A.1.2
Output.....................................................................................................................................58
A.1.3
Discussion................................................................................................................................60
Table of Listings
Listing1:ConfiguringEndpoints......................................................................................................................5
Listing2:SimpleCamelexample....................................................................................................................10
Listing3:DeadLetterChannelfornonmessagingsystemcomponents.......................................................14
Listing4:AMessagingBridgeinApacheCamel.............................................................................................15
Listing5:RequestReplyinApacheCamel.....................................................................................................17
Listing6:MessageExpirationforJMSEndpointsinApacheCamel...............................................................17
Listing7:ApacheCamelsapproachtothePipesandFilterspattern...........................................................19
Listing8:PatternconformapproachtothePipesandFilterspattern..........................................................20
Listing9:FixedrouteinApacheCamel..........................................................................................................20
Listing10:ContentBasedRouterinApacheCamel.......................................................................................21
Listing11:MessageFilterinApacheCamel...................................................................................................21
Listing12:PossibleimplementationoftheDynamicRouterpattern............................................................22
Listing13:RecipientListinApacheCamel.....................................................................................................23
Listing14:SplitterinApacheCamel..............................................................................................................24
Listing15:ApacheCamelsAggregatorwithacustomAggregationCollection..............................................26
Listing16:MessageTranslatorinApacheCamel...........................................................................................27
Listing17:PossibleContentEnricherimplementationinApacheCamel.......................................................28
Listing18:ContentfilteringusinganXPathexpressioninApacheCamel.....................................................29
Listing19:PossibleClaimCheckimplementationinApacheCamel...............................................................29
Listing20:NormalizerinApacheCamel........................................................................................................30
Listing21:PollingConsumerinApacheCamel..............................................................................................31
Listing22:EventDrivenConsumerinApacheCamel....................................................................................32
Listing23:CompetingConsumerusingtheJMSComponentinApacheCamel............................................32
Listing24:MessageDispatcherusingaContentBasedRouter.....................................................................34
Listing25:SelectiveConsumerusingApacheCamelsJMSComponent.......................................................34
Listing26:DurableSubscriberusingApacheCamelsJMSComponent........................................................35
Listing27:ApacheCamelsIdempotentReceiver..........................................................................................35
Listing28:TheServiceActivatorpatterninApacheCamel...........................................................................36
Listing29:UsingtheMessageProducerTemplateoftheEAI2CamelFramework......................................41
Listing30:RetrievingthedatatoenrichinanXSLTstylesheetviaaspecialURL..........................................44
Listing31:RetrievingthedatatoenrichinanXSLTstylesheetviaanXSLTparameter..................................44
vii
Introduction
Enterprise application systems rarely live in isolation as creating a single huge application that
runs a complete business is almost impossible. Thus enterprises typically run hundreds or even
thousands of different application systems. Because most of these application systems typically
needtoworktogethertosupportcommonbusinessprocessesandtosharedataacrossapplication
systems,theseapplicationsystemsneedtobeintegrated.Enterpriseapplicationintegrationneeds
toprovideefficient,reliableandsecuredataexchangebetweenmultipleenterpriseapplications.
An important aspect of application integration is to keep the integrated application system inde
pendent. This isimportant in order toenable the different applicationsystems to evolve without
affecting each other and thus making the overall solution more tolerant to changes. This is often
referredtoasLooseCoupling.LooseCouplingcanbeachievedbyusingasynchronouscommuni
cation,forexamplebyusingmessaging.
Becauseintegratingenterpriseapplicationsisachallengingtopicsomefrequentlyrecurringprob
lemsandtheirsolutionhasbeendescribedinformofpatterns.Patternsareatechniquetodocu
ment expert knowledge and experience. The book Enterprise Integration Patterns by Gregor
HohpeandBoobyWoolf[HW03]describesacollectionofpatternsresidinginthedomainofenter
priseapplicationintegrationusingmessaging.
The main objective of this work is to analyze the implementation of these Enterprise Integration
PatternsinApacheCamel[Cam].
1.1
Task Description
InthisworktheApacheCamelplatformshallbeevaluatedregardingthecorrectimplementation
of the Enterprise Integration Patterns. Missing patterns shall be supplemented and the platform
shall be extended by appropriate mechanisms if required. Thereby an application programming
interface(API)shallbedeveloped,thatenablesthemodelingofintegrationscenariosbasedonthe
enterprise integration patterns. ThisAPI shall also enable the generation of executable code. The
resultsofthisworkshallbedemonstratedbyaprototypeandaconcreteexample.
Intheworkof[Dru07]atoolforthegraphicalmodelingofintegrationscenarioshasalreadybeen
developed. This tool enables the generation of WSBPEL [AAA+07] processes from the modeled
integrationscenario.Thesolutiondevelopedaspartofthisworkisbasedonthistool.Thetoolis
therebyextendedwiththeabilitytogenerateexecutableJavacode.
INTRODUCTION
1.2
Thisthesisisstructuredasfollows:
Inchapter2theworkintroducestotheApacheCamelplatformandsummarizesitsarchitecture.It
isimportanttounderstandApacheCamelsarchitectureasthisisarequirementtounderstandthe
evaluationofApacheCamelanditsimplementationoftheenterpriseintegrationpatterns.
Inchapter3thedifferententerpriseintegrationpatternsdescribedinHohpesandWoolfsbookare
evaluatedregardingtheirimplementationinApacheCamel.Theevaluationofthepatternsisstruc
turedingroupssimilartotheiroccurrenceinHohpesandWoolfsbook.
Inchapter4theresultsfromchapter3areusedtoextendthemodelingtoolwhichwasdeveloped
as part of the work from [Dru07]. The tool is extended with the ability to create executable Java
codefromthemodeledintegrationscenario.
2
2.1
ThischapterintroducestoApacheCamel[Cam].TheApacheCamelversiondiscussedinthiswork
andusedfortheimplementationdescribedinchapter4belowisApacheCamelrelease1.2.0,the
mostrecentreleasetodate.TheApacheCamelprojectisarelativelyyoungprojectitwasstarted
inearly2007andisthuslackinggooddocumentation.Forthisreason,thischapterintroducesto
Camels architecture so the reader doesnt need to crawl through the projects little and unstruc
tured documentation or Camels API specification, to be able to follow the evaluation of Camel
regardingitsimplementationoftheEnterpriseIntegrationPatterns[HW03]inchapter3below.
Apache Camel is a routing and mediation engine which implements the Enterprise Integration
Patternsfrom[HW03].Itprovidesaframeworkwhichcanbeusedtointegratedifferentapplica
tionsusingtheEnterpriseIntegrationPatternsanditcanbeusedasaroutingandmediationen
gineforthefollowingApacheprojects:
ApacheActiveMQ,anopensourcemessagebroker[Act]
ApacheCXF,anopensourcewebserviceframework(JAXWS)[Cxf]
ApacheMINA,anetworkingframework[Min]
ApacheServiceMix,anopensourceESBandJBIcontainer[Ser]
TheCamelenginecanrunasastandaloneJavaApplicationorcanbedeployedasaJBIcomponent
intoApache ServiceMix. SinceActiveMQ 5.0 [Act] it is also possible to run the Camel Engine in
ActiveMQs broker process. For details about the integration of Camel in ServiceMix and Acti
veMQ see the respective project pages documentation. To configure the routing and mediation
rulesCamelsupportstwoapproaches.OneapproachistoconfigureCamelviaSpring[Spr]based
XMLConfigurationfiles.TheotherapproachistoconfigureCamelviaCamelsJavabasedDomain
SpecificLanguage(DSL),wheretheconfigurationisdonebychainedJavamethodcallsinafashion
thattheproducedJavacodeiseasilyhumanreadable,thusCamelsDSLisalsocalledFluentAPI
(SeeListing2belowforanexampleoftheFluentAPI).Witheitherapproachtheconfigurationis
facilitatedtroughsmartcompletionoftheroutingrulesbyeithertheXMLortheJavaeditor.Dueto
the time constraints of this work, and since theApache Camel developers recommend using the
Java DSL in preference over the Spring based XML configuration because it is more expressive
andoffersmaximumsmartcompletionbytheIDEthefocusofthisworkisontheconfiguration
ofCamelviaitsJavaDomainSpecificLanguage.
APACHECAMELFUNDAMENTALS
2.2
Figure1belowgivesanoverviewofCamelsarchitecture.ThemainbuildingblocksofCamelare
Components, Endpoints and Processors. Endpoints and Processors are wired together to Routes.
Routes represent the routing and mediation rules and are added to a Camel Context which is a
containerforthewholeconfiguration.Thefollowingparagraphsexplainthesebuildingblocksin
moredetail.
Figure1:ApacheCamelsArchitecture[Cam]
2.2.1
Tobeabletointegratewithdifferentapplicationsondifferentplatforms,ApacheCamelsupports
multiple so called Components, where each of these Components enablesApache Camel to send
2.2ApacheCamelsArchitecture
andreceivemessagesusingacertainprotocolormiddlewareforexampleamessagebroker.Some
commonComponentsare:
TheJMSComponentwhichenablesApacheCameltoconnecttoanyJMSprovider.
TheFileComponentwhichenablesCameltoreadfilesfromafilesystemortowritemessages
asfilestoafilesystem.
The DirectComponent where a message producer directly, i.e. synchronously, invokes the
messageconsumers.
The SEDAComponent which implements inmemory blocking queues to be able to produce
andconsumemessagesasynchronously.
ForalistofthecurrentlysupportedcomponentsrefertoCamelsprojectpage[Cam].AComponent
actsasconnectortoothersystemsormiddlewareandisessentiallyafactoryforCamelEndpoints,
to which messages can be sent and from which messages can be received. In that sense Camel
EndpointsrepresentachannelasintheChannelpatternfrom[HW03].ACamelEndpointcreated
byCamelsJMS ComponentforexamplewouldrepresentaJMSqueueortopic.CamelusesURIs
to identify Endpoints and lazily creates them using the appropriate Component if they dont al
ready exist. This makes it simple to configure routes, as Endpoints dont have to be instantiated
explicitly.TheURIschemeoftheEndpointURIidentifiesthecomponentwhichisresponsiblefor
creatingtheEndpoint.CamelautodiscoversComponentsbytheirscheme.ThereforeaComponent
hastohaveaconfigurationfileintheproperdirectory 1 ,whichhastoresidesomewhereintheclass
path. Alternatively the Component can be registered explicitly with the Camel Context. Compo
nents with a complex configuration are usually registered explicitly with the Camel Context as
seenwiththeJMSComponent(myComponent)inListing2below.
Components always implement the Component 2 interface and are usually not used directly to
create Endpoint instances. Instead the Endpoint instances are created implicitly when an URI is
usedinaRouteorwhenanEndpointforanURIisrequestedfromtheCamel Context.Endpoints
always implement the Endpoint 3 interface and are used as interface for sending and receiving
messages.TheyarepreconfiguredbytheComponenttheyareinstantiatedby,butcanalsobecon
figureddirectlyandusedinroutingrulesinsteadofURIslikeinListing1below.
1
2
3
4
5
SomeEndpointClass myEndpoint
= (SomeEndpointClass) camelContext.getEndpoint("myEndpointURI");
myEndpoint.setSomething("aValue");
from(myEndpoint).to("anotherEndpointURI")
Listing1:ConfiguringEndpoints
META-INF/services/org/apache/camel/component/
org.apache.camel.Component
3org.apache.camel.Endpoint
1
2
APACHECAMELFUNDAMENTALS
The sending and receiving of messages to and from Endpoints is done via Producer 1 and
Consumer 2 instancescreatedbyanEndpoint.AConsumerconsumesmessagesfromanEndpoints
underlying channel. Camel supports the Eventdriven Consumer pattern by using the
createConsumer(Processor)method,whichcreatesaConsumerinstance,invokingthesup
pliedProcessor 3 onmessagearrival.CamelalsosupportsthePolling Consumerpatternbyus
ing the createPollingConsumer() method, which creates a PollingConsumer 4 that can be
polledfornewmessagesinablockingorinanonblockingway.
A Producer adds messages to an Endpoints underlying channel and is implemented in Camel
trough the Producer3 interface which offers methods for the creation of Exchanges (see 2.2.2
CamelExchangeandMessagebelow)andamethodforthesendingoftheseExchanges.Itisimpor
tanttonotethatthesendingofExchangesisdoneviatheprocess()methodoftheProcessor3
interface.ThisallowstheusageofaProducerasaProcessorwhichprocessesmessagesbyadding
themtotheEndpointsunderlyingchannelandwhichalsosetstheExchangesoutputmessageto
thereceivedresponsemessageincaseofin/outexchangepatterns,likerequest/replyexchangesfor
example.
2.2.2
To support various message exchange patterns, like request/reply message exchanges or event
messages,CamelofferstheExchange 5 interfacewhichbasicallycontainsaninput,outputanda
faultmessage,dependingontheExchangePattern 6 .AnExchangecanalsobeandusuallyis
extendedbyaComponenttoexposetheunderlyingtransportsemanticsofthatComponent.
Theinput,outputorfaultmessagescontainedinanExchangeimplementtheMessage 7 interface
representingtheMessagepatternandbasicallycontainingamessagebodyandacollectionofmes
sage headers. The message body can contain any Java object, but for almost all Components the
messagebodyneedstocontainaserializable 8 object,asthemessagewillleavethesendersaddress
spaceoreventhemachineitoriginatesfrom.
2.2.3
Because some Endpoints always return messages of a certain type the FileEndpoint 9 for ex
amplealwaysreturnsaninstanceofFile 10 asmessagebodyandbecauseitsquitecommonto
org.apache.camel.Producer
org.apache.camel.Consumer
3org.apache.camel.Processor
4org.apache.camel.PollingConsumer
5org.apache.camel.Exchange
6org.apache.camel.ExchangePattern
7org.apache.camel.Message
8i.e.implementthejava.io.Serializableinterface
9org.apache.camel.component.file.FileEndpoint
10java.io.File
1
2
2.2ApacheCamelsArchitecture
needtoconvertamessagebodytoandfromcertaintypes,Cameloffersanextensibletypeconver
sionstrategyviasocalledTypeConverters.
CamelprovidesthemethodgetBody(Class)intheMessage 1 interface,whichreturnsthemes
sage payload converted to the given type. The conversion is done by the implementation of the
TypeConverter 2 interfacewhichisassociatedwiththecurrentCamelContext 3 .Camelsdefault
implementationoftheconverteristheDefaultTypeConverter 4 classwhichdiscoverstypecon
vertersbysearchingtroughdefined 5 packagesforclassesandmethodswhichareannotatedwith
the @Converter 6 annotation. To support common conversions, Camel provides already some
builtintypeconverters.
2.2.4
Camel Processor
Another building block ofApache Camel, besides the Component, is the Processor which, as the
name indicates, processesmessages.AProcessor is handed overan Exchange(i.e. a message) by
theCamelengine,andafterprocessingit,CamelsendstheExchangetoachannelorinvokesthe
following Processor. This seems to follow the PipesandFilters pattern, where the pipes are the
channels represented by the Camel Endpoints and the filters are the Camel Processors. And in
deed,ifappliedinaproperway,itimplementsthePipesandFilterspattern.Butitisalsopossible
tochainCamelProcessorsdirectlywhereoneProcessordirectlyinvokesthenext,whichviolates
thePipesandFilterspattern.Thisisdiscussedindetailinchapter3.3below.ACamelProcessor
canalsoperformroutingbydecidingwheretosendamessagetoandthuscanalsobeusedtoim
plementtheRoutingpatterns.
Camel Processors are EventDriven Consumers (as in [HW03]) and implement the Processor 7
interface. Most patterns implemented in Apache Camel are EventDriven Consumers as this
enablestheCamelcontainertomanagepoolingandthreading.Oneofthefewpatternimplementa
tions in Camel which are not EventDriven Consumers is the Aggregator pattern which imple
mentsthePollingConsumerpattern.
2.2.5
Camel Context
ACamel Contextisthecontainerforaspecificintegrationscenarioandrepresentsthatscenarios
routing rule base. It implements the CamelContext 8 interface and contains a collection of all
Component instances used in theintegration scenarioand all specified Camel Routes of the inte
org.apache.camel.Message
org.apache.camel.TypeConverter
3org.apache.camel.CamelContext
4org.apache.camel.impl.converter.DefaultTypeConverter
5Thepackagestobesearchedhavetobedefinedinthefollowingfile:
META-INF/services/org/apache/camel/TypeConverter
6org.apache.camel.Converter
7org.apache.camel.Processor
8org.apache.camel.CamelContext
1
2
APACHECAMELFUNDAMENTALS
gration scenario. The Routes define the processing used on inbound message exchanges from a
specific Endpoint. To add Routes to a Camel Context using the Java DSL aka FluentAPI, Camel
provides the RouteBuilder 1 class, which can be used, as in the example in listing 2 below, to
createRoutes.
Camel provides a simple Service 2 interface for managing Camels lifecycle. The interface pro
videstwomethods,thestart()andthestop()method.MostComponentsandEndpointsim
plementthisinterfaceanditstheCamelContextstasktostartallthenecessaryserviceswhenthe
Camelengineisstarted.TheCamelContextitselfimplementstheServiceinterfacewhichisused
tostarttheCamelengineasseenintheexampleinlisting2below.
CamelalsosupportsaregistrypluginstrategywhichallowsCameltoretrieveCamelProcessors
or Endpoints for example from a registry. The Registry 3 is associated with the Camel Context
and can be replaced by any registry provider implementing this interface. Camel offers builtin
supportforJNDIasaregistry.
2.2.6
Asmentionedbefore,CameloffersaJavaDomainSpecificLanguage(DSL)alsoknownasFluent
APIwhichallowsthewritingofroutingrulesinaneasilyhumanreadableformatsupportedbythe
Javadevelopmentenvironmentssmartcompletioncapabilities.CamelsDSLisveryexpressiveas
itallowstomixowncodewiththeDSLbyusingcustomProcessors,ExpressionsandPredicatesas
itwillbedemonstratedlater.
Expressions are used in Camels DSL to configure dynamic rules, where they offer evaluation of
messageexchanges.TheRecipientListPatternforinstanceusesanExpressionforgettingthereci
pient list contained in a message. Camel comes with already builtin support for a variety of ex
pressionlanguageslikeXPath[CD99]forexample,whichisimplementedintheXPathBuilder 4
class.
InadditiontoExpressions,CameloffersalsoPredicatesinitsDSLtocheckifamessageexchange
hasacertainproperty.AsfortheExpressions,Camelalsooffersbuiltinsupportforpredicatelan
guages, one of them is XPath implemented in the XPathBuilder class. Message Filters, for ex
ample,usePredicatestodecidewhetheramessageshouldbeforwardedorfiltered.
2.2.7
Camel Routes
RoutesarerulestoconfigurehowCamelprocessesincomingmessages.ARouteisachainofCa
mel Processors, implemented by the Pipeline 5 class, where the result of one Processor is the
org.apache.camel.builder.RouteBuilder
org.apache.camel.Service
3org.apache.camel.spi.Registry
4org.apache.camel.builder.xml.XPathBuilder
5org.apache.camel.processor.Pipeline
1
2
2.3AsimpleCamelexample
inputofthefollowingProcessorandsoontillthelastProcessorisreachedandthePipelinere
turnsfromitsprocess()methodinvocation.ThefirstelementofarouteisalwaysaConsumer
ofanEndpointwhichinvokesthePipeline.ItisimportanttoknowthatthePipelinereturnsonly
afterthewholeroutei.e.thewholeprocessingchainhasbeenprocessed,whichmeansthatthe
Consumer of an Endpoint is only done processing an Exchange after the message has been
processedbythewholeroute.Thisisimportantfirstinordertoprocessrequestresponsemessage
exchangeswhicharereturnedtotheconsumer.Andsecondtoensurethatamessageisonlysuc
cessfullyconsumedaftertheprocessingbythelastprocessor,whichisusuallyanEndpointsPro
ducer,isfinished.
2.3
The code in listing 2 below shows a simple example of Apache Camel, where messages are re
ceivedfromtheJMSqueue'test.queue',processedbytheProcessor'myProcessor'andput
inthe'testFolder'.AsmentionedbeforetheCamelContextisthecontainerofourintegration
scenario,soourexamplestartswithcreatingaCamelContext(line1),thenaddsaComponentto
it(line9),thenaddsRoutestoit(line11)andfinallytheCamelContextisexecutedfor10minutes
(lines3638).
In this example two Components are used: the 'myComponent'Component which is explicitly
registeredwiththeCamelContextandthe'file'Componentwhichisautodiscovered.Onecan
alsoseehowEndpointsarereferencedbytheirURIsandcreatedimplicitlybyCamel.Lines29to
31demonstratehowtheusageofCamelsDSLakaFluentAPIcreateshumanreadableandeasyto
understand code. The Processor in this example is defined in lines 16 to 25 and doesnt alter the
messagesitprocesses,butsimplyprintsthemessagebodiestotheconsole.TheProcessorscustom
implementation also shows how the type conversion mentioned above is used to get a String
representationofthemessagebody(line22).
APACHECAMELFUNDAMENTALS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
10
InthischapterApacheCamelisevaluatedregardingwhichoftheEnterpriseIntegrationPatterns
[HW03]areimplementedinCamel,towhatextenttheyareimplementedandiftheimplementa
tioniscorrectaccordingtotheirdefinitioninHohpesandWoolfsbookonEnterpriseIntegration
Patterns[HW03].
Because the Camel Project is relatively young and thus has only a rudimentary and incomplete
documentation,theevaluationhasmostlybeendonebyreadingCamelsAPIspecificationinform
of JavaDocs and by reading through Camels implementation itself. Also it has to be mentioned
that the evaluation is based on the latest Camel release at the time of this work, which is release
1.2.0. This release contains several bugs and is also missing functionality that is implied by the
specification. This fact reflects in the following subchapters in form of comments to Camels im
plementation. At the time of the creation of this work the developing of release 1.3.0 was in
progresswheresomebugsmentionedinthisworkarealreadyfixed.Thisisignoredfortheevalua
tionofthepatternsinthiswork,astheevaluationneededtoreflectonedefinedversionofCamel
forwhichrelease1.2.0waschosen,asthemostrecentrelease.Further,itisimportanttomention
thatCamelsdocumentationdoesntrefertoaspecificreleaseofApacheCamel.Ratherthedocu
mentation is updated continuously without mentioning which release of Camel is actually docu
mented.ThisiseventrueforCamelsAPIdocumentationavailableonline,buttheJavaDocdocu
mentation can also be generated from the source code available online by oneself, resulting in a
consistentAPIspecification.
The evaluation of the different patterns is following the order of their appearance in the book of
Hohpe and Woolf [HW03]. The only difference is that the more generic patterns that form their
ownsubchaptercontainingtheirseveralsubpatterns,liketheMessageChannel,theMessage,the
PipesandFilters,theMessageRouter,theMessageTranslatorandtheMessageEndpointarenot
discussedinanintroductorychapterlikeinthecaseofHohpesandWoolfsbook,butintheirre
spectivesubchapter.
Due to thelimited time frame of thiswork notallpatterns could be evaluated. The patterns that
havebeenskippedhavebeenchosenbecausetheywereeithergooddocumentedinCamelsdocu
mentationortheywereadvancedpatternsoftheirrespectivecategory.Amongthepatternsthatare
not evaluated are also all System Management patterns because they are advanced patterns that
describeadifferentaspectofamessagingsolutionandthuscanbeevaluatedseparately.Thefol
lowingpatternsarenotevaluatedeither:
The Resequencer pattern which is implemented in Camel and has a comparably good docu
mentationontheprojectwebsite.
TheRoutingSlippatternwhichisnotimplementedatallinApacheCamel.
11
EAIPATTERNSINAPACHECAMEL
The Process Manager pattern which goes beyond the scope of Apache Camel and is
covered by workflow engines like the one developed in the Apache ODE project
[Ode].
TheMessageBrokerwhichisanarchitecturalpatternthatis opposed to thePipesand
Filtersarchitectureandisthearchitecturalpattern,thegraphicaleditorandBPELge
nerator of the diploma thesis from Druckenmller on Parameterization of EAI Pat
terns[Dru07],whichwillbeextendedinthiswork,isbasedon.
TheCanonicalDataModelpatternwhichisnotimplementableinApacheCamel,butisrather
apatternthatshouldbefollowedbythearchitectofamessagingsolution.
The Transactional Client pattern which is implemented in Camel using Spring transactions
andisacomplexpatternthatneedsadeepevaluation
3.1
Messaging Channels
TheMessageChannelpatternisnotexplicitlyimplementedinApacheCamelinsteadthemessage
channels are provided by the underlying middleware, the operating system or are implemented
completelyinCameldependingonthekindofchannel.WhatCameldoesisprovidingacommon
interface to address and access channels using Endpoints, which are usually identified and ad
dressedbytheirURI.Asexplainedinchapter2.2CamelsupportsdifferentComponentsforinte
grating with different systems. These Components create Endpoints which all implement the
Endpoint 1 interface, providing a unified interface for accessing the channels of the underlying
infrastructure. This can be a channel, implemented by a JMS queue and accessed through the
JmsEndpoint 2 ,aswellasachannelimplementedasadirectoryinafilesystem,accessedthrough
theFileEndpoint 3 .
3.1.1
Point-to-Point Channel
As mentioned above, the Messaging Channels are not explicitly implemented in Apache Camel
butareprovidedbyComponents.AcommonComponentthatenablesApacheCameltousemany
different messagequeuing systems viaJMS[HBS+] is theJMS Component. The JMS Component
provides PointtoPoint Channels as Endpoints1 on JMSQueues. These Endpoints are refe
rencedviaURIsofthefollowingformat:
org.apache.camel.Endpoint
org.apache.camel.component.jms.JmsEndpoint
3org.apache.camel.component.file.FileEndpoint
1
2
12
3.1MessagingChannels
"jms:queue:myQueueNameA"
AnotherComponentthatoffersPointtoPoint ChannelsisCamelsSEDA Componentwhichof
fersaccesstoinmemoryqueues.
3.1.2
Publish-Subscribe Channel
Like for the PointtoPoint Channel also the PublishSubscribe Channel is provided by Camel
Components.TheJMSComponentprovidesPublishSubscribeChannelsasEndpoints 1 onJMS
Topics[HBS+].TheDirectComponentalsoimplementsaPublishSubscribe Channel,asallCon
sumersregisteredonaDirectEndpointreceiveallmessagessenttothatEndpoint.TheJMSTopics
areaddressedusingEndpointURIsofthefollowingformat:
"jms:topic:myTopicNameA"
3.1.3
Datatype Channel
TheDatatypeChannelisaconceptualpatternwhichadvicestouseseparatechannelsformessages
withseparatedatatypes.ThispatternisnotimplementedinApacheCamel,butofcourseCamel
canbeusedtoimplementthepatternusingaseparatechannelforeachmessagetype.
3.1.4
3.1.5
1
2
org.apache.camel.Endpoint
org.apache.camel.Processor
13
EAIPATTERNSINAPACHECAMEL
CamelcanworkwithseveraldifferentComponentswhereofmostofthemdontuseanunderlying
messagingsystem,itcanmakesensetouseanerrorhandlerthatApacheCamelprovideswhichis
called DeadLetterChannel 1 and that can be used to handle errors which occur while a
Processor is processing a message. In fact Camels DeadLetterChannel is the default error
handlerandisconfigurednottosendmessagestoaparticularDeadLetter Channel,buttotryto
redeliverthemessagessixtimes,waitingforonesecondbetweeneachattempt.
TheDeadLetterChannelisparticularlyusefultohandleerrorsofProducers 2 thatdontusean
underlyingmessagingsystemliketheFileProducer 3 whichcouldraiseanexceptionbecauseit
cantdeliveramessageintoafolderbecauseofmissingwritepermissions.Listing3belowshows
howtosetupaDeadLetterChannelFehler! Textmarke nicht definiert.andconfigurearedeliverypolicythat
retries five times to redeliver messages while increasing the delay between the delivery attempts
exponentially,startingfrom0.5seconds.
1
2
3
4
5
6
7
8
from("myComponent:endpointA")
.process(myCustomProcessor)
.errorHandler(
deadLetterChannel("myComponent:myDeadLetterChannel")
.maximumRedeliveries(5)
.initialRedeliveryDelay(500)
.useExponentialBackOff())
.to("file:/path/to/a/directory/without/writing/permission");
Listing3:DeadLetterChannelfornonmessagingsystemcomponents
3.1.6
Guaranteed Delivery
The Guaranteed Deliver pattern is not implemented inApache Camel either, but is provided by
ComponentsliketheJMSComponentthatusespersistentdeliverybydefault,theFileComponent
that stores messages on a filesystem and the JPAComponent which uses a database table as a
messagequeue.
3.1.7
Channel Adapter
The Channel Adapter pattern is not implemented inApache Camel, the contrary is the case: one
canuseCameltoimplementaChannelAdapterforapplicationsthatarewritteninJavabywriting
codethatsendsmessagestoCamelEndpoints.
org.apache.camel.processor.DeadLetterChannel
org.apache.camel.Producer
3org.apache.camel.component.file.FileProducer
1
2
14
3.2MessageConstruction
3.1.8
Messaging Bridge
ApacheCamelcanalsobeusedtoimplementaMessagingBridge,asCamelsupportsmanydiffer
ent Components and can also use the JMSComponent to connect to most messaging systems.A
Messaging Bridgecanbeimplementedbycreatingsimpleroutingrulesthatconnectthedifferent
channelsofthedifferentmessagingsystemsorevenchannelswhicharenotbasedonmessaging
systems.Listing4belowshowshowtherulesforsuchamessagingbridgewouldlooklike.Ifne
cessaryonecouldevenaddsomecustomProcessors 1 totheroutes,thattransformthemessages
tofittherequirementsofthereceivingmessaginginfrastructure.
1
2
3
from("myJmsComponentA:endpointX").to("myJMSComponentB:endpointX");
from("myJmsComponentA:endpointY").to("myJMSComponentB:endpointY");
from("myJmsComponentA:endpointZ").to("file:/my/path/Z");
Listing4:AMessagingBridgeinApacheCamel
3.1.9
Message Bus
CameldoesntimplementtheMessage Buspattern,ratheritcanbeusedtoimplementamessage
bususinganunderlyingmessagingsystemascommoncommunicationinfrastructureandimple
menting the message routing and message transformation using the various patterns which are
implementedinApacheCamel.AsmentionedaboveCamelcanalsobeusedtoimplementChan
nelAdaptersforthoseapplicationsystemsthatareimplementedinJava.
3.2
Message Construction
TheMessagepatternisimplementedinCamelbytheMessage 2 interface.InCamelmessagesare
alwayswrappedbytheExchange 3 interfacetooffersupportfordifferentmessageexchangepat
ternslikerequestreplyoronewaymessaging.Thesimplestexchangepatternwhichisalsooften
usedistheInOnly 4 patternforonewaymessaging.Inthiscasethemessagecanbeobtainedby
thegetIn()methodoftheExchangeinterface.
org.apache.camel.Processor
org.apache.camel.Message
3org.apache.camel.Exchange
4org.apache.camel.ExchangePattern.InOnly
1
2
15
EAIPATTERNSINAPACHECAMEL
3.2.1
AsHohpeandWoolfindicateintheirbook[HW03]therearenospecialmessagetypesforaCom
mandMessage,DocumentMessageoranEventMessage.Ratherthecontentofamessagemakesit
what it is, i.e. a Command Message is a message that contains a command. Thus Camel doesnt
implementthesepatterns;itisratherthearchitectsliabilitytocreateandusemessagesaccording
tothepatterns.
3.2.2
Request-Reply
TheRequestReplypatternistheoreticallyimplementedbyCamelsExchange 1 interfacewhichis
anabstractionofamessageexchangelikearequestanditscorrespondingreplymessage.Touse
the RequestReply pattern the Exchange, which contains the request message, has to be created
using Camels InOut 2 exchange pattern. Usually this is done by invoking the Endpoints 3
createExchange(ExchangePattern.InOut) method. Exchanges, created using the InOut
exchangepatternshouldthencontaintherequestmessageastheExchanges In 4 messageand
thereceiverthenwritesitsreplymessagetotheExchanges Out 5 message.
AtthetimeofthecreationofthisworkalmostnoComponentsupportstheInOut2exchangepat
tern and thus the RequestReply pattern. The JMSComponent doesnt implement the InOut ex
change pattern, neither does the SEDA Component. Then again the Direct Component does im
plementit,asitsynchronouslypassestheExchangeinstancetothereceiver.Toaddsupportfor
the InOut exchange pattern to a Components Producer 6 , that sends a message and would re
ceive the reply asynchronously, the Producer has to add a Return Address (see 3.2.3 ReturnAd
dress) to the messages header and listen on the corresponding channel. In case of the JMS
Component this could be implemented using the JMSReplyTo header specifying a temporary
JMSdestination [HBS+] the reply is expected on. While waiting for the reply message the
Producerhastoblockaftersendingtherequestmessage.Tosupportalsoasynchronouscallback
as described by Hohpe and Woolf [HW03] a Producer could also implement the
AsyncProcessor 7 interfacewhichofferssuchacallbackmechanism.
Listing 5 below demonstrates how the RequestReply pattern is used inApache Camel.As men
tionedbeforethisexampleonlyworkswithComponentsthatsupporttheInOutexchangepattern.
org.apache.camel.Exchange
org.apache.camel.ExchangePattern.InOut
3org.apache.camel.Endpoint
4Viatheorg.apache.camel.Exchange.getIn()method
5Viatheorg.apache.camel.Exchange.getOut()method
6org.apache.camel.Producer
7org.apache.camel.AsyncProcessor
1
2
16
3.2MessageConstruction
1
2
3
4
5
6
7
3.2.3
Return Address
Asmentionedabove(Chapter3.2.2)theReturnAddressisimplicitlyimplementedbyApacheCa
melsEndpointsProducers 1 .IfmessageexchangesaresentusingtheInOut 2 exchangepattern
whichcorrespondstoarequestreplypair,thentheEndpointsProducerhastotakecareofadd
ingareturnaddresstothemessageheader,listenonthechannelcorrespondingtothereturnad
dressandreturnthereceivedreplymessageviatheExchange 3 interface.
3.2.4
Message Expiration
TheMessage ExpirationpatternisnotimplementedinApacheCamelbutmaybeprovidedbya
Components underlying messaging system. For example the JMSComponent provides message
expiration which can be set either as default for all Endpoints of a JMSComponent via its
setTimeToLive()methodorperEndpointviatheEndpointURIasinlisting6below.
TocorrectlyimplementtheMessage ExpirationpatterntheComponentsConsumer 4 shouldalso
discardexpiredmessages(orputthemonthedeadletterqueue)itreceived.Thisiscurrentlynot
thecaseforCamelsJMSComponent.
....to("jms:queue:myDestination?timeToLive=5000");
Listing6:MessageExpirationforJMSEndpointsinApacheCamel
org.apache.camel.Producer
org.apache.camel.ExchangePattern.InOut
3org.apache.camel.Exchange
4org.apache.camel.Consumer
1
2
17
EAIPATTERNSINAPACHECAMEL
3.2.5
The Correlation Identifier, Message Sequence and the Format Indicator pattern are not imple
mentedinApacheCamel,buttheycanbeimplementedbysettingappropriateheadersonthepro
ducer side and evaluating them on the consumer side. Headers are namevalue pairs, which are
addedtomessagesusingthesetHeader()methodoftheMessage 1 interface.
3.3
Camel supports the PipesandFilters pattern using two different approaches, whereas the ap
proach explained in Camels documentation does not correctly implement the PipesandFilters
pattern. The approach according to Camels documentation makes use of the Pipeline 2 class
whichisofferedbyCamelandwhichisaCamelProcessordelegatingtheprocessingofmessage
exchangestoachainofsubprocessors.WeathertheProcessorsinthePipelineareprocessingmes
sagesasrequestresponse,i.e.usingtheExchangesoutmessage,ormodifytheoriginalmessage,
i.e.theinmessage,doesntmatter,asCamelsPipelinehandlesthisaccordingly.
CamelsJavaDSLalsosupportstheusageofthePipeline2classviathepipeline()methodas
usedinlisting7below.IncontrasttothePipelineclasswhichsupportsalistofProcessors 3 as
members,theJavaDSLspipeline()methodsupportsonlyEndpoints 4 whoseProducersare
usedasmemberProcessorsinthePipeline(seechapter2.2CamelComponentsandEndpointsfor
details about Producers). But this is no drawback, as Camels Direct Component can be used (as
seeninlisting7below)toinvoketheFilterProcessors.CamelsDirectComponentisimplemented
such,thatProducersonDirect EndpointssynchronouslyinvoketheConsumersoftheaccording
Endpoint.CamelsdocumentationsuggestexactlythisimplementationusingthePipelineclass
in conjunction with Direct Endpoints as seen in listing 7 below but this implements the Pipes
andFilters pattern only in the broader sense as the pipe is only implemented as a synchronous
method call and is thus lacking the concept of a queue which would decouple the processing of
onefilteranditspredecessor/successor.Whetherthisisaninmemoryqueueoranentiremessage
oriented middleware wouldnt matter for the correct implementation of this pattern. Tightly
coupledlikethat,onlyonemessagecanbeprocessedbythepipelineatthesametimeinsteadof
beingabletoprocessseveralmessagesinparallel,eachmessagebeinginanotherstage.Thiscould
be compensated by configuring Camel to use several threads for executing the Pipeline. But this
wouldstillnotofferthesamesemanticsasqueuebasedpipeswouldofferandwhichisintended
bythePipesandFilterspattern.
org.apache.camel.Message
org.apache.camel.processor.Pipeline
3org.apache.camel.Processor
4org.apache.camel.Endpoint
1
2
18
3.3PipesandFilters
1
2
3
4
5
6
7
8
9
10
org.apache.camel.Producer
org.apache.camel.processor.Pipeline
3org.apache.camel.Processor
1
2
19
EAIPATTERNSINAPACHECAMEL
1
2
3
4
5
6
7
3.4
Message Routing
CamelsupportsmostMessageRoutingpatternstheyaredescribedinthefollowingsubchapters.
Themosttrivialrouter,whichisafixedrouterthatforwardsallmessagestoafixedoutputchan
nel,isimplementedinApacheCamelbysimpleusageoftheJavaDSLasseeninlisting9below.
This fixed route can be useful if the decoupling of two Endpoints is required, for example to re
servethepossibilitytoreplacethesimpleroutethroughamoresophisticatedRouterlater,orifa
MessagingBridgeistobeimplemented.
from("myComponent:endpointA").to("myComponent:endpointB");
Listing9:FixedrouteinApacheCamel
3.4.1
Content-Based Router
ApacheCamelsupportstheContentBased RouterpatternbytheuseofitsChoiceProcessor 1 ,
whichisimplementedbymanagingalistofFilterProcessors.AFilterProcessor 2 isawrapper
classforProcessorsandalsocontainsaPredicate 3 thatisusedtoevaluateExchanges.TheFilter
ProcessordelegatesthemessageprocessingtoitswrappedProcessoronlyifitsPredicateappliesto
thatmessage.TheChoice ProcessorperformstheroutingbyiteratingtroughitslistofFilter Pro
cessorsandchoosingthefirstProcessorinthelistwhosePredicatematchesthemessagesubjectto
routing.IfnoneofthePredicatesinthelistmatches,theChoiceProcessordelegatestheprocessing
toitsassociatedOtherwiseProcessor.
EventhoughtheChoiceProcessorusesalistofFilterProcessorsforitsimplementation,itcorrectly
implementstheContentBased RouterpatternasitjustusestheFilter ProcessorsPredicateasa
containerforProcessorPredicatepairs.Itsimplementationperformspredictiveroutingasrequired
org.apache.camel.processor.ChoiceProcessor
org.apache.camel.processor.FilterProcessor
3org.apache.camel.Predicate
1
2
20
3.4MessageRouting
bytheContentBased Routerpatternincontrasttoareactivefilteringapproachbytheuseofsev
eral Message Filters. The only critique to Camels implementation is that it discards messages if
noneofthePredicatesmatchandnoOtherwiseProcessorisdefined,insteadofputtingthosemes
sagesonaDeadLetterChannelorhandlingthemsomehow.
CamelalsosupportstheChoiceProcessorviaitsJavaDSLasdemonstratedinlisting10below.
1
2
3
4
5
from("myComponent:endpointA").choice()
.when(myPredicate1).to("myComponent:endpointB")
.when(myPredicate2).to("myComponent:endpointC")
.when(myPredicate3).to("myComponent:endpointD")
.otherwise().to("myComponent:endpointE");
Listing10:ContentBasedRouterinApacheCamel
3.4.2
Message Filter
The Message Filter is implemented in Apache Camel using the FilterProcessor 1 class. As
mentioned above the Filter Processor processes messages only if the associated Predicate 2
matches a message and discards it otherwise. The Filter Processor is also integrated in Camels
JavaDSLusingthefilter()methodsasdemonstratedinlisting11below.
CamelsFilter Processorsupportsonlystatelessfiltering.Ifstatefulfilteringisrequired,asforthe
filteringofduplicatemessages,theFilterProcessorwouldhavetobeextended.Butinthiscasethe
JavaDSLwouldhavetobeextendedtoo,tosupportthestatefulMessageFilteroritwouldhaveto
bewiredtotheEndpointswithouttheuseoftheJavaDSL.
6
7
from("myComponent:endpointA").filter(myFilterPredicate)
.to("myComponent:endpointB");
Listing11:MessageFilterinApacheCamel
3.4.3
Dynamic Router
The Dynamic Router pattern is not implemented at all inApache Camel. It can be implemented
thoughbyextendingtheChoiceProcessor 3 classbyaddingasubprocessorforhandlingcontrol
messagesandbyaddingadynamicrulebasewhichcouldbepersistedforexamplebyusingthe
Java PersistenceAPI (JPA). Even though such a DynamicRouterProcessor would not be sup
org.apache.camel.processor.FilterProcessor
org.apache.camel.Predicate
3org.apache.camel.processor.ChoiceProcessor
1
2
21
EAIPATTERNSINAPACHECAMEL
porteddirectlyinCamelsJavaDSLitcouldstillbeusedintheDSLwithouthavingtomodifythe
DSL. Listing 12 below demonstrates how the use of an extended ChoiceProcessor 1 class
(named DynamicRouterProcessor in the listing), which persists its rule base via the JPA and
usesauniquerulebasenametoidentifyitsassociatedrulebase,couldlooklike.Inthelistingthe
constructortakesEndpointURIsasparametersforthecontrolmessagechannelandtheotherwise
channeltosupporteasyusageinCamelsJavaDSL.Butitshouldbenotedthatforanimplementa
tion to be consistent with Camels architecture, such a DynamicRouterProcessor class should
alsohaveaconstructorthattakesProcessor 2 instancesasparametersinsteadofEndpointURIs.
1
2
3
4
5
from("myComponent:endpointA").process(
new DynamicRouterProcessor("myComponent:controlEndpoint",
"rulebase-test1",
"myComponent:otherwiseEndpoint")
);
Listing12:PossibleimplementationoftheDynamicRouterpattern
3.4.4
Recipient List
ApacheCamelsupportstheRecipientListPatternbyasimpleclass,theRecipientList 3 class,
which implements the Recipient List by using an Expression which evaluates the message ex
changes and outputs a list of recipients as EndpointURIs. The Expression can be created using
any of Camels builtin Expression 4 classes, for example by the XPathExpression 5 class, or
canbeacustomExpressionclass.TheonlyconstraintsuchanExpressionhastofulfillisthatit
hastoreturnthelistinoneofthefollowingformats:
AsaCollection 6 ofEndpoints 7 orofStringrepresentationsofEndpointURIs
AsanArrayofEndpointsorofStringrepresentationsofEndpointURIs
AsaNodeList 8
AsasingleEndpointorasingleStringrepresentationofanEndpointURI
Camels Recipient List implementation iterates through the list gained from the Expression and
sendsacopyofthemessageexchangetoeachchannelrepresentedbyanEndpointinthelist.
Thesendingofthemessagesisimplementedsequentially,dependingontheEndpoints.Aparallel
implementationcouldbeconsidered,whichisnotavailableinApacheCamel.
org.apache.camel.processor.ChoiceProcessor
org.apache.camel.Processor
3org.apache.camel.processor.RecipientList
4org.apache.camel.Expression
5org.apache.camel.model.language.XPathExpression
6java.util.Collection
7org.apache.camel.Endpoint
8org.w3c.dom.NodeList
1
2
22
3.4MessageRouting
IncasetheEndpoints ProducersmodifytheExchangewhileprocessing,likeitcanbethecaseif
the Direct Component is used, then the resulting Exchange of letting a Recipient List process a
message, would be the result returned by the last Endpoint in the list. Even if this possibility is
implemented, it wouldnt be of any use to process the result returned by a Recipient List and is
thususuallynotdone.
CamelsJavaDSLalsosupportsthispatternbyusingtherecipientListmethodasdemonstrat
ed in listing 13 below. Note that for the reasons just mentioned it is not common to append the
to()expressiontotheroutingruleseeninlisting13below.
from("myComponent:endpointA").recipientList(myExpression);
Listing13:RecipientListinApacheCamel
ADynamic Recipient Listasdescribedby[HW03]isnotimplementedinApacheCamel,butthe
existingRecipientListcouldbemadedynamicbyimplementingacustomExpression,whichuses
a persisted rule base that can be modified through control messages to evaluate a message ex
changesimilartotheDynamicRouterdescribedinchapter3.4.3above.
3.4.5
Splitter
The Splitter pattern is implemented in Apache Camel by the Splitter 1 class, using an
Expression 2 to get a list of the split message parts which are then processed by the Splitters
child Processor. Camels Splitter also supports an AggregationStrategy 3 which it uses to
aggregatetheresultsoftheprocessingofthedifferentmessageparts.Thisfeatureisnotpartofthe
Splitterpatternfrom[HW03],butcanbeusefulinconjunctionwithInOut 4 Exchangeswherethe
SplitterreturnstheaggregatedmessageasresponsetoamessagesenttotheSplitter.Thisispar
ticularlyusefulforasimpleimplementationoftheScatterGatherpattern.Astheactualsplittingis
done by an Expression, the Splitter class can be used to implement Iterating Splitters as
well as Static Splitters (see [HW03]). The message parts split by the Expression are then all
processedbytheSplitterschildProcessor,whichmeans,incaseofProducersaschildProcessors,
thatallmessagepartsareaddedtotheProducerscorrespondingMessage Channel.Similartothe
Recipient Lists Expression, also the Expression of the Splitter needs to return a list of message
partswhichhastobeofoneofthefollowingformats:
ACollection 5 ofmessagebodies(i.e.arbitraryJavaObjects)
AnArrayofmessagebodies
org.apache.camel.processor.Splitter
org.apache.camel.Expression
3org.apache.camel.processor.aggregate.AggregationStrategy
4org.apache.camel.ExchangePattern.InOut
5java.util.Collection
1
2
23
EAIPATTERNSINAPACHECAMEL
ANodeList 1
Asinglemessagebody
TheSplittercopiesallheadersfromthesourcemessagetothesplitmessageparts,thusalsoinclud
ingpossiblecorrelationidentifiers,andalsoaddstwonewheaders:
TheSPLIT_SIZE 2 headerwhichindicatesintohowmanypartstheoriginalmessagewassplit.
The SPLIT_COUNTER 3 header which is a sequence number ranging from zero to
(SPLIT_SIZE2 1),andindicatestheorderofthemessageparts,originatingfromthesame
sourcemessage.
Thefactthatthemessageheadersarecopiedandthatthetwomentionedheadersareadded,can
simplifythetaskoftheAggregatorifusedinconjunctionwiththeSplitterpatterntoimplement
theScatterGatherpattern.
LiketheRecipientList,theSplitterprocessesthemessagepartsinsequence,butespeciallyifcom
plexmessageProcessors(i.e.longrunningones)areused,itisdesirablethatallmessagepartsare
processed in parallel. Parallel processing is not implemented in Camels Splitter, but can be
achieved using Producers of Endpoints as Processors that run quickly to decouple the message
Processors from the Splitter. For example the SEDAComponent that uses inmemory queues or
theJMSComponentthatjustsendsamessageusingitsunderlyingmessagingmiddlewarecould
be used.And despite the parallel processing, the PipesandFilters architecture requires anyway
thedecouplingoftheSplitterfromitsfollowingProcessors(i.e.filters).
Like the other patterns also the Splitter is integrated in Camels Java DSL and can be used with
eitheracustomExpressionorwithanExpressioncreatedbyCamelsbuiltinexpressionlanguag
es.Listing14belowshowshowtheSplitterisusedwithCamelsJavaDSL.
1
2
3
from("myComponent:endpointA")
.splitter(mySplitterExpression)
.to("myComponent:endpointB");
Listing14:SplitterinApacheCamel
3.4.6
Aggregator
TheAggregatorpatternisnotfullyimplementedinApacheCamel,butCamelcanbeextendedto
fully support the Aggregator pattern. Camels Aggregator is implemented in the Aggregator 4
classwhichis,unlikemostotherpatternimplementationsbyCamel,aPollingConsumerthatthus
runsinitsownthread.CamelsAggregatorusesaCorrelationExpressiontocorrelatetheincoming
org.w3c.dom.NodeList
org.apache.camel.processor.Splitter.SPLIT_SIZE=org.apache.camel.splitSize
3org.apache.camel.processor.Splitter.SPLIT_COUNTER=org.apache.camel.splitCounter
4org.apache.camel.processor.Aggregator
1
2
24
3.4MessageRouting
messagesandthusforbeingabletodecidewhichmessagesbelongtogetherandshouldbeaggre
gated. The Correlation Expression can be any Expression 1 and needs to return an arbitrary
Object 2 thatuniquely identifies the group of messages toaggregate. This Correlation Identifier
Objectreturnedneedstobeequal,inthesenseoftheObjectsequals()method,toallother
Objectsreturnedformessagesthatbelongtogether.CamelsAggregatorperformstheactualag
gregationofthemessagesthroughtheAggregationStrategy 3 interfacewhoseaggregate()
methodneedstobeimplementedtosupplytheAggregatorwithanaggregationstrategy.Theag
gregationstrategyisusedbyinvokingtheaggregate()methodwithtwoparameterseachtime
a new message arrives. One parameter is the current aggregate (i.e. the Exchange 4 which
representsthemessageswithacertainCorrelation Identifierthathavebeenaggregatedtillnow)
andtheotheristhenewlyarrivedExchange4.Theaggregate()methodthenreturnsthenew
aggregate.
ThethirdpropertyofanAggregator,besidesthemessagecorrelationandtheaggregationstrategy,
isthecompletenessconditionwhichisnotimplementedinCamelsAggregator.Camelaggregates
messagestilladefinedamountofmessagesarrivedortilladefinedamountoftimepassed.Butas
themessagecounterandthetimeoutarecommontoallarrivingmessages,insteadofhavingsepa
rateonesforeachaggregate,thisdoesntevenimplementabasiccompletenessconditionbecause
the decision whether an aggregate is complete, does neither depend on how many messages ar
rivedforanaggregate, nor on howlong itis ago that the first messagearrived for an aggregate.
Thusfromanaggregatespointofviewthecompletionissomehowrandom.
To implement a completeness condition the Aggregator 5 can be extended by using a custom
AggregationCollection 6 .TheAggregatorusestheAggregation Collectiontostorehisaggre
gates,anditeratesthroughthecollectionafterthedefinedamountofmessagesarrivedorafterthe
defined amount of time passed, sending all aggregates of the collection to its sub processor. The
Aggregation Collection thereby makes use of the Correlation Identifier Expression and the Ag
gregationStrategymentionedabove.
One way to add a completeness condition to the AggregationCollection could be to extend
the AggregationCollection and to expose only aggregates that are complete, according to a
completeness condition, which could be implemented using Camels Predicates 7 . Using this
approach only the messages exposed to the Aggregator and thus only the complete aggregates
wouldbeforwardedtotheAggregatorschildProcessor 8 .
AnothershortcomingofCamelsAggregatorimplementationisthatitdoesntsupportapersistent
state, namely it doesnt include a persistent implementation of the AggregationCollection.
This shortcoming could also be fixed by developing a custom implementation of the
org.apache.camel.Expression
java.lang.Object
3org.apache.camel.processor.aggregate.AggregationStrategy
4org.apache.camel.Exchange
5org.apache.camel.processor.Aggregator
6org.apache.camel.processor.aggregate.AggregationCollection
7org.apache.camel.Predicate
8org.apache.camel.Processor
1
2
25
EAIPATTERNSINAPACHECAMEL
AggregationCollection myAggregationCollection
= new MyAggregationCollection(myCorrelationExpression,
myAggregationStrategy,
myCompletnessConditionPredicate);
Aggregator myAggregator
= new Aggregator(getEndpoint("myComponent:endpointA"),
getEndpoint("myComponent:endpointB")
.createProducer(),
myAggregationCollection);
Listing15:ApacheCamelsAggregatorwithacustomAggregationCollection
3.4.7
org.apache.camel.processor.aggregate.AggregationCollection
org.apache.camel.Predicate
3org.apache.camel.Service
1
2
26
3.5MessageTransformation
3.5
Message Transformation
MessageTransformation,andthustheMessageTranslatorpattern,issupportedbyApacheCamel
in several different ways and for several different levels of transformation. Transportlevel trans
formationisimplicitlydonebyApacheCamelsComponents.Datarepresentationleveltransforma
tion is supported by Apache Camels Type Converter (see chapter 2.2.3 Camel Type Converter
above)forsimpledatatypetransformationandbyCamelsDataFormat 1 interface,whichoffersa
pluginstrategyforthemarshallingandunmarshallingofmessages.
Data type and data structure level transformations are supported in Camel by using custom
Processors 2 whichallowthetransformationofmessagesusingarbitraryJavacodeorbyusing
an Expression whose result replaces the old message body. Listing 16 below demonstrates both
approaches.
1
2
3
4
5
6
7
8
9
3.5.1
Envelope Wrapper
TheEnvelopeWrapperpatternisimplementedinApacheCamelbyitsComponents.Ifamessaging
system or a transport protocol requires a special message format, its the corresponding Compo
nentstasktowrapthemessagesothatthemessageiscomplianttotheinfrastructuretheCompo
nentinterfacesto.ForexampletheJMSComponentwrapsaCamelmessageinaJMSmessageand
also adds the Camel message headers as JMS properties to the JMS message. If application level
wrappingofmessagesisneededitcanbeimplementedbythesametechniquesdescribedinchap
ter3.5above.
1
2
org.apache.camel.spi.DataFormat
org.apache.camel.Processor
27
EAIPATTERNSINAPACHECAMEL
3.5.2
Content Enricher
TheContentEnricherpatternisnotimplementedinApacheCamel.ThebestwaytoaddaContent
EnrichertoCamelistocreateacustomProcessor 1 whichisableofcollectingtherequireddata
needed for the enriching of the messages. For example the custom Processor could connect to a
database system orinvoke a web service to get the required data. By using the latterapproacha
custom Processor could be implemented that is generic enough to be reusable. Such a Processor
couldinvokeawebservicebysendingincomingmessagestothewebservicewhichthenreturns
therequiredinformationthatcanthenbeusedinanXSLtransformationtogetherwiththeoriginal
messagetogeneratetheenrichedmessage.Listing17belowshowshowsuchanimplementation
couldbeintegratedinCamelsJavaDSL
1
2
3
4
5
6
7
8
9
Processor myContentEnricher
= new MyContentEnricher(myWebserviceWsdlUrl,
myServiceName,
myPortName,
myXsltUrl);
from("myComponent:endpointA")
.process(myContentEnricher)
.to("myComponent:endpointB");
Listing17:PossibleContentEnricherimplementationinApacheCamel
3.5.3
Content Filter
TheContent FilterisnotexplicitlyimplementedinApacheCamelbutthesamegeneralmessage
transformationtechniquesdescribedinchapter3.5abovecanbeusedtoimplementaContentFil
ter. Particularly the use of an Expression 2 to filter content of a message provides a simple ap
proach to a Content Filter where the Expression would return the filtered content. For example
Camels builtin XPathBuilder 3 could be used to filter message content according to an XPath
expression.Listing18belowdemonstratessuchascenarioinCamelsJavaDSL.
10
11
12
from("myComponent:endpointA")
.setBody(XPathBuilder.xpath("/my/xpath/expression"))
.to("myComponent:endpointB");
Listing18:ContentfilteringusinganXPathexpressioninApacheCamel
org.apache.camel.Processor
org.apache.camel.Expression
3org.apache.camel.builder.xml.XPathBuilder
1
2
28
3.5MessageTransformation
3.5.4
Claim Check
Apache Camel doesnt implement the Claim Check pattern, but can be extended to support this
pattern. Unlike for the Content Filter pattern a custom Processor 1 implementation should be
used, as it would be bad design to develop a custom Expression 2 that has side effects like the
storage of the filtered data.A Processor, filtering the content, would need to store the filtered
contentpersistentlytobeabletoretrieveitlater,forexampleitcouldstorethefilteredcontentina
database which could be accessed using the Java Persistence API [DK06]. Also a unique key to
identifythefilteredcontentisneeded,thathastobeeitheralreadypresentinthemessageorgen
erated.
A general implementation of the Claim Check could use three Expressions to identify the re
movedcontent,thecontenttokeepandtheuniquekey,whichalsocanbegenerated.Alessgeneral
implementation that knows about the format of the messages could be implemented using only
one Expression and compute all other necessary information. For example, one that can only
handleXMLdataandusesanXPathExpressiontoidentifythecontenttofilter,andwherethefil
teredmessagecontentiscomputedandtheuniquekeyisgenerated.
Such general implementations would require each instance to have its own storage, especially in
the case of generated keys, so that the filtered content of the different instances is not mixed.
Listing 19 below shows how such a general implementation of the Claim Check pattern, which
handles XML messages, uses an XPath expression to identify the data to filter and identifies its
persistentstorageviaauniquestring,couldbeusedinCamelsJavaDSL.
1
2
3
4
5
6
7
Processor myClaimCheck
= new MyClaimCheck ("/my/xpath/expression",
"myClaimCheck1");
from("myComponent:endpointA1")
.process(myClaimCheck)
.to("myComponent:endpointB1");
Listing19:PossibleClaimCheckimplementationinApacheCamel
3.5.5
Normalizer
TheNormalizerisnotimplementedinApacheCamel,butasitisacomposedpatternconsistingof
aContentBasedRouterandseveralMessageTranslators,itcanbeimplementedbyusingCamels
1
2
org.apache.camel.Processor
org.apache.camel.Expression
29
EAIPATTERNSINAPACHECAMEL
implementationofthosepatterns.BecausetheNormalizerisaseparatepatternandthusitscom
ponentscanandshouldbetightlycoupled,onecouldrenouncetheusageofpipes,i.e.ofchannels,
(see chapter 3.3 Pipes and Filters above) between the ContentBased Router and the Message
Translators. A Normalizer would then be configured in Camels Java DSL as demonstrated in
listing20below.
1
2
3
4
5
6
7
8
9
10
11
from("myComponent:endpointA").choice()
.when(myMessageFormat1Predicate)
.process(myXformProcessor1).to("myComponent:endpointB")
.when(myMessageFormat2Predicate)
.setBody(myXformExpression2).to("myComponent:endpointB")
.when(myMessageFormat3Predicate)
.process(myXformProcessor3).to("myComponent:endpointB")
.when(myMessageFormat4Predicate)
.setBody(myXformExpression4).to("myComponent:endpointB")
.otherwise()
.to("myComponent:invalidMessageChannel");
Listing20:NormalizerinApacheCamel
3.6
3.6.1
Messaging Endpoint
Messaging Gateway
Apache Camel itself provides a lowlevel Messaging Gateway as it abstracts from the infrastruc
tureandmessagingsystemswhichApacheCamelsComponentsinterfacewith.Cameloffersgen
eralmessagingsemanticsthroughgenericinterfacesthatcanbeusedindependentlyfromtheun
derlyingmessaginginfrastructure.IncaseoftheJMSComponentCamelsimplyusestheJMSAPI
[HBS+],whichisalsoalowlevelMessagingGateway.
Camels documentation mentions that the Messaging Gateway is supported using Camels Bean
Component which offers the ProxyHelper 1 class that can generate proxyclasses to invoke me
thods on remote JavaBeans (i.e. remote Java classes). But as the proxy offers only synchronous
remoteinvocationviamessaging,andasthegeneratedproxyclassdoesntperformanyerrorhan
dlingbutexposestheapplicationtomessagingspecificexceptions,thisapproachisonlysuitableto
implementverybasicMessaging Gateways.ButApacheCamelcanbeusedtoimplementhigher
levelMessagingGatewaysthathidethemessagingsemanticsfromanapplication,bydevelopinga
domainspecificAPIthatusestheCamelAPItosendmessages.Bothapproachesareonlypossible
ofcourse,iftheapplication,wewanttoprovideagatewayfor,iswritteninJava.
org.apache.camel.component.bean.ProxyHelper
30
3.6MessagingEndpoint
3.6.2
Messaging Mapper
The Messaging Mapper pattern is not implemented inApache Camel, but Camel can be used to
implementaMessaging MapperifthetargetapplicationisaJavaapplicationbyprovidingauni
fied interface to different messaging infrastructures. For example the Messaging Mapper could
implement Camels Processor 1 interface that handles incoming message exchanges and map
themtoapplicationspecificevents.
3.6.3
Polling Consumer
ThePollingConsumerpatternisimplementedinApacheCamelbythePollingConsumer 2 inter
face which offers blocking as well as nonblocking methods to poll for new messages.
PollingConsumer 3 instances are obtained using the createPollingConsumer() method of
the Endpoint 4 interface as Camels Java DSL doesnt offer support for Polling Consumers yet.
Listing21belowdemonstrateshowapollingconsumerthatpollsfornewmessagesinablocking
wayisimplementedinCamel.NotethatthePollingConsumeronendpointscreatedbyCamels
JMSComponent has a bug that makes the blocking receive() method, used in the example
below, act like a nonblocking receive, which means that the method might return immediately
withanullvalueasresult.
1
2
3
4
5
6
3.6.4
Event-Driven Consumer
org.apache.camel.Processor
org.apache.camel.PollingConsumer
3org.apache.camel.PollingConsumer
4org.apache.camel.Endpoint
5org.apache.camel.Processor
6org.apache.camel.Consumer
1
2
31
EAIPATTERNSINAPACHECAMEL
CamelbecauseCameloffersaThreadProcessorwhichallowspoolingandmanagementofthe
threads that are used to process messages by a Processor. But note that although Camels
Consumers 1 usetheProcessorinterfacetonotifytheattachedmessageprocessorsofincoming
messagesand thus seemto make these message processors EventDriven Consumers they inter
nally implement the Polling Consumer pattern. This is for example true for the FileComponent
andtheSEDAComponentbutnotfortheJMSComponent.Listing22belowdemonstrateshowan
EventDrivenConsumerisimplementedinCamel.
1
2
3
4
5
from("myComponent:endpointA").process(new Processor() {
public void process(Exchange exchange) {
// process message here
}
});
Listing22:EventDrivenConsumerinApacheCamel
3.6.5
Competing Consumers
Competing ConsumerscanbeimplementedinApacheCamelbysimplycreatingtworoutesthat
havethesameendpoint,whichhastobeanendpointonaPointtoPointChannel,astheirincom
ing channel. The JMSComponent also supports the Competing Consumer pattern using a single
routeif the incoming JMSEndpoint is configuredto support concurrent consuming,as done for
theendpointinlisting23below.
6
from("jms:queue:myQueueA?concurrentConsumers=5").process(myProcessor);
Listing23:CompetingConsumerusingtheJMSComponentinApacheCamel
3.6.6
Message Dispatcher
TheMessage DispatcherpatternisnotimplementedinApacheCamel,butcouldbeimplemented
by developing a custom Processor 2 that delegates the message processing to some child
Processorsthatrunintheirownthread.Thepatterncanalsobeimplementedbycombininga
ChoiceProcessor 3 , which basically implements a Content Based Router and a
ThreadProcessor 4 which enables asynchronous processing of its child Processors using a
thread pool. Because a Consumer is only done processing a message when the whole route has
Consumersarecreatedviaorg.apache.camel.Endpoint.createConsumer(Processor processor)
org.apache.camel.Processor
3org.apache.camel.processor.ChoiceProcessor
4org.apache.camel.processor.ThreadProcessor
1
2
32
3.6MessagingEndpoint
been processed (see chapter 2.2.7 above for details) the Message Dispatcher can only be imple
mented if the incoming Endpoint support Competing Consumers, as the JMSComponents End
points do, if configured appropriately. Note that using asynchronous processing doesnt change
thisbehavioritjustpreventstheConsumersthreadfromblocking.Allthisisalsotrueforacus
tom implementation of a Message Dispatcher as a custom Processor, as long as the Processor
behaves like intended by Camels architecture. This means it should return only after the
Processor,itdispatchedto,returnedtoo.Butifneeded,thatrulecouldbeviolatedandthecus
tomProcessor 1 couldreturnfromtheprocess()methodwithoutwaitingforthecompletion
of its child processor. The drawback would be thatInOut 2 message exchanges wouldnt be sup
portedbysuchaRouteandthattheDispatcherwouldsuccessfullyconsumemessagesbeforethe
processingiscompleteandthusbeforethemessagehasbeenaddedtothefollowingchannel.This
couldcausemessagestogetlostincasetheDispatchercrashes.
Another approach could be to implement a custom Message Dispatcher as a Polling Consumer.
Heretherestrictionsjustmentioneddontapply,asthePolling ConsumerdoesntsupportInOut
exchangesanywayandthemessagesareimmediatelyconsumedanywaybythePollingconsumer,
unlessanacknowledgementmechanismliketheoneofJMSisused.ThussuchaDispatchercould
delegatetheprocessingtoitschildProcessorsinseparatethreads.
Listing24 below demonstrates howaMessage Dispatcher can be implemented inApacheCamel
usingaContentBased RouterandanEndpointthatallowsCompeting Consumers,asmentioned
before.
1
2
3
4
5
6
7
8
from("jms:queue:myDestination?concurrentConsumers=5").thread(5).choice()
.when(header("type").isEqualTo("A"))
.process(myProcessorForTypeA)
.when(header("type").isEqualTo("B"))
.process(myProcessorForTypeB)
.when(header("type").isEqualTo("C"))
.process(myProcessorForTypeC)
.otherwise().to("jms:queue:myInvalidMessageQueue");
Listing24:MessageDispatcherusingaContentBasedRouter
3.6.7
Selective Consumer
TheSelectiveConsumerpatternisnotimplementedinApacheCamelanditcantbeimplemented
withoutsupportbytheunderlyingmessagingsystem.Iftheusedmessagingsystemandthecor
respondingCamelComponentsupporttheSelective Consumerpattern,asthisisthecaseforthe
JMSComponent,thentheEndpointhasjusttobeconfiguredaccordinglyusuallyviaitsURI.If
themessagingsystemdoesntsupporttheSelectiveConsumerpatternbutsupportsmessagepeek
1
2
org.apache.camel.Processor
org.apache.camel.ExchangePattern.InOut
33
EAIPATTERNSINAPACHECAMEL
ing, i.e. the receiving of a message without to consume it, the pattern could be implemented by
extendingaComponentwiththeavailabilitytopeekformessagesthatmatchsomeExpressionand
to deliver and consume only those. If the Message Channel is a PublishSubscribe Channel the
SelectiveConsumercanalsobeimplementedwithoutsupportbythemessagingsystem,byusinga
MessageFilter.Ifthemessagingsystemdoesntsupportselectiveconsumersnormessagepeeking
and the channel is not a PublishSubscribe Channel, then a Message Dispatcher could be consi
deredinsteadofaSelectiveConsumer.
AsJMSsupportstheSelective Consumerpatternbyusingaselector,whichisaSQL92predicate
onmessageheaderscalledpropertiesinJMS.AndastheJMSComponentsupportsthisfeature,
theSelectiveConsumerpatterncanbeimplementedonJMSEndpointsasdemonstratedinlisting
25below.NotethattheselectorhastobeescapedfortheendpointURItobevalid.
1
2
from("jms:queue:myDestination?selector=type%3D%27A%27")
.process(myProcessor); // selector: type=A
Listing25:SelectiveConsumerusingApacheCamelsJMSComponent
3.6.8
Durable Subscriber
LiketheSelectiveConsumer,theDurableSubscriberisamessagingsystemspecificpatternandis
implemented for example in Camels JMSComponent. Listing 26 below demonstrates how an
EndpointonaJMStopiccanbemadeaDurableSubscriber.Notethat,whenusingJMSdirectly,a
uniqueclientIDandauniquesubscriptionnamemustbeprovidedtoregisterasaDurable Sub
scriber.IfaComponentdoesntsupportDurableSubscribers,Camelcanalsobeusedtoimplement
a Durable Subscriber by creating a route from a PublishSubscribe channel to a PointtoPoint
Channel,fromwhichtheclient,thatneedsadurablesubscription,canreceiveitsmessages.
3
4
from("jms:queue:myDestination?clientId=myClientId1&durableSubscriptionNam
e=mySubscriptionName1").process(myProcessor);
Listing26:DurableSubscriberusingApacheCamelsJMSComponent
3.6.9
Idempotent Receiver
org.apache.camel.processor.idempotent.IdempotentConsumer
org.apache.camel.Expression
3org.apache.camel.processor.idempotent.MessageIdRepository
1
2
34
3.6MessagingEndpoint
forlater comparison withincoming messages.A simple Expression could just returna messages
uniquemessageIDwhichisoftengeneratedbythemessaginginfrastructure.Usingthesetwogen
eral interfaces Camels Idempotent Receiver can be adapted to fit the current requirements. The
implementation of the MessageIdRepository interface, that Camel offers, is an inmemory
basedimplementationthatalsoallowsthesettingofamaximumcachesize.Ifpersistentstorageof
the receive message identifiers is required, a custom implementation of the
MessageIdRepository interface storing the values can be used. Listing 27 below shows how
CamelsIdempotent ReceivercanbeconfiguredusingCamelsJavaDSL.Inthisexamplethemes
sages "MyMessageId"header is used as unique identifier and Camels inmemory
MessageIdRepository with a maximum capacity of 100 entries isusedfor storing these iden
tifiers.
1
2
3
4
5
from("myComponent:endpointA")
.idempotentConsumer(header("MyMessageId"),
MemoryMessageIdRepository
.memoryMessageIdRepository(100))
.process(myProcessor);
Listing27:ApacheCamelsIdempotentReceiver
org.apache.camel.component.bean.BeanProcessor
35
EAIPATTERNSINAPACHECAMEL
1
2
3
4
5
6
7
from("myComponent:endpointA")
.to("bean:myService?methodName=myMethod")
.to("myComponent:endpointB"); // using the Bean-Component
from("myComponent:endpointC")
.bean(new MyService(), "myMethod")
.to("myComponent:endpointD"); // using the BeanProcessor
Listing28:TheServiceActivatorpatterninApacheCamel
36
Implementation
In chapter 3 the Enterprise Application Integration (EAI) Patterns from [HW03] were evaluated
regardingifandhowtheyareimplementedinApacheCamel.Inthispartoftheworktheresults
fromchapter3areusedtoextendtheEclipsebasededitorwhichwascreatedaspartofthediplo
ma thesis from [Dru07]. This Eclipse based editor was developed as an Eclipse plugin which
enablesthegraphicalmodelingofmessagingsystems.Thegraphicaleditorallowscombiningthe
differentEAIpatternstomodelamessagingsystemthatimplementsthePipesandFiltersarchi
tecture.ThismessagingsystemmodelisthenusedtogenerateaWSBPEL[AAA+07]processthat
implementsthemessagingsystemmodeled.ThegeneratedWSBPELprocessuseswebservicesto
providemostofthefunctionalityofferedbythedifferentpatternsandinturnofferstheexecution
ofthatprocessaswebservice.
ThegoalofextendingtheEclipseplugin,developedbyDruckenmller[Dru07],istoaddtheabili
ty to generate Apache Camel based Javacode out of the messaging system modeled. This Java
codeshallimplementastandaloneapplicationthatusesanunderlyingmessageorientedmiddle
waretoimplementtheMessage ChannelsandthatusesApacheCameltoimplementtherouting
andthetransformationlogicaswellasthemessageendpoints.
LikethegeneratedWSBPEL[AAA+07]process,alsothegeneratedCamelbasedapplicationshall
usewebservicestosupportthevariousEAIpatternimplementations.Althoughthemodeledmes
sagingsystemwouldntneedtoofferitsfunctionalityaswebservice,becauseitcouldinteractwith
theoutsideworldusingmessaging,thesolutiondevelopedinthisworkshallalsobeabletopro
videitsfunctionalityasawebservice.Thereasonthesolutionhastobeabletodoso,isthatthe
generatedJavaapplicationshouldhavethesamesemanticsandinterfacestotheoutsideworldas
theWSBPELprocessgeneratedbytheEclipseplugin.
4.1
Concept
org.apache.camel.Processor
37
IMPLEMENTATION
TofillthegapbetweentheJavacodecentricpatternimplementationofCamelandthewebtech
nologybasedimplementationof[Dru07]aframeworkisbeingdeveloped.Thisframeworkconsists
ofclassesthatimplementthedifferentEAIpatternsorsupportCamelsimplementationofthepat
terns.TheseclassesareallbasedonCamelandaimtoextendCamelinaconsistentandreusable
fashion, while using web based technology like XPath, XSLT and web services to implement the
patterns.Usingthesetechnologiesaddstheconstraint,thatallprocessedmessageshavetobeXML
messages.ButasXMLisawidelyacceptedstandardthisisnodrawbackinthesenseofcompatibil
itywithothersolutions.
Byusingthisframework,theJavacodegenerationprocess,whichistheactualgoalofextending
the Eclipse plugin, is reduced to the generation of Javacode that instantiates the classes of the
frameworkcorrespondingtothepatterns.Theclassesareinstantiatedusingtheparametersofthe
correspondingpatternandareconnectedbybuildingApacheCamelRoutes.
TheextensionoftheEclipsepluginfrom[Dru07]isdonebyaddingacustomsocalledActionDe
legate 1 tothepluginwhichiteratesthroughthemodeledmessagingsystemandtherebygenerates
theappropriateJavacode.Becausethetimeconstraintsonthisworkdontallowtheimplementa
tionofallEAIpatterns,thecodegenerationisbeingimplementedinanextensiblefashiontoallow
easy completion by future works. Thecode generation being done by an Eclipse plugin and Ec
lipse being also a Java development environment just calls for an implementation that generates
theJavacodeusingEclipsesJavaDevelopmentTools[Jdt].ThatwayaJavaprojectiscreatedin
sideEclipsecontainingapackagewiththegeneratedJavacode.BeinggeneratedasaJavaproject
inEclipse,themessagingsystemcanconvenientlybemodifiedandbuildinsideofEclipse.
4.2
Used Technologies
The implementation, done in this work, uses several technologies. These technologies were used
together withApache Camel to implement the framework mentioned above as well as to imple
ment the code generator. In the following these technologies exceptApache Camel, which was
describedinitsownchapteraredescribed:
JAX-WS 2.0
TheJavaAPIforXMLBasedWebServices(JAXWS)[CHM06]offersastandardizedinterfacefor
invokingandprovidingwebservicesusingtheJavaprogramminglanguage.JAXWSoffersahigh
levelandalowlevelAPI,wherethehighlevelAPIcanbeusedtocomfortablyinvokeorprovidea
webservicebybindingaJavainterfacetoawebservicedefinedinaWSDLfile[BL07].Thehigh
levelAPI handles things like type conversion and enables the programmer to use a web service
throughasimplemethodcall,ortoprovideawebservicebysimplyimplementingaJavamethod.
The lowlevel API provided by JAXWS enables the programmer to work on the message level.
HereawebservicecanbeinvokedbycreatingeitheracompleteSOAPmessage[ML07]orbyjust
org.eclipse.ui.IWorkbenchWindowActionDelegate
38
4.3TheEAI2CamelFramework
providing the message payload (i.e. the message body) and letting JAXWS handle the message
headers.ThelowlevelinvocationofwebservicesisofferedbyJAXWSsService 1 interface.Pro
vidingawebserviceusingJAXWSslowlevelAPIenablestheimplementertoworkonthemes
sagelevelinthesamewayasforthelowlevelinvocation.Thismeansthatthewebserviceprovid
ercaneitherworkwiththewholemessageorjustwiththemessagepayload.Suchalowlevelweb
serviceproviderneedstoimplementJAXWSsProvider 2 interface.
JAXP 1.4
TheJavaAPIforXMLProcessing(JAXP)offersseveralAPIsforthevalidation,parsing,transfor
mationandextractionofcontentfromXMLdocuments.Intheframework,implementedaspartof
this work, XML transformation using XSLT [Cla99] stylesheets is done using JAXPs XML trans
formation API located in the javax.xml.transform package. This is the main technology used to
implement the Message Translator pattern and isalso used frequently in thisframework in con
junctionwiththeinvocationofwebservices.AnotherJAXPAPIfrequentlyusedinthisframework
isJAXPs XPathAPI which is foundin the javax.xml.xpath package. ThisAPI is used to evaluate
XPathexpressions[CD99]toselectaspecificportionofanXMLdocument.
4.3
TheEAI2CamelframeworkwasimplementedtofillthegapbetweentheJavacodecentricpattern
implementationofCamelandthewebtechnologybasedimplementationof[Dru07].Itconsistsof
severalclasses,eitherimplementingoneoftheEAIpatternsorsupportingtheimplementationof
theEAIpatterns.
1
2
javax.xml.ws.Service
javax.xml.ws.Provider
39
IMPLEMENTATION
4.3.1
Helper Classes
The framework contains some helper classes that are used to support the implementation of the
patterns in the framework. One of these helper classes is the Eai2CamelNamespaceContext 1
whichisasimpleimplementationofJAXPsNamespaceContext 2 interface.Thisinterfaceisused
byJAXPtoresolvenamespaceprefixesusedforexampleinXPathexpressions.
ThesecondhelperclassistheWebServiceFilter 3 classthatisthebasicclasswhichisextended
by all patterns that invoke a web service in their implementation. The WebServiceFilter im
plementsCamelsProcessor 4 interfaceandisthusanEventDrivenConsumer.ItusesJAXWSs
lowlevelAPItoinvokeawebservicebysendingtheincomingmessagesasthemessagebodyof
thewebserviceinvocation.Becauseawebserviceinvocationcantakesometime,thewebserviceis
invoked asynchronously. It is using JAXWSs callback mechanism to get notification about the
completionoftheinvocation.FortheProcessornottoblockwhilethewebserviceisinvoked,the
WebServiceFilteralsoimplementsCamelsAsyncProcessor 5 interface,whichenablesCamel
to invoke the WebServiceFilter asynchronously. This enables the complete asynchronous
processingofmessages.TheWebServiceFilteralsousesJAXPsmessagetranslatortotranslate
theresponsemessageofthewebserviceinvocationtoadifferentJavatype,requiredbytheimple
mentation. Here the identity transformation is done, but classes extending the
WebServiceFiltermightchoosetotransformaccordingtoanXSLTstylesheet.
Despite the WebServiceFilter being used to implement the EAI patterns that are using web
servicesfortheirimplementation,italsoimplementsapartoftheExternalServicepatternintro
ducedby[Dru07].ThisExternalServicepatternisbasicallyafilterinthePipesandFiltersarchi
tecturethatisimplementedbyawebservice,i.e.thewholemessageisprocessedbythewebser
vice. In addition to the invocation this External Service pattern also allows to provide a web
servicetotheoutside.ThisisnotimplementedbytheWebServiceFilterbutbytheWebService
Providermentionedbelow.
The framework also contains the Eai2CamelContext 6 class which extendsApache Camels de
faultimplementationoftheCamel Context.ThisextendedCamel Contextallowsaddingservices,
i.e. classes implementing Camels Service 7 interface, to the Camel Context. These Services life
cyclewillthenbemanagedbytheCamel Contexttogetherwithitsownlifecycle.Particularlythe
Camel Contextwillstarttheservicesafteritwasstarteditselfandwillstopthembeforestopping
itself.
de.unistuttgart.iaas.framework.eai2camel.Eai2CamelNamespaceContext
javax.xml.namespace.NamespaceContext
3de.unistuttgart.iaas.framework.eai2camel.WebServiceFilter
4org.apache.camel.Processor
5org.apache.camel.AsyncProcessor
6de.unistuttgart.iaas.framework.eai2camel.Eai2CamelContext
7org.apache.camel.Service
1
2
40
4.3TheEAI2CamelFramework
4.3.2
Theframeworkoffersamessageproducertemplatethatfacilitatesthecreationofamessagepro
ducer. Itis provided by the abstract class MessageProducerTemplate 1 which extends Camels
CamelTemplate 2 andimplementstheService 3 interfaceenablingCameltomanageitslifecycle.
ClassesextendingtheMessageProducerTemplateneedtoimplementtherun()methodfrom
theRunnableinterfacewhichisinvokedinaseparatethreadwhentheCamel Contextisstarted.
Theimplementationoftherun()methodmustregularly,inparticularbeforeproducingmessages,
checkiftheCamelContextisstillrunningbyusingtheisRunAllowed()method.Theadvantage
ofthismessageproducertemplateisthatitprovidesseveraleasytousemethodstosendmessages
tosomeEndpoint.Theexampleinlisting29belowdemonstratesanimplementationoftherun()
method which sends messages to the default Endpoint, passed to the constructor of this
MessageProducerTemplateinstance.
1
2
3
4
5
6
7
8
4.3.3
TheEAI2CamelframeworkalsoaddsanewEndpointtoApacheCamelthatcanbeusedtoin
vokewebservices.TheWebServiceEndpointworksinasimilarwayastheWebServiceFilter
class mentioned in chapter 4.3.1 above. It also uses JAXWSs Service class to invoke the web
serviceasynchronouslyandJAXPtotransformtheresponsemessagetoarequiredtype.TheWeb
ServiceEndpointisimplementedusingthreeclasses,onefortheEndpoint,onefortheConsumer
and one for the Producer. The implementation is located in the following package:
de.unistuttgart.iaas.framework.eai2camel.component.ws.
Note that this is just theimplementation ofan Endpoint not of a complete Component. Thus the
useofURIstocreateWeb Service Endpointsisnotsupported.AfutureworkcouldcreateaWeb
Service Component which would enable Apache Camel to use web services as a channel. This
couldbeusefulforexampletoperformtransformationonthewirebyawebserviceortoimple
mentaMessageChannelthatprovidesGuaranteedDeliveryusingawebservice.ThisComponent
couldalsoaddtheabilitytoprovideawebservicetotheoutsideworldwhichisimplementedus
de.unistuttgart.iaas.framework.eai2camel.endpoint.MessageProducerTemplate
org.apache.camel.CamelTemplate
3org.apache.camel.Service
1
2
41
IMPLEMENTATION
4.3.4
TheEAI2CamelframeworkenablesApacheCameltoofferawebservicewhichisimplemented
byprocessingamessagethroughaCamelRoute.AstheWebServiceProvideroffersawebservice
totheoutsideitisamessageconsumerfromtheinvokerspointofview.ButtoApacheCamelthe
Web Service Provider is in first place a message producer, as it implements the web service by
producingamessageandsendingittosomeEndpoint.OntheotherhandtheWebServiceProvid
ersupportssendingaresponsemessagetoareceivedrequest,thusitisalsoaconsumerofmessag
esfromCamelspointofview.Thisisbecausetheresponse,whichwillbesenttotheinvokerofthe
webservice,isreceivedandconsumedbysomeEndpoint.
TheWebServiceProviderisimplementedbytheWebServiceProvider 1 classoftheframework.
This class supports the implementation of a web service which sends the request message to an
Endpoint,andexpectstheresponsemessageonadifferentEndpointtoforwardtheresponsetothe
web service invoker. The Web Service Provider is intentionally not implemented using Camels
abilitytoprocessmessagesasInOutExchangesduetotheincompleteimplementationmentioned
in chapter 3.2.2 (RequestReply pattern). The WebServiceProvider implements Camels
Processor 2 interfacetoactasanEventDrivenConsumerontheEndpointtheWebServicePro
vider expects the reply message. When the web service is invoked the WebServiceProvider
packs therequest message ina CamelExchange and sends it tothe Endpoint passed in the con
structor. Because JAXWS 2.0 does only support synchronous web service implementations the
WebServiceProvider blocks till it receives the answer via its process() method of the
Processorinterface.Thisisnotanidealimplementation,butJAXWS2.1,whichsupportsasyn
chronousimplementationsofwebservices,isnotimplementedyetbyallJAXWSproviders.And
evenwithJAXWS2.1thewebserviceclientstaysconnectedduringtheexecutionofthewebser
vice, weather executed synchronously or asynchronously. This is because messagingstyle web
serviceinvocationisnotsupportedbyJAXWSyet.
The WebServiceProvider implementation also supports the implementation of a web service
where the invoker doesnt expect any response. In this case the web service just creates a Camel
Exchange,sendsittotheEndpointandreturns.
ToallowCameltomanageitslifecycle,whichmeansprovidingornotprovidingthewebservice,
theWebServiceProviderimplementsCamelsService 3 interface.
de.unistuttgart.iaas.framework.eai2camel.endpoint.WebServiceProvider
org.apache.camel.Processor
3org.apache.camel.Service
1
2
42
4.3TheEAI2CamelFramework
4.3.5
Message Translator
To support the Message Translator pattern from [HW03] using web technologies the
MessageTranslator 1 class was implemented in the EAI2Camel framework. This class is an
EventDriven Consumer and thus implements Camels Processor 2 interface. It supports the
transformationbyeitherawebserviceorbyanXSLTstylesheet.Whichofthosetechnologiesare
used for the transformation depends on which constructor is used to instantiate the
MessageTranslator.
If the transformation by a web service is chosen, the MessageTranslator simply forwards its
incomingmessagesandexpectsthetranslatedmessageasresponse.Thewebserviceinvocationis
donebyextendingtheWebServiceFilter 3 classwhichalreadyprovidesthatfunctionality.
In case of transformation using XSLT, the MessageTranslator uses JAXPs TransformAPI 4 to
performtheXSLTtransformationusingthesuppliedXSLTstylesheet.
4.3.6
Content Enricher
de.unistuttgart.iaas.framework.eai2camel.transformation.MessageTranslator
org.apache.camel.Processor
3de.unistuttgart.iaas.framework.eai2camel.WebServiceFilter
4javax.xml.transform
5de.unistuttgart.iaas.framework.eai2camel.transformation.MessageTranslator
6de.unistuttgart.iaas.framework.eai2camel.transformation.ContentEnricher
7javax.xml.transform.URIResolver
1
2
43
IMPLEMENTATION
ment residing on that special URL. This is demonstrated in the XSLT snippet in listing 30 below
whereyoucanalsoseethespecialURLused.
1
2
<xsl:copy-of select="document('http://contentenricher.transformation
.eai2camel.framework.iaas.unistuttgart.de')" />
Listing30:RetrievingthedatatoenrichinanXSLTstylesheetviaaspecialURL
AlternativelythedatareturnedfromthewebserviceisalsomadeavailabletotheXSLTprocessor
using a XSLT parameter. Using this approach a XSLT stylesheet could reference to this data by
declaring the parameter NewData and using the XSLT variable $NewData that contains the
datareturnedbythewebservice.ThisisdemonstratedintheXSLTsnippetinlisting31below.
3
4
5
4.3.7
Recipient List
Like suggested in the evaluation of the Recipient List pattern(see3.4.4Recipient List),a custom
CamelExpressionisdevelopedaspartoftheEAI2Camelframework.ThisExpression 3 creates
a list of recipients depending on the message received and is implemented in the
RecipientListExpression 4 class.TheRecipientListExpressionsupportsthreepossibili
tiestocreatethelistofrecipients.
Onepossibilityistosendthemessagewhichissubjecttotheevaluationtoawebservicethatre
turns a list of recipients. The RecipientListExpression doesnt require the web service to
returnalistofrecipientsofaspecificXMLSchema[FW04].Itjustrequiresittoreturnamessage
javax.xml.xpath
javax.xml.namespace.NamespaceContext
3org.apache.camel.Expression
4de.unistuttgart.iaas.framework.eai2camel.routing.RecipientListExpression
1
2
44
4.3TheEAI2CamelFramework
whosepayloadcontainsanarbitraryXMLrootelementwhichcontainsoneormorearbitrarychild
elements.ThestringvaluesofthesechildelementsarethenmappedtoApacheCamelEndpoint
URIs.ThewebserviceimplementationcouldbedeemedtoreturnCamelEndpointURIsdirectly,
but this would tightly couple the web service toApache Camel. Thus the indirection of using a
mapping between the channel identifiers returned by the web service and the Camel Endpoint
URIs is introduced. This mapping can be passed to the constructor as a Map 1 instance or can be
created by multiple calls to the setMapping() method of the RecipientListExpression.
ThewebserviceisinvokedusingtheJAXWSAPIasdescribedfortheWebBasedFilterabove.
Theonlydifferenceisthatthewebserviceisinvokedsynchronouslybecausetheprocessingcant
continuewhiletheExpressionisevaluated.ParticularlyApacheCameldoesntofferanasynchron
ousversionoftheExpression 2 interface.
Another possibility is to extract the recipient list from the message which is subject to routing.
Thereforethemessageneedstocontainalreadyalistoftherecipients.Thislistcouldforexample
beaddedtothemessageusingaContent Enricher.Likeforthewebservicebasedapproach,the
recipientlistcontainedinthemessageneedsnottobeofaspecificXMLSchema.Itjustneedsto
haveonerootelementwithseveralchildelementswhosestringvaluesaremappedtoCamelEnd
pointURIsusingthesamemappingmechanismadescribedbefore.Thispreventsatightcoupling
betweenthecomponentthataddstherecipienttothemessageandtheRecipientListimplementa
tion. The recipient list contained in themessage payload isidentified usinganXPath expression.
This XPath expression is evaluated using JAXPs XPathAPI and, like described for the Content
Enricher (4.3.6),a NamespaceContext 3 is needed to resolve thenamespace prefixesused in the
XPathexpression.
Thethirdpossibilityistodeterminetowhichrecipienttosendamessageto,basedonasetofCa
melPredicates.EachPredicateisassociatedwithaCamelEndpointURIandifamessagemeetsa
Predicate, that message is sent to the corresponding EndpointURI. This implementation resem
bles Camelsimplementation of the ChoiceProcessor, i.e. theContentBased Router. The only
differenceisthatacopyofthemessageissenttoallrecipients,notonlytotheonewiththefirst
matchingPredicate.
4.3.8
Aggregator
TheAggregatorpatternisimplementedintheEAI2Camelframeworkassuggestedintheevalua
tion of the pattern in chapter 3.4.6 above. This means it is implemented using a custom
AggregationCollection 4 thathidestheaggregatestoCamelsAggregator 5 tilltheaggregate
is complete. This custom AggregationCollection is implemented in the frameworks
ExtendedAggregationCollection 6 class.As mentioned by [HW03] and in the evaluation of
java.util.Map
org.apache.camel.Expression
3javax.xml.namespace.NamespaceContext
4org.apache.camel.processor.aggregate.AggregationCollection
5org.apache.camel.processor.Aggregator
6de.unistuttgart.iaas.framework.eai2camel.routing.aggregator.ExtendedAggregationCollection
1
2
45
IMPLEMENTATION
theAggregatorpattern(chapter3.4.6),animplementationoftheAggregatorpatternneedstospeci
fythreeproperties:Acorrelationbetweenthemessagestoaggregate,acompletenessconditionto
decidewhenanaggregateiscompleteandanaggregationalgorithmthatcomputestheaggregated
message.ApacheCameloffersinterfacesfortheimplementationoftheaggregationalgorithmand
ofthecorrelationidentifieraswellasforthecompletenesscondition.Theseinterfacesareusedby
theExtendedAggregationCollectionimplementationofthisframework.
The aggregation algorithm is implemented in Apache Camel by classes implementing the
AggregationStrategy 1 interface.Thisinterfaceimplementsaniterativeaggregationapproach.
Each time a new message in form of an Exchange 2 arrives, the AggregationStrategys
aggregate()methodisinvokedthatshallthencomputeanewExchangeormodifytheexist
ingonetorepresenttheaggregationofthemessagesarrivedtillthen.Thisiterativeapproachsaves
storageastheaggregateiskeptsmallbyperformingtheaggregationeachtimeamessagearrives.
Butsomeaggregationstrategiesmightrequireperformingtheaggregationafterallmessagesofan
aggregate arrived. To accommodate for those aggregation strategies and to support the
ExtendedAggregationCollections implementation of aggregate timeouts, all aggregates
are wrapped in an AggregateExchange 3 . The AggregateExchange transparently offers all
methods of the wrapped Exchange and adds some useful functionality that can be used to im
plementanaggregationstrategy.Amongthisfunctionalityistheabilitytostorealistofthemes
sageswhichbelongtothisaggregate.Italsostorestheamountofmessagesthatwereaggregatedin
this aggregate, which can be useful when implementing a completeness condition based on the
amountofaggregatedmessages.
TheEAI2Camelframeworkdevelopedinthisworkimplementsalreadytwoaggregationstrate
gies.OneofthemistheAggregationStrategyBest 4 thatperformstheaggregationbychoosing
the best message as the aggregated message. The best message is selected according to a value
contained in the message which is identified using an XPath expression. The messages are then
aggregatedbycomparingthisdesignatedvalueofanincomingmessagewiththecurrentaggregate
and choosing the highest or the lowest value. The comparison is done numerically if possible or
lexicographicallyotherwise.Theotheraggregationstrategyimplementedintheframeworkisthe
AggregationStrategyMostRecent. This strategy uses the most recently arrived message as
theaggregatedmessage.
TheExtendedAggregationCollectionusesaCamelPredicatetoimplementthecompleteness
condition.ThiscompletenessconditionPredicate 5 canuseallinformationavailablethroughthe
AggregateExchange interface. Especially it can use the message count or a possible message
historystoredthere.ThreecompletenessPredicatesarealreadyimplementedintheframework.
Two of them are simple Predicates that never respectively always hold. The
CompletnessPredicateNever 6 is particularlyusefulinconjunction with the timeout mechan
org.apache.camel.processor.aggregate.AggregationStrategy
org.apache.camel.Exchange
3de.unistuttgart.iaas.framework.eai2camel.routing.aggregator.AggregateExchange
4de.unistuttgart.iaas.framework.eai2camel.routing.aggregator.AggregationStrategyBest
5org.apache.camel.Predicate
6de.unistuttgart.iaas.framework.eai2camel.routing.aggregator.CompletnessPredicateNever
1
2
46
4.4GenerationofApacheCamelbasedJavacode
4.4
ThissectiondescribeshowtheactualgenerationofApacheCamelbasedJavacodeisdone.Itde
scribeshowthegeneratorcodeisintegratedinthegraphicaleditorimplementedby[Dru07],and
howthemessagingsystemmodelistraversedtogeneratethecode.
4.4.1
Intheworkof[Dru07]theEAIpatternswereanalyzedregardingwhatparametersareneededto
usethepatterns.Theseparameterswerefirstanalyzedtheoreticallyandthenusedfortheimple
mentationoftheEclipsebasededitorimplementedby[Dru07].Toimplementthemodeledmessag
ingsystemsasCamelbasedJavaapplicationstheparametersstoredinthemessagingsystemmod
el,developedby[Dru07],hadtobeused.Butforsomepatternsthesuppliedparameterswerenot
sufficienttogenerateasolutionthatexecutesthismessagingsystem.Thereasonstheparameters
didnt suffice were mostly not because the theoretical parameterization was lacking a parameter,
butbecausesomeparametersintheimplementationoftheeditordidntcontaindeploymentspecif
icinformationwhichwasarequirementtotheeditordesign.Inparticularthepatternsthatusea
web service had only the WSDL porttype and the WSDL operation specified. But to actually in
vokethewebservicewithoutusinganydiscoverymechanism,theconcreteWSDLserviceandthe
concreteWSDLport,theoperationshallbeinvokedon,needstobeknown.
1de.unistuttgart.iaas.framework.eai2camel.routing.aggregator
.CompletnessPredicateMessageCount
2org.apache.camel.model.language.XPathExpression
47
IMPLEMENTATION
OnlytheAggregatorpatternwaslackingaparameterthatisnotadeploymentspecificparameter.
Namelyintheworkof[Dru07]theAggregatorpatternislackingacorrelationidentifier.Therea
sonthisparameterwasomittedisprobablybecausetheimplementationofthisworkwastargeted
to WSBPEL. A WSBPEL process is instance based, i.e. the data flowing through a WSBPEL
processalwaysbelongstoacertainprocessinstance.ThustheAggregatorimplementationinWS
BPELdoesntneedtocorrelatethemessagestoanaggregateastheyarealreadycorrelatedbythe
processinstancetheybelongto.
Togettheneededadditionalparametersforthewebservice,agraphicaldialogwascreatedinthis
work.ThisdialogisimplementedintheEai2CamelWebServiceConfigurationDialog 1 class
and is shown for each pattern, needing the information during the code generation. This is not
reallyauserfriendlywayofcollectingtherequiredparameters,andcouldbeimprovedbyfuture
works.ThesameapproachisusedtocollecttherequiredcorrelationidentifierfortheAggregator,
wherethedialogisimplementedintheEai2CamelAggregatorConfigurationDialog 2 class.
4.4.2
The integration into the Eclipse based Editor from [Dru07] is being done in a minimal invasive
fashion.ThegeneratorintegratesintotheeditorbyimplementingasocalledActionDelegate 3 .
ThisprovidesanadditionalactioninformofabuttoninEclipsestoolbarandanadditionalentry
in the menu bar. All classes invoked by the ActionDelegate are independent of the Eclipse
basededitorimplementation.Theyjustrelyonthemodel 4 usedtostorethemessagingsystem.
4.4.3
ThegenerationstartswhentheGenerateCamelActionDelegate 5 isinvoked.Itchecksthemes
saging system for errors in the same way the corresponding ActionDelegate of the WSBPEL
generatingpartdoes.ThenitcreatesaCamelWriter 6 instanceandinvokesitswrite()method.
This method adds the JavaNature to the project the current messaging model is located in. This
means it makes the project a java project. Then it adds the libraries that are required to run the
generated messaging solution to the Java project. Theselibrariesare listedinsection4.4.4below.
AftertheJavaprojecthasbeeninitializedapackageundertheeai2camel.generatedSystems 7
iscreatedandthecreatedpackageispopulatedwithsometemplates.
The actual messaging system is then generated by traversing the messaging system model in a
breathfirstmanner,startingfromanodethatisaninterfacetotheoutsideworld.Usuallythisisan
ExternalServicepatternthathasonlyanoutgoingchannelconnectedtoit.Thereasonfortravers
de.unistuttgart.iaas.eaiparam.editors.dialogs.Eai2CamelWebServiceConfigurationDialog
de.unistuttgart.iaas.eaiparam.editors.dialogs.Eai2CamelAggregatorConfigurationDialog
3org.eclipse.ui.IWorkbenchWindowActionDelegate
4de.unistuttgart.iaas.eaiparam.model.*
5de.unistuttgart.iaas.eaiparam.actions.GenerateCamelActionDelegate
6de.unistuttgart.iaas.eaiparam.actions.CamelWriter
7de.unistuttgart.iaas.eaiparam.eai2camel.generatedSystems
1
2
48
4.5ExampleMessagingSystem
ingthemessagingsystemusingbreathfirstsearchistogenerateamessagingsystemthatishuman
readable.Usingthisapproachthepatternsappearinthegeneratedsourcecodeintheorderofthe
messageflow.
While traversing the messaging system a generator method for each filter (in the sense of the
PipesandFilters architecture) of the messagingsystem isinvoked. Thesegenerator methodsare
implemented in a separate class, the CamelFilterPatternGenerator 1 class. To create an ex
tensiblesolutiontheappropriategeneratormethodforafilterdoesntneedtobeinvokeddirectly.
Instead the CamelFilterPatternGenerator offers a getGeneratorMethod() method
whichusesintrospectiontodiscovertheappropriategeneratormethodforthecurrentfilter.This
enables the implementation of additional patterns by simply adding an appropriate generator
methodtotheCamelFilterPatternGeneratorclass.
4.4.4
Required Libraries
ThegeneratedmessagingsystemrequiressomeJavalibrariestobeabletorun.Theselibrariesand
theversionusedwhiledevelopingtheEAI2Camelgeneratorarelistedinthefollowing:
ApacheCamel1.2.0[Cam]isneededasthegeneratedJavaapplicationisbasedonthisApache
Camel.
TheSpringFramework2.5[Spr]isaframeworkthatisusedbyApacheCamelandisthusre
quired.
TheEAI2Camelframework,whichwasdevelopedaspartofthisworkandcontainstheac
tualimplementationoftheEAIpatterns,isalsoneeded.
ApacheActiveMQ4.1.1[Act]whichisrequiredasitisusedasJMSproviderforthegenerated
messagingsystems.
Apache CXF 2.0.3 [Cxf] which is used as JAXWS provider and is thus needed to invoke the
webservicesthedifferentpatternsuse.
4.5
To demonstrate the Java generator and the EAI2Camel framework developed in this work an
example messaging system has been created. This created example implements the LoanBroker
scenario,whereamessagingsystemismodeledthatprovidesawebservice.Thiswebserviceim
plementstheLoanBrokerscenariobysendingtheloanquoterequestthroughachainofEAIpat
terns and returning the resulting message to the web service client. Figure 2 shows the modeled
messagingsystem.
de.unistuttgart.iaas.eaiparam.actions.CamelFilterPatternGenerator
49
IMPLEMENTATION
Figure2:TheLoanBrokermessagingsystem
The modeled messaging system starts with a pair of External Service patterns that provide the
webservice.IncomingrequestmessagesaresenttoaContent Enricher thatenrichestherequest
with a credit score by asking a credit bureau for the customers credit standing. Then the list of
banksthatfitthecustomerprofileiscomputedbyanXSLTstylesheetandaddedtothemessage.
Here,aMessage Translator isused, because the computationis done by an XSLT stylesheet, but
actuallythecreationoftherecipientlistimplementstheContent Enricherpattern.Afterthisstep
the message is distributed to the banks according to the recipient list contained in the message,
whereupontheresponsesreceivedfromthebanksareaggregatedtoasinglemessagebyselecting
the best loan offer. Finally the aggregated message is translated to fit the web services response
messagetype,andthensentasresponsetothewebserviceclient.
To be able to run the generated messaging system implementation of this example, all necessary
webservicesandXSLTstylesheetswereimplementedaspartofthiswork.
50
Bibliography
[AAA+07]
Alexandre Alves, Assaf Arkin, Sid Askary, Charlton Barreto, Ben Bloch, Francisco
Curbera,MarkFord,YaronGoland,AlejandroGuzar,NeelakantanKartha,Canyang
Kevin Liu, Rania Khalaf, Dieter Knig, Mike Marin, Vinkesh Mehta, Satish Thatte,
DannyvanderRijn,PrasadYendluriandAlexYiu.Web Services Business Process
Execution Language, Version 2.0. Comitee Specification,April 2007.Available elec
tronicallyat:
http://docs.oasisopen.org/wsbpel/2.0/wsbpelv2.0.pdf
Accessedon:07.04.2008
[Act]
ApacheActiveMQ,Version4.1.1.Availableelectronicallyat:
http://activemq.apache.org/
Accessedon:02.04.2008
[BL07]
DavidBoothandCanyangKevinLiu.WebServicesDescriptionLanguage(WSDL),
Version: 2.0. W3C Recommendation, June 2007. Available electronically at:
http://www.w3.org/TR/wsdl20primer/
Accessedon:13.04.2008
[BO06]
[BPS+06]
Tim Bray, Jean Paoli, C. M. SperbergMcQueen, Eve Maler and Franois Yergeau.
ExtensibleMarkupLanguage(XML)1.0(FourthEdition).W3CRecommendation,
September2006.Availableelectronicallyat:
http://www.w3.org/TR/xml/
Accessedon:13.04.2008
[Cam]
ApacheCamel,Version:1.2.0.Availableelectronicallyat:
http://activemq.apache.org/camel/index.html
Accessedon:02.04.2008
[CD99]
James Clark and Steve DeRose. XML Path Language (XPath), Version: 1.0. W3C
Recommendation,November1999.Availableelectronicallyat:
http://www.w3.org/TR/xpath/
Accessedon:07.04.2008
51
BIBLIOGRAPHY
[CHM06]
[Cla99]
Roberto Chinnici, Marc Hadley and Rajiv Mordani. The Java API for XMLBased
WebServices(JAXWS)2.0.Specification,April2006.Availableelectronicallyat:
http://jcp.org/aboutJava/communityprocess/final/jsr224/index.html
Accessedon:13.04.2008
James Clark. XSL Transformations (XSLT), Version: 1.0. W3C Recommendation,
November1999.Availableelectronicallyat:
http://www.w3.org/TR/xslt/
Accessedon:13.04.2008
[Cxf]
ApacheCXF,Version2.0.3.Availableelectronicallyat:
http://incubator.apache.org/cxf/
Accessedon:02.04.2008
[DK06]
[Dru07]
BettinaDruckenmller.ParametrisierungvonEAIPatterns.DiplomarbeitNr.2583,
UniversittStuttgart,2007.
[Ecl]
EclipseDevelopmentPlatform,Version:3.2.2.Availableelectronicallyat:
http://www.eclipse.org/
Accessedon:22.11.2007
[FW04]
[HBS+]
MarkHapner,RichBurridge,RahulSharma,JosephFialliandKateStout.JavaMes
sage Service Specification Final Release 1.1. Specification, April 2002. Available
electronicallyat:
http://jcp.org/aboutJava/communityprocess/final/jsr914/index.html
Accessedon:07.04.2008
[HW03]
[Jdt]
Eclipse:JavaDevelopmentTools(JDT),Version:3.2.2.Availableelectronicallyat:
http://www.eclipse.org/jdt/
Accessedon:13.04.2008
[Min]
ApacheMINA.Availableelectronicallyat:
http://mina.apache.org/
Accessedon:02.04.2008
52
[ML07]
NiloMitraandYvesLafon.SOAP,Version:1.2.W3CRecommendation,April2007.
Availableelectronicallyat:
http://www.w3.org/TR/soap12part0/
Accessedon:13.04.2008
[Ode]
ApacheODE.Availableelectronicallyat:
http://ode.apache.org/
Accessedon:18.04.2008
[Ser]
ApacheServiceMix.Availableelectronicallyat:
http://servicemix.apache.org/
Accessedon:02.04.2008
[Spr]
SpringFramework,Version2.5.Availableelectronicallyat:
http://www.springframework.org/
Accessedon:04.04.2008
[Vep]
Eclipse:VisualEditorProject,Version:1.2.Availableelectronicallyat:
http://www.eclipse.org/vep/
Accessedon:13.04.2008
[Wal06]
NormanWalsh.JavaAPIforXMLProcessing.Specification,August2006.Available
electronicallyat:
http://jcp.org/aboutJava/communityprocess/mrel/jsr206/
Accessedon:13.04.2008
53
Appendix
A.1
This example demonstrates the differences discussed in chapter 3.3 using Camels Pipeline with
synchronousorasynchronousComponents,wheretheasynchronousComponentdoesntsupport
InOut 1 messageExchanges.TheexampleconfigurestwodifferentPipelines 2 ,onestartingfrom
the Endpoint seda:endpointA using the SEDAComponent which implements inmemory
queuesandisthusasynchronousandonestartingfromtheEndpointdirect:endpointAus
ingtheDirectComponentwhoseProducerdirectlyinvokesitsConsumerandthusissynchronous.
When executed, this example sends five test messages to each ofthe two Pipelines andprints
themessagesreceivedasoutputfromthePipelinetotheconsoleincludingthereceivingthreads
ID. Also the two Filter Processors print a message to the console on processing, including their
threads ID. The second Filter Processor also waits for 0.5 seconds to provoke the parallel
processingofthedifferenttestmessages.TheJavacodeofthisexampleiscompleteandreadytobe
compiled.Afterthecodeyoucanfindapossibleoutputandadiscussionoftheoutput.
A.1.1
import
import
import
import
import
import
import
Java Code
org.apache.camel.CamelContext;
org.apache.camel.CamelTemplate;
org.apache.camel.Exchange;
org.apache.camel.Message;
org.apache.camel.Processor;
org.apache.camel.builder.RouteBuilder;
org.apache.camel.impl.DefaultCamelContext;
1
2
org.apache.camel.ExchangePattern.InOut
org.apache.camel.processor.Pipeline
55
APPENDIX
A.1CamelexampleusingbuiltinPipeline
+ Thread.currentThread().getId()
+ "]: \n"
+ inboundMessage
.getBody(String.class));
}
};
APPENDIX
A.1.2
Output
58
body
body
body
body
#2
#3
#4
#5
A.1CamelexampleusingbuiltinPipeline
Filter
Filter
Filter
Filter
Filter
2
2
2
2
2
[9]
[9]
[9]
[9]
[9]
processing:message
processing:message
processing:message
processing:message
processing:message
body
body
body
body
body
#1
#2
#3
#4
#5
A.1.3
Discussion
Theoutputshowstwothings:FirstyoucanseetheproblemofusingasynchronousComponents
thatdontimplementtheInOutmessageexchangepatternwithCamelsPipeline,whichwasmen
59
APPENDIX
tioned in chapter 3.3, in the first part of the results (#### Example with asynchronous endpoints
####). You can see that the messages leave the Pipeline unaltered due to the fact that the Filters
outputisnotreusedbythefollowingFilter,neitheritisreceivedbythefinalEndpoint(foranex
planationonwhythisis,seechapter3.3).Alsoyoucanseethatthetestmessagesarereceivedby
thefinalEndpointevenbeforetheyareprocessedbythesecondFilterProcessor(thisisalsodis
cussed in chapter 3.3). Second you can see in the second part of the results (#### Example with
synchronous endpoints ####) that due to the DirectComponent, which is synchronous, there is
onlyonemessageinthePipelineateachpointintime(foradiscussionseechapter3.3).
60
Erklrung
Icherklrehiermit,dassichdievorliegendeArbeitselbstn
dig und ohne fremde Hilfe verfasst und keine anderen als
dieangegebenenHilfsmittelverwendethabe.
Stuttgart,24.04.2008
_______________________________
(PascalKolb)
61