You are on page 1of 986

"QBDIF $BNFM

64&3 (6*%& 7FSTJPO 2.11.0

"LMVOFDEQ 2007-2013,

M>@EB 2LCQT>OB %LRKA>QFLK

3>?IB LC "LKQBKQP

3>?IB LC "LKQBKQP......................................................................... FF $IBQUFS 1 (KQOLAR@QFLK ...................................................................................1 $IBQUFS 1 0RF@HPQ>OQ .......................................................................................1 $IBQUFS 1 &BQQFKD 2Q>OQBA..............................................................................7 $IBQUFS 1 O@EFQB@QROB ................................................................................ 17 $IBQUFS 1 $KQBOMOFPB (KQBDO>QFLK />QQBOKP.............................................. 37 $IBQUFS 1 "LLH !LLH ................................................................................... 42 $IBQUFS 1 3RQLOF>IP..................................................................................... 122 $IBQUFS 1 +>KDR>DB $IBQUFS 1 #>Q>%LOJ>Q $IBQUFS 1 />QQBOK $IBQUFS 1 "LJMLKBKQ MMBKAFU ............................................................. 532 (KABU ................................................................................................0 MMBKAFU..................................................................... 383 MMBKAFU............................................................. 297 MMBKAFU.................................................................. 221

JJ

"1 " $ ) & $ " . & -

"' YYYY

/3$1

(KQOLAR@QFLK

"QBDIF $BNFM a JT B WFSTBUJMF PQFO-TPVSDF JOUFHSBUJPO GSBNFXPSL CBTFE PO LOPXO &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT. $BNFM FNQPXFST ZPV UP EFGJOF SPVUJOH BOE NFEJBUJPO SVMFT JO B WBSJFUZ PG EPNBJO-TQFDJGJD MBOHVBHFT, JODMVEJOH B +BWB-CBTFE 'MVFOU "1*, 4QSJOH PS #MVFQSJOU 9.- $POGJHVSBUJPO GJMFT, BOE B 4DBMB %4-. 5IJT NFBOT ZPV HFU TNBSU DPNQMFUJPO PG SPVUJOH SVMFT JO ZPVS *%&, XIFUIFS JO B +BWB, 4DBMB PS 9.- FEJUPS. "QBDIF $BNFM VTFT 63*T UP XPSL EJSFDUMZ XJUI BOZ LJOE PG 5SBOTQPSU PS NFTTBHJOH NPEFM TVDI BT )551, "DUJWF.2, +.4, +#*, 4$", .*/" PS $9', BT XFMM BT QMVHHBCMF $PNQPOFOUT BOE %BUB 'PSNBU PQUJPOT. "QBDIF $BNFM JT B TNBMM MJCSBSZ XJUI NJOJNBM EFQFOEFODJFT GPS FBTZ FNCFEEJOH JO BOZ +BWB BQQMJDBUJPO. "QBDIF $BNFM MFUT ZPV XPSL XJUI UIF TBNF "1* SFHBSEMFTT XIJDI LJOE PG 5SBOTQPSU JT VTFE - TP MFBSO UIF "1* PODF BOE ZPV DBO JOUFSBDU XJUI BMM UIF $PNQPOFOUT QSPWJEFE PVU-PG-CPY. "QBDIF $BNFM QSPWJEFT TVQQPSU GPS #FBO #JOEJOH BOE TFBNMFTT JOUFHSBUJPO XJUI QPQVMBS GSBNFXPSLT TVDI BT 4QSJOH, #MVFQSJOU BOE (VJDF. $BNFM BMTP IBT FYUFOTJWF TVQQPSU GPS VOJU UFTUJOH ZPVS SPVUFT. 5IF GPMMPXJOH QSPKFDUT DBO MFWFSBHF "QBDIF $BNFM BT B SPVUJOH BOE NFEJBUJPO FOHJOF: ` "QBDIF 4FSWJDF.JY - B QPQVMBS EJTUSJCVUFE PQFO TPVSDF &4# BOE +#* DPOUBJOFS ` "QBDIF "DUJWF.2 - B NBUVSF, XJEFMZ VTFE PQFO TPVSDF NFTTBHF CSPLFS ` "QBDIF $9' - B TNBSU XFC TFSWJDFT TVJUF (+"9-84 BOE +"9-34) ` "QBDIF ,BSBG - B TNBMM 04(J CBTFE SVOUJNF JO XIJDI BQQMJDBUJPOT DBO CF EFQMPZFE ` "QBDIF .*/" - B IJHI-QFSGPSNBODF /*0-ESJWFO OFUXPSLJOH GSBNFXPSL 4P EPO'U HFU UIF IVNQ - USZ $BNFM UPEBZ!

$) "15 &3 1 - */ 5 3 0 %6$5 *0 /

3LL J>KV ?RWWTLOAP - TE>Q BU>@QIV FP ">JBI? 0LBZ, TP UIF EFTDSJQUJPO BCPWF JT UFDIOPMPHZ GPDVTFE. 5IFSF'T B HSFBU EJTDVTTJPO BCPVU $BNFM BU 4UBDL 0WFSGMPX. 8F TVHHFTU ZPV WJFX UIF QPTU, SFBE UIF DPNNFOUT, BOE CSPXTF UIF TVHHFTUFE MJOLT GPS NPSF EFUBJMT.

$) " 15& 3 1 - * / 5 3 0% 6$5 * 0/

"' YYYY

/3$1

0RF@HPQ>OQ

5P TUBSU VTJOH "QBDIF $BNFM RVJDLMZ, ZPV DBO SFBE UISPVHI TPNF TJNQMF FYBNQMFT JO UIJT DIBQUFS. 'PS SFBEFST XIP XPVME MJLF B NPSF UIPSPVHI JOUSPEVDUJPO, QMFBTF TLJQ BIFBE UP $IBQUFS 3.

6 +* 3'1.4&'

- $7 ,/+$ ".#$

5IJT NJOJ-HVJEF UBLFT ZPV UISPVHI UIF TPVSDF DPEF PG B TJNQMF FYBNQMF. $BNFM DBO CF DPOGJHVSFE FJUIFS CZ VTJOH 4QSJOH PS EJSFDUMZ JO +BWB - XIJDI UIJT FYBNQMF EPFT. 5IJT FYBNQMF JT BWBJMBCMF JO UIF examples\camel-example-jms-file EJSFDUPSZ PG UIF $BNFM EJTUSJCVUJPO. 8F TUBSU XJUI DSFBUJOH B $BNFM$POUFYU - XIJDI JT B DPOUBJOFS GPS $PNQPOFOUT, 3PVUFT FUD:
CamelContext context = new DefaultCamelContext();

5IFSF JT NPSF UIBO POF XBZ PG BEEJOH B $PNQPOFOU UP UIF $BNFM$POUFYU. :PV DBO BEE DPNQPOFOUT JNQMJDJUMZ - XIFO XF TFU VQ UIF SPVUJOH - BT XF EP IFSF GPS UIF 'JMF$PNQPOFOU:
context.addRoutes(new RouteBuilder() { public void configure() { from("test-jms:queue:test.queue").to("file://test"); } });

PS FYQMJDJUMZ - BT XF EP IFSF XIFO XF BEE UIF +.4 $PNQPOFOU:


ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?broker.persistent=false"); // Note we can explicit name the component context.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));

5IF BCPWF XPSLT XJUI BOZ +.4 QSPWJEFS. *G XF LOPX XF BSF VTJOH "DUJWF.2 XF DBO VTF BO FWFO TJNQMFS GPSN VTJOH UIF activeMQComponent() NFUIPE XIJMF TQFDJGZJOH UIF CSPLFS63- VTFE UP DPOOFDU UP "DUJWF.2

$) "15 &3 2 - 2 6*$, 45 "3 5

camelContext.addComponent("activemq", activeMQComponent("vm://localhost?broker.persistent=false"));

*O OPSNBM VTF, BO FYUFSOBM TZTUFN XPVME CF GJSJOH NFTTBHFT PS FWFOUT EJSFDUMZ JOUP $BNFM UISPVHI POF JG JUT $PNQPOFOUT CVU XF BSF HPJOH UP VTF UIF 1SPEVDFS5FNQMBUF XIJDI JT B SFBMMZ FBTZ XBZ GPS UFTUJOH ZPVS DPOGJHVSBUJPO:
ProducerTemplate template = context.createProducerTemplate();

/FYU ZPV JRPQ TUBSU UIF DBNFM DPOUFYU. *G ZPV BSF VTJOH 4QSJOH UP DPOGJHVSF UIF DBNFM DPOUFYU UIJT JT BVUPNBUJDBMMZ EPOF GPS ZPV; UIPVHI JG ZPV BSF VTJOH B QVSF +BWB BQQSPBDI UIFO ZPV KVTU OFFE UP DBMM UIF TUBSU() NFUIPE
camelContext.start();

5IJT XJMM TUBSU BMM PG UIF DPOGJHVSFE SPVUJOH SVMFT. 4P BGUFS TUBSUJOH UIF $BNFM$POUFYU, XF DBO GJSF TPNF PCKFDUT JOUP DBNFM:
for (int i = 0; i < 10; i++) { template.sendBody("test-jms:queue:test.queue", "Test Message: " + i); }

6' 3 ' //$-2?


'SPN UIF 1SPEVDFS5FNQMBUF - XF TFOE PCKFDUT (JO UIJT DBTF UFYU) JOUP UIF $BNFM$POUFYU UP UIF $PNQPOFOU test-jms:queue:test.queue. 5IFTF UFYU PCKFDUT XJMM CF DPOWFSUFE BVUPNBUJDBMMZ JOUP +.4 .FTTBHFT BOE QPTUFE UP B +.4 2VFVF OBNFE test.queue. 8IFO XF TFU VQ UIF 3PVUF, XF DPOGJHVSFE UIF 'JMF$PNQPOFOU UP MJTUFO PG UIF test.queue. 5IF 'JMF 'JMF$PNQPOFOU XJMM UBLF NFTTBHFT PGG UIF 2VFVF, BOE TBWF UIFN UP B EJSFDUPSZ OBNFE test. &WFSZ NFTTBHF XJMM CF TBWFE JO B GJMF UIBU DPSSFTQPOET UP JUT EFTUJOBUJPO BOE NFTTBHF JE. 'JOBMMZ, XF DPOGJHVSFE PVS PXO MJTUFOFS JO UIF 3PVUF - UP UBLF OPUJGJDBUJPOT GSPN UIF 'JMF$PNQPOFOU BOE QSJOU UIFN PVU BT UFYU. 3E>Q'P FQ! *G ZPV IBWF UIF UJNF UIFO VTF 5 NPSF NJOVUFT UP 8BML UISPVHI BOPUIFS FYBNQMF UIBU EFNPOTUSBUFT UIF 4QSJOH %4- (9.- CBTFE) SPVUJOH.

$) " 15& 3 2 - 2 6 * $,4 5 " 3 5

6 +* 3'1.4&'
(KQOLAR@QFLK

-.3'$1 $7 ,/+$

$POUJOVJOH UIF XBML GSPN PVS GJSTU FYBNQMF, XF UBLF B DMPTFS MPPL BU UIF SPVUJOH BOE FYQMBJO B GFX QPJOUFST - TP ZPV XPO'U XBML JOUP B CFBS USBQ, CVU DBO FOKPZ BO BGUFS-IPVST XBML UP UIF MPDBM QVC GPS B MBSHF CFFS 'JSTU XF UBLF B NPNFOU UP MPPL BU UIF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT - UIF CBTF QBUUFSO DBUBMPH GPS JOUFHSBUJPO TDFOBSJPT. *O QBSUJDVMBS XF GPDVT PO 1JQFT BOE 'JMUFST - B DFOUSBM QBUUFSO. 5IJT JT VTFE UP SPVUF NFTTBHFT UISPVHI B TFRVFODF PG QSPDFTTJOH TUFQT, FBDI QFSGPSNJOH B TQFDJGJD GVODUJPO - NVDI MJLF UIF +BWB 4FSWMFU 'JMUFST. /FMBP >KA CFIQBOP *O UIJT TBNQMF XF XBOU UP QSPDFTT B NFTTBHF JO B TFRVFODF PG TUFQT XIFSF FBDI TUFQT DBO QFSGPSN UIFJS TQFDJGJD GVODUJPO. *O PVS FYBNQMF XF IBWF B +.4 RVFVF GPS SFDFJWJOH OFX PSEFST. 8IFO BO PSEFS JT SFDFJWFE XF OFFE UP QSPDFTT JU JO TFWFSBM TUFQT: WBMJEBUF SFHJTUFS TFOE DPOGJSN FNBJM 5IJT DBO CF DSFBUFE JO B SPVUF MJLF UIJT:
<route> <from uri="jms:queue:order"/> <pipeline> <bean ref="validateOrder"/> <bean ref="registerOrder"/> <bean ref="sendConfirmEmail"/> </pipeline> </route>

8IFSF BT UIF bean ref JT B SFGFSFODF GPS B TQSJOH CFBO JE, TP XF EFGJOF PVS CFBOT VTJOH SFHVMBS 4QSJOH 9.- BT:
<bean id="validateOrder" class="com.mycompany.MyOrderValidator"/>

0VS WBMJEBUPS CFBO JT B QMBJO 10+0 UIBU IBT OP EFQFOEFODJFT UP $BNFM XIBU TP FWFS. 4P ZPV DBO JNQMFNFOU UIJT 10+0 BT ZPV MJLF. $BNFM VTFT SBUIFS JOUFMMJHFOU #FBO #JOEJOH UP JOWPLF ZPVS 10+0 XJUI UIF QBZMPBE PG UIF SFDFJWFE NFTTBHF. *O UIJT FYBNQMF XF XJMM KLQ EJH JOUP UIJT IPX UIJT IBQQFOT. :PV TIPVME SFUVSO UP UIJT UPQJD MBUFS XIFO ZPV HPU TPNF IBOET PO FYQFSJFODF XJUI $BNFM IPX JU DBO FBTJMZ CJOE SPVUJOH VTJOH ZPVS FYJTUJOH 10+0 CFBOT. 4P XIBU IBQQFOT JO UIF SPVUF BCPWF. 8FMM XIFO BO PSEFS JT SFDFJWFE GSPN UIF +.4 RVFVF UIF NFTTBHF JT SPVUFE MJLF 1JQFT BOE 'JMUFST: 1. QBZMPBE GSPN UIF +.4 JT TFOU BT JOQVU UP UIF WBMJEBUF0SEFS CFBO

$) "15 &3 2 - 2 6*$, 45 "3 5

/FMBIFKB FP ABC>RIQ *O UIF SPVUF BCPWF XF TQFDJGZ pipeline CVU JU DBO CF PNJUUFE BT JUT EFGBVMU, TP ZPV DBO XSJUF UIF SPVUF BT:
<route> <from <bean <bean <bean </route>

uri="jms:queue:order"/> ref="validateOrder"/> ref="registerOrder"/> ref="sendConfirmEmail"/>

5IJT JT DPNNPOMZ VTFE OPU UP TUBUF UIF QJQFMJOF. "O FYBNQMF XIFSF UIF QJQFMJOF OFFET UP CF VTFE, JT XIFO VTJOH B NVMUJDBTU BOE "POF" PG UIF FOEQPJOUT UP TFOE UP (BT B MPHJDBM HSPVQ) JT B QJQFMJOF PG PUIFS FOEQPJOUT. 'PS FYBNQMF.
<route> <from uri="jms:queue:order"/> <multicast> <to uri="log:org.company.log.Category"/> <pipeline> <bean ref="validateOrder"/> <bean ref="registerOrder"/> <bean ref="sendConfirmEmail"/> </pipeline> </multicast> </route>

5IF BCPWF TFOET UIF PSEFS (GSPN jms:queue:order) UP UXP MPDBUJPOT BU UIF TBNF UJNF, PVS MPH DPNQPOFOU, BOE UP UIF "QJQFMJOF" PG CFBOT XIJDI HPFT POF UP UIF PUIFS. *G ZPV DPOTJEFS UIF PQQPTJUF, TBOT UIF <pipeline>
<route> <from uri="jms:queue:order"/> <multicast> <to uri="log:org.company.log.Category"/> <bean ref="validateOrder"/> <bean ref="registerOrder"/> <bean ref="sendConfirmEmail"/> </multicast> </route>

ZPV XPVME TFF UIBU NVMUJDBTU XPVME OPU "GMPX" UIF NFTTBHF GSPN POF CFBO UP UIF OFYU, CVU SBUIFS TFOE UIF PSEFS UP BMM 4 FOEQPJOUT (1Y MPH, 3Y CFBO) JO QBSBMMFM, XIJDI JT OPU (GPS UIJT

$) " 15& 3 2 - 2 6 * $,4 5 " 3 5

FYBNQMF) XIBU XF XBOU. 8F OFFE UIF NFTTBHF UP GMPX UP UIF WBMJEBUF0SEFS, UIFO UP UIF SFHJTUFS0SEFS, UIFO UIF TFOE$POGJSN&NBJM TP BEEJOH UIF QJQFMJOF, QSPWJEFT UIJT GBDJMJUZ.

2. UIF PVUQVU GSPN WBMJEBUF0SEFS CFBO JT TFOU BT JOQVU UP UIF SFHJTUFS0SEFS CFBO 3. UIF PVUQVU GSPN SFHJTUFS0SEFS CFBO JT TFOU BT JOQVU UP UIF TFOE$POGJSN&NBJM CFBO 4PFKD ">JBI "LJMLKBKQP *O UIF SPVUF MFUT JNBHJOF UIBU UIF SFHJTUSBUJPO PG UIF PSEFS IBT UP CF EPOF CZ TFOEJOH EBUB UP B 5$1 TPDLFU UIBU DPVME CF B CJH NBJOGSBNF. "T $BNFM IBT NBOZ $PNQPOFOUT XF XJMM VTF UIF DBNFM-NJOB DPNQPOFOU UIBU TVQQPSUT 5$1 DPOOFDUJWJUZ. 4P XF DIBOHF UIF SPVUF UP:
<route> <from uri="jms:queue:order"/> <bean ref="validateOrder"/> <to uri="mina:tcp://mainframeip:4444?textline=true"/> <bean ref="sendConfirmEmail"/> </route>

8IBU XF OPX IBWF JO UIF SPVUF JT B to UZQF UIBU DBO CF VTFE BT B EJSFDU SFQMBDFNFOU GPS UIF CFBO UZQF. 5IF TUFQT JT OPX: 1. QBZMPBE GSPN UIF +.4 JT TFOU BT JOQVU UP UIF WBMJEBUF0SEFS CFBO 2. UIF PVUQVU GSPN WBMJEBUF0SEFS CFBO JT TFOU BT UFYU UP UIF NBJOGSBNF VTJOH 5$1 3. UIF PVUQVU GSPN NBJOGSBNF JT TFOU CBDL BT JOQVU UP UIF TFOE$POGJSN&NBJ CFBO 8IBU UP OPUJDF IFSF JT UIBU UIF to JT OPU UIF FOE PG UIF SPVUF (UIF XPSME ) JO UIJT FYBNQMF JU'T VTFE JO UIF NJEEMF PG UIF 1JQFT BOE 'JMUFST. *O GBDU XF DBO DIBOHF UIF bean UZQFT UP to BT XFMM:
<route> <from uri="jms:queue:order"/> <to uri="bean:validateOrder"/> <to uri="mina:tcp://mainframeip:4444?textline=true"/> <to uri="bean:sendConfirmEmail"/> </route>

"T UIF to JT B HFOFSJD UZQF XF NVTU TUBUF JO UIF VSJ TDIFNF XIJDI DPNQPOFOU JU JT. 4P XF NVTU XSJUF ?B>K: GPS UIF #FBO DPNQPOFOU UIBU XF BSF VTJOH.

$) "15 &3 2 - 2 6*$, 45 "3 5

"LK@IRPFLK 5IJT FYBNQMF XBT QSPWJEFE UP EFNPOTUSBUF UIF 4QSJOH %4- (9.- CBTFE) BT PQQPTFE UP UIF QVSF +BWB %4- GSPN UIF GJSTU FYBNQMF. "OE BT XFMM UP QPJOU BCPVU UIBU UIF to EPFTO'U IBWF UP CF UIF MBTU OPEF JO B SPVUF HSBQI. 5IJT FYBNQMF JT BMTP CBTFE PO UIF FK-LKIV NFTTBHF FYDIBOHF QBUUFSO. 8IBU ZPV NVTU VOEFSTUBOE BT XFMM JT UIF FK-LRQ NFTTBHF FYDIBOHF QBUUFSO, XIFSF UIF DBMMFS FYQFDUT B SFTQPOTF. 8F XJMM MPPL JOUP UIJT JO BOPUIFS FYBNQMF. 2BB >IPL &YBNQMFT 5VUPSJBMT 6TFS (VJEF

$) " 15& 3 2 - 2 6 * $,4 5 " 3 5

"' YYYY

/3$1

&BQQFKD 2Q>OQBA TFQE ">JBI

M>@EB

3'$ ENTERPRISE INTEGRATION PATTERNS ($(/) !..*


5IF QVSQPTF PG B "QBUUFSOT" CPPL JT OPU UP BEWPDBUF OFX UFDIOJRVFT UIBU UIF BVUIPST IBWF JOWFOUFE, CVU SBUIFS UP EPDVNFOU FYJTUJOH CFTU QSBDUJDFT XJUIJO B QBSUJDVMBS GJFME. #Z EPJOH UIJT, UIF BVUIPST PG B QBUUFSOT CPPL IPQF UP TQSFBE LOPXMFEHF PG CFTU QSBDUJDFT BOE QSPNPUF B WPDBCVMBSZ GPS EJTDVTTJOH BSDIJUFDUVSBM EFTJHOT. 0OF PG UIF NPTU GBNPVT QBUUFSOT CPPLT JT Design Patterns: Elements of Reusable Object-oriented Software CZ &SJDI (BNNB, 3JDIBSE )FMN, 3BMQI +PIOTPO BOE +PIO 7MJTTJEFT, DPNNPOMZ LOPXO BT UIF "(BOH PG 'PVS" ((P') CPPL. 4JODF UIF QVCMJDBUJPO PG Design Patterns, NBOZ PUIFS QBUUFSO CPPLT, PG WBSZJOH RVBMJUZ, IBWF CFFO XSJUUFO. 0OF GBNPVT QBUUFSOT CPPL JT DBMMFE Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions CZ (SFHPS )PIQF BOE #PCCZ 8PPMG. *U JT DPNNPO GPS QFPQMF UP SFGFS UP UIJT CPPL CZ JUT JOJUJBMT EIP. "T UIF TVCUJUMF PG &*1 TVHHFTUT, UIF CPPL GPDVTFT PO EFTJHO QBUUFSOT GPS BTZODISPOPVT NFTTBHJOH TZTUFNT. 5IF CPPL EJTDVTTFT 65 QBUUFSOT. &BDI QBUUFSO JT HJWFO B UFYUVBM OBNF BOE NPTU BSF BMTP HJWFO B HSBQIJDBM TZNCPM, JOUFOEFE UP CF VTFE JO BSDIJUFDUVSBM EJBHSBNT.

3'$ " ,$+ /1.)$"3


$BNFM (IUUQ://DBNFM.BQBDIF.PSH) JT BO PQFO-TPVSDF, +BWB-CBTFE QSPKFDU UIBU IFMQT UIF VTFS JNQMFNFOU NBOZ PG UIF EFTJHO QBUUFSOT JO UIF &*1 CPPL. #FDBVTF $BNFM JNQMFNFOUT NBOZ PG UIF EFTJHO QBUUFSOT JO UIF &*1 CPPL, JU XPVME CF B HPPE JEFB GPS QFPQMF XIP XPSL XJUI $BNFM UP IBWF UIF &*1 CPPL BT B SFGFSFODF.

.-+(-$ #."4,$-3 3(.- %.1 " ,$+


5IF EPDVNFOUBUJPO JT BMM VOEFS UIF %PDVNFOUBUJPO DBUFHPSZ PO UIF SJHIU-TJEF NFOV PG UIF $BNFM XFCTJUF (BMTP BWBJMBCMF JO 1%' GPSN. $BNFM-SFMBUFE CPPLT BSF BMTP BWBJMBCMF, JO QBSUJDVMBS UIF $BNFM JO "DUJPO CPPL, QSFTFOUMZ TFSWJOH BT UIF $BNFM CJCMF--JU IBT B GSFF $IBQUFS 0OF (QEG), XIJDI JT IJHIMZ SFDPNNFOEFE UP SFBE UP HFU NPSF GBNJMJBS XJUI $BNFM.

$ ) " 1 5 & 3 3 - ( &5 5 */ ( 45 "3 5 &% 8 *5 ) "1"$) & $". &-

RPBCRI QFM CLO K>SFD>QFKD QEB LKIFKB AL@RJBKQ>QFLK 5IF CSFBEDSVNCT BU UIF UPQ PG UIF POMJOF $BNFM EPDVNFOUBUJPO DBO IFMQ ZPV OBWJHBUF CFUXFFO QBSFOU BOE DIJME TVCTFDUJPOT. 'PS FYBNQMF, *G ZPV BSF PO UIF "-BOHVBHFT" EPDVNFOUBUJPO QBHF UIFO UIF MFGU-IBOE TJEF PG UIF SFEEJTI CBS DPOUBJOT UIF GPMMPXJOH MJOLT.
Apache Camel > Documentation > Architecture > Languages

"T ZPV NJHIU FYQFDU, DMJDLJOH PO ""QBDIF $BNFM" UBLFT ZPV CBDL UP UIF IPNF QBHF PG UIF "QBDIF $BNFM QSPKFDU, BOE DMJDLJOH PO "%PDVNFOUBUJPO" UBLFT ZPV UP UIF NBJO EPDVNFOUBUJPO QBHF. :PV DBO JOUFSQSFU UIF ""SDIJUFDUVSF" BOE "-BOHVBHFT" CVUUPOT BT JOEJDBUJOH ZPV BSF JO UIF "-BOHVBHFT" TFDUJPO PG UIF ""SDIJUFDUVSF" DIBQUFS. "EEJOH CSPXTFS CPPLNBSLT UP QBHFT UIBU ZPV GSFRVFOUMZ SFGFSFODF DBO BMTP TBWF UJNF.

.-+(-$ ) 5 #." #."4,$-3 3(.5IF "QBDIF $BNFM XFCTJUF QSPWJEFT +BWBEPD EPDVNFOUBUJPO. *U JT JNQPSUBOU UP OPUF UIBU UIF +BWBEPD EPDVNFOUBUJPO JT TQSFBE PWFS TFWFSBM independent +BWBEPD IJFSBSDIJFT SBUIFS UIBO CFJOH BMM DPOUBJOFE JO B TJOHMF +BWBEPD IJFSBSDIZ. *O QBSUJDVMBS, UIFSF JT POF +BWBEPD IJFSBSDIZ GPS UIF core "1*T PG $BNFM, BOE B TFQBSBUF +BWBEPD IJFSBSDIZ GPS FBDI DPNQPOFOU UFDIOPMPHZ TVQQPSUFE CZ $BNFM. 'PS FYBNQMF, JG ZPV XJMM CF VTJOH $BNFM XJUI "DUJWF.2 BOE '51 UIFO ZPV OFFE UP MPPL BU UIF +BWBEPD IJFSBSDIJFT GPS UIF DPSF "1* BOE 4QSJOH "1*.

".-"$/32

-# 3$1,(-.+.&8 %4-# ,$-3 + 3. " ,$+

*O UIJT TFDUJPO TPNF PG UIF DPODFQUT BOE UFSNJOPMPHZ UIBU BSF GVOEBNFOUBM UP $BNFM BSF FYQMBJOFE. 5IJT TFDUJPO JT OPU NFBOU BT B DPNQMFUF $BNFM UVUPSJBM, CVU BT B GJSTU TUFQ JO UIBU EJSFDUJPO. $KAMLFKQ 5IF UFSN endpoint JT PGUFO VTFE XIFO UBMLJOH BCPVU JOUFS-QSPDFTT DPNNVOJDBUJPO. 'PS FYBNQMF, JO DMJFOU-TFSWFS DPNNVOJDBUJPO, UIF DMJFOU JT POF FOEQPJOU BOE UIF TFSWFS JT UIF PUIFS FOEQPJOU. %FQFOEJOH PO UIF DPOUFYU, BO FOEQPJOU NJHIU SFGFS UP BO address, TVDI BT B IPTU:QPSU QBJS GPS 5$1-CBTFE DPNNVOJDBUJPO, PS JU NJHIU SFGFS UP B software entity UIBU JT DPOUBDUBCMF BU UIBU BEESFTT. 'PS FYBNQMF, JG TPNFCPEZ VTFT "XXX.FYBNQMF.DPN:80" BT BO FYBNQMF PG BO FOEQPJOU, UIFZ NJHIU CF SFGFSSJOH UP UIF BDUVBM QPSU BU UIBU IPTU OBNF (UIBU JT, BO BEESFTT), PS UIFZ NJHIU CF SFGFSSJOH UP UIF XFC TFSWFS (UIBU JT, TPGUXBSF DPOUBDUBCMF BU UIBU BEESFTT). 0GUFO, UIF EJTUJODUJPO CFUXFFO UIF BEESFTT BOE TPGUXBSF DPOUBDUBCMF BU UIBU BEESFTT JT OPU BO JNQPSUBOU POF. 4PNF NJEEMFXBSF UFDIOPMPHJFT NBLF JU QPTTJCMF GPS TFWFSBM TPGUXBSF FOUJUJFT UP CF DPOUBDUBCMF BU UIF TBNF QIZTJDBM BEESFTT. 'PS FYBNQMF, $03#" JT BO PCKFDU-PSJFOUFE, SFNPUF-QSPDFEVSF-

$) " 15& 3 3 - (& 5 5 * /( 4 5 " 3 5 & % 8 * 5 ) " 1"$) & $". &-

DBMM (31$) NJEEMFXBSF TUBOEBSE. *G B $03#" TFSWFS QSPDFTT DPOUBJOT TFWFSBM PCKFDUT UIFO B DMJFOU DBO DPNNVOJDBUF XJUI BOZ PG UIFTF PCKFDUT BU UIF TBNF physical BEESFTT (IPTU:QPSU), CVU B DMJFOU DPNNVOJDBUFT XJUI B QBSUJDVMBS PCKFDU WJB UIBU PCKFDU'T logical BEESFTT (DBMMFE BO IOR JO $03#" UFSNJOPMPHZ), XIJDI DPOTJTUT PG UIF QIZTJDBM BEESFTT (IPTU:QPSU) QMVT BO JE UIBU VOJRVFMZ JEFOUJGJFT UIF PCKFDU XJUIJO JUT TFSWFS QSPDFTT. ("O *03 DPOUBJOT TPNF BEEJUJPOBM JOGPSNBUJPO UIBU JT OPU SFMFWBOU UP UIJT QSFTFOU EJTDVTTJPO.) 8IFO UBMLJOH BCPVU $03#", TPNF QFPQMF NBZ VTF UIF UFSN "FOEQPJOU" UP SFGFS UP B $03#" TFSWFS'T physical address, XIJMF PUIFS QFPQMF NBZ VTF UIF UFSN UP SFGFS UP UIF logical address PG B TJOHMF $03#" PCKFDU, BOE PUIFS QFPQMF TUJMM NJHIU VTF UIF UFSN UP SFGFS UP BOZ PG UIF GPMMPXJOH: ` 5IF QIZTJDBM BEESFTT (IPTU:QPSU) PG UIF $03#" TFSWFS QSPDFTT ` 5IF MPHJDBM BEESFTT (IPTU:QPSU QMVT JE) PG B $03#" PCKFDU. ` 5IF $03#" TFSWFS QSPDFTT (B SFMBUJWFMZ IFBWZXFJHIU TPGUXBSF FOUJUZ) ` " $03#" PCKFDU (B MJHIUXFJHIU TPGUXBSF FOUJUZ) #FDBVTF PG UIJT, ZPV DBO TFF UIBU UIF UFSN endpoint JT BNCJHVPVT JO BU MFBTU UXP XBZT. 'JSTU, JU JT BNCJHVPVT CFDBVTF JU NJHIU SFGFS UP BO BEESFTT PS UP B TPGUXBSF FOUJUZ DPOUBDUBCMF BU UIBU BEESFTT. 4FDPOE, JU JT BNCJHVPVT JO UIF granularity PG XIBU JU SFGFST UP: B IFBWZXFJHIU WFSTVT MJHIUXFJHIU TPGUXBSF FOUJUZ, PS QIZTJDBM BEESFTT WFSTVT MPHJDBM BEESFTT. *U JT VTFGVM UP VOEFSTUBOE UIBU EJGGFSFOU QFPQMF VTF UIF UFSN endpoint JO TMJHIUMZ EJGGFSFOU (BOE IFODF BNCJHVPVT) XBZT CFDBVTF $BNFM'T VTBHF PG UIJT UFSN NJHIU CF EJGGFSFOU UP XIBUFWFS NFBOJOH ZPV IBE QSFWJPVTMZ BTTPDJBUFE XJUI UIF UFSN. $BNFM QSPWJEFT PVU-PG-UIF-CPY TVQQPSU GPS FOEQPJOUT JNQMFNFOUFE XJUI NBOZ EJGGFSFOU DPNNVOJDBUJPO UFDIOPMPHJFT. )FSF BSF TPNF FYBNQMFT PG UIF $BNFM-TVQQPSUFE FOEQPJOU UFDIOPMPHJFT. ` " +.4 RVFVF. ` " XFC TFSWJDF. ` " GJMF. " GJMF NBZ TPVOE MJLF BO VOMJLFMZ UZQF PG FOEQPJOU, VOUJM ZPV SFBMJ[F UIBU JO TPNF TZTUFNT POF BQQMJDBUJPO NJHIU XSJUF JOGPSNBUJPO UP B GJMF BOE, MBUFS, BOPUIFS BQQMJDBUJPO NJHIU SFBE UIBU GJMF. ` "O '51 TFSWFS. ` "O FNBJM BEESFTT. " DMJFOU DBO TFOE B NFTTBHF UP BO FNBJM BEESFTT, BOE B TFSWFS DBO SFBE BO JODPNJOH NFTTBHF GSPN B NBJM TFSWFS. ` " 10+0 (QMBJO PME +BWB PCKFDU). *O B $BNFM-CBTFE BQQMJDBUJPO, ZPV DSFBUF ($BNFM XSBQQFST BSPVOE) TPNF FOEQPJOUT BOE DPOOFDU UIFTF FOEQPJOUT XJUI routes, XIJDI * XJMM EJTDVTT MBUFS JO 4FDUJPO 4.8 ("3PVUFT, 3PVUF#VJMEFST BOE +BWB %4-"). $BNFM EFGJOFT B +BWB JOUFSGBDF DBMMFE Endpoint. &BDI $BNFMTVQQPSUFE FOEQPJOU IBT B DMBTT UIBU JNQMFNFOUT UIJT Endpoint JOUFSGBDF. "T * EJTDVTTFE JO 4FDUJPO 3.3 ("0OMJOF +BWBEPD EPDVNFOUBUJPO"), $BNFM QSPWJEFT B TFQBSBUF +BWBEPD IJFSBSDIZ GPS FBDI DPNNVOJDBUJPOT UFDIOPMPHZ TVQQPSUFE CZ $BNFM. #FDBVTF PG UIJT, ZPV XJMM GJOE EPDVNFOUBUJPO PO, TBZ, UIF JmsEndpoint DMBTT JO UIF +.4 +BWBEPD IJFSBSDIZ, XIJMF EPDVNFOUBUJPO GPS, TBZ, UIF FtpEndpoint DMBTT JT JO UIF '51 +BWBEPD IJFSBSDIZ.

$ ) " 1 5 & 3 3 - ( &5 5 */ ( 45 "3 5 &% 8 *5 ) "1"$) & $". &-

">JBI"LKQBUQ " CamelContext PCKFDU SFQSFTFOUT UIF $BNFM SVOUJNF TZTUFN. :PV UZQJDBMMZ IBWF POF CamelContext PCKFDU JO BO BQQMJDBUJPO. " UZQJDBM BQQMJDBUJPO FYFDVUFT UIF GPMMPXJOH TUFQT. 1. $SFBUF B CamelContext PCKFDU. 2. "EE FOEQPJOUT f BOE QPTTJCMZ $PNQPOFOUT, XIJDI BSF EJTDVTTFE JO 4FDUJPO 4.5 ("$PNQPOFOUT") f UP UIF CamelContext PCKFDU. 3. "EE SPVUFT UP UIF CamelContext PCKFDU UP DPOOFDU UIF FOEQPJOUT. 4. *OWPLF UIF start() PQFSBUJPO PO UIF CamelContext PCKFDU. 5IJT TUBSUT $BNFMJOUFSOBM UISFBET UIBU BSF VTFE UP QSPDFTT UIF TFOEJOH, SFDFJWJOH BOE QSPDFTTJOH PG NFTTBHFT JO UIF FOEQPJOUT. 5. &WFOUVBMMZ JOWPLF UIF stop() PQFSBUJPO PO UIF CamelContext PCKFDU. %PJOH UIJT HSBDFGVMMZ TUPQT BMM UIF FOEQPJOUT BOE $BNFM-JOUFSOBM UISFBET. /PUF UIBU UIF CamelContext.start() PQFSBUJPO EPFT OPU CMPDL JOEFGJOJUFMZ. 3BUIFS, JU TUBSUT UISFBET JOUFSOBM UP FBDI Component BOE Endpoint BOE UIFO start() SFUVSOT. $POWFSTFMZ, CamelContext.stop() XBJUT GPS BMM UIF UISFBET JOUFSOBM UP FBDI Endpoint BOE Component UP UFSNJOBUF BOE UIFO stop() SFUVSOT. *G ZPV OFHMFDU UP DBMM CamelContext.start() JO ZPVS BQQMJDBUJPO UIFO NFTTBHFT XJMM OPU CF QSPDFTTFE CFDBVTF JOUFSOBM UISFBET XJMM OPU IBWF CFFO DSFBUFE. *G ZPV OFHMFDU UP DBMM CamelContext.stop() CFGPSF UFSNJOBUJOH ZPVS BQQMJDBUJPO UIFO UIF BQQMJDBUJPO NBZ UFSNJOBUF JO BO JODPOTJTUFOU TUBUF. *G ZPV OFHMFDU UP DBMM CamelContext.stop() JO B +6OJU UFTU UIFO UIF UFTU NBZ GBJM EVF UP NFTTBHFT OPU IBWJOH IBE B DIBODF UP CF GVMMZ QSPDFTTFE. ">JBI3BJMI>QB $BNFM VTFE UP IBWF B DMBTT DBMMFE CamelClient, CVU UIJT XBT SFOBNFE UP CF CamelTemplate UP CF TJNJMBS UP B OBNJOH DPOWFOUJPO VTFE JO TPNF PUIFS PQFO-TPVSDF QSPKFDUT, TVDI BT UIF TransactionTemplate BOE JmsTemplate DMBTTFT JO 4QSJOH. 5IF CamelTemplate DMBTT JT B UIJO XSBQQFS BSPVOE UIF CamelContext DMBTT. *U IBT NFUIPET UIBU TFOE B Message PS Exchange f CPUI EJTDVTTFE JO 4FDUJPO 4.6 (".FTTBHF BOE &YDIBOHF")) f UP BO Endpoint f EJTDVTTFE JO 4FDUJPO 4.1 ("&OEQPJOU"). 5IJT QSPWJEFT B XBZ UP FOUFS NFTTBHFT JOUP TPVSDF FOEQPJOUT, TP UIBU UIF NFTTBHFT XJMM NPWF BMPOH SPVUFT f EJTDVTTFE JO 4FDUJPO 4.8 ("3PVUFT, 3PVUF#VJMEFST BOE +BWB %4-") f UP EFTUJOBUJPO FOEQPJOUT. 3EB ,B>KFKD LC 41+, 41(, 41- >KA (1( 4PNF $BNFM NFUIPET UBLF B QBSBNFUFS UIBU JT B URI TUSJOH. .BOZ QFPQMF LOPX UIBU B 63* JT "TPNFUIJOH MJLF B 63-" CVU EP OPU QSPQFSMZ VOEFSTUBOE UIF SFMBUJPOTIJQ CFUXFFO 63* BOE 63-, PS JOEFFE JUT SFMBUJPOTIJQ XJUI PUIFS BDSPOZNT TVDI BT *3* BOE 63/. .PTU QFPQMF BSF GBNJMJBS XJUI URLs (VOJGPSN SFTPVSDF MPDBUPST), TVDI BT "IUUQ://...", "GUQ://...", "NBJMUP:...". 1VU TJNQMZ, B 63- TQFDJGJFT UIF location PG B SFTPVSDF. " URI (VOJGPSN SFTPVSDF JEFOUJGJFS) JT B 63- or B 63/. 4P, UP GVMMZ VOEFSTUBOE XIBU 63* NFBOT,

10

$) " 15& 3 3 - (& 5 5 * /( 4 5 " 3 5 & % 8 * 5 ) " 1"$) & $". &-

ZPV OFFE UP GJSTU VOEFSTUBOE XIBU JT B 63/. URN JT BO BDSPOZN GPS uniform resource name. 5IFSF BSF NBZ "VOJRVF JEFOUJGJFS" TDIFNFT JO UIF XPSME, GPS FYBNQMF, *4#/T (HMPCBMMZ VOJRVF GPS CPPLT), TPDJBM TFDVSJUZ OVNCFST (VOJRVF XJUIJO B DPVOUSZ), DVTUPNFS OVNCFST (VOJRVF XJUIJO B DPNQBOZ'T DVTUPNFST EBUBCBTF) BOE UFMFQIPOF OVNCFST. &BDI "VOJRVF JEFOUJGJFS" TDIFNF IBT JUT PXO OPUBUJPO. " 63/ JT B XSBQQFS GPS EJGGFSFOU "VOJRVF JEFOUJGJFS" TDIFNFT. 5IF TZOUBY PG B 63/ JT "VSO:<TDIFNF-OBNF>:<VOJRVFJEFOUJGJFS>". " 63/ VOJRVFMZ JEFOUJGJFT B resource, TVDI BT B CPPL, QFSTPO PS QJFDF PG FRVJQNFOU. #Z JUTFMG, B 63/ EPFT OPU TQFDJGZ UIF location PG UIF SFTPVSDF. *OTUFBE, JU JT BTTVNFE UIBU B registry QSPWJEFT B NBQQJOH GSPN B SFTPVSDF'T 63/ UP JUT MPDBUJPO. 5IF 63/ TQFDJGJDBUJPO EPFT OPU TUBUF XIBU GPSN B SFHJTUSZ UBLFT, CVU JU NJHIU CF B EBUBCBTF, B TFSWFS BQQMJDBUJPO, B XBMM DIBSU PS BOZUIJOH FMTF UIBU JT DPOWFOJFOU. 4PNF IZQPUIFUJDBM FYBNQMFT PG 63/T BSF "VSO:FNQMPZFF:08765245", "VSO:DVTUPNFS:VL:3458:IVM8" BOE "VSO:GPP:0000-0000-9&59-0000-5&-2". 5IF <TDIFNF-OBNF> ("FNQMPZFF", "DVTUPNFS" BOE "GPP" JO UIFTF FYBNQMFT) QBSU PG B 63/ JNQMJDJUMZ EFGJOFT IPX UP QBSTF BOE JOUFSQSFU UIF <VOJRVFJEFOUJGJFS> UIBU GPMMPXT JU. "O BSCJUSBSZ 63/ JT NFBOJOHMFTT VOMFTT: (1) ZPV LOPX UIF TFNBOUJDT JNQMJFE CZ UIF <TDIFNF-OBNF>, BOE (2) ZPV IBWF BDDFTT UP UIF SFHJTUSZ BQQSPQSJBUF GPS UIF <TDIFNF-OBNF>. " SFHJTUSZ EPFT OPU IBWF UP CF QVCMJD PS HMPCBMMZ BDDFTTJCMF. 'PS FYBNQMF, "VSO:FNQMPZFF:08765245" NJHIU CF NFBOJOHGVM POMZ XJUIJO B TQFDJGJD DPNQBOZ. 5P EBUF, 63/T BSF OPU (ZFU) BT QPQVMBS BT 63-T. 'PS UIJT SFBTPO, 63* JT XJEFMZ NJTVTFE BT B TZOPOZN GPS 63-. IRI JT BO BDSPOZN GPS internationalized resource identifier. "O *3* JT TJNQMZ BO JOUFSOBUJPOBMJ[FE WFSTJPO PG B 63*. *O QBSUJDVMBS, B 63* DBO DPOUBJO MFUUFST BOE EJHJUT JO UIF 64-"4$** DIBSBDUFS TFU, XIJMF B *3* DBO DPOUBJO UIPTF TBNF MFUUFST BOE EJHJUT, BOE also &VSPQFBO BDDFOUFE DIBSBDUFST, (SFFL MFUUFST, $IJOFTF JEFPHSBNT BOE TP PO. "LJMLKBKQP Component JT DPOGVTJOH UFSNJOPMPHZ; EndpointFactory XPVME IBWF CFFO NPSF BQQSPQSJBUF CFDBVTF B Component JT B GBDUPSZ GPS DSFBUJOH Endpoint JOTUBODFT. 'PS FYBNQMF, JG B $BNFM-CBTFE BQQMJDBUJPO VTFT TFWFSBM +.4 RVFVFT UIFO UIF BQQMJDBUJPO XJMM DSFBUF POF JOTUBODF PG UIF JmsComponent DMBTT (XIJDI JNQMFNFOUT UIF Component JOUFSGBDF), BOE UIFO UIF BQQMJDBUJPO JOWPLFT UIF createEndpoint() PQFSBUJPO PO UIJT JmsComponent PCKFDU TFWFSBM UJNFT. &BDI JOWPDBUJPO PG JmsComponent.createEndpoint() DSFBUFT BO JOTUBODF PG UIF JmsEndpoint DMBTT (XIJDI JNQMFNFOUT UIF Endpoint JOUFSGBDF). "DUVBMMZ, BQQMJDBUJPO-MFWFM DPEF EPFT OPU JOWPLF Component.createEndpoint() EJSFDUMZ. *OTUFBE, BQQMJDBUJPO-MFWFM DPEF OPSNBMMZ JOWPLFT CamelContext.getEndpoint(); JOUFSOBMMZ, UIF CamelContext PCKFDU GJOET UIF EFTJSFE Component PCKFDU (BT * XJMM EJTDVTT TIPSUMZ) BOE UIFO JOWPLFT createEndpoint() PO JU. $POTJEFS UIF GPMMPXJOH DPEF.
myCamelContext.getEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword");

$ ) " 1 5 & 3 3 - ( &5 5 */ ( 45 "3 5 &% 8 *5 ) "1"$) & $". &-

11

5IF QBSBNFUFS UP getEndpoint() JT B 63*. 5IF 63* prefix (UIBU JT, UIF QBSU CFGPSF ":") TQFDJGJFT UIF OBNF PG B DPNQPOFOU. *OUFSOBMMZ, UIF CamelContext PCKFDU NBJOUBJOT B NBQQJOH GSPN OBNFT PG DPNQPOFOUT UP Component PCKFDUT. 'PS UIF 63* HJWFO JO UIF BCPWF FYBNQMF, UIF CamelContext PCKFDU XPVME QSPCBCMZ NBQ UIF pop3 QSFGJY UP BO JOTUBODF PG UIF MailComponent DMBTT. 5IFO UIF CamelContext PCKFDU JOWPLFT createEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword" PO UIBU MailComponent PCKFDU. 5IF createEndpoint() PQFSBUJPO TQMJUT UIF 63* JOUP JUT DPNQPOFOU QBSUT BOE VTFT UIFTF QBSUT UP DSFBUF BOE DPOGJHVSF BO Endpoint PCKFDU. *O UIF QSFWJPVT QBSBHSBQI, * NFOUJPOFE UIBU B CamelContext PCKFDU NBJOUBJOT B NBQQJOH GSPN DPNQPOFOU OBNFT UP Component PCKFDUT. 5IJT SBJTFT UIF RVFTUJPO PG IPX UIJT NBQ JT QPQVMBUFE XJUI OBNFE Component PCKFDUT. 5IFSF BSF UXP XBZT PG QPQVMBUJOH UIF NBQ. 5IF GJSTU XBZ JT GPS BQQMJDBUJPO-MFWFM DPEF UP JOWPLF CamelContext.addComponent(String componentName, Component component). 5IF FYBNQMF CFMPX TIPXT B TJOHMF MailComponent PCKFDU CFJOH SFHJTUFSFE JO UIF NBQ VOEFS 3 EJGGFSFOU OBNFT.
Component mailComponent = new org.apache.camel.component.mail.MailComponent(); myCamelContext.addComponent("pop3", mailComponent); myCamelContext.addComponent("imap", mailComponent); myCamelContext.addComponent("smtp", mailComponent);

5IF TFDPOE (BOE QSFGFSSFE) XBZ UP QPQVMBUF UIF NBQ PG OBNFE Component PCKFDUT JO UIF CamelContext PCKFDU JT UP MFU UIF CamelContext PCKFDU QFSGPSN MB[Z JOJUJBMJ[BUJPO. 5IJT BQQSPBDI SFMJFT PO EFWFMPQFST GPMMPXJOH B DPOWFOUJPO XIFO UIFZ XSJUF B DMBTT UIBU JNQMFNFOUT UIF Component JOUFSGBDF. * JMMVTUSBUF UIF DPOWFOUJPO CZ BO FYBNQMF. -FU'T BTTVNF ZPV XSJUF B DMBTT DBMMFE com.example.myproject.FooComponent BOE ZPV XBOU $BNFM UP BVUPNBUJDBMMZ SFDPHOJ[F UIJT CZ UIF OBNF "GPP". 5P EP UIJT, ZPV IBWF UP XSJUF B QSPQFSUJFT GJMF DBMMFE ".&5"-*/'/TFSWJDFT/PSH/BQBDIF/DBNFM/DPNQPOFOU/GPP" (XJUIPVU B ".QSPQFSUJFT" GJMF FYUFOTJPO) UIBU IBT B TJOHMF FOUSZ JO JU DBMMFE class, UIF WBMVF PG XIJDI JT UIF GVMMZ-TDPQFE OBNF PG ZPVS DMBTT. 5IJT JT TIPXO CFMPX.
Listing 1. META-INF/services/org/apache/camel/component/foo
class=com.example.myproject.FooComponent

*G ZPV XBOU $BNFM UP BMTP SFDPHOJ[F UIF DMBTT CZ UIF OBNF "CBS" UIFO ZPV XSJUF BOPUIFS QSPQFSUJFT GJMF JO UIF TBNF EJSFDUPSZ DBMMFE "CBS" UIBU IBT UIF TBNF DPOUFOUT. 0ODF ZPV IBWF XSJUUFO UIF QSPQFSUJFT GJMF(T), ZPV DSFBUF B KBS GJMF UIBU DPOUBJOT UIF com.example.myproject.FooComponent DMBTT BOE UIF QSPQFSUJFT GJMF(T), BOE ZPV BEE UIJT KBS GJMF UP ZPVS $-"441"5). 5IFO, XIFO BQQMJDBUJPO-MFWFM DPEF JOWPLFT createEndpoint("foo:...") PO B CamelContext PCKFDU, $BNFM XJMM GJOE UIF "GPP"" QSPQFSUJFT GJMF PO UIF $-"441"5), HFU UIF WBMVF PG UIF class QSPQFSUZ GSPN UIBU QSPQFSUJFT GJMF, BOE VTF SFGMFDUJPO "1*T UP DSFBUF BO JOTUBODF PG UIF TQFDJGJFE DMBTT. "T * TBJE JO 4FDUJPO 4.1 ("&OEQPJOU"), $BNFM QSPWJEFT PVU-PG-UIF-CPY TVQQPSU GPS OVNFSPVT DPNNVOJDBUJPO UFDIOPMPHJFT. 5IF PVU-PG-UIF-CPY TVQQPSU DPOTJTUT PG DMBTTFT UIBU JNQMFNFOU UIF

12

$) " 15& 3 3 - (& 5 5 * /( 4 5 " 3 5 & % 8 * 5 ) " 1"$) & $". &-

Component JOUFSGBDF QMVT QSPQFSUJFT GJMFT UIBU FOBCMF B CamelContext PCKFDU UP QPQVMBUF JUT NBQ PG OBNFE Component PCKFDUT. &BSMJFS JO UIJT TFDUJPO * HBWF UIF GPMMPXJOH FYBNQMF PG DBMMJOH CamelContext.getEndpoint().
myCamelContext.getEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword");

8IFO * PSJHJOBMMZ HBWF UIBU FYBNQMF, * TBJE UIBU UIF QBSBNFUFS UP getEndpoint() XBT B 63*. * TBJE UIBU CFDBVTF UIF POMJOF $BNFM EPDVNFOUBUJPO BOE UIF $BNFM TPVSDF DPEF CPUI DMBJN UIF QBSBNFUFS JT B 63*. *O SFBMJUZ, UIF QBSBNFUFS JT SFTUSJDUFE UP CFJOH B 63-. 5IJT JT CFDBVTF XIFO $BNFM FYUSBDUT UIF DPNQPOFOU OBNF GSPN UIF QBSBNFUFS, JU MPPLT GPS UIF GJSTU ":", XIJDI JT B TJNQMJTUJD BMHPSJUIN. 5P VOEFSTUBOE XIZ, SFDBMM GSPN 4FDUJPO 4.4 ("5IF .FBOJOH PG 63-, 63*, 63/ BOE *3*") UIBU B 63* DBO CF B 63- or B 63/. /PX DPOTJEFS UIF GPMMPXJOH DBMMT UP getEndpoint.
myCamelContext.getEndpoint("pop3:..."); myCamelContext.getEndpoint("jms:..."); myCamelContext.getEndpoint("urn:foo:..."); myCamelContext.getEndpoint("urn:bar:...");

$BNFM JEFOUJGJFT UIF DPNQPOFOUT JO UIF BCPWF FYBNQMF BT "QPQ3", "KNT", "VSO" BOE "VSO". *U XPVME CF NPSF VTFGVM JG UIF MBUUFS DPNQPOFOUT XFSF JEFOUJGJFE BT "VSO:GPP" BOE "VSO:CBS" PS, BMUFSOBUJWFMZ, BT "GPP" BOE "CBS" (UIBU JT, CZ TLJQQJOH PWFS UIF "VSO:" QSFGJY). 4P, JO QSBDUJDF ZPV NVTU JEFOUJGZ BO FOEQPJOU XJUI B 63- (B TUSJOH PG UIF GPSN "<TDIFNF>:...") SBUIFS UIBO XJUI B 63/ (B TUSJOH PG UIF GPSN "VSO:<TDIFNF>:..."). 5IJT MBDL PG QSPQFS TVQQPSU GPS 63/T NFBOT UIF ZPV TIPVME DPOTJEFS UIF QBSBNFUFS UP getEndpoint() BT CFJOH B 63- SBUIFS UIBO (BT DMBJNFE) B 63*. ,BPP>DB >KA $U@E>KDB 5IF Message JOUFSGBDF QSPWJEFT BO BCTUSBDUJPO GPS B TJOHMF NFTTBHF, TVDI BT B SFRVFTU, SFQMZ PS FYDFQUJPO NFTTBHF. 5IFSF BSF DPODSFUF DMBTTFT UIBU JNQMFNFOU UIF Message JOUFSGBDF GPS FBDI $BNFM-TVQQPSUFE DPNNVOJDBUJPOT UFDIOPMPHZ. 'PS FYBNQMF, UIF JmsMessage DMBTT QSPWJEFT B +.4-TQFDJGJD JNQMFNFOUBUJPO PG UIF Message JOUFSGBDF. 5IF QVCMJD "1* PG UIF Message JOUFSGBDF QSPWJEFT HFU- BOE TFU-TUZMF NFUIPET UP BDDFTT UIF message id, body BOE JOEJWJEVBM header GJFMET PG B NFTTHF. 5IF Exchange JOUFSGBDF QSPWJEFT BO BCTUSBDUJPO GPS BO FYDIBOHF PG NFTTBHFT, UIBU JT, B SFRVFTU NFTTBHF BOE JUT DPSSFTQPOEJOH SFQMZ PS FYDFQUJPO NFTTBHF. *O $BNFM UFSNJOPMPHZ, UIF SFRVFTU, SFQMZ BOE FYDFQUJPO NFTTBHFT BSF DBMMFE in, out BOE fault NFTTBHFT. 5IFSF BSF DPODSFUF DMBTTFT UIBU JNQMFNFOU UIF Exchange JOUFSGBDF GPS FBDI $BNFM-TVQQPSUFE DPNNVOJDBUJPOT UFDIOPMPHZ. 'PS FYBNQMF, UIF JmsExchange DMBTT QSPWJEFT B +.4-TQFDJGJD JNQMFNFOUBUJPO PG UIF Exchange JOUFSGBDF. 5IF QVCMJD "1* PG UIF Exchange JOUFSGBDF JT RVJUF

$ ) " 1 5 & 3 3 - ( &5 5 */ ( 45 "3 5 &% 8 *5 ) "1"$) & $". &-

13

MJNJUFE. 5IJT JT JOUFOUJPOBM, BOE JU JT FYQFDUFE UIBU FBDI DMBTT UIBU JNQMFNFOUT UIJT JOUFSGBDF XJMM QSPWJEF JUT PXO UFDIOPMPHZ-TQFDJGJD PQFSBUJPOT. "QQMJDBUJPO-MFWFM QSPHSBNNFST SBSFMZ BDDFTT UIF Exchange JOUFSGBDF (PS DMBTTFT UIBU JNQMFNFOU JU) EJSFDUMZ. )PXFWFS, NBOZ DMBTTFT JO $BNFM BSF HFOFSJD UZQFT UIBU BSF JOTUBOUJBUFE PO (B DMBTT UIBU JNQMFNFOUT) Exchange. #FDBVTF PG UIJT, UIF Exchange JOUFSGBDF BQQFBST B MPU JO UIF HFOFSJD TJHOBUVSFT PG DMBTTFT BOE NFUIPET. /OL@BPPLO 5IF Processor JOUFSGBDF SFQSFTFOUT B DMBTT UIBU QSPDFTTFT B NFTTBHF. 5IF TJHOBUVSF PG UIJT JOUFSGBDF JT TIPXO CFMPX.
Listing 1. Processor
package org.apache.camel; public interface Processor { void process(Exchange exchange) throws Exception; }

/PUJDF UIBU UIF QBSBNFUFS UP UIF process() NFUIPE JT BO Exchange SBUIFS UIBO B Message. 5IJT QSPWJEFT GMFYJCJMJUZ. 'PS FYBNQMF, BO JNQMFNFOUBUJPO PG UIJT NFUIPE JOJUJBMMZ NJHIU DBMM exchange.getIn() UP HFU UIF JOQVU NFTTBHF BOE QSPDFTT JU. *G BO FSSPS PDDVST EVSJOH QSPDFTTJOH UIFO UIF NFUIPE DBO DBMM exchange.setException(). "O BQQMJDBUJPO-MFWFM EFWFMPQFS NJHIU JNQMFNFOU UIF Processor JOUFSGBDF XJUI B DMBTT UIBU FYFDVUFT TPNF CVTJOFTT MPHJD. )PXFWFS, UIFSF BSF NBOZ DMBTTFT JO UIF $BNFM MJCSBSZ UIBU JNQMFNFOU UIF Processor JOUFSGBDF JO B XBZ UIBU QSPWJEFT TVQQPSU GPS B EFTJHO QBUUFSO JO UIF &*1 CPPL. 'PS FYBNQMF, ChoiceProcessor JNQMFNFOUT UIF NFTTBHF SPVUFS QBUUFSO, UIBU JT, JU VTFT B DBTDBEJOH JG-UIFO-FMTF TUBUFNFOU UP SPVUF B NFTTBHF GSPN BO JOQVU RVFVF UP POF PG TFWFSBM PVUQVU RVFVFT. "OPUIFS FYBNQMF JT UIF FilterProcessor DMBTT XIJDI EJTDBSET NFTTBHFT UIBU EP OPU TBUJTGZ B TUBUFE predicate (UIBU JT, DPOEJUJPO). 1LRQBP, 1LRQB!RFIABOP >KA )>S> #2+ " route JT UIF TUFQ-CZ-TUFQ NPWFNFOU PG B Message GSPN BO JOQVU RVFVF, UISPVHI BSCJUSBSZ UZQFT PG EFDJTJPO NBLJOH (TVDI BT GJMUFST BOE SPVUFST) UP B EFTUJOBUJPO RVFVF (JG BOZ). $BNFM QSPWJEFT UXP XBZT GPS BO BQQMJDBUJPO EFWFMPQFS UP TQFDJGZ SPVUFT. 0OF XBZ JT UP TQFDJGZ SPVUF JOGPSNBUJPO JO BO 9.- GJMF. " EJTDVTTJPO PG UIBU BQQSPBDI JT PVUTJEF UIF TDPQF PG UIJT EPDVNFOU. 5IF PUIFS XBZ JT UISPVHI XIBU $BNFM DBMMT B +BWB DSL (EPNBJO-TQFDJGJD MBOHVBHF).

(KQOLAR@QFLK QL )>S> #2+


'PS NBOZ QFPQMF, UIF UFSN "EPNBJO-TQFDJGJD MBOHVBHF" JNQMJFT B DPNQJMFS PS JOUFSQSFUFS UIBU DBO QSPDFTT BO JOQVU GJMF DPOUBJOJOH LFZXPSET BOE TZOUBY TQFDJGJD UP B QBSUJDVMBS EPNBJO. 5IJT JT not UIF BQQSPBDI UBLFO CZ $BNFM. $BNFM EPDVNFOUBUJPO DPOTJTUFOUMZ VTFT UIF UFSN "+BWB %4-"

14

$) " 15& 3 3 - (& 5 5 * /( 4 5 " 3 5 & % 8 * 5 ) " 1"$) & $". &-

JOTUFBE PG "%4-", CVU UIJT EPFT OPU FOUJSFMZ BWPJE QPUFOUJBM DPOGVTJPO. 5IF $BNFM "+BWB %4-" JT B DMBTT MJCSBSZ UIBU DBO CF VTFE JO B XBZ UIBU MPPLT BMNPTU MJLF B %4-, FYDFQU UIBU JU IBT B CJU PG +BWB TZOUBDUJD CBHHBHF. :PV DBO TFF UIJT JO UIF FYBNQMF CFMPX. $PNNFOUT BGUFSXBSET FYQMBJO TPNF PG UIF DPOTUSVDUT VTFE JO UIF FYBNQMF.
Listing 1. Example of Camel's "Java DSL"
RouteBuilder builder = new RouteBuilder() { public void configure() { from("queue:a").filter(header("foo").isEqualTo("bar")).to("queue:b"); from("queue:c").choice() .when(header("foo").isEqualTo("bar")).to("queue:d") .when(header("foo").isEqualTo("cheese")).to("queue:e") .otherwise().to("queue:f"); } }; CamelContext myCamelContext = new DefaultCamelContext(); myCamelContext.addRoutes(builder);

5IF GJSTU MJOF JO UIF BCPWF FYBNQMF DSFBUFT BO PCKFDU XIJDI JT BO JOTUBODF PG BO BOPOZNPVT TVCDMBTT PG RouteBuilder XJUI UIF TQFDJGJFE configure() NFUIPE. 5IF CamelContext.addRoutes(RouterBuilder builder) NFUIPE JOWPLFT builder.setContext(this) f TP UIF RouteBuilder PCKFDU LOPXT XIJDI CamelContext PCKFDU JU JT BTTPDJBUFE XJUI f BOE UIFO JOWPLFT builder.configure(). 5IF CPEZ PG configure() JOWPLFT NFUIPET TVDI BT from(), filter(), choice(), when(), isEqualTo(), otherwise() BOE to(). 5IF RouteBuilder.from(String uri) NFUIPE JOWPLFT getEndpoint(uri) PO UIF CamelContext BTTPDJBUFE XJUI UIF RouteBuilder PCKFDU UP HFU UIF TQFDJGJFE Endpoint BOE UIFO QVUT B FromBuilder "XSBQQFS" BSPVOE UIJT Endpoint. 5IF FromBuilder.filter(Predicate predicate) NFUIPE DSFBUFT B FilterProcessor PCKFDU GPS UIF Predicate (UIBU JT, DPOEJUJPO) PCKFDU CVJMU GSPN UIF header("foo").isEqualTo("bar") FYQSFTTJPO. *O UIJT XBZ, UIFTF PQFSBUJPOT JODSFNFOUBMMZ CVJME VQ B Route PCKFDU (XJUI B RouteBuilder XSBQQFS BSPVOE JU) BOE BEE JU UP UIF CamelContext PCKFDU BTTPDJBUFE XJUI UIF RouteBuilder.

"OFQFNRB LC )>S> #2+


5IF POMJOF $BNFM EPDVNFOUBUJPO DPNQBSFT +BWB %4- GBWPVSBCMZ BHBJOTU UIF BMUFSOBUJWF PG DPOGJHVSJOH SPVUFT BOE FOEQPJOUT JO B 9.--CBTFE 4QSJOH DPOGJHVSBUJPO GJMF. *O QBSUJDVMBS, +BWB %4- JT MFTT WFSCPTF UIBO JUT 9.- DPVOUFSQBSU. *O BEEJUJPO, NBOZ JOUFHSBUFE EFWFMPQNFOU FOWJSPONFOUT (*%&T) QSPWJEF BO BVUP-DPNQMFUJPO GFBUVSF JO UIFJS FEJUPST. 5IJT BVUP-DPNQMFUJPO GFBUVSF XPSLT XJUI +BWB %4-, UIFSFCZ NBLJOH JU FBTJFS GPS EFWFMPQFST UP XSJUF +BWB %4-. )PXFWFS, UIFSF JT BOPUIFS PQUJPO UIBU UIF $BNFM EPDVNFOUBUJPO OFHMFDUT UP DPOTJEFS: UIBU PG XSJUJOH B QBSTFS UIBU DBO QSPDFTT %4- TUPSFE JO, TBZ, BO FYUFSOBM GJMF. $VSSFOUMZ, $BNFM EPFT OPU QSPWJEF TVDI B %4- QBSTFS, BOE * EP OPU LOPX JG JU JT PO UIF "UP EP" MJTU PG UIF $BNFM

$ ) " 1 5 & 3 3 - ( &5 5 */ ( 45 "3 5 &% 8 *5 ) "1"$) & $". &-

15

NBJOUBJOFST. * UIJOL UIBU B %4- QBSTFS XPVME PGGFS B TJHOJGJDBOU CFOFGJU PWFS UIF DVSSFOU +BWB %4-. *O QBSUJDVMBS, UIF %4- XPVME IBWF B TZOUBDUJD EFGJOJUJPO UIBU DPVME CF FYQSFTTFE JO B SFMBUJWFMZ TIPSU #/' GPSN. 5IF FGGPSU SFRVJSFE CZ B $BNFM VTFS UP MFBSO IPX UP VTF %4- CZ SFBEJOH UIJT #/' XPVME BMNPTU DFSUBJOMZ CF TJHOJGJDBOUMZ MFTT UIBO UIF FGGPSU DVSSFOUMZ SFRVJSFE UP TUVEZ UIF "1* PG UIF RouterBuilder DMBTTFT. "LKQFKRB +B>OKFKD >?LRQ ">JBI 3FUVSO UP UIF NBJO (FUUJOH 4UBSUFE QBHF GPS BEEJUJPOBM JOUSPEVDUPSZ SFGFSFODF JOGPSNBUJPO.

16

$) " 15& 3 3 - (& 5 5 * /( 4 5 " 3 5 & % 8 * 5 ) " 1"$) & $". &-

"' YYYY

/3$1

O@EFQB@QROB

$BNFM VTFT B +BWB CBTFE 3PVUJOH %PNBJO 4QFDJGJD -BOHVBHF (%4-) PS BO 9NM $POGJHVSBUJPO UP DPOGJHVSF SPVUJOH BOE NFEJBUJPO SVMFT XIJDI BSF BEEFE UP B $BNFM$POUFYU UP JNQMFNFOU UIF WBSJPVT &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT. "U B IJHI MFWFM $BNFM DPOTJTUT PG B $BNFM$POUFYU XIJDI DPOUBJOT B DPMMFDUJPO PG $PNQPOFOU JOTUBODFT. " $PNQPOFOU JT FTTFOUJBMMZ B GBDUPSZ PG &OEQPJOU JOTUBODFT. :PV DBO FYQMJDJUMZ DPOGJHVSF $PNQPOFOU JOTUBODFT JO +BWB DPEF PS BO *P$ DPOUBJOFS MJLF 4QSJOH PS (VJDF, PS UIFZ DBO CF BVUP-EJTDPWFSFE VTJOH 63*T. "O &OEQPJOU BDUT SBUIFS MJLF B 63* PS 63- JO B XFC BQQMJDBUJPO PS B %FTUJOBUJPO JO B +.4 TZTUFN; ZPV DBO DPNNVOJDBUF XJUI BO FOEQPJOU; FJUIFS TFOEJOH NFTTBHFT UP JU PS DPOTVNJOH NFTTBHFT GSPN JU. :PV DBO UIFO DSFBUF B 1SPEVDFS PS $POTVNFS PO BO &OEQPJOU UP FYDIBOHF NFTTBHFT XJUI JU. 5IF %4- NBLFT IFBWZ VTF PG QMVHHBCMF -BOHVBHFT UP DSFBUF BO &YQSFTTJPO PS 1SFEJDBUF UP NBLF B USVMZ QPXFSGVM %4- XIJDI JT FYUFOTJCMF UP UIF NPTU TVJUBCMF MBOHVBHF EFQFOEJOH PO ZPVS OFFET. 5IF GPMMPXJOH MBOHVBHFT BSF TVQQPSUFE ` #FBO -BOHVBHF GPS VTJOH +BWB GPS FYQSFTTJPOT ` $POTUBOU ` UIF VOJGJFE &- GSPN +41 BOE +4' ` )FBEFS ` +91BUI ` .WFM ` 0(/` 3FG -BOHVBHF ` 1SPQFSUZ ` 4DSJQUJOH -BOHVBHFT TVDI BT #FBO4IFMM +BWB4DSJQU (SPPWZ 1ZUIPO 1)1 3VCZ ` 4JNQMF 'JMF -BOHVBHF ` 4QSJOH &YQSFTTJPO -BOHVBHF ` 42$) "15 &3 4 - "3 $) *5 &$5 63 & 17

` 5PLFOJ[FS ` 91BUI ` 92VFSZ ` 75%-9..PTU PG UIFTF MBOHVBHFT JT BMTP TVQQPSUFE VTFE BT "OOPUBUJPO #BTFE &YQSFTTJPO -BOHVBHF. 'PS B GVMM EFUBJMT PG UIF JOEJWJEVBM MBOHVBHFT TFF UIF -BOHVBHF "QQFOEJY

41(2
$BNFM NBLFT FYUFOTJWF VTF PG 63*T UP BMMPX ZPV UP SFGFS UP FOEQPJOUT XIJDI BSF MB[JMZ DSFBUFE CZ B $PNQPOFOU JG ZPV SFGFS UP UIFN XJUIJO 3PVUFT. "ROOBKQ 2RMMLOQBA 41(P "LJMLKBKQ / ")$ / DBNFM-BID
ahc:hostname:[port]

OQFC>@Q(A / 41(

#BP@OFMQFLK 5P DBMM FYUFSOBM )551 TFSWJDFT VTJOH "TZOD )UUQ $MJFOU

".21 / DBNFM-BNRQ
amqp:[topic:]destinationName

'PS .FTTBHJOH XJUI ".21 QSPUPDPM

"1/4 / DBNFM-BQOT
apns:notify[?options]

'PS TFOEJOH OPUJGJDBUJPOT UP "QQMF J04 EFWJDFT

"UPN / DBNFM-BUPN
atom:uri

8PSLJOH XJUI "QBDIF "CEFSB GPS BUPN JOUFHSBUJPO, TVDI BT DPOTVNJOH BO BUPN GFFE.

"WSP / DBNFM-BWSP
avro:http://hostname[:port][?options]

8PSLJOH XJUI "QBDIF "WSP GPS EBUB TFSJBMJ[BUJPO.

18

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

FJMLOQ>KQ .BLF TVSF UP SFBE )PX EP * DPOGJHVSF FOEQPJOUT UP MFBSO NPSF BCPVU DPOGJHVSJOH FOEQPJOUT. 'PS FYBNQMF IPX UP SFGFS UP CFBOT JO UIF 3FHJTUSZ PS IPX UP VTF SBX WBMVFT GPS QBTTXPSE PQUJPOT, BOE VTJOH QSPQFSUZ QMBDFIPMEFST FUD.

"84-$8 / DBNFM-BXT
aws-cw://namespace[?options]

'PS XPSLJOH XJUI "NB[PO'T $MPVE8BUDI ($8).

"84-%%# / DBNFM-BXT
aws-ddb://tableName[?options]

'PS XPSLJOH XJUI "NB[PO'T %ZOBNP%# (%%#).

"84-4%# / DBNFM-BXT
aws-sdb://domainName[?options]

'PS XPSLJOH XJUI "NB[PO'T 4JNQMF%# (4%#).

"84-4&4 / DBNFM-BXT
aws-ses://from[?options]

'PS XPSLJOH XJUI "NB[PO'T 4JNQMF &NBJM 4FSWJDF (4&4).

"84-4/4 / DBNFM-BXT
aws-sns://topicname[?options]

'PS .FTTBHJOH XJUI "NB[PO'T 4JNQMF /PUJGJDBUJPO 4FSWJDF (4/4).

"84-424 / DBNFM-BXT
aws-sqs://queuename[?options]

'PS .FTTBHJOH XJUI "NB[PO'T 4JNQMF 2VFVF 4FSWJDF (424).

"84-43 / DBNFM-BXT
aws-s3://bucketname[?options]

'PS XPSLJOH XJUI "NB[PO'T 4JNQMF 4UPSBHF 4FSWJDF (43).

$) "15 &3 4 - "3 $) *5 &$5 63 &

19

#FBO / DBNFM-DPSF
bean:beanName[?method=someMethod]

6TFT UIF #FBO #JOEJOH UP CJOE NFTTBHF FYDIBOHFT UP CFBOT JO UIF 3FHJTUSZ. *T BMTP VTFE GPS FYQPTJOH BOE JOWPLJOH 10+0 (1MBJO 0ME +BWB 0CKFDUT). 7BMJEBUFT UIF QBZMPBE PG B NFTTBHF VTJOH UIF +BWB 7BMJEBUJPO "1* (+43 303 BOE +"91 7BMJEBUJPO) BOE JUT SFGFSFODF JNQMFNFOUBUJPO )JCFSOBUF 7BMJEBUPS 1SPWJEFT B TJNQMF #SPXTBCMF&OEQPJOU XIJDI DBO CF VTFGVM GPS UFTUJOH, WJTVBMJTBUJPO UPPMT PS EFCVHHJOH. 5IF FYDIBOHFT TFOU UP UIF FOEQPJOU BSF BMM BWBJMBCMF UP CF CSPXTFE. 5IF DBDIF DPNQPOFOU GBDJMJUBUFT DSFBUJPO PG DBDIJOH FOEQPJOUT BOE QSPDFTTPST VTJOH &)$BDIF BT UIF DBDIF JNQMFNFOUBUJPO. 6TFT UIF #FBO #JOEJOH UP CJOE NFTTBHF FYDIBOHFT UP CFBOT JO UIF 3FHJTUSZ. *T BMTP VTFE GPS FYQPTJOH BOE JOWPLJOH 10+0 (1MBJO 0ME +BWB 0CKFDUT). 6TFT UIF "QBDIF $IFNJTUSZ DMJFOU "1* UP JOUFSGBDF XJUI $.*4 TVQQPSUJOH $.4 6TFE UP EFMJWFS NFTTBHFT VTJOH UIF KFUUZ DPNFUE JNQMFNFOUBUJPO PG UIF CBZFVY QSPUPDPM

#FBO 7BMJEBUJPO / DBNFM-CFBO-WBMJEBUPS


bean-validator:something

#SPXTF / DBNFM-DPSF
browse:someName

$BDIF / DBNFM-DBDIF
cache://cachename[?options]

$MBTT / DBNFM-DPSF
class:className[?method=someMethod]

$.*4 / DBNFM-DNJT
cmis://cmisServerUrl[?options]

$PNFUE / DBNFM-DPNFUE
cometd://host:port/channelname

20

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

$POUFYU / DBNFM-DPOUFYU
context:camelContextId:localEndpointName

6TFE UP SFGFS UP FOEQPJOUT XJUIJO B TFQBSBUF $BNFM$POUFYU UP QSPWJEF B TJNQMF CMBDL CPY DPNQPTJUJPO BQQSPBDI TP UIBU SPVUFT DBO CF DPNCJOFE JOUP B $BNFM$POUFYU BOE UIFO VTFE BT B CMBDL CPY DPNQPOFOU JOTJEF PUIFS SPVUFT JO PUIFS $BNFM$POUFYUT $POUSPM#VT &*1 UIBU BMMPXT UP TFOE NFTTBHFT UP &OEQPJOUT GPS NBOBHJOH BOE NPOJUPSJOH ZPVS $BNFM BQQMJDBUJPOT. 5P JOUFHSBUF XJUI "QBDIF $PVDI%#.

$POUSPM#VT / DBNFM-DPSF
controlbus:command[?options]

$PVDI%# / DBNFM-DPVDIEC
couchdb:http://hostname[:port]/database[?options]

$SZQUP (%JHJUBM 4JHOBUVSFT) / DBNFM-DSZQUP


crypto:sign:name[?options] crypto:verify:name[?options]

6TFE UP TJHO BOE WFSJGZ FYDIBOHFT VTJOH UIF 4JHOBUVSF 4FSWJDF PG UIF +BWB $SZQUPHSBQIJD &YUFOTJPO.

$9' / DBNFM-DYG
cxf:address[?serviceClass=...]

8PSLJOH XJUI "QBDIF $9' GPS XFC TFSWJDFT JOUFHSBUJPO 1SPDFFTT UIF FYDIBOHF VTJOH B +"9 84 PS +"9 34 BOOPUBUFE CFBO GSPN UIF SFHJTUSZ. 3FRVJSFT MFTT DPOGJHVSBUJPO UIBO UIF BCPWF $9' $PNQPOFOU 8PSLJOH XJUI "QBDIF $9' GPS 3&45 TFSWJDFT JOUFHSBUJPO

$9' #FBO / DBNFM-DYG


cxf:bean name

$9'34 / DBNFM-DYG
cxfrs:address[?resourcesClasses=...]

$) "15 &3 4 - "3 $) *5 &$5 63 &

21

%BUB4FU / DBNFM-DPSF
dataset:name

'PS MPBE & TPBL UFTUJOH UIF %BUB4FU QSPWJEFT B XBZ UP DSFBUF IVHF OVNCFST PG NFTTBHFT GPS TFOEJOH UP $PNQPOFOUT PS BTTFSUJOH UIBU UIFZ BSF DPOTVNFE DPSSFDUMZ 4ZODISPOPVT DBMM UP BOPUIFS FOEQPJOU GSPN P>JB $BNFM$POUFYU. 4ZODISPOPVT DBMM UP BOPUIFS FOEQPJOU JO BOPUIFS $BNFM$POUFYU SVOOJOH JO UIF TBNF +7.. 5P MPPLVQ EPNBJO JOGPSNBUJPO BOE SVO %/4 RVFSJFT VTJOH %/4+BWB 6TFT UIF #FBO #JOEJOH UP CJOE NFTTBHF FYDIBOHFT UP &+#T. *U XPSLT MJLF UIF #FBO DPNQPOFOU CVU KVTU GPS BDDFTTJOH &+#T. 4VQQPSUT &+# 3.0 POXBSET. 'PS JOUFSGBDJOH XJUI BO &MBTUJD4FBSDI TFSWFS.

%JSFDU / DBNFM-DPSF
direct:name

%JSFDU-7. / DBNFM-DPSF
direct-vm:name

%/4 / DBNFM-EOT
dns:operation

&+# / DBNFM-FKC
ejb:ejbName[?method=someMethod]

&MBTUJD4FBSDI / DBNFM-FMBTUJDTFBSDI
elasticsearch://clusterName

&WFOU / DBNFM-TQSJOH
event://default spring-event://default

8PSLJOH XJUI 4QSJOH "QQMJDBUJPO&WFOUT

&WFOU"ENJO / DBNFM-FWFOUBENJO
eventadmin:topic

3FDFJWJOH 04(J &WFOU"ENJO FWFOUT

22

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

&YFD / DBNFM-FYFD
exec://executable[?options]

'PS FYFDVUJOH TZTUFN DPNNBOET

'JMF / DBNFM-DPSF
file://nameOfFileOrDirectory

4FOEJOH NFTTBHFT UP B GJMF PS QPMMJOH B GJMF PS EJSFDUPSZ.

'MBUQBDL / DBNFM-GMBUQBDL
flatpack:[fixed|delim]:configFile

1SPDFTTJOH GJYFE XJEUI PS EFMJNJUFE GJMFT PS NFTTBHFT VTJOH UIF 'MBU1BDL MJCSBSZ 3FOEFST UIF NFTTBHF JOUP EJGGFSFOU PVUQVU GPSNBUT VTJOH "QBDIF '01

'01 / DBNFM-GPQ
fop:outputFormat

'SFF.BSLFS / DBNFM-GSFFNBSLFS
freemarker:someTemplateResource

(FOFSBUFT B SFTQPOTF VTJOH B 'SFF.BSLFS UFNQMBUF

'51 / DBNFM-GUQ
ftp://host[:port]/fileName

4FOEJOH BOE SFDFJWJOH GJMFT PWFS '51.

'514 / DBNFM-GUQ
ftps://host[:port]/fileName

4FOEJOH BOE SFDFJWJOH GJMFT PWFS '51 4FDVSF (5-4 BOE 44-). 6TFE CZ XFC BQQMJDBUJPOT UP JNQMFNFOU BO 0"VUI DPOTVNFS. 4FF BMTP $BNFM $PNQPOFOUT GPS (PPHMF "QQ &OHJOF. 1SPWJEFT DPOOFDUJWJUZ UP UIF 63GFUDI TFSWJDF PG (PPHMF "QQ &OHJOF CVU DBO BMTP CF VTFE UP SFDFJWF NFTTBHFT GSPN TFSWMFUT. 4FF BMTP $BNFM $PNQPOFOUT GPS (PPHMF "QQ &OHJOF.

("VUI / DBNFM-HBF
gauth://name[?options]

()UUQ / DBNFM-HBF
ghttp://hostname[:port][/path][?options] ghttp:///path[?options]

$) "15 &3 4 - "3 $) *5 &$5 63 &

23

(-PHJO / DBNFM-HBF
glogin://hostname[:port][?options]

6TFE CZ $BNFM BQQMJDBUJPOT PVUTJEF (PPHMF "QQ &OHJOF (("&) GPS QSPHSBNNBUJD MPHJO UP ("& BQQMJDBUJPOT. 4FF BMTP $BNFM $PNQPOFOUT GPS (PPHMF "QQ &OHJOF. 4VQQPSUT BTZODISPOPVT NFTTBHF QSPDFTTJOH PO (PPHMF "QQ &OHJOF CZ VTJOH UIF UBTL RVFVFJOH TFSWJDF BT NFTTBHF RVFVF. 4FF BMTP $BNFM $PNQPOFOUT GPS (PPHMF "QQ &OHJOF. 4VQQPSUT TFOEJOH PG FNBJMT WJB UIF NBJM TFSWJDF PG (PPHMF "QQ &OHJOF. 4FF BMTP $BNFM $PNQPOFOUT GPS (PPHMF "QQ &OHJOF. 5IF (PPHMF (VBWB &WFOU#VT BMMPXT QVCMJTI-TVCTDSJCF-TUZMF DPNNVOJDBUJPO CFUXFFO DPNQPOFOUT XJUIPVU SFRVJSJOH UIF DPNQPOFOUT UP FYQMJDJUMZ SFHJTUFS XJUI POF BOPUIFS (BOE UIVT CF BXBSF PG FBDI PUIFS). 5IJT DPNQPOFOU QSPWJEFT JOUFHSBUJPO CSJEHF CFUXFFO $BNFM BOE (PPHMF (VBWB &WFOU#VT JOGSBTUSVDUVSF. )B[FMDBTU JT B EBUB HSJE FOUJSFMZ JNQMFNFOUFE JO +BWB (TJOHMF KBS). 5IJT DPNQPOFOU TVQQPSUT NBQ, NVMUJNBQ, TFEB, RVFVF, TFU, BUPNJD OVNCFS BOE TJNQMF DMVTUFS TVQQPSU. 'PS SFBEJOH/XSJUJOH GSPN/UP BO )#BTF TUPSF ()BEPPQ EBUBCBTF)

(5BTL / DBNFM-HBF
gtask://queue-name

(.BJM / DBNFM-HBF
gmail://user@gmail.com[?options] gmail://user@googlemail.com[?options]

(PPHMF (VBWB &WFOU#VT / DBNFM-HVBWB-FWFOUCVT


guava-eventbus:busName[?eventClass=className]

)B[FMDBTU / DBNFM-IB[FMDBTU
hazelcast://[type]:cachename[?options]

)#BTF / DBNFM-ICBTF
hbase://table[?options]

24

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

)%'4 / DBNFM-IEGT
hdfs://path[?options]

'PS SFBEJOH/XSJUJOH GSPN/UP BO )%'4 GJMFTZTUFN

)-7 / DBNFM-IM7
mina:tcp://hostname[:port]

'PS XPSLJOH XJUI UIF )-7 .--1 QSPUPDPM BOE UIF )-7 NPEFM VTJOH UIF )"1* MJCSBSZ 'PS DBMMJOH PVU UP FYUFSOBM )551 TFSWFST VTJOH "QBDIF )551 $MJFOU 3.Y 'PS DBMMJOH PVU UP FYUFSOBM )551 TFSWFST VTJOH "QBDIF )551 $MJFOU 4.Y 1FSGPSNT B RVFSZ, QPMM, JOTFSU, VQEBUF PS EFMFUF JO B SFMBUJPOBM EBUBCBTF VTJOH "QBDIF J#"5*4

)551 / DBNFM-IUUQ
http://hostname[:port]

)5514 / DBNFM-IUUQ4
http4://hostname[:port]

J#"5*4 / DBNFM-JCBUJT
ibatis://statementName

*."1 / DBNFM-NBJM
imap://hostname[:port]

3FDFJWJOH FNBJM VTJOH *."1

*3$ / DBNFM-JSD
irc:host[:port]/#room

'PS *3$ DPNNVOJDBUJPO

+BWB4QBDF / DBNFM-KBWBTQBDF
javaspace:jini://host?spaceName=mySpace?...

4FOEJOH BOE SFDFJWJOH NFTTBHFT UISPVHI +BWB4QBDF

+#* / TFSWJDFNJY-DBNFM
jbi:serviceName

'PS +#* JOUFHSBUJPO TVDI BT XPSLJOH XJUI "QBDIF 4FSWJDF.JY

$) "15 &3 4 - "3 $) *5 &$5 63 &

25

KDMPVET / KDMPVET
jclouds:[blobstore|computservice]:provider

'PS JOUFSBDUJOH XJUI DMPVE DPNQVUF & CMPCTUPSF TFSWJDF WJB KDMPVET 4UPSJOH B NFTTBHF JO B +$3 DPNQMJBOU SFQPTJUPSZ MJLF "QBDIF +BDLSBCCJU

+$3 / DBNFM-KDS
jcr://user:password@repository/path/to/node

+%#$ / DBNFM-KECD
jdbc:dataSourceName?options

'PS QFSGPSNJOH +%#$ RVFSJFT BOE PQFSBUJPOT

+FUUZ / DBNFM-KFUUZ
jetty:url

'PS FYQPTJOH TFSWJDFT PWFS )551

+.4 / DBNFM-KNT
jms:[topic:]destinationName

8PSLJOH XJUI +.4 QSPWJEFST

+.9 / DBNFM-KNY
jmx://platform?options

'PS XPSLJOH XJUI +.9 OPUJGJDBUJPO MJTUFOFST 'PS VTJOH B EBUBCBTF BT B RVFVF WJB UIF +1" TQFDJGJDBUJPO GPS XPSLJOH XJUI 0QFO+1", )JCFSOBUF PS 5PQ-JOL

+1" / DBNFM-KQB
jpa://entityName

+TDI / DBNFM-KTDI
scp://localhost/destination

4VQQPSU GPS UIF TDQ QSPUPDPM

+5/400 / DBNFM-KU400
jt400://user:pwd@system/<path_to_dtaq>

'PS JOUFHSBUJOH XJUI EBUB RVFVFT PO BO "4/400 (BLB 4ZTUFN J, *#. J, J5, ...) TZTUFN

26

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

,FTUSFM / DBNFM-LFTUSFM
kestrel://[addresslist/]queuename[?options]

'PS QSPEVDJOH UP PS DPOTVNJOH GSPN ,FTUSFM RVFVFT

,SBUJ / DBNFM-LSBUJ
krati://[path to datastore/][?options]

'PS QSPEVDJOH UP PS DPOTVNJOH UP ,SBUJ EBUBTUPSFT

-BOHVBHF / DBNFM-DPSF
language://languageName[:script][?options]

&YFDVUFT -BOHVBHFT TDSJQUT

-%"1 / DBNFM-MEBQ
ldap:host[:port]?base=...[&scope=<scope>]

1FSGPSNJOH TFBSDIFT PO -%"1 TFSWFST (<TDPQF> NVTU CF POF PG PCKFDU]POFMFWFM]TVCUSFF) 6TFT +BLBSUB $PNNPOT -PHHJOH UP MPH UIF NFTTBHF FYDIBOHF UP TPNF VOEFSMZJOH MPHHJOH TZTUFN MJLF MPH4K 6TFT "QBDIF -VDFOF UP QFSGPSN +BWB-CBTFE JOEFYJOH BOE GVMM UFYU CBTFE TFBSDIFT VTJOH BEWBODFE BOBMZTJT/UPLFOJ[BUJPO DBQBCJMJUJFT

-PH / DBNFM-DPSF
log:loggingCategory[?level=ERROR]

-VDFOF / DBNFM-MVDFOF
lucene:searcherName:insert[?analyzer=<analyzer>] lucene:searcherName:query[?analyzer=<analyzer>]

.BJM / DBNFM-NBJM
mail://user-info@host:port

4FOEJOH BOE SFDFJWJOH FNBJM

.*/" / DBNFM-NJOB
[tcp|udp|vm]:host[:port]

8PSLJOH XJUI "QBDIF .*/"

.PDL / DBNFM-DPSF
mock:name

'PS UFTUJOH SPVUFT BOE NFEJBUJPO SVMFT VTJOH NPDLT

$) "15 &3 4 - "3 $) *5 &$5 63 &

27

.POHP%# / DBNFM-NPOHPEC
mongodb:connection?options

*OUFSBDUT XJUI .POHP%# EBUBCBTFT BOE DPMMFDUJPOT. 0GGFST QSPEVDFS FOEQPJOUT UP QFSGPSN $36%-TUZMF PQFSBUJPOT BOE NPSF BHBJOTU EBUBCBTFT BOE DPMMFDUJPOT, BT XFMM BT DPOTVNFS FOEQPJOUT UP MJTUFO PO DPMMFDUJPOT BOE EJTQBUDI PCKFDUT UP $BNFM SPVUFT $PNQPOFOU GPS DPNNVOJDBUJOH XJUI .255 .2. NFTTBHF CSPLFST

.255 / DBNFM-NRUU
mqtt:name

.47 / DBNFM-NTW
msv:someLocalOrRemoteResource

7BMJEBUFT UIF QBZMPBE PG B NFTTBHF VTJOH UIF .47 -JCSBSZ

.Z#BUJT / DBNFM-NZCBUJT
mybatis://statementName

1FSGPSNT B RVFSZ, QPMM, JOTFSU, VQEBUF PS EFMFUF JO B SFMBUJPOBM EBUBCBTF VTJOH .Z#BUJT

/BHJPT / DBNFM-OBHJPT
nagios://host[:port]?options

4FOEJOH QBTTJWF DIFDLT UP /BHJPT VTJOH +4FOE/4$"

/FUUZ / DBNFM-OFUUZ
netty:tcp//host[:port]?options netty:udp//host[:port]?options

8PSLJOH XJUI 5$1 BOE 6%1 QSPUPDPMT VTJOH +BWB /*0 CBTFE DBQBCJMJUJFT PGGFSFE CZ UIF +#PTT /FUUZ DPNNVOJUZ QSPKFDU

1BY--PHHJOH / DBNFM-QBYMPHHJOH
paxlogging:appender

3FDFJWJOH 1BY--PHHJOH FWFOUT JO 04(J

101 / DBNFM-NBJM
pop3://user-info@host:port

3FDFJWJOH FNBJM VTJOH 1013 BOE +BWB.BJM

28

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

1SJOUFS / DBNFM-QSJOUFS
lpr://host:port/path/to/printer[?options]

5IF QSJOUFS DPNQPOFOU GBDJMJUBUFT DSFBUJPO PG QSJOUFS FOEQPJOUT UP MPDBM, SFNPUF BOE XJSFMFTT QSJOUFST. 5IF FOEQPJOUT QSPWJEF UIF BCJMJUZ UP QSJOU DBNFM EJSFDUFE QBZMPBET XIFO VUJMJ[FE PO DBNFM SPVUFT. 5IF QSPQFSUJFT DPNQPOFOU GBDJMJUBUFT VTJOH QSPQFSUZ QMBDFIPMEFST EJSFDUMZ JO FOEQPJOU VSJ EFGJOJUJPOT. 1SPWJEFT B TDIFEVMFE EFMJWFSZ PG NFTTBHFT VTJOH UIF 2VBSU[ TDIFEVMFS

1SPQFSUJFT / DBNFM-DPSF
properties://key[?options]

2VBSU[ / DBNFM-RVBSU[
quartz://groupName/timerName

2VJDLGJY / DBNFM-RVJDLGJY
quickfix-server:config file quickfix-client:config-file

*NQMFNFOUBUJPO PG UIF 2VJDL'JY GPS +BWB FOHJOF XIJDI BMMPX UP TFOE/SFDFJWF '*9 NFTTBHFT

3FG / DBNFM-DPSF
ref:name

$PNQPOFOU GPS MPPLVQ PG FYJTUJOH FOEQPJOUT CPVOE JO UIF 3FHJTUSZ.

3FTUMFU / DBNFM-SFTUMFU
restlet:restletUrl[?options]

$PNQPOFOU GPS DPOTVNJOH BOE QSPEVDJOH 3FTUGVM SFTPVSDFT VTJOH 3FTUMFU

3.* / DBNFM-SNJ
rmi://host[:port]

8PSLJOH XJUI 3.*

3/$ / DBNFM-KJOH
rnc:/relativeOrAbsoluteUri

7BMJEBUFT UIF QBZMPBE PG B NFTTBHF VTJOH 3FMBY/( $PNQBDU 4ZOUBY

$) "15 &3 4 - "3 $) *5 &$5 63 &

29

3/( / DBNFM-KJOH
rng:/relativeOrAbsoluteUri

7BMJEBUFT UIF QBZMPBE PG B NFTTBHF VTJOH 3FMBY/( 'BDJMJUBUFT UIF DSFBUJPO PG TQFDJBMJ[FE FOEQPJOUT UIBU PGGFS FODBQTVMBUJPO BOE B TUSBUFHZ/NBQ CBTFE JOEJSFDUJPO TFSWJDF UP B DPMMFDUJPO PG DBNFM SPVUFT IPTUFE JO BO BVUPNBUJDBMMZ DSFBUFE PS VTFS JOKFDUFE DBNFM DPOUFYU 8PSLJOH XJUI 30.& GPS 344 JOUFHSBUJPO, TVDI BT DPOTVNJOH BO 344 GFFE. "TZODISPOPVT DBMM UP BOPUIFS FOEQPJOU JO UIF TBNF $BNFM $POUFYU 'PS FYQPTJOH TFSWJDFT PWFS )551 UISPVHI UIF TFSWMFU XIJDI JT EFQMPZFE JOUP UIF 8FC DPOUBJOFS.

3PVUFCPY / DBNFM-SPVUFCPY
routebox:routeboxName[?options]

344 / DBNFM-STT
rss:uri

4&%" / DBNFM-DPSF
seda:name

4&37-&5 / DBNFM-TFSWMFU
servlet:uri

4'51 / DBNFM-GUQ
sftp://host[:port]/fileName

4FOEJOH BOE SFDFJWJOH GJMFT PWFS 4'51 ('51 PWFS 44)). 1VCMJTI/4VCTDSJCF DPNNVOJDBUJPO DBQBCJMJUZ VTJOH UIF 5FMFDPN 4*1 QSPUPDPM. 3'$3903 - 4FTTJPO *OJUJBUJPO 1SPUPDPM (4*1) &YUFOTJPO GPS &WFOU " HSPVOE VQ JNQMFNFOUBUJPO PG B +.4 DMJFOU

4JQ / DBNFM-TJQ
sip://user@host[:port]?[options] sips://user@host[:port]?[options]

4+.4 / DBNFM-TKNT
sjms:[topic:]destinationName?[options]

30

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

4.51 / DBNFM-NBJM
smtp://user-info@host[:port]

4FOEJOH FNBJM VTJOH 4.51 BOE +BWB.BJM

4.11 / DBNFM-TNQQ
smpp://user-info@host[:port]?options

5P TFOE BOE SFDFJWF 4.4 VTJOH 4IPSU .FTTBHJOH 4FSWJDF $FOUFS VTJOH UIF +4.11 MJCSBSZ 1PMMJOH 0*% WBMVFT BOE SFDFJWJOH USBQT VTJOH 4/.1 WJB 4/.14+ MJCSBSZ 6TFT UIF 4PMSK DMJFOU "1* UP JOUFSGBDF XJUI BO "QBDIF -VDFOF 4PMS TFSWFS

4/.1 / DBNFM-TONQ
snmp://host[:port]?options

4PMS / DBNFM-TPMS
solr://host[:port]/solr?[options]

4QSJOH#BUDI / DBNFM-TQSJOH-CBUDI
spring-batch:job[?options]

5P CSJEHF $BNFM BOE 4QSJOH #BUDI

4QSJOH*OUFHSBUJPO / DBNFM-TQSJOH-JOUFHSBUJPO
spring-integration:defaultChannelName

5IF CSJEHF DPNQPOFOU PG $BNFM BOE 4QSJOH *OUFHSBUJPO

4QSJOH -%"1 / DBNFM-TQSJOH-MEBQ


spring-ldap:spring-ldap-template-bean?options

$BNFM XSBQQFS GPS 4QSJOH -%"1

4QSJOH 3FEJT / DBNFM-TQSJOH-SFEJT


spring-redis:restletUrl[?options]

$PNQPOFOU GPS DPOTVNJOH BOE QSPEVDJOH GSPN 3FEJT LFZ-WBMVF TUPSF 3FEJT $MJFOU-TJEF TVQQPSU GPS BDDFTTJOH XFC TFSWJDFT, BOE TFSWFS-TJEF TVQQPSU GPS DSFBUJOH ZPVS PXO DPOUSBDU-GJSTU XFC TFSWJDFT VTJOH 4QSJOH 8FC 4FSWJDFT

4QSJOH 8FC 4FSWJDFT / DBNFM-TQSJOH-XT


spring-ws:[mapping-type:]address[?options]

$) "15 &3 4 - "3 $) *5 &$5 63 &

31

42- / DBNFM-TRM
sql:select * from table where id=#

1FSGPSNJOH 42- RVFSJFT VTJOH +%#$

44) DPNQPOFOU / DBNFM-TTI


ssh:[username[:password]@]host[:port][?options]

'PS TFOEJOH DPNNBOET UP B 44) TFSWFS

4U"9 / DBNFM-TUBY
stax:contentHandlerClassName

1SPDFTT NFTTBHFT UISPVHI B 4"9 $POUFOU)BOEMFS.

4USFBN / DBNFM-TUSFBN
stream:[in|out|err|file]

3FBE PS XSJUF UP BO JOQVU/PVUQVU/ FSSPS/GJMF TUSFBN SBUIFS MJLF VOJY QJQFT

4USJOH5FNQMBUF / DBNFM-TUSJOHUFNQMBUF
string-template:someTemplateResource

(FOFSBUFT B SFTQPOTF VTJOH B 4USJOH 5FNQMBUF

4UVC / DBNFM-DPSF
stub:someOtherCamelUri

"MMPXT ZPV UP TUVC PVU TPNF QIZTJDBM NJEEMFXBSF FOEQPJOU GPS FBTJFS UFTUJOH PS EFCVHHJOH

5$1 / DBNFM-NJOB
mina:tcp://host:port

8PSLJOH XJUI 5$1 QSPUPDPMT VTJOH "QBDIF .*/" $SFBUFT B .PDL FOEQPJOU XIJDI FYQFDUT UP SFDFJWF BMM UIF NFTTBHF CPEJFT UIBU DPVME CF QPMMFE GSPN UIF HJWFO VOEFSMZJOH FOEQPJOU

5FTU / DBNFM-TQSJOH
test:expectedMessagesEndpointUri

5JNFS / DBNFM-DPSF
timer://name

" UJNFS FOEQPJOU

32

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

5XJUUFS / DBNFM-UXJUUFS
twitter://[endpoint]?[options]

" UXJUUFS FOEQPJOU

6%1 / DBNFM-NJOB
mina:udp://host:port

8PSLJOH XJUI 6%1 QSPUPDPMT VTJOH "QBDIF .*/"

7BMJEBUJPO / DBNFM-DPSF (DBNFM-TQSJOH GPS $BNFM 2.8 PS PMEFS)


validation:someLocalOrRemoteResource

7BMJEBUFT UIF QBZMPBE PG B NFTTBHF VTJOH 9.- 4DIFNB BOE +"91 7BMJEBUJPO

7FMPDJUZ / DBNFM-WFMPDJUZ
velocity:someTemplateResource

(FOFSBUFT B SFTQPOTF VTJOH BO "QBDIF 7FMPDJUZ UFNQMBUF

7. / DBNFM-DPSF
vm:name

"TZODISPOPVT DBMM UP BOPUIFS FOEQPJOU JO UIF TBNF +7.

8FCTPDLFU / DBNFM-XFCTPDLFU
websocket://host:port/path

$PNNVOJDBUJOH XJUI 8FCTPDLFU DMJFOUT

9.11 / DBNFM-YNQQ
xmpp://host:port/room

8PSLJOH XJUI 9.11 BOE +BCCFS

92VFSZ / DBNFM-TBYPO
xquery:someXQueryResource

(FOFSBUFT B SFTQPOTF VTJOH BO 92VFSZ UFNQMBUF

94-5 / DBNFM-DPSF (DBNFM-TQSJOH GPS $BNFM 2.8 PS PMEFS)


xslt:someTemplateResource

(FOFSBUFT B SFTQPOTF VTJOH BO 94-5 UFNQMBUF

$) "15 &3 4 - "3 $) *5 &$5 63 &

33

;PPLFFQFS / DBNFM-[PPLFFQFS
zookeeper://host:port/path

8PSLJOH XJUI ;PP,FFQFS DMVTUFS(T)

41('P CLO BUQBOK>I @LJMLKBKQP 0UIFS QSPKFDUT BOE DPNQBOJFT IBWF BMTP DSFBUFE $BNFM DPNQPOFOUT UP JOUFHSBUF BEEJUJPOBM GVODUJPOBMJUZ JOUP $BNFM. 5IFTF DPNQPOFOUT NBZ CF QSPWJEFE VOEFS MJDFOTFT UIBU BSF OPU DPNQBUJCMF XJUI UIF "QBDIF -JDFOTF, VTF MJCSBSJFT UIBU BSF OPU DPNQBUJCMF, FUD... 5IFTF DPNQPOFOUT BSF OPU TVQQPSUFE CZ UIF $BNFM UFBN, CVU XF QSPWJEF MJOLT IFSF UP IFMQ VTFST GJOE UIF BEEJUJPOBM GVODUJPOBMJUZ. "LJMLKBKQ / OQFC>@Q(A / 41( +F@BKPB #BP@OFMQFLK 'PS +.4 .FTTBHJOH XJUI "QBDIF "DUJWF.2 6TFT "DUJWF.2'T GBTU EJTL KPVSOBMJOH JNQMFNFOUBUJPO UP TUPSF NFTTBHF CPEJFT JO B SPMMJOH MPH GJMF 'PS XPSLJOH XJUI "DUJWJUJ, B MJHIU-XFJHIU XPSLGMPX BOE #VTJOFTT 1SPDFTT .BOBHFNFOU (#1.) QMBUGPSN XIJDI TVQQPSUT #1./ 2 'PS VTJOH B EC4P EBUBTUPSF BT B RVFVF WJB UIF EC4P MJCSBSZ "DUJWF.2 / BDUJWFNR-DBNFM
activemq:[topic:]destinationName

"QBDIF

"DUJWF.2 +PVSOBM / BDUJWFNR-DPSF


activemq.journal:directory-on-filesystem

"QBDIF

"DUJWJUJ / BDUJWJUJ-DBNFM
activiti:camelProcess:serviceTask

"QBDIF

%C4P / DBNFM-EC4P JO DBNFM-FYUSB


db4o://className

(1-

34

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

&TQFS / DBNFM-FTQFS JO DBNFM-FYUSB


esper:name

(1-

8PSLJOH XJUI UIF &TQFS -JCSBSZ GPS &WFOU 4USFBN 1SPDFTTJOH 'PS VTJOH B EBUBCBTF BT B RVFVF WJB UIF )JCFSOBUF MJCSBSZ 5IF jgroups: DPNQPOFOU QSPWJEFT FYDIBOHF PG NFTTBHFT CFUXFFO $BNFM JOGSBTUSVDUVSF BOE +(SPVQT DMVTUFST. *OUFHSBUJPO XJUI UIF /PSNBMJ[FE .FTTBHF 3PVUFS #64 JO 4FSWJDF.JY 4.Y 6TFT UIF HJWFO 4DBMBUF UFNQMBUF UP USBOTGPSN UIF NFTTBHF 'PS XPSLJOH XJUI &%* QBSTJOH VTJOH UIF 4NPPLT MJCSBSZ. 5IJT DPNQPOFOU JT ABMOB@>QBA BT 4NPPLT OPX QSPWJEFT $BNFM JOUFHSBUJPO PVU PG UIF CPY

)JCFSOBUF / DBNFM-IJCFSOBUF JO DBNFM-FYUSB


hibernate://entityName

(1-

+(SPVQT / DBNFM-KHSPVQT JO DBNFM-FYUSB


jgroups://clusterName

-(1-

/.3 / TFSWJDFNJY-ONS
nmr://serviceName

"QBDIF

4DBMBUF / TDBMBUF-DBNFM "QBDIF


scalate:templateName

4NPPLT / DBNFM-TNPPLT JO DBNFM-FYUSB.


unmarshal(edi)

(1-

$) "15 &3 4 - "3 $) *5 &$5 63 &

35

4QSJOH /FP4K / DBNFM-TQSJOH-OFP4K JO DBNFM-FYUSB


spring-neo4j:http://hostname[:port]/database[?options]

UP CFF DMBSJGJFE

$PNQPOFOU GPS QSPEVDJOH UP /FP4K EBUBTUPSF VTJOH UIF 4QSJOH %BUB /FP4K MJCSBSZ 5IF ;FSP.2 DPNQPOFOU BMMPXT ZPV UP DPOTVNFS PS QSPEVDF NFTTBHFT VTJOH ;FSP.2.

;FSP.2 / DBNFM-[FSPNR JO DBNFM-FYUSB.


zeromq:(tcp|ipc)://hostname:port

-(1-

'PS B GVMM EFUBJMT PG UIF JOEJWJEVBM DPNQPOFOUT TFF UIF $PNQPOFOU "QQFOEJY

36

$) " 15& 3 4 - "3 $ ) * 5 & $ 5 6 3 &

"' YYYY

/3$1

$KQBOMOFPB (KQBDO>QFLK />QQBOKP

$BNFM TVQQPSUT NPTU PG UIF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT GSPN UIF FYDFMMFOU CPPL PG UIF TBNF OBNF CZ (SFHPS )PIQF BOE #PCCZ 8PPMG. *UT B IJHIMZ SFDPNNFOEFE CPPL, QBSUJDVMBSMZ GPS VTFST PG $BNFM.

/ 33$1- (-#$7
5IFSF OPX GPMMPXT B MJTU PG UIF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT GSPN UIF CPPL BMPOH XJUI FYBNQMFT PG UIF WBSJPVT QBUUFSOT VTJOH "QBDIF $BNFM ,BPP>DFKD 2VPQBJP .FTTBHF $IBOOFM .FTTBHF 1JQFT BOE 'JMUFST .FTTBHF 3PVUFS .FTTBHF 5SBOTMBUPS .FTTBHF &OEQPJOU )PX EPFT POF BQQMJDBUJPO DPNNVOJDBUF XJUI BOPUIFS VTJOH NFTTBHJOH )PX DBO UXP BQQMJDBUJPOT DPOOFDUFE CZ B NFTTBHF DIBOOFM FYDIBOHF B QJFDF PG JOGPSNBUJPO )PX DBO XF QFSGPSN DPNQMFY QSPDFTTJOH PO B NFTTBHF XIJMF NBJOUBJOJOH JOEFQFOEFODF BOE GMFYJCJMJUZ )PX DBO ZPV EFDPVQMF JOEJWJEVBM QSPDFTTJOH TUFQT TP UIBU NFTTBHFT DBO CF QBTTFE UP EJGGFSFOU GJMUFST EFQFOEJOH PO B TFU PG DPOEJUJPOT )PX DBO TZTUFNT VTJOH EJGGFSFOU EBUB GPSNBUT DPNNVOJDBUF XJUI FBDI PUIFS VTJOH NFTTBHJOH )PX EPFT BO BQQMJDBUJPO DPOOFDU UP B NFTTBHJOH DIBOOFM UP TFOE BOE SFDFJWF NFTTBHFT

$ ) " 1 5 & 3 5 - &/ 5 &3 13 *4& */ 5 &(3 "5 *0 / 1"5 5 &3 / 4

37

,BPP>DFKD "E>KKBIP 1PJOU UP 1PJOU $IBOOFM 1VCMJTI 4VCTDSJCF $IBOOFM %FBE -FUUFS $IBOOFM (VBSBOUFFE %FMJWFSZ .FTTBHF #VT )PX DBO UIF DBMMFS CF TVSF UIBU FYBDUMZ POF SFDFJWFS XJMM SFDFJWF UIF EPDVNFOU PS QFSGPSN UIF DBMM )PX DBO UIF TFOEFS CSPBEDBTU BO FWFOU UP BMM JOUFSFTUFE SFDFJWFST 8IBU XJMM UIF NFTTBHJOH TZTUFN EP XJUI B NFTTBHF JU DBOOPU EFMJWFS )PX DBO UIF TFOEFS NBLF TVSF UIBU B NFTTBHF XJMM CF EFMJWFSFE, FWFO JG UIF NFTTBHJOH TZTUFN GBJMT 8IBU JT BO BSDIJUFDUVSF UIBU FOBCMFT TFQBSBUF BQQMJDBUJPOT UP XPSL UPHFUIFS, CVU JO B EF-DPVQMFE GBTIJPO TVDI UIBU BQQMJDBUJPOT DBO CF FBTJMZ BEEFE PS SFNPWFE XJUIPVU BGGFDUJOH UIF PUIFST

,BPP>DB "LKPQOR@QFLK &WFOU .FTTBHF 3FRVFTU 3FQMZ $PSSFMBUJPO *EFOUJGJFS 3FUVSO "EESFTT )PX DBO NFTTBHJOH CF VTFE UP USBOTNJU FWFOUT GSPN POF BQQMJDBUJPO UP BOPUIFS 8IFO BO BQQMJDBUJPO TFOET B NFTTBHF, IPX DBO JU HFU B SFTQPOTF GSPN UIF SFDFJWFS )PX EPFT B SFRVFTUPS UIBU IBT SFDFJWFE B SFQMZ LOPX XIJDI SFRVFTU UIJT JT UIF SFQMZ GPS )PX EPFT B SFQMJFS LOPX XIFSF UP TFOE UIF SFQMZ

,BPP>DB 1LRQFKD $POUFOU #BTFE 3PVUFS .FTTBHF 'JMUFS %ZOBNJD 3PVUFS )PX EP XF IBOEMF B TJUVBUJPO XIFSF UIF JNQMFNFOUBUJPO PG B TJOHMF MPHJDBM GVODUJPO (F.H., JOWFOUPSZ DIFDL) JT TQSFBE BDSPTT NVMUJQMF QIZTJDBM TZTUFNT )PX DBO B DPNQPOFOU BWPJE SFDFJWJOH VOJOUFSFTUJOH NFTTBHFT )PX DBO ZPV BWPJE UIF EFQFOEFODZ PG UIF SPVUFS PO BMM QPTTJCMF EFTUJOBUJPOT XIJMF NBJOUBJOJOH JUT FGGJDJFODZ

38

$) " 15& 3 5 - & / 5 & 3 1 3 * 4& * /5 & ( 3 " 5 * 0/ 1 "5 5 &3 / 4

3FDJQJFOU -JTU 4QMJUUFS

)PX EP XF SPVUF B NFTTBHF UP B MJTU PG (TUBUJD PS EZOBNJDBMMZ) TQFDJGJFE SFDJQJFOUT )PX DBO XF QSPDFTT B NFTTBHF JG JU DPOUBJOT NVMUJQMF FMFNFOUT, FBDI PG XIJDI NBZ IBWF UP CF QSPDFTTFE JO B EJGGFSFOU XBZ )PX EP XF DPNCJOF UIF SFTVMUT PG JOEJWJEVBM, CVU SFMBUFE NFTTBHFT TP UIBU UIFZ DBO CF QSPDFTTFE BT B XIPMF )PX DBO XF HFU B TUSFBN PG SFMBUFE CVU PVU-PG-TFRVFODF NFTTBHFT CBDL JOUP UIF DPSSFDU PSEFS )PX DBO ZPV NBJOUBJO UIF PWFSBMM NFTTBHF GMPX XIFO QSPDFTTJOH B NFTTBHF DPOTJTUJOH PG NVMUJQMF FMFNFOUT, FBDI PG XIJDI NBZ SFRVJSF EJGGFSFOU QSPDFTTJOH )PX EP ZPV NBJOUBJO UIF PWFSBMM NFTTBHF GMPX XIFO B NFTTBHF OFFET UP CF TFOU UP NVMUJQMF SFDJQJFOUT, FBDI PG XIJDI NBZ TFOE B SFQMZ )PX EP XF SPVUF B NFTTBHF DPOTFDVUJWFMZ UISPVHI B TFSJFT PG QSPDFTTJOH TUFQT XIFO UIF TFRVFODF PG TUFQT JT OPU LOPXO BU EFTJHO-UJNF BOE NBZ WBSZ GPS FBDI NFTTBHF )PX DBO * UISPUUMF NFTTBHFT UP FOTVSF UIBU B TQFDJGJD FOEQPJOU EPFT OPU HFU PWFSMPBEFE, PS XF EPO'U FYDFFE BO BHSFFE 4-" XJUI TPNF FYUFSOBM TFSWJDF )PX DBO * TBNQMF POF NFTTBHF PVU PG NBOZ JO B HJWFO QFSJPE UP BWPJE EPXOTUSFBN SPVUF EPFT OPU HFU PWFSMPBEFE )PX DBO * EFMBZ UIF TFOEJOH PG B NFTTBHF )PX DBO * CBMBODF MPBE BDSPTT B OVNCFS PG FOEQPJOUT )PX DBO * SPVUF B NFTTBHF UP B OVNCFS PG FOEQPJOUT BU UIF TBNF UJNF )PX DBO * SFQFBU QSPDFTTJOH B NFTTBHF JO B MPPQ

"HHSFHBUPS 3FTFRVFODFS $PNQPTFE .FTTBHF 1SPDFTTPS 4DBUUFS(BUIFS

3PVUJOH 4MJQ

5ISPUUMFS

4BNQMJOH %FMBZFS -PBE #BMBODFS .VMUJDBTU -PPQ

,BPP>DB 3O>KPCLOJ>QFLK $POUFOU &OSJDIFS )PX EP XF DPNNVOJDBUF XJUI BOPUIFS TZTUFN JG UIF NFTTBHF PSJHJOBUPS EPFT OPU IBWF BMM UIF SFRVJSFE EBUB JUFNT BWBJMBCMF

$ ) " 1 5 & 3 5 - &/ 5 &3 13 *4& */ 5 &(3 "5 *0 / 1"5 5 &3 / 4

39

$POUFOU 'JMUFS $MBJN $IFDL /PSNBMJ[FS 4PSU 7BMJEBUF

)PX EP ZPV TJNQMJGZ EFBMJOH XJUI B MBSHF NFTTBHF, XIFO ZPV BSF JOUFSFTUFE POMZ JO B GFX EBUB JUFNT )PX DBO XF SFEVDF UIF EBUB WPMVNF PG NFTTBHF TFOU BDSPTT UIF TZTUFN XJUIPVU TBDSJGJDJOH JOGPSNBUJPO DPOUFOU )PX EP ZPV QSPDFTT NFTTBHFT UIBU BSF TFNBOUJDBMMZ FRVJWBMFOU, CVU BSSJWF JO B EJGGFSFOU GPSNBU )PX DBO * TPSU UIF CPEZ PG B NFTTBHF )PX DBO * WBMJEBUF B NFTTBHF

,BPP>DFKD $KAMLFKQP .FTTBHJOH .BQQFS &WFOU %SJWFO $POTVNFS 1PMMJOH $POTVNFS $PNQFUJOH $POTVNFST .FTTBHF %JTQBUDIFS 4FMFDUJWF $POTVNFS %VSBCMF 4VCTDSJCFS *EFNQPUFOU $POTVNFS 5SBOTBDUJPOBM $MJFOU .FTTBHJOH (BUFXBZ )PX EP ZPV NPWF EBUB CFUXFFO EPNBJO PCKFDUT BOE UIF NFTTBHJOH JOGSBTUSVDUVSF XIJMF LFFQJOH UIF UXP JOEFQFOEFOU PG FBDI PUIFS )PX DBO BO BQQMJDBUJPO BVUPNBUJDBMMZ DPOTVNF NFTTBHFT BT UIFZ CFDPNF BWBJMBCMF )PX DBO BO BQQMJDBUJPO DPOTVNF B NFTTBHF XIFO UIF BQQMJDBUJPO JT SFBEZ )PX DBO B NFTTBHJOH DMJFOU QSPDFTT NVMUJQMF NFTTBHFT DPODVSSFOUMZ )PX DBO NVMUJQMF DPOTVNFST PO B TJOHMF DIBOOFM DPPSEJOBUF UIFJS NFTTBHF QSPDFTTJOH )PX DBO B NFTTBHF DPOTVNFS TFMFDU XIJDI NFTTBHFT JU XJTIFT UP SFDFJWF )PX DBO B TVCTDSJCFS BWPJE NJTTJOH NFTTBHFT XIJMF JU'T OPU MJTUFOJOH GPS UIFN )PX DBO B NFTTBHF SFDFJWFS EFBM XJUI EVQMJDBUF NFTTBHFT )PX DBO B DMJFOU DPOUSPM JUT USBOTBDUJPOT XJUI UIF NFTTBHJOH TZTUFN )PX EP ZPV FODBQTVMBUF BDDFTT UP UIF NFTTBHJOH TZTUFN GSPN UIF SFTU PG UIF BQQMJDBUJPO

40

$) " 15& 3 5 - & / 5 & 3 1 3 * 4& * /5 & ( 3 " 5 * 0/ 1 "5 5 &3 / 4

4FSWJDF "DUJWBUPS

)PX DBO BO BQQMJDBUJPO EFTJHO B TFSWJDF UP CF JOWPLFE CPUI WJB WBSJPVT NFTTBHJOH UFDIOPMPHJFT BOE WJB OPO-NFTTBHJOH UFDIOJRVFT

2VPQBJ ,>K>DBJBKQ $POUSPM#VT %FUPVS 8JSF 5BQ .FTTBHF )JTUPSZ -PH )PX DBO XF FGGFDUJWFMZ BENJOJTUFS B NFTTBHJOH TZTUFN UIBU JT EJTUSJCVUFE BDSPTT NVMUJQMF QMBUGPSNT BOE B XJEF HFPHSBQIJD BSFB )PX DBO ZPV SPVUF B NFTTBHF UISPVHI JOUFSNFEJBUF TUFQT UP QFSGPSN WBMJEBUJPO, UFTUJOH PS EFCVHHJOH GVODUJPOT )PX EP ZPV JOTQFDU NFTTBHFT UIBU USBWFM PO B QPJOU-UP-QPJOU DIBOOFM )PX DBO XF FGGFDUJWFMZ BOBMZ[F BOE EFCVH UIF GMPX PG NFTTBHFT JO B MPPTFMZ DPVQMFE TZTUFN )PX DBO * MPH QSPDFTTJOH B NFTTBHF

'PS B GVMM CSFBLEPXO PG FBDI QBUUFSO TFF UIF #PPL 1BUUFSO "QQFOEJY

$ ) " 1 5 & 3 5 - &/ 5 &3 13 *4& */ 5 &(3 "5 *0 / 1"5 5 &3 / 4

41

"LLH!LLH

5IJT EPDVNFOU EFTDSJCFT WBSJPVT SFDJQFT GPS XPSLJOH XJUI $BNFM ` #FBO *OUFHSBUJPO EFTDSJCFT IPX UP XPSL XJUI CFBOT BOE $BNFM JO B MPPTFMZ DPVQMFE XBZ TP UIBU ZPVS CFBOT EP OPU IBWF UP EFQFOE PO BOZ $BNFM "1*T "OOPUBUJPO #BTFE &YQSFTTJPO -BOHVBHF CJOET FYQSFTTJPOT UP NFUIPE QBSBNFUFST #FBO #JOEJOH EFGJOFT XIJDI NFUIPET BSF JOWPLFE BOE IPX UIF .FTTBHF JT DPOWFSUFE JOUP UIF QBSBNFUFST PG UIF NFUIPE XIFO JU JT JOWPLFE #FBO *OKFDUJPO GPS JOKFDUJOH $BNFM SFMBUFE SFTPVSDFT JOUP ZPVS 10+0T 1BSBNFUFS #JOEJOH "OOPUBUJPOT GPS FYUSBDUJOH WBSJPVT IFBEFST, QSPQFSUJFT PS QBZMPBET GSPN B .FTTBHF 10+0 $POTVNJOH GPS DPOTVNJOH BOE QPTTJCMZ SPVUJOH NFTTBHFT GSPN $BNFM 10+0 1SPEVDJOH GPS QSPEVDJOH DBNFM NFTTBHFT GSPN ZPVS 10+0T 3FDJQJFOU-JTU "OOPUBUJPO GPS DSFBUJOH B 3FDJQJFOU -JTU GSPN B 10+0 NFUIPE 6TJOH &YDIBOHF 1BUUFSO "OOPUBUJPOT EFTDSJCFT IPX QBUUFSO BOOPUBUJPOT DBO CF VTFE UP DIBOHF UIF CFIBWJPVS PG NFUIPE JOWPDBUJPOT ` )JEJOH .JEEMFXBSF EFTDSJCFT IPX UP BWPJE ZPVS CVTJOFTT MPHJD CFJOH DPVQMFE UP BOZ QBSUJDVMBS NJEEMFXBSF "1*T BMMPXJOH ZPV UP FBTJMZ TXJUDI GSPN JO +7. 4&%" UP +.4, "DUJWF.2, )JCFSOBUF, +1", +%#$, J#"5*4 PS +BWB4QBDF FUD. ` 7JTVBMJTBUJPO EFTDSJCFT IPX UP WJTVBMJTF ZPVS &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT UP IFMQ ZPV VOEFSTUBOE ZPVS SPVUJOH SVMFT ` #VTJOFTT "DUJWJUZ .POJUPSJOH (#".) GPS NPOJUPSJOH CVTJOFTT QSPDFTTFT BDSPTT TZTUFNT ` &YUSBDU 5SBOTGPSN -PBE (&5-) UP MPBE EBUB JOUP TZTUFNT PS EBUBCBTFT ` 5FTUJOH GPS UFTUJOH EJTUSJCVUFE BOE BTZODISPOPVT TZTUFNT VTJOH B NFTTBHJOH BQQSPBDI $BNFM 5FTU GPS DSFBUJOH UFTU DBTFT VTJOH B TJOHMF +BWB DMBTT GPS BMM ZPVS DPOGJHVSBUJPO BOE SPVUJOH 4QSJOH 5FTUJOH VTFT 4QSJOH 5FTU UPHFUIFS XJUI FJUIFS 9.- PS +BWB $POGJH UP EFQFOEFODZ JOKFDU ZPVS UFTU DMBTTFT (VJDF VTFT (VJDF UP EFQFOEFODZ JOKFDU ZPVS UFTU DMBTTFT ` 5FNQMBUJOH JT B HSFBU XBZ UP DSFBUF TFSWJDF TUVCT UP CF BCMF UP UFTU ZPVS TZTUFN XJUIPVU TPNF CBDL FOE TZTUFN. ` %BUBCBTF GPS XPSLJOH XJUI EBUBCBTFT ` 1BSBMMFM 1SPDFTTJOH BOE 0SEFSJOH PO IPX VTJOH QBSBMMFM QSPDFTTJOH BOE 4&%" PS +.4 CBTFE MPBE CBMBODJOH DBO CF BDIJFWFE. ` "TZODISPOPVT 1SPDFTTJOH JO $BNFM 3PVUFT. ` *NQMFNFOUJOH 7JSUVBM 5PQJDT PO PUIFS +.4 QSPWJEFST TIPXT IPX UP HFU UIF FGGFDU PG 7JSUVBM 5PQJDT BOE BWPJE JTTVFT XJUI +.4 EVSBCMF UPQJDT ` $BNFM 5SBOTQPSU GPS $9' EFTDSJCFT IPX UP QVU UIF $BNFM DPOUFYU JOUP UIF $9' USBOTQPSU MBZFS.

42

$00 , #0 0 ,

` 'JOF (SBJOFE $POUSPM 0WFS B $IBOOFM EFTDSJCFT IPX UP EFMJWFS B TFRVFODF PG NFTTBHFT PWFS B TJOHMF DIBOOFM BOE UIFO TUPQQJOH BOZ NPSF NFTTBHFT CFJOH TFOU PWFS UIBU DIBOOFM. 5ZQJDBMMZ VTFE GPS TFOEJOH EBUB PWFS B TPDLFU BOE UIFO DMPTJOH UIF TPDLFU. ` &WFOU/PUJGJFS UP MPH EFUBJMT BCPVU BMM TFOU &YDIBOHFT TIPXT IPX UP MFU $BNFMT EventNotifier MPH BMM TFOU UP FOEQPJOU FWFOUT BOE IPX MPOH UJNF JU UPPL. ` -PBEJOH SPVUFT GSPN 9.- GJMFT JOUP BO FYJTUJOH $BNFM$POUFYU. ` 6TJOH .%$ MPHHJOH XJUI $BNFM ` 3VOOJOH $BNFM TUBOEBMPOF BOE IBWF JU LFFQ SVOOJOH TIPXT IPX UP LFFQ $BNFM SVOOJOH XIFO ZPV SVO JU TUBOEBMPOF. ` )B[FMDBTU *EFNQPUFOU 3FQPTJUPSZ 5VUPSJBM TIPXT IPX UP BWPJE UP DPOTVNF EVQMJDBUFE NFTTBHFT JO B DMVTUFSFE FOWJSPONFOU. ` )PX UP VTF $BNFM BT B )551 QSPYZ CFUXFFO B DMJFOU BOE TFSWFS TIPXT IPX UP VTF $BNFM BT B )551 BEBQUFS/QSPYZ CFUXFFO B DMJFOU BOE )551 TFSWJDF.

!$ - (-3$&1 3(.$BNFM TVQQPSUT UIF JOUFHSBUJPO PG CFBOT BOE 10+0T JO B OVNCFS PG XBZT KKLQ>QFLKP *G B CFBO JT EFGJOFE JO 4QSJOH 9.- PS TDBOOFE VTJOH UIF 4QSJOH DPNQPOFOU TDBOOJOH NFDIBOJTN BOE B <@>JBI"LKQBUQ> JT VTFE PS B CamelBeanPostProcessor UIFO XF QSPDFTT B OVNCFS PG $BNFM BOOPUBUJPOT UP EP WBSJPVT UIJOHT TVDI BT JOKFDUJOH SFTPVSDFT PS QSPEVDJOH, DPOTVNJOH PS SPVUJOH NFTTBHFT. ` 10+0 $POTVNJOH UP DPOTVNF BOE QPTTJCMZ SPVUF NFTTBHFT GSPN $BNFM ` 10+0 1SPEVDJOH UP NBLF JU FBTZ UP QSPEVDF DBNFM NFTTBHFT GSPN ZPVS 10+0T ` %ZOBNJD3PVUFS "OOPUBUJPO GPS DSFBUJOH B %ZOBNJD 3PVUFS GSPN B 10+0 NFUIPE ` 3FDJQJFOU-JTU "OOPUBUJPO GPS DSFBUJOH B 3FDJQJFOU -JTU GSPN B 10+0 NFUIPE ` 3PVUJOH4MJQ "OOPUBUJPO GPS DSFBUJOH B 3PVUJOH 4MJQ GPS B 10+0 NFUIPE ` #FBO *OKFDUJPO UP JOKFDU $BNFM SFMBUFE SFTPVSDFT JOUP ZPVS 10+0T ` 6TJOH &YDIBOHF 1BUUFSO "OOPUBUJPOT EFTDSJCFT IPX UIF QBUUFSO BOOPUBUJPOT DBO CF VTFE UP DIBOHF UIF CFIBWJPVS PG NFUIPE JOWPDBUJPOT XJUI 4QSJOH 3FNPUJOH PS 10+0 1SPEVDJOH !B>K "LJMLKBKQ 5IF #FBO DPNQPOFOU BMMPXT POF UP JOWPLF B QBSUJDVMBS NFUIPE. "MUFSOBUFMZ UIF #FBO DPNQPOFOU TVQQPSUT UIF DSFBUJPO PG B QSPYZ WJB 1SPYZ)FMQFS UP B +BWB JOUFSGBDF; XIJDI UIF JNQMFNFOUBUJPO KVTU TFOET B NFTTBHF DPOUBJOJOH B #FBO*OWPDBUJPO UP TPNF $BNFM FOEQPJOU.

$0 0 , # 0 0 ,

43

$U>JMIB 4FF UIF 10+0 .FTTBHJOH &YBNQMF GPS IPX UP VTF UIF BOOPUBUJPOT GPS SPVUJOH BOE NFTTBHJOH. 2MOFKD 1BJLQFKD 8F TVQQPSU B 4QSJOH 3FNPUJOH QSPWJEFS XIJDI VTFT $BNFM BT UIF VOEFSMZJOH USBOTQPSU NFDIBOJTN. 5IF OJDF UIJOH BCPVU UIJT BQQSPBDI JT XF DBO VTF BOZ PG UIF $BNFM USBOTQPSU $PNQPOFOUT UP DPNNVOJDBUF CFUXFFO CFBOT. *U BMTP NFBOT XF DBO VTF $POUFOU #BTFE 3PVUFS BOE UIF PUIFS &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT JO CFUXFFO UIF CFBOT; JO QBSUJDVMBS XF DBO VTF .FTTBHF 5SBOTMBUPS UP CF BCMF UP DPOWFSU XIBU UIF PO-UIF-XJSF NFTTBHFT MPPL MJLF JO BEEJUJPO UP BEEJOH WBSJPVT IFBEFST BOE TP GPSUI. KKLQ>QFLK !>PBA $UMOBPPFLK +>KDR>DB :PV DBO BMTP VTF BOZ PG UIF -BOHVBHFT TVQQPSUFE JO $BNFM UP CJOE FYQSFTTJPOT UP NFUIPE QBSBNFUFST XIFO VTJOH #FBO *OUFHSBUJPO. 'PS FYBNQMF ZPV DBO VTF BOZ PG UIFTF BOOPUBUJPOT: KKLQ>QFLK !#FBO !#FBO4IFMM !$POTUBOU !&!(SPPWZ !)FBEFS !+BWB4DSJQU !.7&!0(/!1)1 !1ZUIPO !3VCZ !4JNQMF !91BUI !92VFSZ #BP@OFMQFLK *OKFDU B #FBO FYQSFTTJPO *OKFDU B #FBO4IFMM FYQSFTTJPO *OKFDU B $POTUBOU FYQSFTTJPO *OKFDU BO &- FYQSFTTJPO *OKFDU B (SPPWZ FYQSFTTJPO *OKFDU B )FBEFS FYQSFTTJPO *OKFDU B +BWB4DSJQU FYQSFTTJPO *OKFDU B .WFM FYQSFTTJPO *OKFDU BO 0(/- FYQSFTTJPO *OKFDU B 1)1 FYQSFTTJPO *OKFDU B 1ZUIPO FYQSFTTJPO *OKFDU B 3VCZ FYQSFTTJPO *OKFDU BO 4JNQMF FYQSFTTJPO *OKFDU BO 91BUI FYQSFTTJPO *OKFDU BO 92VFSZ FYQSFTTJPO

44

$00 , #0 0 ,

!B>K ?FKAFKD 8IFOFWFS $BNFM JOWPLFT B CFBO NFUIPE WJB POF PG UIF BCPWF NFUIPET (#FBO DPNQPOFOU, 4QSJOH 3FNPUJOH PS 10+0 $POTVNJOH) UIFO UIF !B>K !FKAFKD NFDIBOJTN JT VTFE UP GJHVSF PVU XIBU NFUIPE UP VTF (JG JU JT OPU FYQMJDJU) BOE IPX UP CJOE UIF .FTTBHF UP UIF QBSBNFUFST QPTTJCMZ VTJOH UIF 1BSBNFUFS #JOEJOH "OOPUBUJPOT PS VTJOH B NFUIPE OBNF PQUJPO.

$U>JMIB:
public class Foo { @MessageDriven(uri = "activemq:my.queue") public void doSomething(@XPath("/foo/bar/text()") String correlationID, @Body String body) { // process the inbound message here } }

AS>K@BA BU>JMIB RPFKD @!B>K


"OE BO FYBNQMF PG VTJOH UIF UIF !#FBO CJOEJOH BOOPUBUJPO, XIFSF ZPV DBO VTF B 1PKP XIFSF ZPV DBO EP XIBUFWFS KBWB DPEF ZPV MJLF:
public class Foo { @MessageDriven(uri = "activemq:my.queue") public void doSomething(@Bean("myCorrelationIdGenerator") String correlationID, @Body String body) { // process the inbound message here } }

"OE UIFO XF DBO IBWF B TQSJOH CFBO XJUI UIF JE JV"LOOBI>QFLK(A&BKBO>QLO XIFSF XF DBO DPNQVUF UIF JE.
public class MyIdGenerator { private UserManager userManager; public String generate(@Header(name = "user") String user, @Body String payload) throws Exception { User user = userManager.lookupUser(user); String userId = user.getPrimaryId();

$0 0 , # 0 0 ,

45

String id = userId + generateHashCodeForPayload(payload); return id; } }

5IF 1PKP .Z*E(FOFSBUPS IBT POF QVCMJD NFUIPE UIBU BDDFQUT UXP QBSBNFUFST. )PXFWFS XF IBWF BMTP BOOPUBUFE UIJT POF XJUI UIF !)FBEFS BOE !#PEZ BOOPUBUJPO UP IFMQ $BNFM LOPX XIBU UP CJOE IFSF GSPN UIF .FTTBHF GSPN UIF &YDIBOHF CFJOH QSPDFTTFE. 0G DPVSTF UIJT DPVME CF TJNQMJGJFE B MPU JG ZPV GPS JOTUBODF KVTU IBWF B TJNQMF JE HFOFSBUPS. #VU XF XBOUFE UP EFNPOTUSBUF UIBU ZPV DBO VTF UIF #FBO #JOEJOH BOOPUBUJPOT BOZXIFSF.
public class MySimpleIdGenerator { public static int generate() // generate a unique id return 123; } } {

"OE GJOBMMZ XF KVTU OFFE UP SFNFNCFS UP IBWF PVS CFBO SFHJTUFSFE JO UIF 4QSJOH 3FHJTUSZ:
<bean id="myCorrelationIdGenerator" class="com.mycompany.MySimpleIdGenerator"/>

$U>JMIB RPFKD &OLLSV


*O UIJT FYBNQMF XF IBWF BO &YDIBOHF UIBU IBT B 6TFS PCKFDU TUPSFE JO UIF JO IFBEFS. 5IJT 6TFS PCKFDU IBT NFUIPET UP HFU TPNF VTFS JOGPSNBUJPO. 8F XBOU UP VTF (SPPWZ UP JOKFDU BO FYQSFTTJPO UIBU FYUSBDUT BOE DPODBUT UIF GVMMOBNF PG UIF VTFS JOUP UIF GVMM/BNF QBSBNFUFS.
public void doSomething(@Groovy("$request.header['user'].firstName $request.header['user'].familyName) String fullName, @Body String body) { // process the inbound message here }

(SPPWZ TVQQPSUT (4USJOHT UIBU JT MJLF B UFNQMBUF XIFSF XF DBO JOTFSU $ QMBDFIPMEFST UIBU XJMM CF FWBMVBUFE CZ (SPPWZ.

!$ - !(-#(-&
#FBO #JOEJOH JO $BNFM EFGJOFT CPUI XIJDI NFUIPET BSF JOWPLFE BOE BMTP IPX UIF .FTTBHF JT DPOWFSUFE JOUP UIF QBSBNFUFST PG UIF NFUIPE XIFO JU JT JOWPLFE.

46

$00 , #0 0 ,

"ELLPFKD QEB JBQELA QL FKSLHB 5IF CJOEJOH PG B $BNFM .FTTBHF UP B CFBO NFUIPE DBMM DBO PDDVS JO EJGGFSFOU XBZT, JO UIF GPMMPXJOH PSEFS PG JNQPSUBODF: ` JG UIF NFTTBHF DPOUBJOT UIF IFBEFS ">JBI!B>K,BQELA->JB UIFO UIBU NFUIPE JT JOWPLFE, DPOWFSUJOH UIF CPEZ UP UIF UZQF PG UIF NFUIPE'T BSHVNFOU. 'SPN ">JBI 2.8 POXBSET ZPV DBO RVBMJGZ QBSBNFUFS UZQFT UP TFMFDU FYBDUMZ XIJDI NFUIPE UP VTF BNPOH PWFSMPBET XJUI UIF TBNF OBNF (TFF CFMPX GPS NPSF EFUBJMT). 'SPN ">JBI 2.9 POXBSET ZPV DBO TQFDJGZ QBSBNFUFS WBMVFT EJSFDUMZ JO UIF NFUIPE PQUJPO (TFF CFMPX GPS NPSF EFUBJMT). ` ZPV DBO FYQMJDJUMZ TQFDJGZ UIF NFUIPE OBNF JO UIF %4- PS XIFO VTJOH 10+0 $POTVNJOH PS 10+0 1SPEVDJOH ` JG UIF CFBO IBT B NFUIPE NBSLFE XJUI UIF @Handler BOOPUBUJPO, UIFO UIBU NFUIPE JT TFMFDUFE ` JG UIF CFBO DBO CF DPOWFSUFE UP B 1SPDFTTPS VTJOH UIF 5ZQF $POWFSUFS NFDIBOJTN, UIFO UIJT JT VTFE UP QSPDFTT UIF NFTTBHF. 5IF "DUJWF.2 DPNQPOFOU VTFT UIJT NFDIBOJTN UP BMMPX BOZ +.4 .FTTBHF-JTUFOFS UP CF JOWPLFE EJSFDUMZ CZ $BNFM XJUIPVU IBWJOH UP XSJUF BOZ JOUFHSBUJPO HMVF DPEF. :PV DBO VTF UIF TBNF NFDIBOJTN UP JOUFHSBUF $BNFM JOUP BOZ PUIFS NFTTBHJOH/SFNPUJOH GSBNFXPSLT. ` JG UIF CPEZ PG UIF NFTTBHF DBO CF DPOWFSUFE UP B #FBO*OWPDBUJPO (UIF EFGBVMU QBZMPBE VTFE CZ UIF 1SPYZ)FMQFS) DPNQPOFOU - UIFO UIBU JT VTFE UP JOWPLF UIF NFUIPE BOE QBTT JUT BSHVNFOUT ` PUIFSXJTF UIF UZQF PG UIF CPEZ JT VTFE UP GJOE B NBUDIJOH NFUIPE; BO FSSPS JT UISPXO JG B TJOHMF NFUIPE DBOOPU CF DIPTFO VOBNCJHVPVTMZ. ` ZPV DBO BMTP VTF &YDIBOHF BT UIF QBSBNFUFS JUTFMG, CVU UIFO UIF SFUVSO UZQF NVTU CF WPJE. ` JG UIF CFBO DMBTT JT QSJWBUF (PS QBDLBHF-QSJWBUF), JOUFSGBDF NFUIPET XJMM CF QSFGFSSFE (GSPN ">JBI 2.9 POXBSET) TJODF $BNFM DBO'U JOWPLF DMBTT NFUIPET PO TVDI CFBOT *O DBTFT XIFSF $BNFM DBOOPU DIPPTF B NFUIPE UP JOWPLF, BO AmbiguousMethodCallException JT UISPXO. #Z EFGBVMU UIF SFUVSO WBMVF JT TFU PO UIF PVUCPVOE NFTTBHF CPEZ. />O>JBQBO ?FKAFKD 8IFO B NFUIPE IBT CFFO DIPTFO GPS JOWPLBUJPO, $BNFM XJMM CJOE UP UIF QBSBNFUFST PG UIF NFUIPE. 5IF GPMMPXJOH $BNFM-TQFDJGJD UZQFT BSF BVUPNBUJDBMMZ CPVOE: org.apache.camel.Exchange org.apache.camel.Message org.apache.camel.CamelContext org.apache.camel.TypeConverter org.apache.camel.spi.Registry

$0 0 , # 0 0 ,

47

java.lang.Exception 4P, JG ZPV EFDMBSF BOZ PG UIFTF UZQFT, UIFZ XJMM CF QSPWJEFE CZ $BNFM. -LQB QE>Q Exception TFII ?FKA QL QEB @>RDEQ BU@BMQFLK LC QEB $U@E>KDB - TP JU'T PGUFO VTBCMF JG ZPV FNQMPZ B 1PKP UP IBOEMF, F.H., BO onException SPVUF. 8IBU JT NPTU JOUFSFTUJOH JT UIBU $BNFM XJMM BMTP USZ UP CJOE UIF CPEZ PG UIF &YDIBOHF UP UIF GJSTU QBSBNFUFS PG UIF NFUIPE TJHOBUVSF (BMCFJU OPU PG BOZ PG UIF UZQFT BCPWF). 4P JG, GPS JOTUBODF, XF EFDMBSF B QBSBNFUFS BT String body, UIFO $BNFM XJMM CJOE UIF */ CPEZ UP UIJT UZQF. $BNFM XJMM BMTP BVUPNBUJDBMMZ DPOWFSU UP UIF UZQF EFDMBSFE JO UIF NFUIPE TJHOBUVSF. -FU'T SFWJFX TPNF FYBNQMFT: #FMPX JT B TJNQMF NFUIPE XJUI B CPEZ CJOEJOH. $BNFM XJMM CJOE UIF */ CPEZ UP UIF body QBSBNFUFS BOE DPOWFSU JU UP B String.
public String doSomething(String body)

*O UIF GPMMPXJOH TBNQMF XF HPU POF PG UIF BVUPNBUJDBMMZ-CPVOE UZQFT BT XFMM - GPS JOTUBODF, B Registry UIBU XF DBO VTF UP MPPLVQ CFBOT.
public String doSomething(String body, Registry registry)

8F DBO VTF &YDIBOHF BT XFMM:


public String doSomething(String body, Exchange exchange)

:PV DBO BMTP IBWF NVMUJQMF UZQFT:


public String doSomething(String body, Exchange exchange, TypeConverter converter)

"OE JNBHJOF ZPV VTF B 1PKP UP IBOEMF B HJWFO DVTUPN FYDFQUJPO InvalidOrderException - XF DBO UIFO CJOE UIBU BT XFMM:
public String badOrder(String body, InvalidOrderException invalid)

/PUJDF UIBU XF DBO CJOE UP JU FWFO JG XF VTF B TVC UZQF PG java.lang.Exception BT $BNFM TUJMM LOPXT JU'T BO FYDFQUJPO BOE DBO CJOE UIF DBVTF (JG BOZ FYJTUT). 4P XIBU BCPVU IFBEFST BOE PUIFS TUVGG 8FMM OPX JU HFUT B CJU USJDLZ - TP XF DBO VTF BOOPUBUJPOT UP IFMQ VT, PS TQFDJGZ UIF CJOEJOH JO UIF NFUIPE OBNF PQUJPO. 4FF UIF GPMMPXJOH TFDUJPOT GPS NPSF EFUBJM. !FKAFKD KKLQ>QFLKP

:PV DBO VTF UIF 1BSBNFUFS #JOEJOH "OOPUBUJPOT UP DVTUPNJ[F IPX QBSBNFUFS WBMVFT BSF DSFBUFE GSPN UIF .FTTBHF
48 $00 , #0 0 ,

$U>JMIBP
'PS FYBNQMF, B #FBO TVDI BT:
public class Bar { public String doSomething(String body) { // process the in body and return whatever you want return "Bye World"; }

0S UIF &YDIBOHF FYBNQMF. /PUJDF UIBU UIF SFUVSO UZQF NVTU CF SLFA XIFO UIFSF JT POMZ B TJOHMF QBSBNFUFS PG UIF UZQF org.apache.camel.Exchange:
public class Bar { public void doSomething(Exchange exchange) { // process the exchange exchange.getIn().setBody("Bye World"); }

@'>KAIBO
:PV DBO NBSL B NFUIPE JO ZPVS CFBO XJUI UIF !)BOEMFS BOOPUBUJPO UP JOEJDBUF UIBU UIJT NFUIPE TIPVME CF VTFE GPS #FBO #JOEJOH. 5IJT IBT BO BEWBOUBHF BT ZPV OFFE OPU TQFDJGZ B NFUIPE OBNF JO UIF $BNFM SPVUF, BOE UIFSFGPSF EP OPU SVO JOUP QSPCMFNT BGUFS SFOBNJOH UIF NFUIPE JO BO *%& UIBU DBO'U GJOE BMM JUT SFGFSFODFT.
public class Bar { @Handler public String doSomething(String body) { // process the in body and return whatever you want return "Bye World"; }

/>O>JBQBO ?FKAFKD RPFKD JBQELA LMQFLK S>FI>?IB >P LC ">JBI 2.9 $BNFM VTFT UIF GPMMPXJOH SVMFT UP EFUFSNJOF JG JU'T B QBSBNFUFS WBMVF JO UIF NFUIPE PQUJPO 5IF WBMVF JT FJUIFS true PS false XIJDI EFOPUFT B CPPMFBO WBMVF 5IF WBMVF JT B OVNFSJD WBMVF TVDI BT 123 PS 7 5IF WBMVF JT B 4USJOH FODMPTFE XJUI FJUIFS TJOHMF PS EPVCMF RVPUFT 5IF WBMVF JT OVMM XIJDI EFOPUFT B null WBMVF
$0 0 , # 0 0 , 49

*U DBO CF FWBMVBUFE VTJOH UIF 4JNQMF MBOHVBHF, XIJDI NFBOT ZPV DBO VTF, F.H., CPEZ, IFBEFS.GPP BOE PUIFS 4JNQMF UPLFOT. /PUJDF UIF UPLFOT NVTU CF FODMPTFE XJUI $\ ^. "OZ PUIFS WBMVF JT DPOTJEFS UP CF B UZQF EFDMBSBUJPO JOTUFBE - TFF UIF OFYU TFDUJPO BCPVU TQFDJGZJOH UZQFT GPS PWFSMPBEFE NFUIPET. 8IFO JOWPLJOH B #FBO ZPV DBO JOTUSVDU $BNFM UP JOWPLF B TQFDJGJD NFUIPE CZ QSPWJEJOH UIF NFUIPE OBNF:
.bean(OrderService.class, "doSomething")

)FSF XF UFMM $BNFM UP JOWPLF UIF EP4PNFUIJOH NFUIPE - $BNFM IBOEMFT UIF QBSBNFUFST' CJOEJOH. /PX TVQQPTF UIF NFUIPE IBT 2 QBSBNFUFST, BOE UIF 2OE QBSBNFUFS JT B CPPMFBO XIFSF XF XBOU UP QBTT JO B USVF WBMVF:
public void doSomething(String payload, boolean highPriority) { ... }

5IJT JT OPX QPTTJCMF JO ">JBI 2.9 POXBSET:


.bean(OrderService.class, "doSomething(*, true)")

*O UIF FYBNQMF BCPWF, XF EFGJOFE UIF GJSTU QBSBNFUFS VTJOH UIF XJME DBSE TZNCPM *, XIJDI UFMMT $BNFM UP CJOE UIJT QBSBNFUFS UP BOZ UZQF, BOE MFU $BNFM GJHVSF UIJT PVU. 5IF 2OE QBSBNFUFS IBT B GJYFE WBMVF PG true. *OTUFBE PG UIF XJMEDBSE TZNCPM XF DBO JOTUSVDU $BNFM UP VTF UIF NFTTBHF CPEZ BT TIPXO:
.bean(OrderService.class, "doSomething(${body}, true)")

5IF TZOUBY PG UIF QBSBNFUFST JT VTJOH UIF 4JNQMF FYQSFTTJPO MBOHVBHF TP XF IBWF UP VTF $\ ^ QMBDFIPMEFST JO UIF CPEZ UP SFGFS UP UIF NFTTBHF CPEZ. *G ZPV XBOU UP QBTT JO B null WBMVF, UIFO ZPV DBO FYQMJDJU EFGJOF UIJT JO UIF NFUIPE PQUJPO BT TIPXO CFMPX:
.to("bean:orderService?method=doSomething(null, true)")

4QFDJGZJOH null BT B QBSBNFUFS WBMVF JOTUSVDUT $BNFM UP GPSDF QBTTJOH B null WBMVF. #FTJEFT UIF NFTTBHF CPEZ, ZPV DBO QBTT JO UIF NFTTBHF IFBEFST BT B java.util.Map:
.bean(OrderService.class, "doSomethingWithHeaders(${body}, ${headers})")

:PV DBO BMTP QBTT JO PUIFS GJYFE WBMVFT CFTJEFT CPPMFBOT. 'PS FYBNQMF, ZPV DBO QBTT JO B 4USJOH BOE BO JOUFHFS:

50

$00 , #0 0 ,

.bean(MyBean.class, "echo('World', 5)")

*O UIF FYBNQMF BCPWF, XF JOWPLF UIF FDIP NFUIPE XJUI UXP QBSBNFUFST. 5IF GJSTU IBT UIF DPOUFOU '8PSME' (XJUIPVU RVPUFT), BOE UIF 2OE IBT UIF WBMVF PG 5. $BNFM XJMM BVUPNBUJDBMMZ DPOWFSU UIFTF WBMVFT UP UIF QBSBNFUFST' UZQFT. )BWJOH UIF QPXFS PG UIF 4JNQMF MBOHVBHF BMMPXT VT UP CJOE UP NFTTBHF IFBEFST BOE PUIFS WBMVFT TVDI BT:
.bean(OrderService.class, "doSomething(${body}, ${header.high})")

:PV DBO BMTP VTF UIF 0(/- TVQQPSU PG UIF 4JNQMF FYQSFTTJPO MBOHVBHF. /PX TVQQPTF UIF NFTTBHF CPEZ JT BO PCKFDU XIJDI IBT B NFUIPE OBNFE asXml. 5P JOWPLF UIF asXml NFUIPE XF DBO EP BT GPMMPXT:
.bean(OrderService.class, "doSomething(${body.asXml}, ${header.high})")

*OTUFBE PG VTJOH .bean BT TIPXO JO UIF FYBNQMFT BCPWF, ZPV NBZ XBOU UP VTF .to JOTUFBE BT TIPXO:
.to("bean:orderService?method=doSomething(${body.asXml}, ${header.high})")

4PFKD QVMB NR>IFCFBOP QL PBIB@Q >JLKD LSBOIL>ABA JBQELAP S>FI>?IB >P LC ">JBI 2.8 *G ZPV IBWF B #FBO XJUI PWFSMPBEFE NFUIPET, ZPV DBO OPX TQFDJGZ QBSBNFUFS UZQFT JO UIF NFUIPE OBNF TP $BNFM DBO NBUDI UIF NFUIPE ZPV JOUFOE UP VTF. (JWFO UIF GPMMPXJOH CFBO:
Listing 1. MyBean
public static final class MyBean { public String hello(String name) { return "Hello " + name; } public String hello(String name, @Header("country") String country) { return "Hello " + name + " you are from " + country; } public String times(String name, @Header("times") int times) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { sb.append(name); }

$0 0 , # 0 0 ,

51

return sb.toString(); } public String times(byte[] data, @Header("times") int times) { String s = new String(data); StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { sb.append(s); if (i < times - 1) { sb.append(","); } } return sb.toString(); } public String times(String name, int times, char separator) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < times; i++) { sb.append(name); if (i < times - 1) { sb.append(separator); } } return sb.toString(); } }

5IFO UIF MyBean IBT 2 PWFSMPBEFE NFUIPET XJUI UIF OBNFT hello BOE times. 4P JG XF XBOU UP VTF UIF NFUIPE XIJDI IBT 2 QBSBNFUFST XF DBO EP BT GPMMPXT JO UIF $BNFM SPVUF:
Listing 1. Invoke 2 parameter method
from("direct:start") .bean(MyBean.class, "hello(String,String)") .to("mock:result");

8F DBO BMTP VTF B * BT XJMEDBSE TP XF DBO KVTU TBZ XF XBOU UP FYFDVUF UIF NFUIPE XJUI 2 QBSBNFUFST XF EP
Listing 1. Invoke 2 parameter method using wildcard
from("direct:start") .bean(MyBean.class, "hello(*,*)") .to("mock:result");

#Z EFGBVMU $BNFM XJMM NBUDI UIF UZQF OBNF VTJOH UIF TJNQMF OBNF, F.H. BOZ MFBEJOH QBDLBHF OBNF XJMM CF EJTSFHBSEFE. )PXFWFS JG ZPV XBOU UP NBUDI VTJOH UIF '2/, UIFO TQFDJGZ UIF '2/ UZQF BOE $BNFM XJMM MFWFSBHF UIBU. 4P JG ZPV IBWF B com.foo.MyOrder BOE ZPV XBOU UP NBUDI BHBJOTU UIF '2/, BOE KLQ UIF TJNQMF OBNF ".Z0SEFS", UIFO GPMMPX UIJT FYBNQMF:

52

$00 , #0 0 ,

.bean(OrderService.class, "doSomething(com.foo.MyOrder)")

!B>K (KGB@QFLK 8F TVQQPSU UIF JOKFDUJPO PG WBSJPVT SFTPVSDFT VTJOH !&OEQPJOU*OKFDU. 5IJT DBO CF VTFE UP JOKFDU ` &OEQPJOU JOTUBODFT XIJDI DBO CF VTFE GPS UFTUJOH XIFO VTFE XJUI .PDL FOEQPJOUT; TFF UIF 4QSJOH 5FTUJOH GPS BO FYBNQMF. ` 1SPEVDFS5FNQMBUF JOTUBODFT GPS 10+0 1SPEVDJOH ` DMJFOU TJEF QSPYJFT GPS 10+0 1SPEVDJOH XIJDI JT B TJNQMF BQQSPBDI UP 4QSJOH 3FNPUJOH />O>JBQBO !FKAFKD KKLQ>QFLKP

"OOPUBUJPOT DBO CF VTFE UP EFGJOF BO &YQSFTTJPO PS UP FYUSBDU WBSJPVT IFBEFST, QSPQFSUJFT PS QBZMPBET GSPN B .FTTBHF XIFO JOWPLJOH B CFBO NFUIPE (TFF #FBO *OUFHSBUJPO GPS NPSF EFUBJM PG IPX UP JOWPLF CFBO NFUIPET) UPHFUIFS XJUI CFJOH VTFGVM UP IFMQ EJTBNCJHVBUF XIJDI NFUIPE UP JOWPLF. *G OP BOOPUBUJPOT BSF VTFE UIFO $BNFM BTTVNFT UIBU B TJOHMF QBSBNFUFS JT UIF CPEZ PG UIF NFTTBHF. $BNFM XJMM UIFO VTF UIF 5ZQF $POWFSUFS NFDIBOJTN UP DPOWFSU GSPN UIF FYQSFTTJPO WBMVF UP UIF BDUVBM UZQF PG UIF QBSBNFUFS. 5IF DPSF BOOPUBUJPOT BSF BT GPMMPXT KKLQ>QFLK !#PEZ !&YDIBOHF&YDFQUJPO !)FBEFS !)FBEFST !0VU)FBEFST ,B>KFKD 5P CJOE UP BO JOCPVOE NFTTBHF CPEZ 5P CJOE UP BO &YDFQUJPO TFU PO UIF FYDIBOHF 5P CJOE UP BO JOCPVOE NFTTBHF IFBEFS 5P CJOE UP UIF .BQ PG UIF JOCPVOE NFTTBHF IFBEFST 5P CJOE UP UIF .BQ PG UIF PVUCPVOE NFTTBHF IFBEFST 5P CJOE UP B OBNFE QSPQFSUZ PO UIF FYDIBOHF 5P CJOE UP UIF QSPQFSUZ NBQ PO UIF FYDIBOHF />O>JBQBO c c 4USJOH OBNF PG UIF IFBEFS c c 4USJOH OBNF PG UIF QSPQFSUZ c

!1SPQFSUZ !1SPQFSUJFT

$0 0 , # 0 0 ,

53

$BNFM DVSSFOUMZ POMZ TVQQPSUT FJUIFS TQFDJGZJOH QBSBNFUFS CJOEJOH PS UZQF QFS QBSBNFUFS JO UIF NFUIPE OBNF PQUJPO. :PV @>KKLQ TQFDJGZ CPUI BU UIF TBNF UJNF, TVDI BT
doSomething(com.foo.MyOrder ${body}, boolean ${header.high})

5IJT NBZ DIBOHF JO UIF GVUVSF.

@>JBI-@LOB 5IF BOOPUBUJPOT CFMPX BSF BMM QBSU PG @>JBI-@LOB BOE UIVT EPFT OPU SFRVJSF @>JBI-PMOFKD PS 4QSJOH. 5IFTF BOOPUBUJPOT DBO CF VTFE XJUI UIF #FBO DPNQPOFOU PS XIFO JOWPLJOH CFBOT JO UIF %4-

!)BOEMFS

/PU QBSU BT B UZQF QBSBNFUFS CVU TUBUFE JO UIJT UBCMF BOZXBZ UP TQSFBE UIF HPPE XPSE UIBU XF IBWF UIJT BOOPUBUJPO JO $BNFM OPX. 4FF NPSF BU #FBO #JOEJOH.

5IF GPMMPX BOOPUBUJPOT @Headers, @OutHeaders BOE @Properties CJOET UP UIF CBDLJOH java.util.Map TP ZPV DBO BMUFS UIF DPOUFOU PG UIFTF NBQT EJSFDUMZ, GPS JOTUBODF VTJOH UIF put NFUIPE UP BEE B OFX FOUSZ. 4FF UIF 0SEFS4FSWJDF DMBTT BU &YDFQUJPO $MBVTF GPS TVDI BO FYBNQMF. :PV DBO VTF @Header("myHeader") BOE @Property("myProperty") UP BDDFTT UIF CBDLJOH java.util.Map. $U>JMIB *O UIJT FYBNQMF CFMPX XF IBWF B !$POTVNF DPOTVNFS (MJLF NFTTBHF ESJWFO) UIBU DPOTVNFT +.4 NFTTBHFT GSPN UIF BDUJWFNR RVFVF. 8F VTF UIF !)FBEFS BOE !#PEZ QBSBNFUFS CJOEJOH BOOPUBUJPOT UP CJOE GSPN UIF +.4.FTTBHF UP UIF NFUIPE QBSBNFUFST.
public class Foo { @Consume(uri = "activemq:my.queue") public void doSomething(@Header("JMSCorrelationID") String correlationID, @Body String body) { // process the inbound message here } }

54

$00 , #0 0 ,

*O UIF BCPWF $BNFM XJMM FYUSBDU UIF WBMVF PG .FTTBHF.HFU+.4$PSSFMBUJPO*%(), UIFO VTJOH UIF 5ZQF $POWFSUFS UP BEBQU UIF WBMVF UP UIF UZQF PG UIF QBSBNFUFS JG SFRVJSFE - JU XJMM JOKFDU UIF QBSBNFUFS WBMVF GPS UIF @LOOBI>QFLK(# QBSBNFUFS. 5IFO UIF QBZMPBE PG UIF NFTTBHF XJMM CF DPOWFSUFE UP B 4USJOH BOE JOKFDUFE JOUP UIF ?LAV QBSBNFUFS. :PV EPO'U OFDFTTBSJMZ OFFE UP VTF UIF !$POTVNF BOOPUBUJPO JG ZPV EPO'U XBOU UP BT ZPV DPVME BMTP NBLF VTF PG UIF $BNFM %4- UP SPVUF UP UIF CFBO'T NFUIPE BT XFMM.

4PFKD QEB #2+ QL FKSLHB QEB ?B>K JBQELA


)FSF JT BOPUIFS FYBNQMF XIJDI EPFT OPU VTF 10+0 $POTVNJOH BOOPUBUJPOT CVU JOTUFBE VTFT UIF %4- UP SPVUF NFTTBHFT UP UIF CFBO NFUIPE
public class Foo { public void doSomething(@Header("JMSCorrelationID") String correlationID, @Body String body) { // process the inbound message here } }

5IF SPVUJOH %4- UIFO MPPLT MJLF UIJT


from("activemq:someQueue"). to("bean:myBean");

)FSF JV!B>K XPVME CF MPPLFE VQ JO UIF 3FHJTUSZ (TVDI BT +/%* PS UIF 4QSJOH "QQMJDBUJPO$POUFYU), UIFO UIF CPEZ PG UIF NFTTBHF XPVME CF VTFE UP USZ GJHVSF PVU XIBU NFUIPE UP DBMM. *G ZPV XBOU UP CF FYQMJDJU ZPV DBO VTF
from("activemq:someQueue"). to("bean:myBean?methodName=doSomething");

"OE IFSF XF IBWF B OJGUZ FYBNQMF GPS ZPV UP TIPX TPNF HSFBU QPXFS JO $BNFM. :PV DBO NJY BOE NBUDI UIF BOOPUBUJPOT XJUI UIF OPSNBM QBSBNFUFST, TP XF DBO IBWF UIJT FYBNQMF XJUI BOOPUBUJPOT BOE UIF &YDIBOHF BMTP:
public void doSomething(@Header("user") String user, @Body String body, Exchange exchange) { exchange.getIn().setBody(body + "MyBean"); }

$0 0 , # 0 0 ,

55

KKLQ>QFLK !>PBA $UMOBPPFLK +>KDR>DB :PV DBO BMTP VTF BOZ PG UIF -BOHVBHFT TVQQPSUFE JO $BNFM UP CJOE FYQSFTTJPOT UP NFUIPE QBSBNFUFST XIFO VTJOH #FBO *OUFHSBUJPO. 'PS FYBNQMF ZPV DBO VTF BOZ PG UIFTF BOOPUBUJPOT: KKLQ>QFLK !#FBO !#FBO4IFMM !$POTUBOU !&!(SPPWZ !)FBEFS !+BWB4DSJQU !.7&!0(/!1)1 !1ZUIPO !3VCZ !4JNQMF !91BUI !92VFSZ #BP@OFMQFLK *OKFDU B #FBO FYQSFTTJPO *OKFDU B #FBO4IFMM FYQSFTTJPO *OKFDU B $POTUBOU FYQSFTTJPO *OKFDU BO &- FYQSFTTJPO *OKFDU B (SPPWZ FYQSFTTJPO *OKFDU B )FBEFS FYQSFTTJPO *OKFDU B +BWB4DSJQU FYQSFTTJPO *OKFDU B .WFM FYQSFTTJPO *OKFDU BO 0(/- FYQSFTTJPO *OKFDU B 1)1 FYQSFTTJPO *OKFDU B 1ZUIPO FYQSFTTJPO *OKFDU B 3VCZ FYQSFTTJPO *OKFDU BO 4JNQMF FYQSFTTJPO *OKFDU BO 91BUI FYQSFTTJPO *OKFDU BO 92VFSZ FYQSFTTJPO

$U>JMIB:
public class Foo { @MessageDriven(uri = "activemq:my.queue") public void doSomething(@XPath("/foo/bar/text()") String correlationID, @Body String body) { // process the inbound message here } }

56

$00 , #0 0 ,

AS>K@BA BU>JMIB RPFKD @!B>K


"OE BO FYBNQMF PG VTJOH UIF UIF !#FBO CJOEJOH BOOPUBUJPO, XIFSF ZPV DBO VTF B 1PKP XIFSF ZPV DBO EP XIBUFWFS KBWB DPEF ZPV MJLF:
public class Foo { @MessageDriven(uri = "activemq:my.queue") public void doSomething(@Bean("myCorrelationIdGenerator") String correlationID, @Body String body) { // process the inbound message here } }

"OE UIFO XF DBO IBWF B TQSJOH CFBO XJUI UIF JE JV"LOOBI>QFLK(A&BKBO>QLO XIFSF XF DBO DPNQVUF UIF JE.
public class MyIdGenerator { private UserManager userManager; public String generate(@Header(name = "user") String user, @Body String payload) throws Exception { User user = userManager.lookupUser(user); String userId = user.getPrimaryId(); String id = userId + generateHashCodeForPayload(payload); return id; } }

5IF 1PKP .Z*E(FOFSBUPS IBT POF QVCMJD NFUIPE UIBU BDDFQUT UXP QBSBNFUFST. )PXFWFS XF IBWF BMTP BOOPUBUFE UIJT POF XJUI UIF !)FBEFS BOE !#PEZ BOOPUBUJPO UP IFMQ $BNFM LOPX XIBU UP CJOE IFSF GSPN UIF .FTTBHF GSPN UIF &YDIBOHF CFJOH QSPDFTTFE. 0G DPVSTF UIJT DPVME CF TJNQMJGJFE B MPU JG ZPV GPS JOTUBODF KVTU IBWF B TJNQMF JE HFOFSBUPS. #VU XF XBOUFE UP EFNPOTUSBUF UIBU ZPV DBO VTF UIF #FBO #JOEJOH BOOPUBUJPOT BOZXIFSF.
public class MySimpleIdGenerator { public static int generate() // generate a unique id return 123; } } {

"OE GJOBMMZ XF KVTU OFFE UP SFNFNCFS UP IBWF PVS CFBO SFHJTUFSFE JO UIF 4QSJOH 3FHJTUSZ:
<bean id="myCorrelationIdGenerator" class="com.mycompany.MySimpleIdGenerator"/>

$0 0 , # 0 0 ,

57

$U>JMIB RPFKD &OLLSV


*O UIJT FYBNQMF XF IBWF BO &YDIBOHF UIBU IBT B 6TFS PCKFDU TUPSFE JO UIF JO IFBEFS. 5IJT 6TFS PCKFDU IBT NFUIPET UP HFU TPNF VTFS JOGPSNBUJPO. 8F XBOU UP VTF (SPPWZ UP JOKFDU BO FYQSFTTJPO UIBU FYUSBDUT BOE DPODBUT UIF GVMMOBNF PG UIF VTFS JOUP UIF GVMM/BNF QBSBNFUFS.
public void doSomething(@Groovy("$request.header['user'].firstName $request.header['user'].familyName) String fullName, @Body String body) { // process the inbound message here }

(SPPWZ TVQQPSUT (4USJOHT UIBU JT MJLF B UFNQMBUF XIFSF XF DBO JOTFSU $ QMBDFIPMEFST UIBU XJMM CF FWBMVBUFE CZ (SPPWZ.

@"LKPRJB
5P DPOTVNF B NFTTBHF ZPV VTF UIF !$POTVNF BOOPUBUJPO UP NBSL B QBSUJDVMBS NFUIPE PG B CFBO BT CFJOH B DPOTVNFS NFUIPE. 5IF VSJ PG UIF BOOPUBUJPO EFGJOFT UIF $BNFM &OEQPJOU UP DPOTVNF GSPN. F.H. MFUT JOWPLF UIF onCheese() NFUIPE XJUI UIF 4USJOH CPEZ PG UIF JOCPVOE +.4 NFTTBHF GSPN "DUJWF.2 PO UIF DIFFTF RVFVF; UIJT XJMM VTF UIF 5ZQF $POWFSUFS UP DPOWFSU UIF +.4 0CKFDU.FTTBHF PS #ZUFT.FTTBHF UP B 4USJOH - PS KVTU VTF B 5FYU.FTTBHF GSPN +.4
public class Foo { @Consume(uri="activemq:cheese") public void onCheese(String name) { ... } }

5IF #FBO #JOEJOH JT UIFO VTFE UP DPOWFSU UIF JOCPVOE .FTTBHF UP UIF QBSBNFUFS MJTU VTFE UP JOWPLF UIF NFUIPE . 8IBU UIJT EPFT JT CBTJDBMMZ DSFBUF B SPVUF UIBU MPPLT LJOEB MJLF UIJT
from(uri).bean(theBean, "methodName");

4PFKD @LKQBUQ LMQFLK QL >MMIV LKIV > @BOQ>FK ">JBI"LKQBUQ 4FF UIF XBSOJOH BCPWF. :PV DBO VTF UIF context PQUJPO UP TQFDJGZ XIJDI $BNFM$POUFYU UIF DPOTVNFS TIPVME POMZ BQQMZ GPS. 'PS FYBNQMF:

58

$00 , #0 0 ,

6EBK RPFKD JLOB QE>K LKB ">JBI"LKQBUQ 8IFO ZPV VTF NPSF UIBO 1 $BNFM$POUFYU ZPV NJHIU FOE VQ XJUI FBDI PG UIFN DSFBUJOH B 10+0 $POTVNJOH; UIFSFGPSF VTF UIF PQUJPO context PO @"LKPRJB UIBU BMMPXT ZPV UP TQFDJGZ XIJDI $BNFM$POUFYU JE/OBNF ZPV XBOU JU UP BQQMZ GPS.

@Consume(uri="activemq:cheese", context="camel-1") public void onCheese(String name) {

5IF DPOTVNFS BCPWF XJMM POMZ CF DSFBUFE GPS UIF $BNFM$POUFYU UIBU IBWF UIF DPOUFYU JE = camel-1. :PV TFU UIJT JE JO UIF 9.- UBH:
<camelContext id="camel-1" ...>

4PFKD >K BUMIF@FQ OLRQB


*G ZPV XBOU UP JOWPLF B CFBO NFUIPE GSPN NBOZ EJGGFSFOU FOEQPJOUT PS XJUIJO EJGGFSFOU DPNQMFY SPVUFT JO EJGGFSFOU DJSDVNTUBODFT ZPV DBO KVTU VTF UIF OPSNBM SPVUJOH %4- PS UIF 4QSJOH 9.DPOGJHVSBUJPO GJMF. 'PS FYBNQMF
from(uri).beanRef("myBean", "methodName");

XIJDI XJMM UIFO MPPL VQ JO UIF 3FHJTUSZ BOE GJOE UIF CFBO BOE JOWPLF UIF HJWFO CFBO OBNF. (:PV DBO PNJU UIF NFUIPE OBNF BOE IBWF $BNFM GJHVSF PVU UIF SJHIU NFUIPE CBTFE PO UIF NFUIPE BOOPUBUJPOT BOE CPEZ UZQF).

4PB QEB !B>K BKAMLFKQ


:PV DBO BMXBZT VTF UIF CFBO FOEQPJOU
from(uri).to("bean:myBean?method=methodName");

4PFKD > MOLMBOQV QL ABCFKB QEB BKAMLFKQ


S>FI>?IB >P LC ">JBI 2.11

$0 0 , # 0 0 ,

59

5IF GPMMPXJOH BOOPUBUJPOT !$POTVNF, !1SPEVDF, !&OEQPJOU*OKFDU, OPX PGGFST B property BUUSJCVUF ZPV DBO VTF UP EFGJOF UIF FOEQPJOU BT B QSPQFSUZ PO UIF CFBO. 5IFO $BNFM XJMM VTF UIF HFUUFS NFUIPE UP BDDFTT UIF QSPQFSUZ. 'PS FYBNQMF
public class MyService { private String serviceEndpoint; public void setServiceEndpoint(String uri) { this.serviceEndpoint = uri; } public String getServiceEndpoint() { return serviceEndpoint } @Consume(property = "serviceEndpoint") public void onService(String input) { ... } }

5IF CFBO MyService IBT B QSPQFSUZ OBNFE serviceEndpoint XIJDI IBT HFUUFS/TFUUFS GPS UIF QSPQFSUZ. /PX XF XBOU UP VTF UIF CFBO GPS 10+0 $POTVNJOH, BOE IFODF XIZ XF VTF !$POTVNF JO UIF PO4FSWJDF NFUIPE. /PUJDF IPX XF VTF UIF property = "serviceEndpoint UP DPOGJHVSF UIF QSPQFSUZ UIBU IBT UIF FOEQPJOU VSM. *G ZPV EFGJOF UIF CFBO JO 4QSJOH 9.- PS #MVFQSJOU, UIFO ZPV DBO DPOGJHVSF UIF QSPQFSUZ BT GPMMPXT:
<bean id="myService" class="com.foo.MyService"> <property name="serviceEndpoint" value="activemq:queue:foo"/> </bean>

5IJT BMMPXT ZPV UP DPOGJHVSF UIF CFBO VTJOH BOZ TUBOEBSE *P$ TUZMF. $BNFM PGGFST B OBNJOH DPOWFOUJPO XIJDI BMMPXT ZPV UP OPU IBWF UP FYQMJDJU OBNF UIF QSPQFSUZ. $BNFM VTFT UIJT BMHPSJUIN UP GJOE UIF HFUUFS NFUIPE. 5IF NFUIPE NVTU CF B HFU999 NFUIPE. 1. 6TF UIF QSPQFSUZ OBNF JG FYQMJDJU HJWFO 2. *G OP QSPQFSUZ OBNF XBT DPOGJHVSFE, UIFO VTF UIF NFUIPE OBNF 3. 5SZ UP HFU UIF QSPQFSUZ XJUI OBNF*&OEQPJOU* (FH XJUI &OEQPJOU BT QPTUGJY) 4. 5SZ UP HFU UIF QSPQFSUZ XJUI UIF OBNF BT JT (FH OP QPTUGJY PS QPTUGJY) 5. *G UIF QSPQFSUZ OBNF TUBSUT XJUI LK UIFO PNJU UIBU, BOE USZ TUFQ 3 BOE 4 BHBJO. 4P JO UIF FYBNQMF BCPWF, XF DPVME IBWF EFGJOFE UIF !$POTVNF BOOPUBUJPO BT

60

$00 , #0 0 ,

3EFP >MMIFBP CLO QEBJ >II 5IF FYQMBOBUJPO CFMPX BQQMJFT GPS BMM UIF UISFF BOOPUBUJPOT, FH !$POTVNF, !1SPEVDF, BOE !&OEQPJOU*OKFDU

@Consume(property = "service") public void onService(String input) {

/PX UIF QSPQFSUZ JT OBNFE 'TFSWJDF' XIJDI UIFO XPVME NBUDI TUFQ 3 GSPN UIF BMHPSJUIN, BOE IBWF $BNFM JOWPLF UIF HFU4FSWJDF&OEQPJOU NFUIPE. 8F DPVME BMTP IBWF PNJUUFE UIF QSPQFSUZ BUUSJCVUF, UP NBLF JU JNQMJDJU
@Consume public void onService(String input) {

/PX $BNFM NBUDIFT TUFQ 5, BOE MPTFT UIF QSFGJY LK JO UIF OBNF, BOE MPPLT GPS 'TFSWJDF' BT UIF QSPQFSUZ. "OE CFDBVTF UIFSF JT B HFU4FSWJDF&OEQPJOU NFUIPE, $BNFM XJMM VTF UIBU.

6EF@E >MMOL>@E QL RPB?


6TJOH UIF !$POTVNF BOOPUBUJPOT BSF TJNQMFS XIFO ZPV BSF DSFBUJOH B TJNQMF SPVUF XJUI B TJOHMF XFMM EFGJOFE JOQVU 63*. )PXFWFS JG ZPV SFRVJSF NPSF DPNQMFY SPVUFT PS UIF TBNF CFBO NFUIPE OFFET UP CF JOWPLFE GSPN NBOZ QMBDFT UIFO QMFBTF VTF UIF SPVUJOH %4- BT TIPXO BCPWF. 5IFSF BSF UXP EJGGFSFOU XBZT UP TFOE NFTTBHFT UP BOZ $BNFM &OEQPJOU GSPN B 10+0

@$KAMLFKQ(KGB@Q
5P BMMPX TFOEJOH PG NFTTBHFT GSPN 10+0T ZPV DBO VTF UIF !&OEQPJOU*OKFDU BOOPUBUJPO. 5IJT XJMM JOKFDU B 1SPEVDFS5FNQMBUF TP UIBU UIF CFBO DBO QBSUJDJQBUF JO NFTTBHF FYDIBOHFT. F.H. MFUT TFOE B NFTTBHF UP UIF CLL.?>O RVFVF JO "DUJWF.2 BU TPNF QPJOU

public class Foo { @EndpointInject(uri="activemq:foo.bar") ProducerTemplate producer; public void doSomething() { if (whatever) { producer.sendBody("<hello>world!</hello>"); }

$0 0 , # 0 0 ,

61

} }

5IF EPXOTJEF PG UIJT JT UIBU ZPVS DPEF JT OPX EFQFOEFOU PO B $BNFM "1*, UIF 1SPEVDFS5FNQMBUF. 5IF OFYU TFDUJPO EFTDSJCFT IPX UP SFNPWF UIJT 'FAFKD QEB ">JBI /(P COLJ VLRO @LAB RPFKD @/OLAR@B

8F SFDPNNFOE )JEJOH .JEEMFXBSF "1*T GSPN ZPVS BQQMJDBUJPO DPEF TP UIF OFYU PQUJPO NJHIU CF NPSF TVJUBCMF. :PV DBO BEE UIF !1SPEVDF BOOPUBUJPO UP BO JOKFDUJPO QPJOU (B GJFME PS QSPQFSUZ TFUUFS) VTJOH B 1SPEVDFS5FNQMBUF LO VTJOH TPNF JOUFSGBDF ZPV VTF JO ZPVS CVTJOFTT MPHJD. F.H.
public interface MyListener { String sayHello(String name); } public class MyBean { @Produce(uri = "activemq:foo") protected MyListener producer; public void doSomething() { // lets send a message String response = producer.sayHello("James"); } }

)FSF $BNFM XJMM BVUPNBUJDBMMZ JOKFDU B TNBSU DMJFOU TJEF QSPYZ BU UIF !1SPEVDF BOOPUBUJPO - BO JOTUBODF PG UIF .Z-JTUFOFS JOTUBODF. 8IFO XF JOWPLF NFUIPET PO UIJT JOUFSGBDF UIF NFUIPE DBMM JT UVSOFE JOUP BO PCKFDU BOE VTJOH UIF $BNFM 4QSJOH 3FNPUJOH NFDIBOJTN JU JT TFOU UP UIF FOEQPJOU - JO UIJT DBTF UIF "DUJWF.2 FOEQPJOU UP RVFVF CLL; UIFO UIF DBMMFS CMPDLT GPS B SFTQPOTF. *G ZPV XBOU UP NBLF BTZODISPOPVT NFTTBHF TFOET UIFO VTF BO !*O0OMZ BOOPUBUJPO PO UIF JOKFDUJPO QPJOU.

@1$"(/($-3+(23

--.3 3(.-

8F TVQQPSU UIF VTF PG !3FDJQJFOU-JTU PO B CFBO NFUIPE UP FBTJMZ DSFBUF B EZOBNJD 3FDJQJFOU -JTU VTJOH B +BWB NFUIPE.

62

$00 , #0 0 ,

4FF 10+0 $POTVNJOH GPS IPX UP VTF B QSPQFSUZ PO UIF CFBO BT FOEQPJOU DPOGJHVSBUJPO, FH VTJOH UIF property BUUSJCVUF PO !1SPEVDF, !&OEQPJOU*OKFDU. 2FJMIB $U>JMIB RPFKD @"LKPRJB >KA @1B@FMFBKQ+FPQ
package com.acme.foo; public class RouterBean { @Consume(uri = "activemq:foo") @RecipientList public String[] route(String body) { return new String[]{"activemq:bar", "activemq:whatnot"}; } }

'PS FYBNQMF JG UIF BCPWF CFBO JT DPOGJHVSFE JO 4QSJOH XIFO VTJOH B <@>JBI"LKQBUQ> FMFNFOU BT GPMMPXT
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd "> <camelContext xmlns="http://activemq.apache.org/camel/schema/spring"/> <bean id="myRecipientList" class="com.acme.foo.RouterBean"/> </beans>

UIFO B SPVUF XJMM CF DSFBUFE DPOTVNJOH GSPN UIF CLL RVFVF PO UIF "DUJWF.2 DPNQPOFOU XIJDI XIFO B NFTTBHF JT SFDFJWFE UIF NFTTBHF XJMM CF GPSXBSEFE UP UIF FOEQPJOUT EFGJOFE CZ UIF SFTVMU PG UIJT NFUIPE DBMM - OBNFMZ UIF ?>O BOE TE>QKLQ RVFVFT. 'LT FQ TLOHP 5IF SFUVSO WBMVF PG UIF !3FDJQJFOU-JTU NFUIPE JT DPOWFSUFE UP FJUIFS B KBWB.VUJM.$PMMFDUJPO / KBWB.VUJM.*UFSBUPS PS BSSBZ PG PCKFDUT XIFSF FBDI FMFNFOU JT DPOWFSUFE UP BO &OEQPJOU PS B 4USJOH, PS JG ZPV BSF POMZ HPJOH UP SPVUF UP B TJOHMF FOEQPJOU UIFO KVTU SFUVSO FJUIFS BO &OEQPJOU PCKFDU PS BO PCKFDU UIBU DBO CF DPOWFSUFE UP B 4USJOH. 4P UIF GPMMPXJOH NFUIPET BSF BMM WBMJE

$0 0 , # 0 0 ,

63

@RecipientList public String[] route(String body) { ... } @RecipientList public List<String> route(String body) { ... } @RecipientList public Endpoint route(String body) { ... } @RecipientList public Endpoint[] route(String body) { ... } @RecipientList public Collection<Endpoint> route(String body) { ... } @RecipientList public URI route(String body) { ... } @RecipientList public URI[] route(String body) { ... }

5IFO GPS FBDI FOEQPJOU PS 63* UIF NFTTBHF JT GPSXBSEFE B TFQBSBUF DPQZ UP UIBU FOEQPJOU. :PV DBO UIFO VTF XIBUFWFS +BWB DPEF ZPV XJTI UP GJHVSF PVU XIBU FOEQPJOUT UP SPVUF UP; GPS FYBNQMF ZPV DBO VTF UIF #FBO #JOEJOH BOOPUBUJPOT UP JOKFDU QBSUT PG UIF NFTTBHF CPEZ PS IFBEFST PS VTF &YQSFTTJPO WBMVFT PO UIF NFTTBHF. ,LOB "LJMIBU $U>JMIB 4PFKD #2+ *O UIJT FYBNQMF XF XJMM VTF NPSF DPNQMFY #FBO #JOEJOH, QMVT XF XJMM VTF B TFQBSBUF SPVUF UP JOWPLF UIF 3FDJQJFOU -JTU
public class RouterBean2 { @RecipientList public String route(@Header("customerID") String custID String body) { if (custID == null) return null; return "activemq:Customers.Orders." + custID; } } public class MyRouteBuilder extends RouteBuilder { protected void configure() { from("activemq:Orders.Incoming").recipientList(bean("myRouterBean", "route")); } }

/PUJDF IPX XF BSF JOKFDUJOH TPNF IFBEFST PS FYQSFTTJPOT BOE VTJOH UIFN UP EFUFSNJOF UIF SFDJQJFOUT VTJOH 3FDJQJFOU -JTU &*1. 4FF UIF #FBO *OUFHSBUJPO GPS NPSF EFUBJMT.

64

$00 , #0 0 ,

42(-& $7"' -&$ / 33$1-

--.3 3(.-2

8IFO XPSLJOH XJUI 10+0 1SPEVDJOH PS 4QSJOH 3FNPUJOH ZPV JOWPLF NFUIPET XIJDI UZQJDBMMZ CZ EFGBVMU BSF *O0VU GPS 3FRVFTU 3FQMZ. 5IBU JT UIFSF JT BO *O NFTTBHF BOE BO 0VU GPS UIF SFTVMU. 5ZQJDBMMZ JOWPLJOH UIJT PQFSBUJPO XJMM CF TZODISPOPVT, UIF DBMMFS XJMM CMPDL VOUJM UIF TFSWFS SFUVSOT B SFTVMU. $BNFM IBT GMFYJCMF &YDIBOHF 1BUUFSO TVQQPSU - TP ZPV DBO BMTP TVQQPSU UIF &WFOU .FTTBHF QBUUFSO UP VTF *O0OMZ GPS BTZODISPOPVT PS POF XBZ PQFSBUJPOT. 5IFTF BSF PGUFO DBMMFE 'GJSF BOE GPSHFU' MJLF TFOEJOH B +.4 NFTTBHF CVU OPU XBJUJOH GPS BOZ SFTQPOTF. 'SPN 1.5 POXBSET $BNFM TVQQPSUT BOOPUBUJPOT GPS TQFDJGZJOH UIF NFTTBHF FYDIBOHF QBUUFSO PO SFHVMBS +BWB NFUIPET, DMBTTFT PS JOUFSGBDFT. 2MB@FCVFKD (K.KIV JBQELAP 5ZQJDBMMZ UIF EFGBVMU *O0VU JT XIBU NPTU GPMLT XBOU CVU ZPV DBO DVTUPNJ[F UP VTF *O0OMZ VTJOH BO BOOPUBUJPO.
public interface Foo { Object someInOutMethod(String input); String anotherInOutMethod(Cheese input); @InOnly void someInOnlyMethod(Document input); }

5IF BCPWF DPEF TIPXT UISFF NFUIPET PO BO JOUFSGBDF; UIF GJSTU UXP VTF UIF EFGBVMU *O0VU NFDIBOJTN CVU UIF PLJB(K.KIV,BQELA VTFT UIF *O0OMZ BOOPUBUJPO UP TQFDJGZ JU BT CFJOH B POFXBZ NFUIPE DBMM. "I>PP IBSBI >KKLQ>QFLKP :PV DBO BMTP VTF DMBTT MFWFM BOOPUBUJPOT UP EFGBVMU BMM NFUIPET JO BO JOUFSGBDF UP TPNF QBUUFSO TVDI BT
@InOnly public interface Foo { void someInOnlyMethod(Document input); void anotherInOnlyMethod(String input); }

"OOPUBUJPOT XJMM BMTP CF EFUFDUFE PO CBTF DMBTTFT PS JOUFSGBDFT. 4P GPS FYBNQMF JG ZPV DSFBUFE B DMJFOU TJEF QSPYZ GPS

$0 0 , # 0 0 ,

65

public class MyFoo implements Foo { ... }

5IFO UIF NFUIPET JOIFSJUFE GSPN 'PP XPVME CF *O0OMZ. .SBOIL>AFKD > @I>PP IBSBI >KKLQ>QFLK :PV DBO PWFSMPBE B DMBTT MFWFM BOOPUBUJPO PO TQFDJGJD NFUIPET. " DPNNPO VTF DBTF GPS UIJT JT JG ZPV IBWF B DMBTT PS JOUFSGBDF XJUI NBOZ *O0OMZ NFUIPET CVU ZPV XBOU UP KVTU BOOPUF POF PS UXP NFUIPET BT *O0VU
@InOnly public interface Foo { void someInOnlyMethod(Document input); void anotherInOnlyMethod(String input); @InOut String someInOutMethod(String input); }

*O UIF BCPWF 'PP JOUFSGBDF UIF PLJB(K.RQ,BQELA XJMM CF *O0VU 4PFKD VLRO LTK >KKLQ>QFLKP :PV NJHIU XBOU UP DSFBUF ZPVS PXO BOOPUBUJPOT UP SFQSFTFOU B HSPVQ PG EJGGFSFOU CJUT PG NFUBEBUB; TVDI BT DPNCJOJOH TZODISPOZ, DPODVSSFODZ BOE USBOTBDUJPO CFIBWJPVS. 4P ZPV DPVME BOOPUBUF ZPVS BOOPUBUJPO XJUI UIF !1BUUFSO BOOPUBUJPO UP EFGBVMU UIF FYDIBOHF QBUUFSO ZPV XJTI UP VTF. 'PS FYBNQMF MFUT TBZ XF XBOU UP DSFBUF PVS PXO BOOPUBUJPO DBMMFE !.Z"TZOD4FSWJDF
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) // lets add the message exchange pattern to it @Pattern(ExchangePattern.InOnly) // lets add some other annotations - maybe transaction behaviour? public @interface MyAsyncService { }

/PX XF DBO VTF UIJT BOOPUBUJPO BOE $BNFM XJMM GJHVSF PVU UIF DPSSFDU FYDIBOHF QBUUFSO...

66

$00 , #0 0 ,

public interface Foo { void someInOnlyMethod(Document input); void anotherInOnlyMethod(String input); @MyAsyncService String someInOutMethod(String input); }

8IFO XSJUJOH TPGUXBSF UIFTF EBZT, JUT JNQPSUBOU UP USZ BOE EFDPVQMF BT NVDI NJEEMFXBSF DPEF GSPN ZPVS CVTJOFTT MPHJD BT QPTTJCMF. 5IJT QSPWJEFT B OVNCFS PG CFOFGJUT... ` ZPV DBO DIPPTF UIF SJHIU NJEEMFXBSF TPMVUJPO GPS ZPVS EFQMPZNFOU BOE TXJUDI BU BOZ UJNF ` ZPV EPO'U IBWF UP TQFOE B MBSHF BNPVOU PG UJNF MFBSOJOH UIF TQFDJGJDT PG BOZ QBSUJDVMBS UFDIOPMPHZ, XIFUIFS JUT +.4 PS +BWB4QBDF PS )JCFSOBUF PS +1" PS J#"5*4 XIBUFWFS 'PS FYBNQMF JG ZPV XBOU UP JNQMFNFOU TPNF LJOE PG NFTTBHF QBTTJOH, SFNPUJOH, SFMJBCMF MPBE CBMBODJOH PS BTZODISPOPVT QSPDFTTJOH JO ZPVS BQQMJDBUJPO XF SFDPNNFOE ZPV VTF $BNFM BOOPUBUJPOT UP CJOE ZPVS TFSWJDFT BOE CVTJOFTT MPHJD UP $BNFM $PNQPOFOUT XIJDI NFBOT ZPV DBO UIFO FBTJMZ TXJUDI CFUXFFO UIJOHT MJLF ` JO +7. NFTTBHJOH XJUI 4&%" ` VTJOH +.4 WJB "DUJWF.2 PS PUIFS +.4 QSPWJEFST GPS SFMJBCMF MPBE CBMBODJOH, HSJE PS QVCMJTI BOE TVCTDSJCF ` GPS MPX WPMVNF, CVU FBTJFS BENJOJTUSBUJPO TJODF ZPV'SF QSPCBCMZ BMSFBEZ VTJOH B EBUBCBTF ZPV DPVME VTF )JCFSOBUF PS +1" UP VTF BO FOUJUZ CFBO / UBCMF BT B RVFVF J#"5*4 UP XPSL XJUI 42 +%#$ GPS SBX 42- BDDFTT ` VTF +BWB4QBDF 'LT QL AB@LRMIB COLJ JFAAIBT>OB /(P

5IF CFTU BQQSPBDI XIFO VTJOH SFNPUJOH JT UP VTF 4QSJOH 3FNPUJOH XIJDI DBO UIFO VTF BOZ NFTTBHJOH PS SFNPUJOH UFDIOPMPHZ VOEFS UIF DPWFST. 8IFO VTJOH $BNFM'T JNQMFNFOUBUJPO ZPV DBO UIFO VTF BOZ PG UIF $BNFM $PNQPOFOUT BMPOH XJUI BOZ PG UIF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT. "OPUIFS BQQSPBDI JT UP CJOE +BWB CFBOT UP $BNFM FOEQPJOUT WJB UIF #FBO *OUFHSBUJPO. 'PS FYBNQMF VTJOH 10+0 $POTVNJOH BOE 10+0 1SPEVDJOH ZPV DBO BWPJE VTJOH BOZ $BNFM "1*T UP EFDPVQMF ZPVS DPEF CPUI GSPN NJEEMFXBSF "1*T and $BNFM "1*T!

$0 0 , # 0 0 ,

67

5(24 +(2 3(.$BNFM TVQQPSUT UIF WJTVBMJTBUJPO PG ZPVS &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT VTJOH UIF (SBQI7J[ %05 GJMFT XIJDI DBO FJUIFS CF SFOEFSFE EJSFDUMZ WJB B TVJUBCMF (SBQI7J[ UPPM PS UVSOFE JOUP )5.-, 1/( PS 47( GJMFT WJB UIF $BNFM .BWFO 1MVHJO. )FSF JT B UZQJDBM FYBNQMF PG UIF LJOE PG UIJOH XF DBO HFOFSBUF *G ZPV DMJDL PO UIF BDUVBM HFOFSBUFE IUNMZPV XJMM TFF UIBU ZPV DBO OBWJHBUF GSPN BO &*1 OPEF UP JUT QBUUFSO QBHF, BMPOH XJUI HFUUJOH IPWFS-PWFS UPPM UJQT FD. 'LT QL DBKBO>QB 4FF $BNFM %PU .BWFO (PBM PS UIF PUIFS NBWFO HPBMT $BNFM .BWFO 1MVHJO %LO .2 7 RPBOP *G ZPV BSF VTJOH 04 9 UIFO ZPV DBO PQFO UIF %05 GJMF VTJOH HSBQIWJ[ XIJDI XJMM UIFO BVUPNBUJDBMMZ SF-SFOEFS JG JU DIBOHFT, TP ZPV FOE VQ XJUI B SFBM UJNF HSBQIJDBM SFQSFTFOUBUJPO PG UIF UPQJD BOE RVFVF IJFSBSDIJFT! "MTP JG ZPV XBOU UP FEJU UIF MBZPVU B MJUUMF CFGPSF BEEJOH JU UP B XJLJ UP EJTUSJCVUF UP ZPVS UFBN, PQFO UIF %05 GJMF XJUI 0NOJ(SBGGMF UIFO KVTU FEJU BXBZ

!42(-$22

"3(5(38 ,.-(3.1(-&

5IF ">JBI ! , NPEVMF QSPWJEFT B #VTJOFTT "DUJWJUZ .POJUPSJOH (#".) GSBNFXPSL GPS UFTUJOH CVTJOFTT QSPDFTTFT BDSPTT NVMUJQMF NFTTBHF FYDIBOHFT PO EJGGFSFOU &OEQPJOU JOTUBODFT. $POTJEFS, GPS FYBNQMF, B TJNQMF TZTUFN JO XIJDI ZPV TVCNJU 1VSDIBTF 0SEFST JOUP TZTUFN " BOE UIFO SFDFJWF *OWPJDFT GSPN TZTUFN #. :PV NJHIU XBOU UP UFTU UIBU, GPS B HJWFO 1VSDIBTF 0SEFS, ZPV SFDFJWF B NBUDIJOH *OWPJDF GSPN TZTUFN # XJUIJO B TQFDJGJD UJNF QFSJPE. 'LT ">JBI ! , 6LOHP $BNFM #". VTFT B $PSSFMBUJPO *EFOUJGJFS PO BO JOQVU NFTTBHF UP EFUFSNJOF UIF Process Instance UP XIJDI JU CFMPOHT. 5IF QSPDFTT JOTUBODF JT BO FOUJUZ CFBO XIJDI DBO NBJOUBJO TUBUF GPS FBDI Activity (XIFSF BO BDUJWJUZ UZQJDBMMZ NBQT UP B TJOHMF FOEQPJOU - TVDI BT UIF TVCNJTTJPO PG 1VSDIBTF 0SEFST PS UIF SFDFJQU PG *OWPJDFT). :PV DBO UIFO BEE SVMFT UP CF USJHHFSFE XIFO B NFTTBHF JT SFDFJWFE PO BOZ BDUJWJUZ - TVDI BT UP TFU UJNF FYQFDUBUJPOT PS QFSGPSN SFBM UJNF SFDPODJMJBUJPO PG WBMVFT BDSPTT BDUJWJUJFT.

68

$00 , #0 0 ,

2FJMIB $U>JMIB 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP QFSGPSN TPNF UJNF CBTFE SVMFT PO B TJNQMF CVTJOFTT QSPDFTT PG 2 BDUJWJUJFT - " BOE # - XIJDI DPSSFTQPOE XJUI 1VSDIBTF 0SEFST BOE *OWPJDFT JO UIF FYBNQMF BCPWF. *G ZPV XPVME MJLF UP FYQFSJNFOU XJUI UIJT TDFOBSJP, ZPV NBZ FEJU UIJT 5FTU $BTF, XIJDI EFGJOFT UIF BDUJWJUJFT BOE SVMFT, BOE UIFO UFTUT UIBU UIFZ XPSL.
return new ProcessBuilder(jpaTemplate, transactionTemplate) { public void configure() throws Exception { // let's define some activities, correlating on an XPath on the message bodies ActivityBuilder a = activity("seda:a").name("a") .correlate(xpath("/hello/@id")); ActivityBuilder b = activity("seda:b").name("b") .correlate(xpath("/hello/@id")); // now let's add some rules b.starts().after(a.completes()) .expectWithin(seconds(1)) .errorIfOver(seconds(errorTimeout)).to("mock:overdue"); } };

"T ZPV DBO TFF JO UIF BCPWF FYBNQMF, XF GJSTU EFGJOF UXP BDUJWJUJFT, BOE UIFO SVMFT UP TQFDJGZ XIFO XF FYQFDU UIFN UP DPNQMFUF GPS B QSPDFTT JOTUBODF BOE XIFO BO FSSPS DPOEJUJPO TIPVME CF SBJTFE.Q. 5IF 1SPDFTT#VJMEFS JT B 3PVUF#VJMEFS BOE DBO CF BEEFE UP BOZ $BNFM$POUFYU. "LJMIBQB $U>JMIB 'PS B DPNQMFUF FYBNQMF QMFBTF TFF UIF #". &YBNQMF, XIJDI JT QBSU PG UIF TUBOEBSE $BNFM &YBNQMFT 4PB ">PBP *O UIF XPSME PG GJOBODF, B DPNNPO SFRVJSFNFOU JT USBDLJOH USBEFT. 0GUFO B USBEFS XJMM TVCNJU B 'SPOU 0GGJDF 5SBEF XIJDI UIFO GMPXT UISPVHI UIF .JEEMF 0GGJDF BOE #BDL 0GGJDF UISPVHI WBSJPVT TZTUFNT UP TFUUMF UIF USBEF TP UIBU NPOFZ JT FYDIBOHFE. :PV NBZ XJTI UP UFTU UIBU UIF GSPOU BOE CBDL PGGJDF USBEFT NBUDI VQ XJUIJO B DFSUBJO UJNF QFSJPE; JG UIFZ EPO'U NBUDI PS B CBDL PGGJDF USBEF EPFT OPU BSSJWF XJUIJO B SFRVJSFE BNPVOU PG UJNF, ZPV NJHIU TJHOBM BO BMBSN.

$731 "3 31 -2%.1, +. # ($3+)


5IF &5- (&YUSBDU, 5SBOTGPSN, -PBE) JT B NFDIBOJTN GPS MPBEJOH EBUB JOUP TZTUFNT PS EBUBCBTFT VTJOH TPNF LJOE PG %BUB 'PSNBU GSPN B WBSJFUZ PG TPVSDFT; PGUFO GJMFT UIFO VTJOH 1JQFT BOE 'JMUFST, .FTTBHF 5SBOTMBUPS BOE QPTTJCMF PUIFS &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT.

$0 0 , # 0 0 ,

69

4P ZPV DPVME RVFSZ EBUB GSPN WBSJPVT $BNFM $PNQPOFOUT TVDI BT 'JMF, )551 PS +1", QFSGPSN NVMUJQMF QBUUFSOT TVDI BT 4QMJUUFS PS .FTTBHF 5SBOTMBUPS UIFO TFOE UIF NFTTBHFT UP TPNF PUIFS $PNQPOFOU. 5P TIPX IPX UIJT BMM GJUT UPHFUIFS, USZ UIF &5- &YBNQMF

,."* ".,/.-$-3
5FTUJOH PG EJTUSJCVUFE BOE BTZODISPOPVT QSPDFTTJOH JT OPUPSJPVTMZ EJGGJDVMU. 5IF .PDL, 5FTU BOE %BUB4FU FOEQPJOUT XPSL HSFBU XJUI UIF $BNFM 5FTUJOH 'SBNFXPSL UP TJNQMJGZ ZPVS VOJU BOE JOUFHSBUJPO UFTUJOH VTJOH &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT BOE $BNFM'T MBSHF SBOHF PG $PNQPOFOUT UPHFUIFS XJUI UIF QPXFSGVM #FBO *OUFHSBUJPO. 5IF .PDL DPNQPOFOU QSPWJEFT B QPXFSGVM EFDMBSBUJWF UFTUJOH NFDIBOJTN, XIJDI JT TJNJMBS UP K.PDL JO UIBU JU BMMPXT EFDMBSBUJWF FYQFDUBUJPOT UP CF DSFBUFE PO BOZ .PDL FOEQPJOU CFGPSF B UFTU CFHJOT. 5IFO UIF UFTU JT SVO, XIJDI UZQJDBMMZ GJSFT NFTTBHFT UP POF PS NPSF FOEQPJOUT, BOE GJOBMMZ UIF FYQFDUBUJPOT DBO CF BTTFSUFE JO B UFTU DBTF UP FOTVSF UIF TZTUFN XPSLFE BT FYQFDUFE. 5IJT BMMPXT ZPV UP UFTU WBSJPVT UIJOHT MJLF: ` 5IF DPSSFDU OVNCFS PG NFTTBHFT BSF SFDFJWFE PO FBDI FOEQPJOU, ` 5IF DPSSFDU QBZMPBET BSF SFDFJWFE, JO UIF SJHIU PSEFS, ` .FTTBHFT BSSJWF PO BO FOEQPJOU JO PSEFS, VTJOH TPNF &YQSFTTJPO UP DSFBUF BO PSEFS UFTUJOH GVODUJPO, ` .FTTBHFT BSSJWF NBUDI TPNF LJOE PG 1SFEJDBUF TVDI BT UIBU TQFDJGJD IFBEFST IBWF DFSUBJO WBMVFT, PS UIBU QBSUT PG UIF NFTTBHFT NBUDI TPNF QSFEJDBUF, TVDI BT CZ FWBMVBUJOH BO 91BUI PS 92VFSZ &YQSFTTJPO. -LQB UIBU UIFSF JT BMTP UIF 5FTU FOEQPJOU XIJDI JT B .PDL FOEQPJOU, CVU XIJDI VTFT B TFDPOE FOEQPJOU UP QSPWJEF UIF MJTU PG FYQFDUFE NFTTBHF CPEJFT BOE BVUPNBUJDBMMZ TFUT VQ UIF .PDL FOEQPJOU BTTFSUJPOT. *O PUIFS XPSET, JU'T B .PDL FOEQPJOU UIBU BVUPNBUJDBMMZ TFUT VQ JUT BTTFSUJPOT GSPN TPNF TBNQMF NFTTBHFT JO B 'JMF PS EBUBCBTF, GPS FYBNQMF. 41( CLOJ>Q
mock:someName[?options]

8IFSF PLJB->JB DBO CF BOZ TUSJOH UIBU VOJRVFMZ JEFOUJGJFT UIF FOEQPJOU. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
reportGroup

#BC>RIQ
null

#BP@OFMQFLK
" TJ[F UP VTF B UISPVHIQVU MPHHFS GPS SFQPSUJOH

70

$00 , #0 0 ,

,L@H BKAMLFKQP HBBM OB@BFSBA $U@E>KDBP FK JBJLOV FKABCFKFQBIV 3FNFNCFS UIBU .PDL JT EFTJHOFE GPS UFTUJOH. 8IFO ZPV BEE .PDL FOEQPJOUT UP B SPVUF, FBDI &YDIBOHF TFOU UP UIF FOEQPJOU XJMM CF TUPSFE (UP BMMPX GPS MBUFS WBMJEBUJPO) JO NFNPSZ VOUJM FYQMJDJUMZ SFTFU PS UIF +7. JT SFTUBSUFE. *G ZPV BSF TFOEJOH IJHI WPMVNF BOE/PS MBSHF NFTTBHFT, UIJT NBZ DBVTF FYDFTTJWF NFNPSZ VTF. *G ZPVS HPBM JT UP UFTU EFQMPZBCMF SPVUFT JOMJOF, DPOTJEFS VTJOH /PUJGZ#VJMEFS PS "EWJDF8JUI JO ZPVS UFTUT JOTUFBE PG BEEJOH .PDL FOEQPJOUT UP SPVUFT EJSFDUMZ.
'SPN $BNFM 2.10 POXBSET UIFSF BSF UXP OFX PQUJPOT retainFirst, BOE retainLast UIBU DBO CF VTFE UP MJNJU UIF OVNCFS PG NFTTBHFT UIF .PDL FOEQPJOUT LFFQ JO NFNPSZ.

2FJMIB $U>JMIB )FSF'T B TJNQMF FYBNQMF PG .PDL FOEQPJOU JO VTF. 'JSTU, UIF FOEQPJOU JT SFTPMWFE PO UIF DPOUFYU. 5IFO XF TFU BO FYQFDUBUJPO, BOE UIFO, BGUFS UIF UFTU IBT SVO, XF BTTFSU UIBU PVS FYQFDUBUJPOT IBWF CFFO NFU.
MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class); resultEndpoint.expectedMessageCount(2); // send some messages ... // now lets assert that the mock:foo endpoint received 2 messages resultEndpoint.assertIsSatisfied();

:PV UZQJDBMMZ BMXBZT DBMM UIF BTTFSU*T4BUJTGJFE() NFUIPE UP UFTU UIBU UIF FYQFDUBUJPOT XFSF NFU BGUFS SVOOJOH B UFTU. $BNFM XJMM CZ EFGBVMU XBJU 10 TFDPOET XIFO UIF assertIsSatisfied() JT JOWPLFE. 5IJT DBO CF DPOGJHVSFE CZ TFUUJOH UIF setResultWaitTime(millis) NFUIPE.

4PFKD >PPBOQ/BOFLA
S>FI>?IB >P LC ">JBI 2.7 8IFO UIF BTTFSUJPO JT TBUJTGJFE UIFO $BNFM XJMM TUPQ XBJUJOH BOE DPOUJOVF GSPN UIF assertIsSatisfied NFUIPE. 5IBU NFBOT JG B OFX NFTTBHF BSSJWFT PO UIF NPDL FOEQPJOU, KVTU B CJU MBUFS, UIBU BSSJWBM XJMM OPU BGGFDU UIF PVUDPNF PG UIF BTTFSUJPO. 4VQQPTF ZPV EP XBOU UP UFTU UIBU OP OFX NFTTBHFT BSSJWFT BGUFS B QFSJPE UIFSFBGUFS, UIFO ZPV DBO EP UIBU CZ TFUUJOH UIF setAssertPeriod NFUIPE, GPS FYBNQMF:

$0 0 , # 0 0 ,

71

MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class); resultEndpoint.setAssertPeriod(5000); resultEndpoint.expectedMessageCount(2); // send some messages ... // now lets assert that the mock:foo endpoint received 2 messages resultEndpoint.assertIsSatisfied();

2BQQFKD BUMB@Q>QFLKP :PV DBO TFF GSPN UIF KBWBEPD PG .PDL&OEQPJOU UIF WBSJPVT IFMQFS NFUIPET ZPV DBO VTF UP TFU FYQFDUBUJPOT. 5IF NBJO NFUIPET BSF BT GPMMPXT:
,BQELA
FYQFDUFE.FTTBHF$PVOU(JOU) FYQFDUFE.JOJNVN.FTTBHF$PVOU(JOU) FYQFDUFE#PEJFT3FDFJWFE(...) FYQFDUFE)FBEFS3FDFJWFE(...) FYQFDUT"TDFOEJOH(&YQSFTTJPO) FYQFDUT%FTDFOEJOH(&YQSFTTJPO) FYQFDUT/P%VQMJDBUFT(&YQSFTTJPO)

#BP@OFMQFLK
5P EFGJOF UIF FYQFDUFE NFTTBHF DPVOU PO UIF FOEQPJOU. 5P EFGJOF UIF NJOJNVN OVNCFS PG FYQFDUFE NFTTBHFT PO UIF FOEQPJOU. 5P EFGJOF UIF FYQFDUFE CPEJFT UIBU TIPVME CF SFDFJWFE (JO PSEFS). 5P EFGJOF UIF FYQFDUFE IFBEFS UIBU TIPVME CF SFDFJWFE 5P BEE BO FYQFDUBUJPO UIBU NFTTBHFT BSF SFDFJWFE JO PSEFS, VTJOH UIF HJWFO &YQSFTTJPO UP DPNQBSF NFTTBHFT. 5P BEE BO FYQFDUBUJPO UIBU NFTTBHFT BSF SFDFJWFE JO PSEFS, VTJOH UIF HJWFO &YQSFTTJPO UP DPNQBSF NFTTBHFT. 5P BEE BO FYQFDUBUJPO UIBU OP EVQMJDBUF NFTTBHFT BSF SFDFJWFE; VTJOH BO &YQSFTTJPO UP DBMDVMBUF B VOJRVF JEFOUJGJFS GPS FBDI NFTTBHF. 5IJT DPVME CF TPNFUIJOH MJLF UIF JMSMessageID JG VTJOH +.4, PS TPNF VOJRVF SFGFSFODF OVNCFS XJUIJO UIF NFTTBHF.

)FSF'T BOPUIFS FYBNQMF:


resultEndpoint.expectedBodiesReceived("firstMessageBody", "secondMessageBody", "thirdMessageBody");

AAFKD BUMB@Q>QFLKP QL PMB@FCF@ JBPP>DBP


*O BEEJUJPO, ZPV DBO VTF UIF NFTTBHF(JOU NFTTBHF*OEFY) NFUIPE UP BEE BTTFSUJPOT BCPVU B TQFDJGJD NFTTBHF UIBU JT SFDFJWFE. 'PS FYBNQMF, UP BEE FYQFDUBUJPOT PG UIF IFBEFST PS CPEZ PG UIF GJSTU NFTTBHF (VTJOH [FSPCBTFE JOEFYJOH MJLF java.util.List), ZPV DBO VTF UIF GPMMPXJOH DPEF:
resultEndpoint.message(0).header("foo").isEqualTo("bar");

5IFSF BSF TPNF FYBNQMFT PG UIF .PDL FOEQPJOU JO VTF JO UIF DBNFM-DPSF QSPDFTTPS UFTUT. ,L@HFKD BUFPQFKD BKAMLFKQP S>FI>?IB >P LC ">JBI 2.7 $BNFM OPX BMMPXT ZPV UP BVUPNBUJDBMMZ NPDL FYJTUJOH FOEQPJOUT JO ZPVS $BNFM SPVUFT.

72

$00 , #0 0 ,

'LT FQ TLOHP (JMLOQ>KQ: 5IF FOEQPJOUT BSF TUJMM JO BDUJPO. 8IBU IBQQFOT EJGGFSFOUMZ JT UIBU B .PDL FOEQPJOU JT JOKFDUFE BOE SFDFJWFT UIF NFTTBHF GJSTU BOE UIFO EFMFHBUFT UIF NFTTBHF UP UIF UBSHFU FOEQPJOU. :PV DBO WJFX UIJT BT B LJOE PG JOUFSDFQU BOE EFMFHBUF PS FOEQPJOU MJTUFOFS. 4VQQPTF ZPV IBWF UIF HJWFO SPVUF CFMPX:
Listing 1. Route
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("direct:foo").to("log:foo").to("mock:result"); from("direct:foo").transform(constant("Bye World")); } }; }

:PV DBO UIFO VTF UIF adviceWith GFBUVSF JO $BNFM UP NPDL BMM UIF FOEQPJOUT JO B HJWFO SPVUF GSPN ZPVS VOJU UFTU, BT TIPXO CFMPX:
Listing 1. adviceWith mocking all endpoints
public void testAdvisedMockEndpoints() throws Exception { // advice the first route using the inlined AdviceWith route builder // which has extended capabilities than the regular route builder context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // mock all endpoints mockEndpoints(); } }); getMockEndpoint("mock:direct:start").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World"); getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // additional test to ensure correct endpoints in registry assertNotNull(context.hasEndpoint("direct:start"));

$0 0 , # 0 0 ,

73

assertNotNull(context.hasEndpoint("direct:foo")); assertNotNull(context.hasEndpoint("log:foo")); assertNotNull(context.hasEndpoint("mock:result")); // all the endpoints was mocked assertNotNull(context.hasEndpoint("mock:direct:start")); assertNotNull(context.hasEndpoint("mock:direct:foo")); assertNotNull(context.hasEndpoint("mock:log:foo")); }

/PUJDF UIBU UIF NPDL FOEQPJOUT JT HJWFO UIF VSJ mock:<endpoint>, GPS FYBNQMF mock:direct:foo. $BNFM MPHT BU INFO MFWFM UIF FOEQPJOUT CFJOH NPDLFE:
INFO Adviced endpoint [direct://foo] with mock endpoint [mock:direct:foo]

*UT BMTP QPTTJCMF UP POMZ NPDL DFSUBJO FOEQPJOUT VTJOH B QBUUFSO. 'PS FYBNQMF UP NPDL BMM log FOEQPJOUT ZPV EP BT TIPXO:
Listing 1. adviceWith mocking only log endpoints using a pattern
public void testAdvisedMockEndpointsWithPattern() throws Exception { // advice the first route using the inlined AdviceWith route builder // which has extended capabilities than the regular route builder context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // mock only log endpoints mockEndpoints("log*"); } }); // now we can refer to log:foo as a mock and set our expectations getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World"); getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // additional test to ensure correct endpoints in registry assertNotNull(context.hasEndpoint("direct:start")); assertNotNull(context.hasEndpoint("direct:foo")); assertNotNull(context.hasEndpoint("log:foo")); assertNotNull(context.hasEndpoint("mock:result")); // only the log:foo endpoint was mocked assertNotNull(context.hasEndpoint("mock:log:foo")); assertNull(context.hasEndpoint("mock:direct:start")); assertNull(context.hasEndpoint("mock:direct:foo")); }

74

$00 , #0 0 ,

,L@HBA BKAMLFKQP >OB TFQELRQ M>O>JBQBOP &OEQPJOUT XIJDI BSF NPDLFE XJMM IBWF UIFJS QBSBNFUFST TUSJQQFE PGG. 'PS FYBNQMF UIF FOEQPJOU "MPH:GPP TIPX"MM=USVF" XJMM CF NPDLFE UP UIF GPMMPXJOH FOEQPJOU "NPDL:MPH:GPP". /PUJDF UIF QBSBNFUFST IBWF CFFO SFNPWFE. 5IF QBUUFSO TVQQPSUFE DBO CF B XJMEDBSE PS B SFHVMBS FYQSFTTJPO. 4FF NPSF EFUBJMT BCPVU UIJT BU *OUFSDFQU BT JUT UIF TBNF NBUDIJOH GVODUJPO VTFE CZ $BNFM.

,L@HFKD BUFPQFKD BKAMLFKQP RPFKD QEB camel-test @LJMLKBKQ


*OTUFBE PG VTJOH UIF adviceWith UP JOTUSVDU $BNFM UP NPDL FOEQPJOUT, ZPV DBO FBTJMZ FOBCMF UIJT CFIBWJPS XIFO VTJOH UIF camel-test 5FTU ,JU. 5IF TBNF SPVUF DBO CF UFTUFE BT GPMMPXT. /PUJDF UIBU XF SFUVSO "*" GSPN UIF isMockEndpoints NFUIPE, XIJDI UFMMT $BNFM UP NPDL BMM FOEQPJOUT. *G ZPV POMZ XBOU UP NPDL BMM log FOEQPJOUT ZPV DBO SFUVSO "log*" JOTUFBE.
Listing 1. isMockEndpoints using camel-test kit
public class IsMockEndpointsJUnit4Test extends CamelTestSupport { @Override public String isMockEndpoints() { // override this method and return the pattern for which endpoints to mock. // use * to indicate all return "*"; } @Test public void testMockAllEndpoints() throws Exception { // notice we have automatic mocked all endpoints and the name of the endpoints is "mock:uri" getMockEndpoint("mock:direct:start").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World"); getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // additional test to ensure correct endpoints in registry assertNotNull(context.hasEndpoint("direct:start")); assertNotNull(context.hasEndpoint("direct:foo")); assertNotNull(context.hasEndpoint("log:foo")); assertNotNull(context.hasEndpoint("mock:result")); // all the endpoints was mocked assertNotNull(context.hasEndpoint("mock:direct:start"));

$0 0 , # 0 0 ,

75

.JOE UIBU NPDLJOH FOEQPJOUT DBVTFT UIF NFTTBHFT UP CF DPQJFE XIFO UIFZ BSSJWF PO UIF NPDL. 5IBU NFBOT $BNFM XJMM VTF NPSF NFNPSZ. 5IJT NBZ OPU CF TVJUBCMF XIFO ZPV TFOE JO B MPU PG NFTTBHFT.

assertNotNull(context.hasEndpoint("mock:direct:foo")); assertNotNull(context.hasEndpoint("mock:log:foo")); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("direct:foo").to("log:foo").to("mock:result"); from("direct:foo").transform(constant("Bye World")); } }; } }

,L@HFKD BUFPQFKD BKAMLFKQP TFQE 7,+ #2+


*G ZPV EP OPU VTF UIF camel-test DPNQPOFOU GPS VOJU UFTUJOH (BT TIPXO BCPWF) ZPV DBO VTF B EJGGFSFOU BQQSPBDI XIFO VTJOH 9.- GJMFT GPS SPVUFT. 5IF TPMVUJPO JT UP DSFBUF B OFX 9.- GJMF VTFE CZ UIF VOJU UFTU BOE UIFO JODMVEF UIF JOUFOEFE 9.- GJMF XIJDI IBT UIF SPVUF ZPV XBOU UP UFTU. 4VQQPTF XF IBWF UIF SPVUF JO UIF camel-route.xml GJMF:
Listing 1. camel-route.xml
<!-- this camel route is in the camel-route.xml file --> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <to uri="direct:foo"/> <to uri="log:foo"/> <to uri="mock:result"/> </route> <route> <from uri="direct:foo"/> <transform> <constant>Bye World</constant>

76

$00 , #0 0 ,

</transform> </route> </camelContext>

5IFO XF DSFBUF B OFX 9.- GJMF BT GPMMPXT, XIFSF XF JODMVEF UIF camel-route.xml GJMF BOE EFGJOF B TQSJOH CFBO XJUI UIF DMBTT org.apache.camel.impl.InterceptSendToMockEndpointStrategy XIJDI UFMMT $BNFM UP NPDL BMM FOEQPJOUT:
Listing 1. test-camel-route.xml
<!-- the Camel route is defined in another XML file --> <import resource="camel-route.xml"/> <!-- bean which enables mocking all endpoints --> <bean id="mockAllEndpoints" class="org.apache.camel.impl.InterceptSendToMockEndpointStrategy"/>

5IFO JO ZPVS VOJU UFTU ZPV MPBE UIF OFX 9.- GJMF (test-camel-route.xml) JOTUFBE PG camel-route.xml. 5P POMZ NPDL BMM -PH FOEQPJOUT ZPV DBO EFGJOF UIF QBUUFSO JO UIF DPOTUSVDUPS GPS UIF CFBO:
<bean id="mockAllEndpoints" class="org.apache.camel.impl.InterceptSendToMockEndpointStrategy"> <constructor-arg index="0" value="log*"/> </bean>

,L@HFKD BKAMLFKQP >KA PHFM PBKAFKD QL LOFDFK>I BKAMLFKQ


S>FI>?IB >P LC ">JBI 2.10 4PNFUJNFT ZPV XBOU UP FBTJMZ NPDL BOE TLJQ TFOEJOH UP B DFSUBJO FOEQPJOUT. 4P UIF NFTTBHF JT EFUPVSFE BOE TFOE UP UIF NPDL FOEQPJOU POMZ. 'SPN $BNFM 2.10 POXBSET ZPV DBO OPX VTF UIF mockEndpointsAndSkip NFUIPE VTJOH "EWJDF8JUI PS UIF <5FTU ,JU>. 5IF FYBNQMF CFMPX XJMM TLJQ TFOEJOH UP UIF UXP FOEQPJOUT "direct:foo", BOE "direct:bar".
Listing 1. adviceWith mock and skip sending to endpoints
public void testAdvisedMockEndpointsWithSkip() throws Exception { // advice the first route using the inlined AdviceWith route builder // which has extended capabilities than the regular route builder context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // mock sending to direct:foo and direct:bar and skip send to it

$0 0 , # 0 0 ,

77

mockEndpointsAndSkip("direct:foo", "direct:bar"); } }); getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedMessageCount(1); getMockEndpoint("mock:direct:bar").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // the message was not send to the direct:foo route and thus not sent to the seda endpoint SedaEndpoint seda = context.getEndpoint("seda:foo", SedaEndpoint.class); assertEquals(0, seda.getCurrentQueueSize()); }

5IF TBNF FYBNQMF VTJOH UIF 5FTU ,JU


Listing 1. isMockEndpointsAndSkip using camel-test kit
public class IsMockEndpointsAndSkipJUnit4Test extends CamelTestSupport { @Override public String isMockEndpointsAndSkip() { // override this method and return the pattern for which endpoints to mock, // and skip sending to the original endpoint. return "direct:foo"; } @Test public void testMockEndpointAndSkip() throws Exception { // notice we have automatic mocked the direct:foo endpoints and the name of the endpoints is "mock:uri" getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // the message was not send to the direct:foo route and thus not sent to the seda endpoint SedaEndpoint seda = context.getEndpoint("seda:foo", SedaEndpoint.class); assertEquals(0, seda.getCurrentQueueSize()); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("direct:foo").to("mock:result");

78

$00 , #0 0 ,

from("direct:foo").transform(constant("Bye World")).to("seda:foo"); } }; } }

+FJFQFKD QEB KRJ?BO LC JBPP>DBP QL HBBM S>FI>?IB >P LC ">JBI 2.10 5IF .PDL FOEQPJOUT XJMM CZ EFGBVMU LFFQ B DPQZ PG FWFSZ &YDIBOHF UIBU JU SFDFJWFE. 4P JG ZPV UFTU XJUI B MPU PG NFTTBHFT, UIFO JU XJMM DPOTVNF NFNPSZ. 'SPN $BNFM 2.10 POXBSET XF IBWF JOUSPEVDFE UXP PQUJPOT retainFirst BOE retainLast UIBU DBO CF VTFE UP TQFDJGZ UP POMZ LFFQ /'UI PG UIF GJSTU BOE/PS MBTU &YDIBOHFT. 'PS FYBNQMF JO UIF DPEF CFMPX, XF POMZ XBOU UP SFUBJO B DPQZ PG UIF GJSTU 5 BOE MBTU 5 &YDIBOHFT UIF NPDL SFDFJWFT.
MockEndpoint mock = getMockEndpoint("mock:data"); mock.setRetainFirst(5); mock.setRetainLast(5); mock.expectedMessageCount(2000); ... mock.assertIsSatisfied();

6TJOH UIJT IBT TPNF MJNJUBUJPOT. 5IF getExchanges() BOE getReceivedExchanges() NFUIPET PO UIF MockEndpoint XJMM SFUVSO POMZ UIF SFUBJOFE DPQJFT PG UIF &YDIBOHFT. 4P JO UIF FYBNQMF BCPWF, UIF MJTU XJMM DPOUBJO 10 &YDIBOHFT; UIF GJSTU GJWF, BOE UIF MBTU GJWF. 5IF retainFirst BOE retainLast PQUJPOT BMTP IBWF MJNJUBUJPOT PO XIJDI FYQFDUBUJPO NFUIPET ZPV DBO VTF. 'PS FYBNQMF UIF FYQFDUFE999 NFUIPET UIBU XPSL PO NFTTBHF CPEJFT, IFBEFST, FUD. XJMM POMZ PQFSBUF PO UIF SFUBJOFE NFTTBHFT. *O UIF FYBNQMF BCPWF UIFZ DBO UFTU POMZ UIF FYQFDUBUJPOT PO UIF 10 SFUBJOFE NFTTBHFT. 3BPQFKD TFQE >OOFS>I QFJBP S>FI>?IB >P LC ">JBI 2.7 5IF .PDL FOEQPJOU TUPSFT UIF BSSJWBM UJNF PG UIF NFTTBHF BT B QSPQFSUZ PO UIF &YDIBOHF.
Date time = exchange.getProperty(Exchange.RECEIVED_TIMESTAMP, Date.class);

:PV DBO VTF UIJT JOGPSNBUJPO UP LOPX XIFO UIF NFTTBHF BSSJWFE PO UIF NPDL. #VU JU BMTP QSPWJEFT GPVOEBUJPO UP LOPX UIF UJNF JOUFSWBM CFUXFFO UIF QSFWJPVT BOE OFYU NFTTBHF BSSJWFE

$0 0 , # 0 0 ,

79

PO UIF NPDL. :PV DBO VTF UIJT UP TFU FYQFDUBUJPOT VTJOH UIF arrives %4- PO UIF .PDL FOEQPJOU. 'PS FYBNQMF UP TBZ UIBU UIF GJSTU NFTTBHF TIPVME BSSJWF CFUXFFO 0-2 TFDPOET CFGPSF UIF OFYU ZPV DBO EP:
mock.message(0).arrives().noLaterThan(2).seconds().beforeNext();

:PV DBO BMTP EFGJOF UIJT BT UIBU 2OE NFTTBHF (0 JOEFY CBTFE) TIPVME BSSJWF OP MBUFS UIBO 0-2 TFDPOET BGUFS UIF QSFWJPVT:
mock.message(1).arrives().noLaterThan(2).seconds().afterPrevious();

:PV DBO BMTP VTF CFUXFFO UP TFU B MPXFS CPVOE. 'PS FYBNQMF TVQQPTF UIBU JU TIPVME CF CFUXFFO 1-4 TFDPOET:
mock.message(1).arrives().between(1, 4).seconds().afterPrevious();

:PV DBO BMTP TFU UIF FYQFDUBUJPO PO BMM NFTTBHFT, GPS FYBNQMF UP TBZ UIBU UIF HBQ CFUXFFO UIFN TIPVME CF BU NPTU 1 TFDPOE:
mock.allMessages().arrives().noLaterThan(1).seconds().beforeNext();

2BB

IPL ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4QSJOH 5FTUJOH 5FTUJOH

3$23(-&
5FTUJOH JT B DSVDJBM BDUJWJUZ JO BOZ QJFDF PG TPGUXBSF EFWFMPQNFOU PS JOUFHSBUJPO. 5ZQJDBMMZ $BNFM 3JEFST VTF WBSJPVT EJGGFSFOU UFDIOPMPHJFT XJSFE UPHFUIFS JO B WBSJFUZ PG QBUUFSOT XJUI EJGGFSFOU FYQSFTTJPO MBOHVBHFT UPHFUIFS XJUI EJGGFSFOU GPSNT PG #FBO *OUFHSBUJPO BOE %FQFOEFODZ *OKFDUJPO TP JUT WFSZ FBTZ GPS UIJOHT UP HP XSPOH! . 5FTUJOH JT UIF DSVDJBM XFBQPO UP FOTVSF UIBU UIJOHT XPSL BT ZPV XPVME FYQFDU. $BNFM JT B +BWB MJCSBSZ TP ZPV DBO FBTJMZ XJSF VQ UFTUT JO XIBUFWFS VOJU UFTUJOH GSBNFXPSL ZPV VTF (+6OJU 3.Y (EFQSFDBUFE), 4.Y, PS 5FTU/(). )PXFWFS UIF $BNFM QSPKFDU IBT USJFE UP

80

$00 , #0 0 ,

QFJB RKFQP *O UIF FYBNQMF BCPWF XF VTF seconds BT UIF UJNF VOJU, CVU $BNFM PGGFST milliseconds, BOE minutes BT XFMM. NBLF UIF UFTUJOH PG $BNFM BT FBTZ BOE QPXFSGVM BT QPTTJCMF TP XF IBWF JOUSPEVDFE UIF GPMMPXJOH GFBUVSFT. 3BPQFKD JB@E>KFPJP 5IF GPMMPXJOH NFDIBOJTNT BSF TVQQPSUFE ->JB "LJMLKBKQ #BP@OFMQFLK *T B TUBOEBMPOF +BWB MJCSBSZ MFUUJOH ZPV FBTJMZ DSFBUF $BNFM UFTU DBTFT VTJOH B TJOHMF +BWB DMBTT GPS BMM ZPVS DPOGJHVSBUJPO BOE SPVUJOH XJUIPVU VTJOH 4QSJOH PS (VJDF GPS %FQFOEFODZ *OKFDUJPOcXIJDI EPFT OPU SFRVJSF BO JO-EFQUI LOPXMFEHF PG 4QSJOH + 4QSJOH 5FTU PS (VJDF. c4VQQPSUT +6OJU 3.Y (EFQSFDBUFE) BOE +6OJU 4.Y CBTFE UFTUT. 4VQQPSUT +6OJU 3.Y (EFQSFDBUFE) PS +6OJU 4.Y CBTFE UFTUT UIBU CPPUTUSBQ B UFTU FOWJSPONFOU VTJOH 4QSJOH XJUIPVU OFFEJOH UP CF GBNJMJBS XJUI 4QSJOH 5FTU. c5IF cQMBJO +6OJU 3.Y/4.Y CBTFE UFTUT XPSL WFSZ TJNJMBS UP UIF UFTU TVQQPSU DMBTTFT JO DBNFMUFTU. c"MTP TVQQPSUT 4QSJOH 5FTU CBTFE UFTUT UIBU VTF UIF EFDMBSBUJWF TUZMF PG UFTU DPOGJHVSBUJPO BOE JOKFDUJPO DPNNPO JO 4QSJOH 5FTU. c5IF 4QSJOH 5FTU CBTFE UFTUT QSPWJEF GFBUVSF QBSJUZ XJUI UIF QMBJO +6OJU 3.Y/4.Y CBTFE UFTUJOH BQQSPBDI. c/PUJDF camel-test-spring JT B OFX DPNQPOFOU JO ">JBI 2.10 POXBSET. 'PS PMEFS $BNFM SFMFBTF VTF cameltest XIJDI IBT CVJMU-JO 4QSJOH 5FTUJOH. ">JBI 2.10: 1SPWJEFT UIF BCJMJUZ UP EP VOJU UFTUJOH PO CMVFQSJOU DPOGJHVSBUJPOT 6TFT (VJDF UP EFQFOEFODZ JOKFDU ZPVS UFTU DMBTTFT

$BNFM 5FTU

cameltest

4QSJOH 5FTUJOH

cameltestspring

#MVFQSJOU 5FTUJOH (VJDF

cameltestblueprint camelguice

$0 0 , # 0 0 ,

81

$BNFM 5FTU/(

DBNFM-UFTUOH

4VQQPSUT QMBJO 5FTU/( CBTFE UFTUTcXJUI PS XJUIPVUc4QSJOHcPSc(VJDFcGPSc%FQFOEFODZ *OKFDUJPOcXIJDI EPFT OPU SFRVJSF BO JO-EFQUI LOPXMFEHF PG 4QSJOH + 4QSJOH 5FTU PS (VJDF. c"MTP GSPN ">JBI 2.10 POXBSET, UIJT DPNQPOFOU TVQQPSUT 4QSJOH 5FTUcCBTFE UFTUT UIBU VTF UIF EFDMBSBUJWF TUZMF PG UFTU DPOGJHVSBUJPO BOE JOKFDUJPO DPNNPO JO 4QSJOH 5FTU BOE EFTDSJCFE JO NPSF EFUBJM VOEFS 4QSJOH 5FTUJOH.

*O BMM BQQSPBDIFT UIF UFTU DMBTTFT MPPL QSFUUZ NVDI UIF TBNF JO UIBU UIFZ BMM SFVTF UIF $BNFM CJOEJOH BOE JOKFDUJPO BOOPUBUJPOT.

">JBI 3BPQ $U>JMIB


)FSF JT UIF $BNFM 5FTU FYBNQMF.
public class FilterTest extends CamelTestSupport { @EndpointInject(uri = "mock:result") protected MockEndpoint resultEndpoint; @Produce(uri = "direct:start") protected ProducerTemplate template; @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; resultEndpoint.expectedBodiesReceived(expectedBody); template.sendBodyAndHeader(expectedBody, "foo", "bar"); resultEndpoint.assertIsSatisfied(); } @Test public void testSendNotMatchingMessage() throws Exception { resultEndpoint.expectedMessageCount(0); template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue"); resultEndpoint.assertIsSatisfied(); } @Override protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result"); }

82

$00 , #0 0 ,

}; } }

/PUJDF IPX JU EFSJWFT GSPN UIF $BNFM IFMQFS DMBTT ">JBI3BPQ2RMMLOQ CVU IBT OP 4QSJOH PS (VJDF EFQFOEFODZ JOKFDUJPO DPOGJHVSBUJPO CVU JOTUFBE PWFSSJEFT UIF @OB>QB1LRQB!RFIABO() NFUIPE.

2MOFKD 3BPQ TFQE 7,+ "LKCFD $U>JMIB


)FSF JT UIF 4QSJOH 5FTUJOH FYBNQMF VTJOH 9.- $POGJH.
@ContextConfiguration public class FilterTest extends SpringRunWithTestSupport { @EndpointInject(uri = "mock:result") protected MockEndpoint resultEndpoint; @Produce(uri = "direct:start") protected ProducerTemplate template; @DirtiesContext @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; resultEndpoint.expectedBodiesReceived(expectedBody); template.sendBodyAndHeader(expectedBody, "foo", "bar"); resultEndpoint.assertIsSatisfied(); } @DirtiesContext @Test public void testSendNotMatchingMessage() throws Exception { resultEndpoint.expectedMessageCount(0); template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue"); resultEndpoint.assertIsSatisfied(); } }

/PUJDF UIBU XF VTF @#FOQFBP"LKQBUQ PO UIF UFTU NFUIPET UP GPSDF 4QSJOH 5FTUJOH UP BVUPNBUJDBMMZ SFMPBE UIF $BNFM$POUFYU BGUFS FBDI UFTU NFUIPE - UIJT FOTVSFT UIBU UIF UFTUT EPO'U DMBTI XJUI FBDI PUIFS (F.H. POF UFTU NFUIPE TFOEJOH UP BO FOEQPJOU UIBU JT UIFO SFVTFE JO BOPUIFS UFTU NFUIPE).

$0 0 , # 0 0 ,

83

"MTP OPUJDF UIF VTF PG @"LKQBUQ"LKCFDRO>QFLK UP JOEJDBUF UIBU CZ EFGBVMU XF TIPVME MPPL GPS UIF 'JMUFS5FTU-DPOUFYU.YNM PO UIF DMBTTQBUI UP DPOGJHVSF UIF UFTU DBTF XIJDI MPPLT MJLF UIJT
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd "> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <filter> <xpath>$foo = 'bar'</xpath> <to uri="mock:result"/> </filter> </route> </camelContext> </beans>

2MOFKD 3BPQ TFQE )>S> "LKCFD $U>JMIB


)FSF JT UIF 4QSJOH 5FTUJOH FYBNQMF VTJOH +BWB $POGJH. 'PS NPSF JOGPSNBUJPO TFF 4QSJOH +BWB $POGJH.
@ContextConfiguration( locations = "org.apache.camel.spring.javaconfig.patterns.FilterTest$ContextConfig", loader = JavaConfigContextLoader.class) public class FilterTest extends AbstractJUnit4SpringContextTests { @EndpointInject(uri = "mock:result") protected MockEndpoint resultEndpoint; @Produce(uri = "direct:start") protected ProducerTemplate template; @DirtiesContext @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; resultEndpoint.expectedBodiesReceived(expectedBody);

84

$00 , #0 0 ,

template.sendBodyAndHeader(expectedBody, "foo", "bar"); resultEndpoint.assertIsSatisfied(); } @DirtiesContext @Test public void testSendNotMatchingMessage() throws Exception { resultEndpoint.expectedMessageCount(0); template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue"); resultEndpoint.assertIsSatisfied(); } @Configuration public static class ContextConfig extends SingleRouteCamelConfiguration { @Bean public RouteBuilder route() { return new RouteBuilder() { public void configure() { from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result"); } }; } } }

5IJT JT TJNJMBS UP UIF 9.- $POGJH FYBNQMF BCPWF FYDFQU UIBU UIFSF JT OP 9.- GJMF BOE JOTUFBE UIF OFTUFE "LKQBUQ"LKCFD DMBTT EPFT BMM PG UIF DPOGJHVSBUJPO; TP ZPVS FOUJSF UFTU DBTF JT DPOUBJOFE JO B TJOHMF +BWB DMBTT. 8F DVSSFOUMZ IBWF UP SFGFSFODF CZ DMBTT OBNF UIJT DMBTT JO UIF @"LKQBUQ"LKCFDRO>QFLK XIJDI JT B CJU VHMZ. 1MFBTF WPUF GPS 4+$-238 UP BEESFTT UIJT BOE NBLF 4QSJOH 5FTU XPSL NPSF DMFBOMZ XJUI 4QSJOH +BWB$POGJH. *UT UPUBMMZ PQUJPOBM CVU GPS UIF $POUFYU$POGJH JNQMFNFOUBUJPO XF EFSJWF GSPN 2FKDIB1LRQB">JBI"LKCFDRO>QFLK XIJDI JT B IFMQFS 4QSJOH +BWB $POGJH DMBTT XIJDI XJMM DPOGJHVSF UIF $BNFM$POUFYU GPS VT BOE UIFO SFHJTUFS UIF 3PVUF#VJMEFS XF DSFBUF. 4JODF ">JBI 2.11.0 ZPV DBO VTF UIF $BNFM4QSJOH+6OJU4$MBTT3VOOFS XJUI $BNFM4QSJOH%FMFHBUJOH5FTU$POUFYU-PBEFS MJLF FYBNQMF VTJOH +BWB $POGJH XJUI $BNFM4QSJOH+6OJU4$MBTT3VOOFS.
@RunWith(CamelSpringJUnit4ClassRunner.class) @ContextConfiguration( classes = {CamelSpringDelegatingTestContextLoaderTest.TestConfig.class}, // Since Camel 2.11.0 loader = CamelSpringDelegatingTestContextLoader.class ) @MockEndpoints public class CamelSpringDelegatingTestContextLoaderTest {

$0 0 , # 0 0 ,

85

@EndpointInject(uri = "mock:direct:end") protected MockEndpoint endEndpoint; @EndpointInject(uri = "mock:direct:error") protected MockEndpoint errorEndpoint; @Produce(uri = "direct:test") protected ProducerTemplate testProducer; @Configuration public static class TestConfig extends SingleRouteCamelConfiguration { @Bean @Override public RouteBuilder route() { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:test").errorHandler(deadLetterChannel("direct:error")).to("direct:end"); from("direct:error").log("Received message on direct:error endpoint."); from("direct:end").log("Received message on direct:end endpoint."); } }; } } @Test public void testRoute() throws InterruptedException { endEndpoint.expectedMessageCount(1); errorEndpoint.expectedMessageCount(0); testProducer.sendBody("<name>test</name>"); endEndpoint.assertIsSatisfied(); errorEndpoint.assertIsSatisfied(); } }

2MOFKD 3BPQ TFQE 7,+ "LKCFD >KA #B@I>O>QFSB "LKCFDRO>QFLK $U>JMIB


)FSF JT B $BNFM UFTU TVQQPSU FOIBODFEc4QSJOH 5FTUJOHcFYBNQMF VTJOH 9.- $POGJH BOE QVSF 4QSJOH 5FTU CBTFE DPOGJHVSBUJPO PG UIF $BNFM $POUFYU.

86

$00 , #0 0 ,

@RunWith(CamelSpringJUnit4ClassRunner.class) @ContextConfiguration // Put here to prevent Spring context caching across tests and test methods since some tests inherit // from this test and therefore use the same Spring context. Also because we want to reset the // Camel context and mock endpoints between test methods automatically. @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) public class CamelSpringJUnit4ClassRunnerPlainTest { @Autowired protected CamelContext camelContext; @Autowired protected CamelContext camelContext2; @EndpointInject(uri = "mock:a", context = "camelContext") protected MockEndpoint mockA; @EndpointInject(uri = "mock:b", context = "camelContext") protected MockEndpoint mockB; @EndpointInject(uri = "mock:c", context = "camelContext2") protected MockEndpoint mockC; @Produce(uri = "direct:start", context = "camelContext") protected ProducerTemplate start; @Produce(uri = "direct:start2", context = "camelContext2") protected ProducerTemplate start2; @Test public void testPositive() throws Exception { assertEquals(ServiceStatus.Started, camelContext.getStatus()); assertEquals(ServiceStatus.Started, camelContext2.getStatus()); mockA.expectedBodiesReceived("David"); mockB.expectedBodiesReceived("Hello David"); mockC.expectedBodiesReceived("David"); start.sendBody("David"); start2.sendBody("David"); MockEndpoint.assertIsSatisfied(camelContext); } @Test public void testJmx() throws Exception { assertEquals(DefaultManagementStrategy.class, camelContext.getManagementStrategy().getClass()); } @Test public void testShutdownTimeout() throws Exception {

$0 0 , # 0 0 ,

87

assertEquals(10, camelContext.getShutdownStrategy().getTimeout()); assertEquals(TimeUnit.SECONDS, camelContext.getShutdownStrategy().getTimeUnit()); } @Test public void testStopwatch() { StopWatch stopWatch = StopWatchTestExecutionListener.getStopWatch(); assertNotNull(stopWatch); assertTrue(stopWatch.taken() < 100); } @Test public void testExcludedRoute() { assertNotNull(camelContext.getRoute("excludedRoute")); } @Test public void testProvidesBreakpoint() { assertNull(camelContext.getDebugger()); assertNull(camelContext2.getDebugger()); } @SuppressWarnings("deprecation") @Test public void testLazyLoadTypeConverters() { assertTrue(camelContext.isLazyLoadTypeConverters()); assertTrue(camelContext2.isLazyLoadTypeConverters()); } }

/PUJDF IPX B DVTUPN UFTU SVOOFS JT VTFE XJUI UIFc@1RK6FQEcBOOPUBUJPO UP TVQQPSU UIF GFBUVSFT PGc">JBI3BPQ2RMMLOQcUISPVHI BOOPUBUJPOT PO UIF UFTU DMBTT. c4FFc4QSJOH 5FTUJOHcGPS B MJTU PG BOOPUBUJPOT ZPV DBO VTF JO ZPVS UFTUT.

!IRBMOFKQ 3BPQ
)FSF JT UIF #MVFQSJOU 5FTUJOH FYBNQMF VTJOH 9.- $POGJH.
// to use camel-test-blueprint, then extend the CamelBlueprintTestSupport class, // and add your unit tests methods as shown below. public class DebugBlueprintTest extends CamelBlueprintTestSupport { // override this method, and return the location of our Blueprint XML file to be used for testing @Override protected String getBlueprintDescriptor() { return "org/apache/camel/test/blueprint/camelContext.xml"; }

88

$00 , #0 0 ,

// here we have regular Junit @Test method @Test public void testRoute() throws Exception { // set mock expectations getMockEndpoint("mock:a").expectedMessageCount(1); // send a message template.sendBody("direct:start", "World"); // assert mocks assertMockEndpointsSatisfied(); } }

"MTP OPUJDF UIF VTF PG getBlueprintDescriptors UP JOEJDBUF UIBU CZ EFGBVMU XF TIPVME MPPL GPS UIF DBNFM$POUFYU.YNM JO UIF QBDLBHF UP DPOGJHVSF UIF UFTU DBTF XIJDI MPPLT MJLF UIJT
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/ blueprint/v1.0.0/blueprint.xsd"> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="direct:start"/> <transform> <simple>Hello ${body}</simple> </transform> <to uri="mock:a"/> </route> </camelContext> </blueprint>

3BPQFKD BKAMLFKQP $BNFM QSPWJEFT B OVNCFS PG FOEQPJOUT XIJDI DBO NBLF UFTUJOH FBTJFS. ->JB %BUB4FU #BP@OFMQFLK 'PS MPBE & TPBL UFTUJOH UIJT FOEQPJOU QSPWJEFT B XBZ UP DSFBUF IVHF OVNCFST PG NFTTBHFT GPS TFOEJOH UP $PNQPOFOUT BOE BTTFSUJOH UIBU UIFZ BSF DPOTVNFE DPSSFDUMZ

$0 0 , # 0 0 ,

89

.PDL 5FTU

'PS UFTUJOH SPVUFT BOE NFEJBUJPO SVMFT VTJOH NPDLT BOE BMMPXJOH BTTFSUJPOT UP CF BEEFE UP BO FOEQPJOU $SFBUFT B .PDL FOEQPJOU XIJDI FYQFDUT UP SFDFJWF BMM UIF NFTTBHF CPEJFT UIBU DPVME CF QPMMFE GSPN UIF HJWFO VOEFSMZJOH FOEQPJOU

5IF NBJO FOEQPJOU JT UIF .PDL FOEQPJOU XIJDI BMMPXT FYQFDUBUJPOT UP CF BEEFE UP EJGGFSFOU FOEQPJOUT; ZPV DBO UIFO SVO ZPVS UFTUT BOE BTTFSU UIBU ZPVS FYQFDUBUJPOT BSF NFU BU UIF FOE. 2QR??FKD LRQ MEVPF@>I QO>KPMLOQ QB@EKLILDFBP *G ZPV XJTI UP UFTU PVU B SPVUF CVU XBOU UP BWPJE BDUVBMMZ VTJOH B SFBM QIZTJDBM USBOTQPSU (GPS FYBNQMF UP VOJU UFTU B USBOTGPSNBUJPO SPVUF SBUIFS UIBO QFSGPSNJOH B GVMM JOUFHSBUJPO UFTU) UIFO UIF GPMMPXJOH FOEQPJOUT DBO CF VTFGVM. ->JB %JSFDU #BP@OFMQFLK %JSFDU JOWPDBUJPO PG UIF DPOTVNFS GSPN UIF QSPEVDFS TP UIBU TJOHMF UISFBEFE (OPO-4&%") JO 7. JOWPDBUJPO JT QFSGPSNFE XIJDI DBO CF VTFGVM UP NPDL PVU QIZTJDBM USBOTQPSUT %FMJWFST NFTTBHFT BTZODIPOPVTMZ UP DPOTVNFST WJB B KBWB.VUJM.DPODVSSFOU.#MPDLJOH2VFVF XIJDI JT HPPE GPS UFTUJOH BTZODISPOPVT USBOTQPSUT 8PSLT MJLF 4&%" CVU EPFT OPU WBMJEBUF UIF FOEQPJOU VSJ, XIJDI NBLFT TUVCCJOH NVDI FBTJFS.

4&%"

4UVC

3BPQFKD BUFPQFKD OLRQBP $BNFM QSPWJEFT TPNF GFBUVSFT UP BJE EVSJOH UFTUJOH PG FYJTUJOH SPVUFT XIFSF ZPV DBOOPU PS XJMM OPU VTF .PDL FUD. 'PS FYBNQMF ZPV NBZ IBWF B QSPEVDUJPO SFBEZ SPVUF XIJDI ZPV XBOU UP UFTU XJUI TPNF 3SE QBSUZ "1* XIJDI TFOET NFTTBHFT JOUP UIJT SPVUF. ->JB /PUJGZ#VJMEFS #BP@OFMQFLK "MMPXT ZPV UP CF OPUJGJFE XIFO B DFSUBJO DPOEJUJPO IBT PDDVSSFE. 'PS FYBNQMF XIFO UIF SPVUF IBT DPNQMFUFE 5 NFTTBHFT. :PV DBO CVJME DPNQMFY FYQSFTTJPOT UP NBUDI ZPVS DSJUFSJB XIFO UP CF OPUJGJFE. "MMPXT ZPV UP >ASF@B PS BKE>K@B BO FYJTUJOH SPVUF VTJOH B 3PVUF#VJMEFS TUZMF. 'PS FYBNQMF ZPV DBO BEE JOUFSDFQUPST UP JOUFSDFQU TFOEJOH PVUHPJOH NFTTBHFT UP BTTFSU UIPTF NFTTBHFT BSF BT FYQFDUFE.

"EWJDF8JUI

90

$00 , #0 0 ,

" ,$+ 3$23


"T B TJNQMF BMUFSOBUJWF UP VTJOH 4QSJOH 5FTUJOH PS (VJDF UIF @>JBI-QBPQ NPEVMF XBT JOUSPEVDFE TP ZPV DBO QFSGPSN QPXFSGVM 5FTUJOH PG ZPVS &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT FBTJMZ. AAFKD QL VLRO MLJ.UJI 5P HFU TUBSUFE VTJOH $BNFM 5FTU ZPV XJMM OFFE UP BEE BO FOUSZ UP ZPVS QPN.YNM

)4KFQ
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-test</artifactId> <version>${camel-version}</version> <scope>test</scope> </dependency>

3BPQ-&
S>FI>?IB >P LC ">JBI 2.8
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-testng</artifactId> <version>${camel-version}</version> <scope>test</scope> </dependency>

:PV NJHIU BMTP XBOU UP BEE TMG4K BOE MPH4K UP FOTVSF OJDF MPHHJOH NFTTBHFT (BOE NBZCF BEEJOH B MPH4K.QSPQFSUJFT GJMF JOUP ZPVS TSD/UFTU/SFTPVSDFT EJSFDUPSZ).
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <scope>test</scope> </dependency>

$0 0 , # 0 0 ,

91

5IF camel-test +"3 JT VTJOH +6OJU. 5IFSF JT BO BMUFSOBUJWF camel-testng +"3 ($BNFM 2.8 POXBSET) VTJOH UIF 5FTU/( UFTU GSBNFXPSL. 6OFQFKD VLRO QBPQ :PV GJSTUMZ OFFE UP EFSJWF GSPN UIF DMBTT ">JBI3BPQ2RMMLOQc(PSH.BQBDIF.DBNFM.UFTU.$BNFM5FTU4VQQPSU, PSH.BQBDIF.DBNFM.UFTU.KVOJU4.$BNFM5FTU4VQQPSU, PS PSH.BQBDIF.DBNFM.UFTUOH.$BNFM5FTU4VQQPSU GPS +6OJU 3.Y, +6OJU 4.Y, BOE 5FTU/(, SFTQFDUJWFMZ)cBOE UZQJDBMMZ ZPV XJMM OFFE UP PWFSSJEF UIF @OB>QB1LRQB!RFIABO() PSc@OB>QB1LRQB!RFIABOP()cNFUIPE UP DSFBUF SPVUFT UP CF UFTUFE. )FSF JT BO FYBNQMF.
public class FilterTest extends CamelTestSupport { @EndpointInject(uri = "mock:result") protected MockEndpoint resultEndpoint; @Produce(uri = "direct:start") protected ProducerTemplate template; @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; resultEndpoint.expectedBodiesReceived(expectedBody); template.sendBodyAndHeader(expectedBody, "foo", "bar"); resultEndpoint.assertIsSatisfied(); } @Test public void testSendNotMatchingMessage() throws Exception { resultEndpoint.expectedMessageCount(0); template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue"); resultEndpoint.assertIsSatisfied(); } @Override protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result"); } };

92

$00 , #0 0 ,

} }

/PUJDF IPX ZPV DBO VTF UIF WBSJPVT $BNFM CJOEJOH BOE JOKFDUJPO BOOPUBUJPOT UP JOKFDU JOEJWJEVBM &OEQPJOU PCKFDUT - QBSUJDVMBSMZ UIF .PDL FOEQPJOUT XIJDI BSF WFSZ VTFGVM GPS 5FTUJOH. "MTP ZPV DBO JOKFDU QSPEVDFS PCKFDUT TVDI BT 1SPEVDFS5FNQMBUF PS TPNF BQQMJDBUJPO DPEF JOUFSGBDF GPS TFOEJOH NFTTBHFT PS JOWPLJOH TFSWJDFT.

%B>QROBP /OLSFABA ?V ">JBI3BPQ2RMMLOQ


5IF WBSJPVT ">JBI3BPQ2RMMLOQ DMBTTFT QSPWJEF B TUBOEBSE TFU PG CFIBWJPST SFMBUJOH UP UIF $BNFM$POUFYU VTFE UP IPTU UIF SPVUF(T) VOEFS UFTU. c5IF DMBTTFT QSPWJEF B OVNCFS PG NFUIPET UIBU BMMPX B UFTU UP BMUFS UIF DPOGJHVSBUJPO PG UIF $BNFM$POUFYU VTFE. c5IF GPMMPXJOH UBCMF EFTDSJCFT UIF BWBJMBCMF DVTUPNJ[BUJPO NFUIPET BOE UIF EFGBVMU CFIBWJPS PG UFTUT UIBU BSF CVJMU GSPN Bc">JBI3BPQ2RMMLOQ DMBTT. ,BQELA ->JB CPPMFBO JT6TF3PVUF#VJMEFS() #BP@OFMQFLK

*G UIF SPVUF CVJMEFST GSPN SFUVSOFE GSPNc@OB>QB1LRQB @OB>QB1LRQB!RFIABOP() TIPVME CF BEEFE UP UIF $BN UIF UFTU TIPVME CF TUBSUFE.

CPPMFBO JT6TF"EWJDF8JUI()

*G UIF $BNFM$POUFYU VTF JO UIF UFTU TIPVME CF BVUPNBUJD UFTU NFUIPET BSF JOWPLFE. 0WFSSJEF XIFO VTJOH BEWJDF XJUIcBOE SFUVSO USVF. c5IJT BEWJDF8JUI JT UP CF VTFE, BOE UIFc$BNFM$POUFYUcXJMM OP CFGPSFcUIF BEWJDF XJUI UBLFT QMBDF. 5IJT EFMBZ IFMQT CZ F XJUI IBT CFFO QSPQFSUZ TFUVQ CFGPSF UIFc$BNFM$POUFYU

CPPMFBO JT$SFBUF$BNFM$POUFYU1FS$MBTT()

4FFc4FUVQ $BNFM$POUFYU PODF QFS DMBTT, PS QFS FWFSZ UF

4USJOH JT.PDL&OEQPJOUT()

5SJHHFST UIF BVUP-NPDLJOH PG FOEQPJOUT XIPTF 63*T NBU c5IF EFGBVMUcGJMUFS JT OVMM XIJDI EJTBCMFT UIJT GFBUVSF. c3F FOEQPJOUT. c4FFcPSH.BQBDIF.DBNFM.JNQM.*OUFSDFQU4FOE5P.PDL&OEQP EFUBJMT PO UIF SFHJTUSBUJPO PG UIF NPDL FOEQPJOUT.

$0 0 , # 0 0 ,

93

*UT JNQPSUBOU UP TUBSU UIF $BNFM$POUFYU NBOVBMMZ GSPN UIF VOJU UFTU BGUFS ZPV BSF EPOF EPJOH BMM UIF BEWJDF XJUI.

CPPMFBO JT6TF%FCVHHFS()

*G UIJT NFUIPE SFUVSOT USVF, UIFcAB?RD!BCLOB($U@E> /OL@BPPLO MOL@BPPLO, /OL@BPPLO#BCFKFQFLK<?> ABCFKFQFLK,Z2QOFKD FA, 2QOFKD I>?BI)cBOEc AB?RD CQBO($U@E>KDB BU@E>KDB, /OL@BPPLO MO /OL@BPPLO#BCFKFQFLK<?> ABCFKFQFLK,Z2QOFKD FA, QFJB3>HBK)cNFUIPET BSF JOWPLFE GPS FBDI QSPDFTTPS SPVUFT.

JOU HFU4IVUEPXO5JNFPVU() CPPMFBO VTF+NY() +OEJ3FHJTUSZ DSFBUF3FHJTUSZ() VTF0WFSSJEF1SPQFSUJFT8JUI1SPQFSUJFT$PNQPOFOU JHOPSF.JTTJOH-PDBUJPO8JUI1SPQFSUJFT$PNQPOFOU

3FUVSOT UIF OVNCFS PG TFDPOET UIBU $BNFM TIPVME XBJU G TIVUEPXO. c6TFGVM GPS EFDSFBTJOH UFTU UJNFT XIFO B NFT UIF FOE PG UIF UFTU. *G +.9 TIPVME CF EJTBCMFE PO UIF $BNFM$POUFYU VTFE JO

1SPWJEFT B IPPL GPS BEEJOH PCKFDUT JOUP UIF SFHJTUSZ. c0W UP CJOE PCKFDUT UP UIF SFHJTUSZ CFGPSF UFTU NFUIPET BSF JO

">JBI 2.10: "MMPXT UP BEE/PWFSSJEF QSPQFSUJFT XIFO 6 1SPQFSUZ1MBDFIPMEFS JO $BNFM. ">JBI 2.10: "MMPXT UP DPOUSPM JG $BNFM TIPVME JHOPSF QSPQFSUJFT.

)-#( $BNFM VTFT B 3FHJTUSZ UP BMMPX ZPV UP DPOGJHVSF $PNQPOFOU PS &OEQPJOU JOTUBODFT PS #FBOT VTFE JO ZPVS SPVUFT. *G ZPV BSF OPU VTJOH 4QSJOH PS <04(J> UIFO +/%* JT VTFE BT UIF EFGBVMU SFHJTUSZ JNQMFNFOUBUJPO. 4P ZPV XJMM BMTP OFFE UP DSFBUF B GKAF.MOLMBOQFBP GJMF JO ZPVS PO@/QBPQ/OBPLRO@BP EJSFDUPSZ TP UIBU UIFSF JT B EFGBVMU SFHJTUSZ BWBJMBCMF UP JOJUJBMJTF UIF $BNFM$POUFYU. )FSF JT BO FYBNQMF KOEJ.QSPQFSUJFT GJMF
java.naming.factory.initial = org.apache.camel.util.jndi.CamelInitialContextFactory

#VK>JF@>IIV >PPFDKFKD MLOQP S>FI>?IB >P LC ">JBI 2.7 5FTUT UIBU VTF QPSU OVNCFST XJMM GBJM JG UIBU QPSU JT BMSFBEZ PO VTF. AvailablePortFinder QSPWJEFT NFUIPET GPS GJOEJOH VOVTFE QPSU OVNCFST BU SVOUJNF.

94

$00 , #0 0 ,

// Get the next available port number starting from the default starting port of 1024 int port1 = AvailablePortFinder.getNextAvailable(); /* * Get another port. Note that just getting a port number does not reserve it so * we look starting one past the last port number we got. */ int port2 = AvailablePortFinder.getNextAvailable(port1 + 1);

2BQRM ">JBI"LKQBUQ LK@B MBO @I>PP, LO MBO BSBOV QBPQ JBQELA S>FI>?IB >P LC ">JBI 2.8 5IF $BNFM 5FTU LJU XJMM CZ EFGBVMU TFUVQ BOE TIVUEPXO $BNFM$POUFYU QFS FWFSZ UFTU NFUIPE JO ZPVS UFTU DMBTT. 4P GPS FYBNQMF JG ZPV IBWF 3 UFTU NFUIPET, UIFO $BNFM$POUFYU JT TUBSUFE BOE TIVUEPXO BGUFS FBDI UFTU, UIBU JT 3 UJNFT. :PV NBZ XBOU UP EP UIJT PODF, UP TIBSF UIF $BNFM$POUFYU CFUXFFO UFTU NFUIPET, UP TQFFEVQ VOJU UFTUJOH. 5IJT SFRVJSFT UP VTF +6OJU 4! *O ZPVS VOJU UFTU NFUIPE ZPV IBWF UP FYUFOE UIF org.apache.camel.test.junit4.CamelTestSupport PS UIF org.apache.camel.test.junit4.CamelSpringTestSupport UFTU DMBTT BOE PWFSSJEF UIF isCreateCamelContextPerClass NFUIPE BOE SFUVSO true BT TIPXO JO UIF GPMMPXJOH FYBNQMF:
Listing 1. Setup CamelContext once per class
public class FilterCreateCamelContextPerClassTest extends CamelTestSupport { @Override public boolean isCreateCamelContextPerClass() { // we override this method and return true, to tell Camel test-kit that // it should only create CamelContext once (per class), so we will // re-use the CamelContext between each test method in this class return true; } @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; getMockEndpoint("mock:result").expectedBodiesReceived(expectedBody); template.sendBodyAndHeader("direct:start", expectedBody, "foo", "bar"); assertMockEndpointsSatisfied(); } @Test public void testSendNotMatchingMessage() throws Exception { getMockEndpoint("mock:result").expectedMessageCount(0); template.sendBodyAndHeader("direct:start", "<notMatched/>", "foo",

$0 0 , # 0 0 ,

95

3BPQ-& 5IJT GFBUVSF JT BMTP TVQQPSUFE JO DBNFM-UFTUOH

!BT>OB 8IFO VTJOH UIJT UIF $BNFM$POUFYU XJMM LFFQ TUBUF CFUXFFO UFTUT, TP IBWF UIBU JO NJOE. 4P JG ZPVS VOJU UFTUT TUBSU UP GBJM GPS OP BQQBSFOU SFBTPO, JU DPVME CF EVF UIJT GBDU. 4P VTF UIJT GFBUVSF XJUI B CJU PG DBSF.

"notMatchedHeaderValue"); assertMockEndpointsSatisfied(); } @Override protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result"); } }; } }

2BB

IPL ` 5FTUJOH ` .PDL ` 5FTU

2/1(-& 3$23(-&
5FTUJOH JT B DSVDJBM QBSU PG BOZ EFWFMPQNFOU PS JOUFHSBUJPO XPSL. 5IF 4QSJOH 'SBNFXPSL PGGFST B OVNCFS PG GFBUVSFT UIBU NBLFT JU FBTZ UP UFTU XIJMF VTJOH 4QSJOH GPS *OWFSTJPO PG $POUSPM XIJDI XPSLT XJUI +6OJU 3.Y, +6OJU 4.Y, BOE 5FTU/(. 8F DBO VTF 4QSJOH GPS *P$ BOE UIF $BNFM .PDL BOE 5FTU FOEQPJOUT UP DSFBUF TPQIJTUJDBUFE JOUFHSBUJPO/VOJU UFTUT UIBU BSF FBTZ UP SVO BOE EFCVH JOTJEF ZPVS *%&. c5IFSF BSF UISFF TVQQPSUFE BQQSPBDIFT GPS UFTUJOH XJUI 4QSJOH JO $BNFM.

96

$00 , #0 0 ,

->JB

3BPQFKD %O>JBTLOHP 2RMMLOQBA

#BP@OFMQFLK

$BNFM4QSJOH5FTU4VQQPSU

` +6OJU 3.Y (EFQSFDBUFE) ` +6OJU 4.Y ` 5FTU/( ">JBI 2.8

1SPWJEFE CZ PSH.BQBDIF.DBNFM.UFTU.$BNFM4QSJOH5FTU4VQQP PSH.BQBDIF.DBNFM.UFTUOH.$BNFM4QSJOH5FTU4VQQPSU. c5IFTF 5FTUcCVU EP OPU TVQQPSU 4QSJOH BOOPUBUJPOT PO UIF UFTU D

1MBJO 4QSJOH 5FTU

` +6OJU 3.Y ` +6OJU 4.Y ` 5FTU/(

&YUFOE UIF BCTUSBDU CBTF DMBTTFT (PSH.TQSJOHGSBNFXPSL.UFTU.DPOUFYU.KVOJU38."CTUSBDU+6OJU3 FUD.)cQSPWJEFE JO 4QSJOH 5FTU PS VTF UIF 4QSJOH 5FTU +6OJ OPU IBWF GFBUVSF QBSJUZ XJUIcPSH.BQBDIF.DBNFM.UFTU.$BNF PSH.BQBDIF.DBNFM.UFTUOH.$BNFM4QSJOH5FTU4VQQPSU.

$BNFM &OIBODFE 4QSJOH 5FTU

` +6OJU 4.Y ">JBI 2.10 ` 5FTU/( ">JBI 2.10

6TF UIF PSH.BQBDIF.DBNFM.UFTU.KVOJU4.$BNFM4QSJOH+6OJU4$ PSH.BQBDIF.DBNFM.UFTUOH."CTUSBDU$BNFM5FTU/(4QSJOH$P PSH.BQBDIF.DBNFM.UFTU.KVOJU4.$BNFM5FTU4VQQPSU BOE BMTP T BOE @"LKQBUQ"LKCFDRO>QFLK.

">JBI2MOFKD3BPQ2RMMLOQ PSH.BQBDIF.DBNFM.UFTU.$BNFM4QSJOH5FTU4VQQPSU, PSH.BQBDIF.DBNFM.UFTU.KVOJU4.$BNFM4QSJOH5FTU4VQQPSU, BOE PSH.BQBDIF.DBNFM.UFTUOH.$BNFM4QSJOH5FTU4VQQPSUcFYUFOE UIFJS OPO-4QSJOH BXBSF DPVOUFSQBSUT (PSH.BQBDIF.DBNFM.UFTU.$BNFM5FTU4VQQPSU, PSH.BQBDIF.DBNFM.UFTU.KVOJU4.$BNFM5FTU4VQQPSU, BOE PSH.BQBDIF.DBNFM.UFTUOH.$BNFM5FTU4VQQPSU) BOE EFMJWFS JOUFHSBUJPO XJUI 4QSJOH JOUP ZPVS UFTU DMBTTFT. c*OTUFBE PGcJOTUBOUJBUJOHcUIF $BNFM$POUFYU BOE SPVUFT QSPHSBNNBUJDBMMZ, UIFTF DMBTTFT SFMZ PO B 4QSJOH DPOUFYU UP XJSF UIF OFFEFE DPNQPOFOUT UPHFUIFS. c*G ZPVS UFTU FYUFOET POF PG UIFTF DMBTTFT, ZPV NVTU QSPWJEF UIF 4QSJOH DPOUFYU CZ JNQMFNFOUJOH UIF GPMMPXJOH NFUIPE.

$0 0 , # 0 0 ,

97

protected abstract AbstractApplicationContext createApplicationContext();

:PV BSF SFTQPOTJCMF GPS UIF JOTUBOUJBUJPO PG UIF 4QSJOH DPOUFYU JO UIF NFUIPE JNQMFNFOUBUJPO. c"MM PG UIF GFBUVSFT BWBJMBCMF JO UIF OPO-4QSJOH BXBSF DPVOUFSQBSUT GSPN $BNFM 5FTU BSF BWBJMBCMF JO ZPVS UFTU. /I>FK 2MOFKD 3BPQ *O UIJT BQQSPBDI, ZPVS UFTU DMBTTFT EJSFDUMZ JOIFSJU GSPN UIF 4QSJOH 5FTU BCTUSBDU UFTU DMBTTFT PS VTF UIF +6OJU 4.Y UFTU SVOOFS QSPWJEFE JO 4QSJOH 5FTU. c5IJT BQQSPBDI TVQQPSUTcEFQFOEFODZcJOKFDUJPO JOUP ZPVS UFTU DMBTT BOE UIF GVMM TVJUF PG 4QSJOH 5FTU BOOPUBUJPOT CVU EPFT OPU TVQQPSU UIF GFBUVSFT QSPWJEFE CZ UIF $BNFM4QSJOH5FTU4VQQPSU DMBTTFT.

/I>FK 2MOFKD 3BPQ RPFKD )4KFQ 3.U TFQE 7,+ "LKCFD $U>JMIB
)FSF JT B TJNQMF VOJU UFTU VTJOH +6OJU 3.Y TVQQPSU GSPN 4QSJOH 5FTU VTJOHc9.- $POGJH.
@ContextConfiguration public class FilterTest extends SpringRunWithTestSupport { @EndpointInject(uri = "mock:result") protected MockEndpoint resultEndpoint; @Produce(uri = "direct:start") protected ProducerTemplate template; @DirtiesContext @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; resultEndpoint.expectedBodiesReceived(expectedBody); template.sendBodyAndHeader(expectedBody, "foo", "bar"); resultEndpoint.assertIsSatisfied(); } @DirtiesContext @Test public void testSendNotMatchingMessage() throws Exception { resultEndpoint.expectedMessageCount(0); template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue"); resultEndpoint.assertIsSatisfied(); } }

98

$00 , #0 0 ,

/PUJDF UIBU XF VTFc@#FOQFBP"LKQBUQcPO UIF UFTU NFUIPET UP GPSDFc4QSJOH 5FTUJOHcUP BVUPNBUJDBMMZ SFMPBE UIFc$BNFM$POUFYUcBGUFS FBDI UFTU NFUIPE - UIJT FOTVSFT UIBU UIF UFTUT EPO'U DMBTI XJUI FBDI PUIFS (F.H. POF UFTU NFUIPE TFOEJOH UP BO FOEQPJOU UIBU JT UIFO SFVTFE JO BOPUIFS UFTU NFUIPE). "MTP OPUJDF UIF VTF PGc@"LKQBUQ"LKCFDRO>QFLKcUP JOEJDBUF UIBU CZ EFGBVMU XF TIPVME MPPL GPS UIFc'JMUFS5FTU-DPOUFYU.YNM PO UIF DMBTTQBUIcUP DPOGJHVSF UIF UFTU DBTF XIJDI MPPLT MJLF UIJT
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd "> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <filter> <xpath>$foo = 'bar'</xpath> <to uri="mock:result"/> </filter> </route> </camelContext> </beans>

5IJT UFTU XJMM MPBE B 4QSJOH 9.- DPOGJHVSBUJPO GJMF DBMMFE'JMUFS5FTU-DPOUFYU.YNMcGSPN UIF DMBTTQBUI JO UIF TBNF QBDLBHF TUSVDUVSF BT UIF 'JMUFS5FTU DMBTT BOE JOJUJBMJ[F JU BMPOH XJUI BOZ $BNFM SPVUFT XF EFGJOF JOTJEF JU, UIFO JOKFDU UIF$BNFM$POUFYUJOTUBODF JOUP PVS UFTU DBTF. 'PS JOTUBODF, MJLF UIJT NBWFO GPMEFS MBZPVU:
src/test/java/org/apache/camel/spring/patterns/FilterTest.java src/test/resources/org/apache/camel/spring/patterns/FilterTest-context.xml

/I>FK 2MOFKD 3BPQ RPFKD )4KFQ 4.U TFQE )>S> "LKCFD $U>JMIB
:PV DBO DPNQMFUFMZ BWPJE VTJOH BO 9.- DPOGJHVSBUJPO GJMF CZ VTJOH 4QSJOH +BWB $POGJH. c)FSF JT B VOJU UFTU VTJOH +6OJU 4.Y TVQQPSU GSPN 4QSJOH 5FTU VTJOHc+BWB $POGJH.
@ContextConfiguration( locations = "org.apache.camel.spring.javaconfig.patterns.FilterTest$ContextConfig",

$0 0 , # 0 0 ,

99

loader = JavaConfigContextLoader.class) public class FilterTest extends AbstractJUnit4SpringContextTests { @EndpointInject(uri = "mock:result") protected MockEndpoint resultEndpoint; @Produce(uri = "direct:start") protected ProducerTemplate template; @DirtiesContext @Test public void testSendMatchingMessage() throws Exception { String expectedBody = "<matched/>"; resultEndpoint.expectedBodiesReceived(expectedBody); template.sendBodyAndHeader(expectedBody, "foo", "bar"); resultEndpoint.assertIsSatisfied(); } @DirtiesContext @Test public void testSendNotMatchingMessage() throws Exception { resultEndpoint.expectedMessageCount(0); template.sendBodyAndHeader("<notMatched/>", "foo", "notMatchedHeaderValue"); resultEndpoint.assertIsSatisfied(); } @Configuration public static class ContextConfig extends SingleRouteCamelConfiguration { @Bean public RouteBuilder route() { return new RouteBuilder() { public void configure() { from("direct:start").filter(header("foo").isEqualTo("bar")).to("mock:result"); } }; } } }

5IJT JT TJNJMBS UP UIF 9.- $POGJH FYBNQMF BCPWF FYDFQU UIBU UIFSF JT OP 9.- GJMF BOE JOTUFBE UIF OFTUFE "LKQBUQ"LKCFD DMBTT EPFT BMM PG UIF DPOGJHVSBUJPO; TP ZPVS FOUJSF UFTU DBTF JT DPOUBJOFE JO B TJOHMF +BWB DMBTT. 8F DVSSFOUMZ IBWF UP SFGFSFODF CZ DMBTT OBNF UIJT DMBTT JO UIF @"LKQBUQ"LKCFDRO>QFLK XIJDI JT B CJU VHMZ. 1MFBTF WPUF GPS 4+$-238 UP BEESFTT UIJT BOE NBLF 4QSJOH 5FTU XPSL NPSF DMFBOMZ XJUI 4QSJOH +BWB$POGJH.

100

$00 , #0 0 ,

/I>FK 2MOFKD 3BPQ RPFKD )4KFQ 4.U 1RKKBO TFQE 7,+ "LKCFD
:PV DBO BWPJE FYUFOEJOH 4QSJOH DMBTTFT CZ VTJOH UIF 4QSJOH+6OJU4$MBTT3VOOFS QSPWJEFE CZ 4QSJOH 5FTU. c5IJT DVTUPN +6OJU SVOOFS NFBOT ZPV BSF GSFF UP DIPPTF ZPVS PXO DMBTT IJFSBSDIZ XIJMF SFUBJOJOH BMM UIF DBQBCJMJUJFT PG 4QSJOH 5FTU.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class MyCamelTest { @Autowired protected CamelContext camelContext; @EndpointInject(uri = "mock:foo") protected MockEndpoint foo;

@Test @DirtiesContext public void testMocksAreValid() throws Exception { ... foo.message(0).header("bar").isEqualTo("ABC"); MockEndpoint.assertIsSatisfied(camelContext); } }

">JBI $KE>K@BA 2MOFKD 3BPQ 6TJOH PSH.BQBDIF.DBNFM.UFTU.KVOJU4.$BNFM4QSJOH+6OJU4$MBTT3VOOFScSVOOFS XJUI UIFc@1RK6FQEcBOOPUBUJPO PS FYUFOEJOH PSH.BQBDIF.DBNFM.UFTUOH."CTUSBDU$BNFM5FTU/(4QSJOH$POUFYU5FTUT QSPWJEFT UIF GVMM GFBUVSF TFU PG 4QSJOH 5FTU XJUI TVQQPSU GPS UIF GFBUVSF TFU QSPWJEFE JO UIF $BNFM5FTU4VQQPSU DMBTTFT. c" OVNCFS PG $BNFM TQFDJGJD BOOPUBUJPOT IBWF CFFO EFWFMPQFE JO PSEFS UP QSPWJEF GPS EFDMBSBUJWF NBOJQVMBUJPO PG UIF $BNFM DPOUFYU(T) JOWPMWFE JO UIF UFTU. c5IFTF BOOPUBUJPOT GSFF ZPVS UFTU DMBTTFT GSPN IBWJOH UP JOIFSJU GSPN UIF $BNFM4QSJOH5FTU4VQQPSU DMBTTFT BOE BMTP SFEVDF UIF BNPVOU PG DPEF SFRVJSFE UP DVTUPNJ[F UIF UFTUT. KKLQ>QFLK "I>PP MMIFBP 3L #BP@OFMQFLK

PSH.BQBDIF.DBNFM.UFTU.TQSJOH.%JTBCMF+NY

$MBTT

*OEJDBUFT JG +.9 TIPVME CF HMPCBMMZ EJTBCMF CPPUTUSBQQFE cEVSJOH UIF UFTU UISPVHI UI BQQMJDBUJPO DPOUFYUT.

$0 0 , # 0 0 ,

101

PSH.BQBDIF.DBNFM.UFTU.TQSJOH.&YDMVEF3PVUFT

$MBTT

*OEJDBUFT JG DFSUBJO SPVUF CVJMEFS DMBTTFT T c*OJUJBMJ[FT B PSH.BQBDIF.DBNFM.TQJ.1BDLBHF PG HJWFO DMBTTFT GSPN CFJOH SFTPMWFE. 5ZQ FYDMVEF DFSUBJO SPVUFT,cXIJDI NJHIU PUIF EJTDPWFSFE BOE JOJUJBMJ[FE.

PSH.BQBDIF.DBNFM.UFTU.TQSJOH.-B[Z-PBE5ZQF$POWFSUFST (%FQSFDBUFE)

$MBTT

*OEJDBUFT JG UIFc$BNFM$POUFYUT UIBU BSF C UIF VTF PG 4QSJOH 5FTUcMPBEFE BQQMJDBUJPO UZQF DPOWFSUFST.

PSH.BQBDIF.DBNFM.UFTU.TQSJOH..PDL&OEQPJOUT

$MBTT

5SJHHFST UIF BVUP-NPDLJOH PG FOEQPJOUT X GJMUFS.c 5IF EFGBVMUcGJMUFS JT "*" XIJDI NBU c4FFcPSH.BQBDIF.DBNFM.JNQM.*OUFSDFQU4FO EFUBJMT PO UIF SFHJTUSBUJPO PG UIF NPDL FO

PSH.BQBDIF.DBNFM.UFTU.TQSJOH..PDL&OEQPJOUT"OE4LJQ

$MBTT

5SJHHFST UIF BVUP-NPDLJOH PG FOEQPJOUT X GJMUFS.c 5IF EFGBVMUcGJMUFS JT "*", XIJDI NBU c4FFcPSH.BQBDIF.DBNFM.JNQM.*OUFSDFQU4FO EFUBJMT PO UIF SFHJTUSBUJPO PG UIF NPDL FO TLJQ TFOEJOH UIF NFTTBHF UP NBUDIFE FOE

PSH.BQBDIF.DBNFM.UFTU.TQSJOH.1SPWJEFT#SFBLQPJOU

.FUIPE

*OEJDBUFT UIBU UIF BOOPUBUFE NFUIPE SFUV BOcPSH.BQBDIF.DBNFM.TQJ.#SFBLQPJOUcGPS V JOUFSDFQUJOHcUSBGGJD UP BMM FOEQPJOUT PS TJN *%& GPS EFCVHHJOH.c 5IF NFUIPE NVTUcCF BOE SFUVSO PSH.BQBDIF.DBNFM.TQJ.#SFBLQPJ

PSH.BQBDIF.DBNFM.UFTU.TQSJOH.4IVUEPXO5JNFPVU

$MBTT

*OEJDBUFT UP TFU UIF TIVUEPXO UJNFPVU PG UISPVHI UIFcVTF PG 4QSJOH 5FTU MPBEFE BQ JT VTFE, UIF UJNFPVU JTcBVUPNBUJDBMMZ SFEV GSBNFXPSL.

PSH.BQBDIF.DBNFM.UFTU.TQSJOH.6TF"EWJDF8JUI

$MBTT

*OEJDBUFT UIF VTF PG BEWJDF8JUI() XJUIJO U XJUIcUIJT BOOPUBUJPO BOE 6TF"EWJDF8JUI BOZc$BNFM$POUFYUT CPPUTUSBQQFE EVSJOH 5FTU MPBEFEcBQQMJDBUJPO DPOUFYUT XJMM OPU BVUIPS JT SFTQPOTJCMF GPScJOKFDUJOH UIF $B FYFDVUJOH $BNFM$POUFYU#TUBSU()cPO UIFN BEWJDF IBT CFFO BQQMJFE UP UIF SPVUFT JO U

5IF GPMMPXJOH FYBNQMF JMMVTUSBUFT UIF VTF PG UIF @,L@H$KAMLFKQPcBOOPUBUJPO JO PSEFS UP TFUVQ NPDL FOEQPJOUT BT JOUFSDFQUPST PO BMM FOEQPJOUT VTJOH UIF $BNFM -PH DPNQPOFOU BOE UIF @#FP>?IB)JU BOOPUBUJPO UP FOBCMF +.9 XIJDI JT EJTBCMFE EVSJOH UFTUT CZ EFGBVMU. c/PUF UIBU XF TUJMM VTF UIF @#FOQFBP"LKQBUQ BOOPUBUJPO UP FOTVSF UIBU UIF $BNFM$POUFYU, SPVUFT, BOE NPDL FOEQPJOUT BSF SFJOJUJBMJ[FE CFUXFFO UFTU NFUIPET.

102

$00 , #0 0 ,

@RunWith(CamelSpringJUnit4ClassRunner.class) @ContextConfiguration @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) @MockEndpoints("log:*") @DisableJmx(false) public class CamelSpringJUnit4ClassRunnerPlainTest { @Autowired protected CamelContext camelContext2; protected MockEndpoint mockB; @EndpointInject(uri = "mock:c", context = "camelContext2") protected MockEndpoint mockC; @Produce(uri = "direct:start2", context = "camelContext2") protected ProducerTemplate start2; @EndpointInject(uri = "mock:log:org.apache.camel.test.junit4.spring", context = "camelContext2") protected MockEndpoint mockLog; @Test public void testPositive() throws Exception { mockC.expectedBodiesReceived("David"); mockLog.expectedBodiesReceived("Hello David"); start2.sendBody("David"); MockEndpoint.assertIsSatisfied(camelContext); }

AAFKD JLOB ,L@H BUMB@Q>QFLKP *G ZPV XJTI UP QSPHSBNNBUJDBMMZ BEE BOZ OFX BTTFSUJPOT UP ZPVS UFTU ZPV DBO FBTJMZ EP TP XJUI UIF GPMMPXJOH. /PUJDF IPX XF VTF !&OEQPJOU*OKFDU UP JOKFDU B $BNFM FOEQPJOU JOUP PVS DPEF UIFO UIF .PDL "1* UP BEE BO FYQFDUBUJPO PO B TQFDJGJD NFTTBHF.
@ContextConfiguration public class MyCamelTest extends AbstractJUnit38SpringContextTests { @Autowired protected CamelContext camelContext; @EndpointInject(uri = "mock:foo") protected MockEndpoint foo; public void testMocksAreValid() throws Exception { // lets add more expectations foo.message(0).header("bar").isEqualTo("ABC");

$0 0 , # 0 0 ,

103

MockEndpoint.assertIsSatisfied(camelContext); } }

%ROQEBO MOL@BPPFKD QEB OB@BFSBA JBPP>DBP 4PNFUJNFT PODF B .PDL FOEQPJOU IBT SFDFJWFE TPNF NFTTBHFT ZPV XBOU UP UIFO QSPDFTT UIFN GVSUIFS UP BEE GVSUIFS BTTFSUJPOT UIBU ZPVS UFTU DBTF XPSLFE BT ZPV FYQFDU. 4P ZPV DBO UIFO QSPDFTT UIF SFDFJWFE NFTTBHF FYDIBOHFT JG ZPV MJLF...
@ContextConfiguration public class MyCamelTest extends AbstractJUnit38SpringContextTests { @Autowired protected CamelContext camelContext; @EndpointInject(uri = "mock:foo") protected MockEndpoint foo; public void testMocksAreValid() throws Exception { // lets add more expectations... MockEndpoint.assertIsSatisfied(camelContext); // now lets do some further assertions List<Exchange> list = foo.getReceivedExchanges(); for (Exchange exchange : list) { Message in = exchange.getIn(); ... } } }

2BKAFKD >KA OB@BFSFKD JBPP>DBP *U NJHIU CF UIBU UIF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT ZPV IBWF EFGJOFE JO FJUIFS 4QSJOH 9.- PS VTJOH UIF +BWB %4- EP BMM PG UIF TFOEJOH BOE SFDFJWJOH BOE ZPV NJHIU KVTU XPSL XJUI UIF .PDL FOEQPJOUT BT EFTDSJCFE BCPWF. )PXFWFS TPNFUJNFT JO B UFTU DBTF JUT VTFGVM UP FYQMJDJUMZ TFOE PS SFDFJWF NFTTBHFT EJSFDUMZ. 5P TFOE PS SFDFJWF NFTTBHFT ZPV TIPVME VTF UIF #FBO *OUFHSBUJPO NFDIBOJTN. 'PS FYBNQMF UP TFOE NFTTBHFT JOKFDU B 1SPEVDFS5FNQMBUF VTJOH UIF !&OEQPJOU*OKFDU BOOPUBUJPO UIFO DBMM UIF WBSJPVT TFOE NFUIPET PO UIJT PCKFDU UP TFOE B NFTTBHF UP BO FOEQPJOU. 5P DPOTVNF NFTTBHFT VTF UIF !.FTTBHF%SJWFO BOOPUBUJPO PO B NFUIPE UP IBWF UIF NFUIPE JOWPLFE XIFO B NFTTBHF JT SFDFJWFE.

104

$00 , #0 0 ,

public class Foo { @EndpointInject(uri="activemq:foo.bar") ProducerTemplate producer; public void doSomething() { // lets send a message! producer.sendBody("<hello>world!</hello>"); } // lets consume messages from the 'cheese' queue @MessageDriven(uri="activemq:cheese") public void onCheese(String name) { ... } }

2BB

IPL ` ` ` ` " SFBM FYBNQMF UFTU DBTF VTJOH .PDL BOE 4QSJOH BMPOH XJUI JUT 4QSJOH 9.#FBO *OUFHSBUJPO .PDL FOEQPJOU 5FTU FOEQPJOU

" ,$+ &4("$


8F IBWF TVQQPSU GPS (PPHMF (VJDF BT B EFQFOEFODZ JOKFDUJPO GSBNFXPSL. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-guice</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

#BMBKABK@V (KGB@QFKD ">JBI TFQE &RF@B 5IF (VJDF$BNFM$POUFYU JT EFTJHOFE UP XPSL OJDFMZ JOTJEF (VJDF. :PV UIFO OFFE UP CJOE JU VTJOH TPNF (VJDF .PEVMF. 5IF DBNFM-HVJDF MJCSBSZ DPNFT XJUI B OVNCFS PG SFVTBCMF (VJDF .PEVMFT ZPV DBO VTF JG ZPV XJTI - PS ZPV DBO CJOE UIF (VJDF$BNFM$POUFYU ZPVSTFMG JO ZPVS PXO NPEVMF. ` $BNFM.PEVMF JT UIF CBTF NPEVMF XIJDI CJOET UIF (VJDF$BNFM$POUFYU CVU MFBWFT JU VQ ZPV UP CJOE UIF 3PVUF#VJMEFS JOTUBODFT

$0 0 , # 0 0 ,

105

` $BNFM.PEVMF8JUI3PVUF5ZQFT FYUFOET $BNFM.PEVMF TP UIBU JO UIF DPOTUSVDUPS PG UIF NPEVMF ZPV TQFDJGZ UIF 3PVUF#VJMEFS DMBTTFT PS JOTUBODFT UP VTF ` $BNFM.PEVMF8JUI.BUDIJOH3PVUFT FYUFOET $BNFM.PEVMF TP UIBU BMM CPVOE 3PVUF#VJMEFS JOTUBODFT XJMM CF JOKFDUFE JOUP UIF $BNFM$POUFYU PS ZPV DBO TVQQMZ BO PQUJPOBM .BUDIFS UP GJOE 3PVUF#VJMEFS JOTUBODFT NBUDIJOH TPNF LJOE PG QSFEJDBUF. 4P ZPV DBO TQFDJGZ UIF FYBDU 3PVUF#VJMEFS JOTUBODFT ZPV XBOU
Injector injector = Guice.createInjector(new CamelModuleWithRouteTypes(MyRouteBuilder.class, AnotherRouteBuilder.class)); // if required you can lookup the CamelContext CamelContext camelContext = injector.getInstance(CamelContext.class);

0S JOKFDU UIFN BMM


Injector injector = Guice.createInjector(new CamelModuleWithRouteTypes()); // if required you can lookup the CamelContext CamelContext camelContext = injector.getInstance(CamelContext.class);

:PV DBO UIFO VTF (VJDF JO UIF VTVBM XBZ UP JOKFDU UIF SPVUF JOTUBODFT PS BOZ PUIFS EFQFOEFOU PCKFDUT. !LLQPQO>MMFKD TFQE )-#( " DPNNPO QBUUFSO VTFE JO +2&& JT UP CPPUTUSBQ ZPVS BQQMJDBUJPO PS SPPU PCKFDUT CZ MPPLJOH UIFN VQ JO +/%*. 5IJT IBT MPOH CFFO UIF BQQSPBDI XIFO XPSLJOH XJUI +.4 GPS FYBNQMF MPPLJOH VQ UIF +.4 $POOFDUJPO'BDUPSZ JO +/%* GPS FYBNQMF. :PV DBO GPMMPX B TJNJMBS QBUUFSO XJUI (VJDF VTJOH UIF (VJDFZ'SVJU +/%* 1SPWJEFS XIJDI MFUT ZPV CPPUTUSBQ (VJDF GSPN B GKAF.MOLMBOQFBP GJMF XIJDI DBO JODMVEF UIF (VJDF .PEVMFT UP DSFBUF BMPOH XJUI FOWJSPONFOU TQFDJGJD QSPQFSUJFT ZPV DBO JOKFDU JOUP ZPVS NPEVMFT BOE PCKFDUT. *G UIF GKAF.MOLMBOQFBP JT DPOGMJDU XJUI PUIFS DPNQPOFOU, ZPV DBO TQFDJGZ UIF KOEJ QSPQFSUJFT GJMF OBNF JO UIF (VJDF .BJO XJUI PQUJPO -K PS -KOEJ1SPQFSUJFT XJUI UIF QSPQFSUJFT GJMF MPDBUJPO UP MFU (VJDF .BJO UP MPBE SJHIU KOEJ QSPQFSUJFT GJMF. "LKCFDROFKD "LJMLKBKQ, $KAMLFKQ LO 1LRQB!RFIABO FKPQ>K@BP :PV DBO VTF (VJDF UP EFQFOEFODZ JOKFDU XIBUFWFS PCKFDUT ZPV OFFE UP DSFBUF, CF JU BO &OEQPJOU, $PNQPOFOU, 3PVUF#VJMEFS PS BSCJUSBSZ CFBO VTFE XJUIJO B SPVUF. 5IF FBTJFTU XBZ UP EP UIJT JT UP DSFBUF ZPVS PXO (VJDF .PEVMF DMBTT XIJDI FYUFOET POF PG UIF BCPWF NPEVMF DMBTTFT BOE BEE B QSPWJEFS NFUIPE GPS FBDI PCKFDU ZPV XJTI UP DSFBUF. " QSPWJEFS NFUIPE JT BOOPUBUFE XJUI @/OLSFABP BT GPMMPXT
public class MyModule extends CamelModuleWithMatchingRoutes {

106

$00 , #0 0 ,

@Provides @JndiBind("jms") JmsComponent jms(@Named("activemq.brokerURL") String brokerUrl) { return JmsComponent.jmsComponent(new ActiveMQConnectionFactory(brokerUrl)); } }

:PV DBO PQUJPOBMMZ BOOPUBUF UIF NFUIPE XJUI @)KAF!FKA UP CJOE UIF PCKFDU UP +/%* BU TPNF OBNF JG UIF PCKFDU JT B DPNQPOFOU, FOEQPJOU PS CFBO ZPV XJTI UP SFGFS UP CZ OBNF JO ZPVS SPVUFT. :PV DBO JOKFDU BOZ FOWJSPONFOU TQFDJGJD QSPQFSUJFT (TVDI BT 63-T, NBDIJOF OBNFT, VTFSOBNFT/QBTTXPSET BOE TP GPSUI) GSPN UIF KOEJ.QSPQFSUJFT GJMF FBTJMZ VTJOH UIF @->JBA BOOPUBUJPO BT TIPXO BCPWF. 5IJT BMMPXT NPTU PG ZPVS DPOGJHVSBUJPO UP CF JO +BWB DPEF XIJDI JT UZQFTBGF BOE FBTJMZ SFGBDUPSBCMF - UIFO MFBWJOH TPNF QSPQFSUJFT UP CF FOWJSPONFOU TQFDJGJD (UIF KOEJ.QSPQFSUJFT GJMF) XIJDI ZPV DBO UIFO DIBOHF CBTFE PO EFWFMPQNFOU, UFTUJOH, QSPEVDUJPO FUD. "OB>QFKD JRIQFMIB 1LRQB!RFIABO FKPQ>K@BP MBO QVMB *U JT TPNFUJNFT VTFGVM UP DSFBUF NVMUJQMF JOTUBODFT PG B QBSUJDVMBS 3PVUF#VJMEFS XJUI EJGGFSFOU DPOGJHVSBUJPOT. 5P EP UIJT KVTU DSFBUF NVMUJQMF QSPWJEFS NFUIPET GPS FBDI DPOGJHVSBUJPO; PS DSFBUF B TJOHMF QSPWJEFS NFUIPE UIBU SFUVSOT B DPMMFDUJPO PG 3PVUF#VJMEFS JOTUBODFT. 'PS FYBNQMF
import org.apache.camel.guice.CamelModuleWithMatchingRoutes; import com.google.common.collect.Lists; public class MyModule extends CamelModuleWithMatchingRoutes { @Provides @JndiBind("foo") Collection<RouteBuilder> foo(@Named("fooUrl") String fooUrl) { return Lists.newArrayList(new MyRouteBuilder(fooUrl), new MyRouteBuilder("activemq:CheeseQueue")); } }

2BB

IPL ` UIFSF BSF B OVNCFS PG &YBNQMFT ZPV DBO MPPL BU UP TFF (VJDF BOE $BNFM CFJOH VTFE TVDI BT (VJDF +.4 &YBNQMF ` (VJDF .BWFO 1MVHJO GPS SVOOJOH ZPVS (VJDF CBTFE SPVUFT WJB .BWFO

$0 0 , # 0 0 ,

107

3$,/+ 3(-&
8IFO ZPV BSF UFTUJOH EJTUSJCVUFE TZTUFNT JUT B WFSZ DPNNPO SFRVJSFNFOU UP IBWF UP TUVC PVU DFSUBJO FYUFSOBM TZTUFNT XJUI TPNF TUVC TP UIBU ZPV DBO UFTU PUIFS QBSUT PG UIF TZTUFN VOUJM B TQFDJGJD TZTUFN JT BWBJMBCMF PS XSJUUFO FUD. " HSFBU XBZ UP EP UIJT JT VTJOH TPNF LJOE PG 5FNQMBUF TZTUFN UP HFOFSBUF SFTQPOTFT UP SFRVFTUT HFOFSBUJOH B EZOBNJD NFTTBHF VTJOH B NPTUMZ-TUBUJD CPEZ. 5IFSF BSF B OVNCFS PG UFNQMBUJOH DPNQPOFOUT JODMVEFE JO UIF $BNFM EJTUSJCVUJPO ZPV DPVME VTF ` 'SFF.BSLFS ` 4USJOH5FNQMBUF ` 7FMPDJUZ ` 92VFSZ ` 94-5 PS UIF GPMMPXJOH FYUFSOBM $BNFM DPNQPOFOUT ` 4DBMBUF $U>JMIB )FSF'T B TJNQMF FYBNQMF TIPXJOH IPX XF DBO SFTQPOE UP *O0VU SFRVFTUT PO UIF ,V.0RBRB RVFVF PO "DUJWF.2 XJUI B UFNQMBUF HFOFSBUFE SFTQPOTF. 5IF SFQMZ XPVME CF TFOU CBDL UP UIF +.43FQMZ5P %FTUJOBUJPO.
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm");

*G ZPV XBOU UP VTF *O0OMZ BOE DPOTVNF UIF NFTTBHF BOE TFOE JU UP BOPUIFS EFTUJOBUJPO ZPV DPVME VTF
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm"). to("activemq:Another.Queue");

2BB

IPL ` .PDL GPS EFUBJMT PG NPDL FOEQPJOU UFTUJOH (BT PQQPTFE UP UFNQMBUF CBTFE TUVCT).

# 3 ! 2$
$BNFM DBO XPSL XJUI EBUBCBTFT JO B OVNCFS PG EJGGFSFOU XBZT. 5IJT EPDVNFOU USJFT UP PVUMJOF UIF NPTU DPNNPO BQQSPBDIFT.

108

$00 , #0 0 ,

#>Q>?>PB BKAMLFKQP $BNFM QSPWJEFT B OVNCFS PG EJGGFSFOU FOEQPJOUT GPS XPSLJOH XJUI EBUBCBTFT ` +1" GPS XPSLJOH XJUI IJCFSOBUF, PQFOKQB PS UPQMJOL. 8IFO DPOTVNJOH GSPN UIF FOEQPJOUT FOUJUZ CFBOT BSF SFBE (BOE EFMFUFE/VQEBUFE UP NBSL BT QSPDFTTFE) UIFO XIFO QSPEVDJOH UP UIF FOEQPJOUT UIFZ BSF XSJUUFO UP UIF EBUBCBTF (WJB JOTFSU/VQEBUF). ` J#"5*4 TJNJMBS UP UIF BCPWF CVU VTJOH "QBDIF J#"5*4 ` +%#$ TJNJMBS UIPVHI VTJOH FYQMJDJU 42#>Q>?>PB M>QQBOK FJMIBJBKQ>QFLKP 7BSJPVT QBUUFSOT DBO XPSL XJUI EBUBCBTFT BT GPMMPXT ` *EFNQPUFOU $POTVNFS ` "HHSFHBUPS ` #". GPS CVTJOFTT BDUJWJUZ NPOJUPSJOH

/ 1 ++$+ /1."$22(-&

-# .1#$1(-&

*U JT B DPNNPO SFRVJSFNFOU UP XBOU UP VTF QBSBMMFM QSPDFTTJOH PG NFTTBHFT GPS UISPVHIQVU BOE MPBE CBMBODJOH, XIJMF BU UIF TBNF UJNF QSPDFTT DFSUBJO LJOET PG NFTTBHFT JO PSEFS. 'LT QL >@EFBSB M>O>IIBI MOL@BPPFKD :PV DBO TFOE NFTTBHFT UP B OVNCFS PG $BNFM $PNQPOFOUT UP BDIJFWF QBSBMMFM QSPDFTTJOH BOE MPBE CBMBODJOH TVDI BT ` 4&%" GPS JO-+7. MPBE CBMBODJOH BDSPTT B UISFBE QPPM ` "DUJWF.2 PS +.4 GPS EJTUSJCVUFE MPBE CBMBODJOH BOE QBSBMMFM QSPDFTTJOH ` +1" GPS VTJOH UIF EBUBCBTF BT B QPPS NBOT NFTTBHF CSPLFS 8IFO QSPDFTTJOH NFTTBHFT DPODVSSFOUMZ, ZPV TIPVME DPOTJEFS PSEFSJOH BOE DPODVSSFODZ JTTVFT. 5IFTF BSF EFTDSJCFE CFMPX

"LK@ROOBK@V FPPRBP
/PUF UIBU UIFSF JT OP DPODVSSFODZ PS MPDLJOH JTTVF XIFO VTJOH "DUJWF.2, +.4 PS 4&%" CZ EFTJHO; UIFZ BSF EFTJHOFE GPS IJHIMZ DPODVSSFOU VTF. )PXFWFS UIFSF BSF QPTTJCMF DPODVSSFODZ JTTVFT JO UIF 1SPDFTTPS PG UIF NFTTBHFT J.F. XIBU UIF QSPDFTTPS EPFT XJUI UIF NFTTBHF 'PS FYBNQMF JG B QSPDFTTPS PG B NFTTBHF USBOTGFST NPOFZ GSPN POF BDDPVOU UP BOPUIFS BDDPVOU; ZPV QSPCBCMZ XBOU UP VTF B EBUBCBTF XJUI QFTTJNJTUJD MPDLJOH UP FOTVSF UIBU PQFSBUJPO UBLFT QMBDF BUPNJDBMMZ.

$0 0 , # 0 0 ,

109

.OABOFKD FPPRBP
"T TPPO BT ZPV TFOE NVMUJQMF NFTTBHFT UP EJGGFSFOU UISFBET PS QSPDFTTFT ZPV XJMM FOE VQ XJUI BO VOLOPXO PSEFSJOH BDSPTT UIF FOUJSF NFTTBHF TUSFBN BT FBDI UISFBE JT HPJOH UP QSPDFTT NFTTBHFT DPODVSSFOUMZ. 'PS NBOZ VTF DBTFT UIF PSEFS PG NFTTBHFT JT OPU UPP JNQPSUBOU. )PXFWFS GPS TPNF BQQMJDBUJPOT UIJT DBO CF DSVDJBM. F.H. JG B DVTUPNFS TVCNJUT B QVSDIBTF PSEFS WFSTJPO 1, UIFO BNFOET JU BOE TFOET WFSTJPO 2; ZPV EPO'U XBOU UP QSPDFTT UIF GJSTU WFSTJPO MBTU (TP UIBU ZPV MPPTF UIF VQEBUF). :PVS 1SPDFTTPS NJHIU CF DMFWFS FOPVHI UP JHOPSF PME NFTTBHFT. *G OPU ZPV OFFE UP QSFTFSWF PSEFS. 1B@LJJBKA>QFLKP 5IJT UPQJD JT MBSHF BOE EJWFSTF XJUI MPUT PG EJGGFSFOU SFRVJSFNFOUT; CVU GSPN B IJHI MFWFM IFSF BSF PVS SFDPNNFOEBUJPOT PO QBSBMMFM QSPDFTTJOH, PSEFSJOH BOE DPODVSSFODZ ` GPS EJTUSJCVUFE MPDLJOH, VTF B EBUBCBTF CZ EFGBVMU, UIFZ BSF WFSZ HPPE BU JU ` UP QSFTFSWF PSEFSJOH BDSPTT B +.4 RVFVF DPOTJEFS VTJOH &YDMVTJWF $POTVNFST JO UIF "DUJWF.2 DPNQPOFOU ` FWFO CFUUFS BSF .FTTBHF (SPVQT XIJDI BMMPXT ZPV UP QSFTFSWF PSEFSJOH BDSPTT NFTTBHFT XIJMF TUJMM PGGFSJOH QBSBMMFMJTBUJPO WJB UIF ),27&OLRM(# IFBEFS UP EFUFSNJOF XIBU DBO CF QBSBMMFMJ[FE ` JG ZPV SFDFJWF NFTTBHFT PVU PG PSEFS ZPV DPVME VTF UIF 3FTFRVFODFS UP QVU UIFN CBDL UPHFUIFS BHBJO " HPPE SVMF PG UIVNC UP IFMQ SFEVDF PSEFSJOH QSPCMFNT JT UP NBLF TVSF FBDI TJOHMF DBO CF QSPDFTTFE BT BO BUPNJD VOJU JO QBSBMMFM (FJUIFS XJUIPVU DPODVSSFODZ JTTVFT PS VTJOH TBZ, EBUBCBTF MPDLJOH); PS JG JU DBO'U, VTF B .FTTBHF (SPVQ UP SFMBUF UIF NFTTBHFT UPHFUIFS XIJDI OFFE UP CF QSPDFTTFE JO PSEFS CZ B TJOHMF UISFBE. 4PFKD ,BPP>DB &OLRMP TFQE ">JBI 5P VTF B .FTTBHF (SPVQ XJUI $BNFM ZPV KVTU OFFE UP BEE B IFBEFS UP UIF PVUQVU +.4 NFTTBHF CBTFE PO TPNF LJOE PG $PSSFMBUJPO *EFOUJGJFS UP DPSSFMBUF NFTTBHFT XIJDI TIPVME CF QSPDFTTFE JO PSEFS CZ B TJOHMF UISFBE - TP UIBU UIJOHT XIJDI EPO'U DPSSFMBUF UPHFUIFS DBO CF QSPDFTTFE DPODVSSFOUMZ. 'PS FYBNQMF UIF GPMMPXJOH DPEF TIPXT IPX UP DSFBUF B NFTTBHF HSPVQ VTJOH BO 91BUI FYQSFTTJPO UBLJOH BO JOWPJDF'T QSPEVDU DPEF BT UIF $PSSFMBUJPO *EFOUJGJFS
from("activemq:a").setHeader("JMSXGroupID", xpath("/invoice/ productCode")).to("activemq:b");

:PV DBO PG DPVSTF VTF UIF 9NM $POGJHVSBUJPO JG ZPV QSFGFS

110

$00 , #0 0 ,

28-"'1.-.42 /1."$22(-&
.SBOSFBT $BNFM TVQQPSUT B NPSF DPNQMFY BTZODISPOPVT QSPDFTTJOH NPEFM. 5IF BTZODISPOPVT QSPDFTTPST JNQMFNFOU UIF "TZOD1SPDFTTPS JOUFSGBDF XIJDI JT EFSJWFE GSPN UIF NPSF TZODISPOPVT 1SPDFTTPS JOUFSGBDF. 5IFSF BSF BEWBOUBHFT BOE EJTBEWBOUBHFT XIFO VTJOH BTZODISPOPVT QSPDFTTJOH XIFO DPNQBSFE UP VTJOH UIF TUBOEBSE TZODISPOPVT QSPDFTTJOH NPEFM. "EWBOUBHFT: ` 1SPDFTTJOH SPVUFT UIBU BSF DPNQPTFE GVMMZ PG BTZODISPOPVT QSPDFTTPST EP OPU VTF VQ UISFBET XBJUJOH GPS QSPDFTTPST UP DPNQMFUF PO CMPDLJOH DBMMT. 5IJT DBO JODSFBTF UIF TDBMBCJMJUZ PG ZPVS TZTUFN CZ SFEVDJOH UIF OVNCFS PG UISFBET OFFEFE UP QSPDFTT UIF TBNF XPSLMPBE. ` 1SPDFTTJOH SPVUFT DBO CF CSPLFO VQ JOUP 4&%" QSPDFTTJOH TUBHFT XIFSF EJGGFSFOU UISFBE QPPMT DBO QSPDFTT UIF EJGGFSFOU TUBHFT. 5IJT NFBOT UIBU ZPVS SPVUFT DBO CF QSPDFTTFE DPODVSSFOUMZ. %JTBEWBOUBHFT: ` *NQMFNFOUJOH BTZODISPOPVT QSPDFTTPST JT NPSF DPNQMFY UIBO JNQMFNFOUJOH UIF TZODISPOPVT WFSTJPOT. 6EBK QL 4PB 8F SFDPNNFOE UIBU QSPDFTTPST BOE DPNQPOFOUT CF JNQMFNFOUFE UIF NPSF TJNQMF TZODISPOPVT "1*T VOMFTT ZPV JEFOUJGZ B QFSGPSNBODF PG TDBMBCJMJUZ SFRVJSFNFOU UIBU EJDUBUFT PUIFSXJTF. " 1SPDFTTPS XIPTF QSPDFTT() NFUIPE CMPDLT GPS B MPOH UJNF XPVME CF HPPE DBOEJEBUFT GPS CFJOH DPOWFSUFE JOUP BO BTZODISPOPVT QSPDFTTPS. (KQBOC>@B #BQ>FIP
public interface AsyncProcessor extends Processor { boolean process(Exchange exchange, AsyncCallback callback); }

5IF "TZOD1SPDFTTPS EFGJOFT B TJOHMF process() NFUIPE XIJDI JT WFSZ TJNJMBS UP JU'T TZODISPOPVT 1SPDFTTPS.QSPDFTT() CSFUISFO. )FSF BSF UIF EJGGFSFODFT: ` " OPO-OVMM "TZOD$BMMCBDL ,423 CF TVQQMJFE XIJDI XJMM CF OPUJGJFE XIFO UIF FYDIBOHF QSPDFTTJOH JT DPNQMFUFE. ` *U ,423 OPU UISPX BOZ FYDFQUJPOT UIBU PDDVSSFE XIJMF QSPDFTTJOH UIF FYDIBOHF. "OZ TVDI FYDFQUJPOT NVTU CF TUPSFE PO UIF FYDIBOHF'T &YDFQUJPO QSPQFSUZ. ` *U ,423 LOPX JG JU XJMM DPNQMFUF UIF QSPDFTTJOH TZODISPOPVTMZ PS BTZODISPOPVTMZ. 5IF NFUIPE XJMM SFUVSO true JG JU EPFT DPNQMFUF TZODISPOPVTMZ, PUIFSXJTF JU SFUVSOT false.

$0 0 , # 0 0 ,

111

2RMMLOQBA SBOPFLKP 5IF JOGPSNBUJPO PO UIJT QBHF BQQMJFT GPS $BNFM 2.4 POXBSET. #FGPSF $BNFM 2.4 UIF BTZODISPOPVT QSPDFTTJOH JT POMZ JNQMFNFOUFE GPS +#* XIFSF BT JO $BNFM 2.4 POXBSET XF IBWF JNQMFNFOUFE JU JO NBOZ PUIFS BSFBT. 4FF NPSF BU "TZODISPOPVT 3PVUJOH &OHJOF. ` 8IFO UIF QSPDFTTPS IBT DPNQMFUFE QSPDFTTJOH UIF FYDIBOHF, JU NVTU DBMM UIF callback.done(boolean sync) NFUIPE. 5IF TZOD QBSBNFUFS ,423 NBUDI UIF WBMVF SFUVSOFE CZ UIF process() NFUIPE. (JMIBJBKQFKD /OL@BPPLOP QE>Q 4PB QEB PVK@/OL@BPPLO /(

"MM QSPDFTTPST, FWFO TZODISPOPVT QSPDFTTPST UIBU EP OPU JNQMFNFOU UIF "TZOD1SPDFTTPS JOUFSGBDF, DBO CF DPFSDFE UP JNQMFNFOU UIF "TZOD1SPDFTTPS JOUFSGBDF. 5IJT JT VTVBMMZ EPOF XIFO ZPV BSF JNQMFNFOUJOH B $BNFM DPNQPOFOU DPOTVNFS UIBU TVQQPSUT BTZODISPOPVT DPNQMFUJPO PG UIF FYDIBOHFT UIBU JU JT QVTIJOH UISPVHI UIF $BNFM SPVUFT. $POTVNFST BSF QSPWJEFE B 1SPDFTTPS PCKFDU XIFO DSFBUFE. "MM 1SPDFTTPS PCKFDU DBO CF DPFSDFE UP B "TZOD1SPDFTTPS VTJOH UIF GPMMPXJOH "1*:
Processor processor = ... AsyncProcessor asyncProcessor = AsyncProcessorTypeConverter.convert(processor);

'PS B SPVUF UP CF GVMMZ BTZODISPOPVT BOE SFBQ UIF CFOFGJUT UP MPXFS 5ISFBE VTBHF, JU NVTU TUBSU XJUI UIF DPOTVNFS JNQMFNFOUBUJPO NBLJOH VTF PG UIF BTZODISPOPVT QSPDFTTJOH "1*. *G JU DBMMFE UIF TZODISPOPVT QSPDFTT() NFUIPE JOTUFBE, UIF DPOTVNFS'T UISFBE XPVME CF GPSDFE UP CF CMPDLFE BOE JO VTF GPS UIF EVSBUJPO UIBU JU UBLFT UP QSPDFTT UIF FYDIBOHF. *U JT JNQPSUBOU UP UBLF OPUF UIBU KVTU CFDBVTF ZPV DBMM UIF BTZODISPOPVT "1*, JU EPFT OPU NFBO UIBU UIF QSPDFTTJOH XJMM UBLF QMBDF BTZODISPOPVTMZ. *U POMZ BMMPXT UIF QPTTJCJMJUZ UIBU JU DBO CF EPOF XJUIPVU UZJOH VQ UIF DBMMFS'T UISFBE. *G UIF QSPDFTTJOH IBQQFOT BTZODISPOPVTMZ JT EFQFOEFOU PO UIF DPOGJHVSBUJPO PG UIF $BNFM SPVUF. /PSNBMMZ, UIF UIF QSPDFTT DBMM JT QBTTFE JO BO JOMJOF JOOFS "TZOD$BMMCBDL DMBTT JOTUBODF XIJDI DBO SFGFSFODF UIF FYDIBOHF PCKFDU UIBU XBT EFDMBSFE GJOBM. 5IJT BMMPXT JU UP GJOJTI VQ BOZ QPTU QSPDFTTJOH UIBU JT OFFEFE XIFO UIF DBMMFE QSPDFTTPS JT EPOF QSPDFTTJOH UIF FYDIBOHF. 4FF CFMPX GPS BO FYBNQMF.
final Exchange exchange = ... AsyncProcessor asyncProcessor = ... asyncProcessor.process(exchange, new AsyncCallback() { public void done(boolean sync) { if (exchange.isFailed()) {

112

$00 , #0 0 ,

... // do failure processing.. perhaps rollback etc. } else { ... // processing completed successfully, finish up // perhaps commit etc. } } });

PVK@EOLKLRP 1LRQB 2BNRBK@B 2@BK>OFLP /PX UIBU XF IBWF VOEFSTUPPE UIF JOUFSGBDF DPOUSBDU PG UIF "TZOD1SPDFTTPS, BOE IBWF TFFO IPX UP NBLF VTF PG JU XIFO DBMMJOH QSPDFTTPST, MFUT MPPLT B XIBU UIF UISFBE NPEFM/TFRVFODF TDFOBSJPT XJMM MPPL MJLF GPS TPNF TBNQMF SPVUFT. 5IF +FUUZ DPNQPOFOU'T DPOTVNFST TVQQPSU BTZOD QSPDFTTJOH CZ VTJOH DPOUJOVBUJPOT. 4VGGJDF UP TBZ JU DBO UBLF B IUUQ SFRVFTU BOE QBTT JU UP B DBNFM SPVUF GPS BTZOD QSPDFTTJOH. *G UIF QSPDFTTJOH JT JOEFFE BTZOD, JU VTFT +FUUZ DPOUJOVBUJPO TP UIBU UIF IUUQ SFRVFTU JT 'QBSLFE' BOE UIF UISFBE JT SFMFBTFE. 0ODF UIF DBNFM SPVUF GJOJTIFT QSPDFTTJOH UIF SFRVFTU, UIF KFUUZ DPNQPOFOU VTFT UIF "TZOD$BMMCBDL UP UFMM +FUUZ UP 'VO-QBSL' UIF SFRVFTU. +FUUZ VO-QBSLT UIF SFRVFTU, UIF IUUQ SFTQPOTF SFUVSOFE VTJOH UIF SFTVMU PG UIF FYDIBOHF QSPDFTTJOH. /PUJDF UIBU UIF KFUUZ DPOUJOVBUJPOT GFBUVSF JT POMZ VTFE "*G UIF QSPDFTTJOH JT JOEFFE BTZOD". 5IJT JT XIZ "TZOD1SPDFTTPS.QSPDFTT() JNQMFNFOUBUJPOT .645 BDDVSBUFMZ SFQPSU JG SFRVFTU JT DPNQMFUFE TZODISPOPVTMZ PS OPU. 5IF KID DPNQPOFOU'T QSPEVDFS BMMPXT ZPV UP NBLF )551 SFRVFTUT BOE JNQMFNFOU UIF "TZOD1SPDFTTPS JOUFSGBDF. " SPVUF UIBU VTFT CPUI UIF KFUUZ BTZODISPOPVT DPOTVNFS BOE UIF KID BTZODISPOPVT QSPEVDFS XJMM CF B GVMMZ BTZODISPOPVT SPVUF BOE IBT TPNF OJDF BUUSJCVUFT UIBU DBO CF TFFO JG XF UBLF B MPPL BU B TFRVFODF EJBHSBN PG UIF QSPDFTTJOH SPVUF. 'PS UIF SPVUF:
from("jetty:http://localhost:8080/service").to("jhc:http://localhost/service-impl");

5IF TFRVFODF EJBHSBN XPVME MPPL TPNFUIJOH MJLF UIJT: 5IF EJBHSBN TJNQMJGJFT UIJOHT CZ NBLJOH JU MPPLT MJLF QSPDFTTPST JNQMFNFOU UIF "TZOD$BMMCBDL JOUFSGBDF XIFO JO SFBMJUZ UIF "TZOD$BMMCBDL JOUFSGBDFT BSF JOMJOF JOOFS DMBTTFT, CVU JU JMMVTUSBUFT UIF QSPDFTTJOH GMPX BOE TIPXT IPX 2 TFQBSBUF UISFBET BSF VTFE UP DPNQMFUF UIF QSPDFTTJOH PG UIF PSJHJOBM IUUQ SFRVFTU. 5IF GJSTU UISFBE JT TZODISPOPVT VQ VOUJM QSPDFTTJOH IJUT UIF KID QSPEVDFS XIJDI JTTVFT UIF IUUQ SFRVFTU. *U UIFO SFQPSUT UIBU UIF FYDIBOHF QSPDFTTJOH XJMM DPNQMFUF BTZOD TJODF JU XJMM VTF B /*0 UP DPNQMFUF HFUUJOH UIF SFTQPOTF CBDL. 0ODF UIF KID DPNQPOFOU IBT SFDFJWFE B GVMM SFTQPOTF JU VTFT AsyncCallback.done() NFUIPE UP OPUJGZ UIF DBMMFS. 5IFTF DBMMCBDL OPUJGJDBUJPOT DPOUJOVF VQ VOUJM JU SFBDIFT UIF PSJHJOBM KFUUZ DPOTVNFS XIJDI UIFO VO-QBSLT UIF IUUQ SFRVFTU BOE DPNQMFUFT JU CZ QSPWJEJOH UIF SFTQPOTF.

$0 0 , # 0 0 ,

113

,FUFKD 2VK@EOLKLRP >KA

PVK@EOLKLRP /OL@BPPLOP

*U JT UPUBMMZ QPTTJCMF BOE SFBTPOBCMF UP NJY UIF VTF PG TZODISPOPVT BOE BTZODISPOPVT QSPDFTTPST/DPNQPOFOUT. 5IF QJQFMJOF QSPDFTTPS JT UIF CBDLCPOF PG B $BNFM QSPDFTTJOH SPVUF. *U HMVFT BMM UIF QSPDFTTJOH TUFQT UPHFUIFS. *U JT JNQMFNFOUFE BT BO "TZOD1SPDFTTPS BOE TVQQPSUT JOUFSMFBWJOH TZODISPOPVT BOE BTZODISPOPVT QSPDFTTPST BT UIF QSPDFTTJOH TUFQT JO UIF QJQFMJOF. -FUT TBZ XF IBWF 2 DVTUPN QSPDFTTPST, .Z7BMJEBUPS BOE .Z5SBOTGPSNBUJPO, CPUI PG XIJDI BSF TZODISPOPVT QSPDFTTPST. -FUT TBZ XF XBOU UP MPBE GJMF GSPN UIF EBUB/JO EJSFDUPSZ WBMJEBUF UIFN XJUI UIF .Z7BMJEBUPS() QSPDFTTPS, 5SBOTGPSN UIFN JOUP +1" KBWB PCKFDUT VTJOH .Z5SBOTGPSNBUJPO BOE UIFO JOTFSU UIFN JOUP UIF EBUBCBTF VTJOH UIF +1" DPNQPOFOU. -FUT TBZ UIBU UIF USBOTGPSNBUJPO QSPDFTT UBLFT RVJUF B CJU PG UJNF BOE XF XBOU UP BMMPDBUF 20 UISFBET UP EP QBSBMMFM USBOTGPSNBUJPOT PG UIF JOQVU GJMFT. 5IF TPMVUJPO JT UP NBLF VTF PG UIF UISFBE QSPDFTTPS. 5IF UISFBE JT "TZOD1SPDFTTPS UIBU GPSDFT TVCTFRVFOU QSPDFTTJOH JO BTZODISPOPVT UISFBE GSPN B UISFBE QPPM. 5IF SPVUF NJHIU MPPL MJLF:
from("file:data/in").process(new MyValidator()).threads(20).process(new MyTransformation()).to("jpa:PurchaseOrder");

5IF TFRVFODF EJBHSBN XPVME MPPL TPNFUIJOH MJLF UIJT: :PV XPVME BDUVBMMZ IBWF NVMUJQMF UISFBET FYFDVUJOH UIF 2OE QBSU PG UIF UISFBE TFRVFODF. 2Q>VFKD PVK@EOLKLRP FK >K PVK@/OL@BPPLO

(FOFSBMMZ TQFBLJOH ZPV HFU CFUUFS UISPVHIQVU QSPDFTTJOH XIFO ZPV QSPDFTT UIJOHT TZODISPOPVTMZ. 5IJT JT EVF UP UIF GBDU UIBU TUBSUJOH VQ BO BTZODISPOPVT UISFBE BOE EPJOH B DPOUFYU TXJUDI UP JU BEET B MJUUMF CJU PG PG PWFSIFBE. 4P JU JT HFOFSBMMZ FODPVSBHFE UIBU "TZOD1SPDFTTPST EP BT NVDI XPSL BT UIFZ DBO TZODISPOPVTMZ. 8IFO UIFZ HFU UP B TUFQ UIBU XPVME CMPDL GPS B MPOH UJNF, BU UIBU QPJOU UIFZ TIPVME SFUVSO GSPN UIF QSPDFTT DBMM BOE MFU UIF DBMMFS LOPX UIBU JU XJMM CF DPNQMFUJOH UIF DBMM BTZODISPOPVTMZ.

(,/+$,$-3(-& 5(134 + 3./("2 .- .3'$1 ),2 /1.5(#$12


"DUJWF.2 TVQQPSUT 7JSUVBM 5PQJDT TJODF EVSBCMF UPQJD TVCTDSJQUJPOT LJOEB TVDL (TFF UIJT QBHF GPS NPSF EFUBJM) NPTUMZ TJODF UIFZ EPO'U TVQQPSU $PNQFUJOH $POTVNFST. .PTU GPMLT XBOU 2VFVF TFNBOUJDT XIFO DPOTVNJOH NFTTBHFT; TP UIBU ZPV DBO TVQQPSU $PNQFUJOH $POTVNFST GPS MPBE CBMBODJOH BMPOH XJUI UIJOHT MJLF .FTTBHF (SPVQT BOE &YDMVTJWF $POTVNFST UP QSFTFSWF PSEFSJOH PS QBSUJUJPO UIF RVFVF BDSPTT DPOTVNFST. )PXFWFS JG ZPV BSF VTJOH BOPUIFS +.4 QSPWJEFS ZPV DBO JNQMFNFOU 7JSUVBM 5PQJDT CZ TXJUDIJOH UP "DUJWF.2 PS ZPV DBO VTF UIF GPMMPXJOH $BNFM QBUUFSO.

114

$00 , #0 0 ,

'JSTU IFSF'T UIF "DUJWF.2 BQQSPBDI. ` TFOE UP >@QFSBJN:QLMF@:5FOQR>I3LMF@..OABOP ` GPS DPOTVNFS " DPOTVNF GSPN >@QFSBJN:"LKPRJBO. .5FOQR>I3LMF@..OABOP 8IFO VTJOH BOPUIFS NFTTBHF CSPLFS VTF UIF GPMMPXJOH QBUUFSO ` TFOE UP GJP:.OABOP ` BEE UIJT SPVUF XJUI B UP() GPS FBDI MPHJDBM EVSBCMF UPQJD TVCTDSJCFS
from("jms:Orders").to("jms:Consumer.A", "jms:Consumer.B", ...);

` GPS DPOTVNFS " DPOTVNF GSPN GJP:"LKPRJBO.

6' 3'2 3'$ " ,$+ 31 -2/.13 %.1 "7%


*O $9' ZPV PGGFS PS DPOTVNF B XFCTFSWJDF CZ EFGJOJOH JUbT BEESFTT. 5IF GJSTU QBSU PG UIF BEESFTT TQFDJGJFT UIF QSPUPDPM UP VTF. 'PS FYBNQMF BEESFTT="IUUQ://MPDBMIPTU:9000" JO BO FOEQPJOU DPOGJHVSBUJPO NFBOT ZPVS TFSWJDF XJMM CF PGGFSFE VTJOH UIF IUUQ QSPUPDPM PO QPSU 9000 PG MPDBMIPTU. 8IFO ZPV JOUFHSBUF $BNFM 5SBOQPSU JOUP $9' ZPV HFU B OFX USBOTQPSU "DBNFM". 4P ZPV DBO TQFDJGZ BEESFTT="DBNFM://EJSFDU:.Z&OEQPJOU/BNF" UP CJOE UIF $9' TFSWJDF BEESFTT UP B DBNFM EJSFDU FOEQPJOU. 5FDIOJDBMMZ TQFBLJOH $BNFM USBOTQPSU GPS $9' JT B DPNQPOFOU XIJDI JNQMFNFOUT UIF $9' USBOTQPSU "1* XJUI UIF $BNFM DPSF MJCSBSZ. 5IJT BMMPXT ZPV UP VTF DBNFMbT SPVUJOH FOHJOF BOE JOUFHSBUJPO QBUUFSOT TVQQPSU TNPPUIMZ UPHFUIFS XJUI ZPVS $9' TFSWJDFT.

(-3$&1 3$ " ,$+ (-3. "7% 31 -2/.13 + 8$1


5P JODMVEF UIF $BNFM 5SBOQPSU JOUP ZPVS $9' CVT ZPV VTF UIF $BNFM5SBOTQPSU'BDUPSZ. :PV DBO EP UIJT JO +BWB BT XFMM BT JO 4QSJOH. 2BQQFKD RM QEB ">JBI 3O>KPMLOQ FK 2MOFKD :PV DBO VTF UIF GPMMPXJOH TOJQQFU JO ZPVS BQQMJDBUJPODPOUFYU JG ZPV XBOU UP DPOGJHVSF BOZUIJOH TQFDJBM. *G ZPV POMZ XBOU UP BDUJWBUF UIF DBNFM USBOTQPSU ZPV EP OPU IBWF UP EP BOZUIJOH JO ZPVS BQQMJDBUJPO DPOUFYU. "T TPPO BT ZPV JODMVEF UIF DBNFM-DYG-USBOTQPSU KBS (PS DBNFM-DYG.KBS JG ZPVS DBNFM WFSTJPO JT MFTT UIBO 2.7.Y) JO ZPVS BQQ DYG XJMM TDBO UIF KBS BOE MPBE B $BNFM5SBOTQPSU'BDUPSZ GPS ZPV.
<!-- you don't need to specify the CamelTransportFactory configuration as it is auto load by CXF bus --> <bean class="org.apache.camel.component.cxf.transport.CamelTransportFactory"> <property name="bus" ref="cxf" /> <property name="camelContext" ref="camelContext" /> <!-- checkException new added in Camel 2.1 and Camel 1.6.2 -->

$0 0 , # 0 0 ,

115

<!-- If checkException is true , CamelDestination will check the outMessage's exception and set it into camel exchange. You can also override this value in CamelDestination's configuration. The default value is false. This option should be set true when you want to leverage the camel's error handler to deal with fault message --> <property name="checkException" value="true" /> <property name="transportIds"> <list> <value>http://cxf.apache.org/transports/camel</value> </list> </property> </bean>

(KQBDO>QFKD QEB ">JBI 3O>KPMLOQ FK > MOLDO>JJ>QF@ T>V $BNFM USBOTQPSU QSPWJEFT B TFU$POUFYU NFUIPE UIBU ZPV DPVME VTF UP TFU UIF $BNFM DPOUFYU JOUP UIF USBOTQPSU GBDUPSZ. *G ZPV XBOU UIJT GBDUPSZ UBLF FGGFDU, ZPV OFFE UP SFHJTUFS UIF GBDUPSZ JOUP UIF $9' CVT. )FSF JT B GVMM FYBNQMF GPS ZPV.
import import import import ... org.apache.cxf.Bus; org.apache.cxf.BusFactory; org.apache.cxf.transport.ConduitInitiatorManager; org.apache.cxf.transport.DestinationFactoryManager;

BusFactory bf = BusFactory.newInstance(); Bus bus = bf.createBus(); CamelTransportFactory camelTransportFactory = new CamelTransportFactory(); // set up the CamelContext which will be use by the CamelTransportFactory camelTransportFactory.setCamelContext(context) // if you are using CXF higher then 2.4.x the camelTransportFactory.setBus(bus); // if you are lower CXF, you need to register the ConduitInitiatorManager and DestinationFactoryManager like below // register the conduit initiator ConduitInitiatorManager cim = bus.getExtension(ConduitInitiatorManager.class); cim.registerConduitInitiator(CamelTransportFactory.TRANSPORT_ID, camelTransportFactory); // register the destination factory DestinationFactoryManager dfm = bus.getExtension(DestinationFactoryManager.class); dfm.registerDestinationFactory(CamelTransportFactory.TRANSPORT_ID, camelTransportFactory); // set or bus as the default bus for cxf BusFactory.setDefaultBus(bus);

116

$00 , #0 0 ,

".-%(&41$ 3'$ #$23(- 3(.2/1(-&


->JBPM>@B

-# ".-#4(3 6(3'

5IF FMFNFOUT VTFE UP DPOGJHVSF BO $BNFM USBOTQPSU FOEQPJOU BSF EFGJOFE JO UIF OBNFTQBDF http://cxf.apache.org/transports/camel. *U JT DPNNPOMZ SFGFSSFE UP VTJOH UIF QSFGJY camel. *O PSEFS UP VTF UIF $BNFM USBOTQPSU DPOGJHVSBUJPO FMFNFOUT ZPV XJMM OFFE UP BEE UIF MJOFT TIPXO CFMPX UP UIF CFBOT FMFNFOU PG ZPVS FOEQPJOU'T DPOGJHVSBUJPO GJMF. *O BEEJUJPO, ZPV XJMM OFFE UP BEE UIF DPOGJHVSBUJPO FMFNFOUT' OBNFTQBDF UP UIF xsi:schemaLocation BUUSJCVUF.
Listing 1. Adding the Configuration Namespace
<beans ... xmlns:camel="http://cxf.apache.org/transports/camel ... xsi:schemaLocation="... http://cxf.apache.org/transports/camel http://cxf.apache.org/transports/camel.xsd ...>

3EB destination BIBJBKQ :PV DPOGJHVSF BO $BNFM USBOTQPSU TFSWFS FOEQPJOU VTJOH UIF camel:destination FMFNFOU BOE JUT DIJMESFO. 5IF camel:destination FMFNFOU UBLFT B TJOHMF BUUSJCVUF, name, UIF TQFDJGJFT UIF 84%- QPSU FMFNFOU UIBU DPSSFTQPOET UP UIF FOEQPJOU. 5IF WBMVF GPS UIF name BUUSJCVUF UBLFT UIF GPSN portQName.camel-destination. 5IF FYBNQMF CFMPX TIPXT UIF camel:destination FMFNFOU UIBU XPVME CF VTFE UP BEE DPOGJHVSBUJPO GPS BO FOEQPJOU UIBU XBT TQFDJGJFE CZ UIF 84%- GSBHNFOU <port binding="widgetSOAPBinding" name="widgetSOAPPort> JG UIF FOEQPJOU'T UBSHFU OBNFTQBDF XBT http://widgets.widgetvendor.net.
Listing 1. camel:destination Element
... <camel:destination name="{http://widgets/ widgetvendor.net}widgetSOAPPort.http-destination> <camelContext id="context" xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="direct:EndpointC" /> <to uri="direct:EndpointD" /> </route> </camelContext> </camel:destination>

$0 0 , # 0 0 ,

117

<!-- new added feature since Camel 2.11.x <camel:destination name="{http://widgets/ widgetvendor.net}widgetSOAPPort.camel-destination" camelContextId="context" /> ...

5IF camel:destination FMFNFOU GPS 4QSJOH IBT B OVNCFS PG DIJME FMFNFOUT UIBU TQFDJGZ DPOGJHVSBUJPO JOGPSNBUJPO. 5IFZ BSF EFTDSJCFE CFMPX. $IBJBKQ camelspring:camelContext camel:camelContextRef #BP@OFMQFLK :PV DBO TQFDJGZ UIF DBNFM DPOUFYU JO UIF DBNFM EFTUJOBUJPO 5IF DBNFM DPOUFYU JE XIJDI ZPV XBOU JOKFDU JOUP UIF DBNFM EFTUJOBUJPO

3EB conduit BIBJBKQ :PV DPOGJHVSF BO $BNFM USBOTQPSU DMJFOU VTJOH UIF camel:conduit FMFNFOU BOE JUT DIJMESFO. 5IF camel:conduit FMFNFOU UBLFT B TJOHMF BUUSJCVUF, name, UIBU TQFDJGJFT UIF 84%- QPSU FMFNFOU UIBU DPSSFTQPOET UP UIF FOEQPJOU. 5IF WBMVF GPS UIF name BUUSJCVUF UBLFT UIF GPSN portQName.camel-conduit. 'PS FYBNQMF, UIF DPEF CFMPX TIPXT UIF camel:conduit FMFNFOU UIBU XPVME CF VTFE UP BEE DPOGJHVSBUJPO GPS BO FOEQPJOU UIBU XBT TQFDJGJFE CZ UIF 84%- GSBHNFOU <port binding="widgetSOAPBinding" name="widgetSOAPPort> JG UIF FOEQPJOU'T UBSHFU OBNFTQBDF XBT http://widgets.widgetvendor.net.
Listing 1. http-conf:conduit Element
... <camelContext id="conduit_context" xmlns="http://activemq.apache.org/camel/schema/ spring"> <route> <from uri="direct:EndpointA" /> <to uri="direct:EndpointB" /> </route> </camelContext> <camel:conduit name="{http://widgets/widgetvendor.net}widgetSOAPPort.camel-conduit"> <camel:camelContextRef>conduit_context</camel:camelContextRef> </camel:conduit> <!-- new added feature since Camel 2.11.x <camel:conduit name="{http://widgets/widgetvendor.net}widgetSOAPPort.camel-conduit" camelContextId="conduit_context" />

<camel:conduit name="*.camel-conduit">

118

$00 , #0 0 ,

<!-- you can also using the wild card to specify the camel-conduit that you want to configure --> ... </camel:conduit> ...

5IF camel:conduit FMFNFOU IBT B OVNCFS PG DIJME FMFNFOUT UIBU TQFDJGZ DPOGJHVSBUJPO JOGPSNBUJPO. 5IFZ BSF EFTDSJCFE CFMPX. $IBJBKQ camelspring:camelContext camel:camelContextRef #BP@OFMQFLK :PV DBO TQFDJGZ UIF DBNFM DPOUFYU JO UIF DBNFM DPOEVJU 5IF DBNFM DPOUFYU JE XIJDI ZPV XBOU JOKFDU JOUP UIF DBNFM DPOEVJU

".-%(&41$ 3'$ #$23(- 3(.!+4$/1(-3

-# ".-#4(3 6(3'

'SPN ">JBI 2.11.U, $BNFM 5SBOTQPSU TVQQPSUT UP CF DPOGJHVSFE XJUI #MVFQSJOU *G ZPV BSF VTJOH CMVFQSJOU, ZPV TIPVME VTF UIF UIF OBNFTQBDF http://cxf.apache.org/transports/camel/blueprint BOE JNQPSU UIF TDIFNB MJLF UIF CMPX.
Listing 1. Adding the Configuration Namespace for blueprint
<beans ... xmlns:camel="http://cxf.apache.org/transports/camel/blueprint" ... xsi:schemaLocation="... http://cxf.apache.org/transports/camel/blueprint http://cxf.apache.org/schmemas/blueprint/camel.xsd ...>

*O CMVFQSJOU camel:conduit camel:destination POMZ IBT POF DBNFM$POUFYU*E BUUSJCVUF, UIFZ EPFTO'U TVQQPSU UP TQFDJGZ UIF DBNFM DPOUFYU JO UIF DBNFM EFTUJOBUJPO.
<camel:conduit id="*.camel-conduit" camelContextId="camel1" /> <camel:destination id="*.camel-destination" camelContextId="camel1" />

$0 0 , # 0 0 ,

119

$7 ,/+$ 42(-& " ,$+

+. # ! + -"$1 %.1 "7%

5IJT FYBNQMF TIPX IPX UP VTF UIF DBNFM MPBE CBMBODF GFBUVSF JO $9', BOE ZPV OFFE MPBE UIF DPOGJHVSBUJPO GJMF JO $9' BOE QVCMJTI UIF FOEQPJOUT PO UIF BEESFTT "DBNFM://EJSFDU:&OEQPJOU"" BOE "DBNFM://EJSFDU:&OEQPJOU#"
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://cxf.apache.org/transports/camel" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/transports/camel http://cxf.apache.org/transports/ camel.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/ cxfEndpoint.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd "> <!-- Enable bridge between Camel Property Placeholder and Spring Property placeholder so we can use system properties to dynamically set the port number for unit testing the example. --> <bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"/> <bean id = "roundRobinRef" class="org.apache.camel.processor.loadbalancer.RoundRobinLoadBalancer" /> <camelContext id="dest_context" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="jetty:http://localhost:{{port}}/GreeterContext/GreeterPort"/> <loadBalance ref="roundRobinRef"> <to uri="direct:EndpointA"/> <to uri="direct:EndpointB"/> </loadBalance> </route> </camelContext> <!-- Inject the camel context to the Camel transport's destination --> <camel:destination name="{http://apache.org/ hello_world_soap_http}CamelPort.camel-destination"> <camel:camelContextRef>dest_context</camel:camelContextRef> </camel:destination> </beans>

".,/+$3$ '.63. " ,$+ 3. "7%

-# $7 ,/+$ %.1

33 "'(-&

#FUUFS +.4 5SBOTQPSU GPS $9' 8FCTFSWJDF VTJOH "QBDIF $BNFMc

120

$00 , #0 0 ,

(-31.#4"3(.8IFO TFOEJOH BO &YDIBOHF UP BO &OEQPJOU ZPV DBO FJUIFS VTF B 3PVUF PS B 1SPEVDFS5FNQMBUF. 5IJT XPSLT GJOF JO NBOZ TDFOBSJPT. )PXFWFS ZPV NBZ OFFE UP HVBSBOUFF UIBU BO FYDIBOHF JT EFMJWFSFE UP UIF TBNF FOEQPJOU UIBU ZPV EFMJWFSFE B QSFWJPVT FYDIBOHF PO. 'PS FYBNQMF JO UIF DBTF PG EFMJWFSJOH B CBUDI PG FYDIBOHFT UP B .*/" TPDLFU ZPV NBZ OFFE UP FOTVSF UIBU UIFZ BSF BMM EFMJWFSFE UISPVHI UIF TBNF TPDLFU DPOOFDUJPO. 'VSUIFSNPSF PODF UIF CBUDI PG FYDIBOHFT IBWF CFFO EFMJWFSFE UIF QSPUPDPM SFRVJSFNFOUT NBZ CF TVDI UIBU ZPV BSF SFTQPOTJCMF GPS DMPTJOH UIF TPDLFU.

42(-&

/1.#4"$1

5P BDIJFWF GJOF HSBJOFE DPOUSPM PWFS TFOEJOH FYDIBOHFT ZPV XJMM OFFE UP QSPHSBN EJSFDUMZ UP B 1SPEVDFS. :PVS DPEF XJMM MPPL TJNJMBS UP:
CamelContext camelContext = ... // Obtain an endpoint and create the producer we will be using. Endpoint endpoint = camelContext.getEndpoint("someuri:etc"); Producer producer = endpoint.createProducer(); producer.start(); try { // For each message to send... Object requestMessage = ... Exchange exchangeToSend = producer.createExchange(); exchangeToSend().setBody(requestMessage); producer.process(exchangeToSend); ... } finally { // Tidy the producer up. producer.stop(); }

*O UIF DBTF PG VTJOH "QBDIF .*/" UIF QSPEVDFS.TUPQ() JOWPDBUJPO XJMM DBVTF UIF TPDLFU UP CF DMPTFE.

$0 0 , # 0 0 ,

121

3RQLOF>IP

5IFSF OPX GPMMPXT UIF EPDVNFOUBUJPO PO DBNFM UVUPSJBMT 8F IBWF B OVNCFS PG UVUPSJBMT BT MJTUFE CFMPX. 5IF UVUPSJBMT PGUFO DPNFT XJUI TPVSDF DPEF XIJDI JT FJUIFS BWBJMBCMF JO UIF $BNFM %PXOMPBE PS BUUBDIFE UP UIF XJLJ QBHF. ` 0"VUI 5VUPSJBM 5IJT UVUPSJBM EFNPOTUSBUFT IPX UP JNQMFNFOU 0"VUI GPS B XFC BQQMJDBUJPO XJUI $BNFM'T HBVUI DPNQPOFOU. 5IF TBNQMF BQQMJDBUJPO PG UIJT UVUPSJBM JT BMTP POMJOF BU IUUQ://HBVUIDMPVE.BQQTQPU.DPN/ ` 5VUPSJBM GPS $BNFM PO (PPHMF "QQ &OHJOF 5IJT UVUPSJBM EFNPOTUSBUFT UIF VTBHF PG UIF $BNFM $PNQPOFOUT GPS (PPHMF "QQ &OHJOF. 5IF TBNQMF BQQMJDBUJPO PG UIJT UVUPSJBM JT BMTP POMJOF BU IUUQ://DBNFMDMPVE.BQQTQPU.DPN/ ` 5VUPSJBM PO 4QSJOH 3FNPUJOH XJUI +.4 5IJT UVUPSJBM JT GPDVTFE PO EJGGFSFOU UFDIOJRVFT XJUI $BNFM GPS $MJFOU-4FSWFS DPNNVOJDBUJPO. ` 3FQPSU *ODJEFOU - 5IJT UVUPSJBM JOUSPEVDFT $BNFM TUFBEJMZ BOE JT CBTFE PO B SFBM MJGF JOUFHSBUJPO QSPCMFN 5IJT JT B WFSZ MPOH UVUPSJBM CFHJOOJOH GSPN UIF TUBSU; JUT GPS FOUSZ MFWFM UP $BNFM. *UT CBTFE PO B SFBM MJGF JOUFHSBUJPO, TIPXJOH IPX $BNFM DBO CF JOUSPEVDFE JO BO FYJTUJOH TPMVUJPO. 8F EP UIJT JO CBCZ TUFQT. 5IF UVUPSJBM JT DVSSFOUMZ XPSL JO QSPHSFTT, TP DIFDL JU PVU GSPN UJNF UP UJNF. 5IF UVUPSJBM FYQMBJOT TPNF PG UIF JOOFS CVJMEJOH CMPDLT $BNFM VTFT VOEFS UIF DPWFST. 5IJT JT HPPE LOPXMFEHF UP IBWF XIFO ZPV TUBSU VTJOH $BNFM PO B IJHIFS BCTUSBDU MFWFM XIFSF JU DBO EP XPOEFST JO B GFX MJOFT PG SPVUJOH %4-. ` 6TJOH $BNFM XJUI 4FSWJDF.JY B UVUPSJBM PO VTJOH $BNFM JOTJEF "QBDIF 4FSWJDF.JY. ` #FUUFS +.4 5SBOTQPSU GPS $9' 8FCTFSWJDF VTJOH "QBDIF $BNFM %FTDSJCFT IPX UP VTF UIF $BNFM 5SBOTQPSU GPS $9' UP BUUBDI B $9' 8FCTFSWJDF UP B +.4 2VFVF ` 5VUPSJBM IPX UP VTF HPPE PME "YJT 1.4 XJUI $BNFM 5IJT UVUPSJBM TIPXT UIBU $BNFM EPFT XPSL XJUI UIF HPPE PME GSBNFXPSLT TVDI BT "9*4 UIBU JT/XBT XJEFMZ VTFE GPS 8FC4FSWJDF. ` 5VUPSJBM PO VTJOH $BNFM JO B 8FC "QQMJDBUJPO 5IJT UVUPSJBM HJWFT BO PWFSWJFX PG IPX UP VTF $BNFM JOTJEF 5PNDBU, +FUUZ PS BOZ PUIFS TFSWMFU FOHJOF ` 5VUPSJBM PO $BNFM 1.4 GPS *OUFHSBUJPO "OPUIFS SFBM-MJGF TDFOBSJP. 5IF DPNQBOZ TFMMT XJEHFUT, XJUI B TPNFXIBU VOJRVF CVTJOFTT QSPDFTT (UIFJS DVTUPNFST QFSJPEJDBMMZ SFQPSU XIBU UIFZ'WF QVSDIBTFE JO PSEFS UP HFU CJMMFE). )PXFWFS FWFSZ DVTUPNFS VTFT B EJGGFSFOU EBUB GPSNBU BOE QSPUPDPM. 5IJT UVUPSJBM HPFT UISPVHI UIF QSPDFTT PG JOUFHSBUJOH (BOE UFTUJOH!) TFWFSBM DVTUPNFST

122

56 50 3* " - 4

-LQF@B 5IFTF UVUPSJBMT MJTUFE CFMPX, JT IPTUFE BU "QBDIF. 8F PGGFS UIF "SUJDMFT QBHF XIFSF XF IBWF B MJOL DPMMFDUJPO GPS 3SE QBSUZ $BNFM NBUFSJBM, TVDI BT UVUPSJBMT, CMPH QPTUT, QVCMJTIFE BSUJDMFT, WJEFPT, QPE DBTUT, QSFTFOUBUJPOT, BOE TP GPSUI.
*G ZPV IBWF XSJUUFO B $BNFM SFMBUFE BSUJDMF, UIFO XF BSF IBQQZ UP QSPWJEF B MJOL UP JU. :PV DBO DPOUBDU UIF $BNFM 5FBN, GPS FYBNQMF VTJOH UIF .BJMJOH -JTUT, (PS QPTU B UXFFU XJUI UIF XPSE "QBDIF $BNFM).

BOE UIFJS FMFDUSPOJD SFQPSUJOH PG UIF XJEHFUT UIFZ'WF CPVHIU, BMPOH XJUI UIF DPNQBOZ'T SFTQPOTF. ` 5VUPSJBM IPX UP CVJME B 4FSWJDF 0SJFOUFE "SDIJUFDUVSF VTJOH $BNFM XJUI 04(* 6QEBUFE 20/11/2009 5IF UVUPSJBM IBT CFFO EFTJHOFE JO UXP QBSUT. 5IF GJSTU QBSU JOUSPEVDFT CBTJD DPODFQU UP DSFBUF B TJNQMF 40" TPMVUJPO VTJOH $BNFM BOE 04(* BOE EFQMPZ JU JO B 04(* 4FSWFS MJLF "QBDIF 'FMJY ,BSBG BOE 4QSJOH %. 4FSWFS XIJMF UIF TFDPOE FYUFOET UIF 3FQPSU*ODJEFOU UVUPSJBM QBSU 4 UP TIPX )PX XF DBO TFQBSBUF UIF EJGGFSFOU MBZFST (EPNBJO, TFSWJDF, ...) PG BO BQQMJDBUJPO BOE EFQMPZ UIFN JO TFQBSBUF CVOEMFT. 5IF 8FC "QQMJDBUJPO IBT BMTP CF NPEJGJFE JO PSEFS UP DPNNVOJDBUF UP UIF 04(* CVOEMFT. ` 4FWFSBM PG UIF WFOEPST PO UIF $PNNFSDJBM $BNFM 0GGFSJOHT QBHF BMTP PGGFS WBSJPVT UVUPSJBMT, XFCJOBST, FYBNQMFT, FUD.... UIBU NBZ CF VTFGVM. ` &YBNQMFT 8IJMF OPU BDUVBM UVUPSJBMT ZPV NJHIU GJOE XPSLJOH UISPVHI UIF TPVSDF PG UIF WBSJPVT &YBNQMFT VTFGVM.

343.1( + .- 2/1(-& 1$,.3(-& 6(3' ),2


c

/1$% "$
5IJT UVUPSJBM BJNT UP HVJEF UIF SFBEFS UISPVHI UIF TUBHFT PG DSFBUJOH B QSPKFDU XIJDI VTFT $BNFM UP GBDJMJUBUF UIF SPVUJOH PG NFTTBHFT GSPN B +.4 RVFVF UP B 4QSJOH TFSWJDF. 5IF SPVUF XPSLT JO B TZODISPOPVT GBTIJPO SFUVSOJOH B SFTQPOTF UP UIF DMJFOU. ` 5VUPSJBM PO 4QSJOH 3FNPUJOH XJUI +.4 ` 1SFGBDF ` 1SFSFRVJTJUFT ` %JTUSJCVUJPO ` "CPVU ` $SFBUF UIF $BNFM 1SPKFDU ` 6QEBUF UIF 10. XJUI %FQFOEFODJFT
5 65 0 3 *"-4 123

3E>KHP 5IJT UVUPSJBM XBT LJOEMZ EPOBUFE UP "QBDIF $BNFM CZ .BSUJO (JMEBZ. ` ` ` ` ` ` ` ` ` ` ` ` ` 8SJUJOH UIF 4FSWFS $SFBUF UIF 4QSJOH 4FSWJDF %FGJOF UIF $BNFM 3PVUFT $POGJHVSF 4QSJOH 3VO UIF 4FSWFS 8SJUJOH 5IF $MJFOUT $MJFOU 6TJOH 5IF 1SPEVDFS5FNQMBUF $MJFOU 6TJOH 4QSJOH 3FNPUJOH $MJFOU 6TJOH .FTTBHF &OEQPJOU &*1 1BUUFSO 3VO UIF $MJFOUT 6TJOH UIF $BNFM .BWFO 1MVHJO 6TJOH $BNFM +.9 4FF "MTP

/1$1$04(2(3$2
5IJT UVUPSJBM VTFT .BWFO UP TFUVQ UIF $BNFM QSPKFDU BOE GPS EFQFOEFODJFT GPS BSUJGBDUT.

#(231(!43(.5IJT TBNQMF JT EJTUSJCVUFE XJUI UIF $BNFM EJTUSJCVUJPO BT examples/camel-examplespring-jms.

!.43
5IJT UVUPSJBM JT B TJNQMF FYBNQMF UIBU EFNPOTUSBUFT NPSF UIF GBDU IPX XFMM $BNFM JT TFBNMFTT JOUFHSBUFE XJUI 4QSJOH UP MFWFSBHF UIF CFTU PG CPUI XPSMET. 5IJT TBNQMF JT DMJFOU TFSWFS TPMVUJPO VTJOH +.4 NFTTBHJOH BT UIF USBOTQPSU. 5IF TBNQMF IBT UXP GMBWPST PG TFSWFST BOE BMTP GPS DMJFOUT EFNPOTUSBUJOH EJGGFSFOU UFDIOJRVFT GPS FBTZ DPNNVOJDBUJPO. 5IF 4FSWFS JT B +.4 NFTTBHF CSPLFS UIBU SPVUFT JODPNJOH NFTTBHFT UP B CVTJOFTT TFSWJDF UIBU EPFT DPNQVUBUJPOT PO UIF SFDFJWFE NFTTBHF BOE SFUVSOT B SFTQPOTF. 5IF &*1 QBUUFSOT VTFE JO UIJT TBNQMF BSF: />QQBOK .FTTBHF $IBOOFM #BP@OFMQFLK 8F OFFE B DIBOOFM TP UIF $MJFOUT DBO DPNNVOJDBUF XJUI UIF TFSWFS.

124

56 50 3* " - 4

.FTTBHF .FTTBHF 5SBOTMBUPS

5IF JOGPSNBUJPO JT FYDIBOHFE VTJOH UIF $BNFM .FTTBHF JOUFSGBDF. 5IJT JT XIFSF $BNFM TIJOFT BT UIF NFTTBHF FYDIBOHF CFUXFFO UIF 4FSWFS BOE UIF $MJFOUT BSF UFYU CBTFE TUSJOHT XJUI OVNCFST. )PXFWFS PVS CVTJOFTT TFSWJDF VTFT JOU GPS OVNCFST. 4P $BNFM DBO EP UIF NFTTBHF USBOTMBUJPO BVUPNBUJDBMMZ. *U TIPVME CF FBTZ UP TFOE NFTTBHFT UP UIF 4FSWFS GSPN UIF UIF DMJFOUT. 5IJT JT BSDIJWFE XJUI $BNFMT QPXFSGVM &OEQPJOU QBUUFSO UIBU FWFO DBO CF NPSF QPXFSGVM DPNCJOFE XJUI 4QSJOH SFNPUJOH. 5IF UVUPSJBM IBWF DMJFOUT VTJOH FBDI LJOE PG UFDIOJRVF GPS UIJT. 8F VTJOH +.4 RVFVFT TP UIFSF BSF POMZ POF SFDFJWF PG UIF NFTTBHF FYDIBOHF

.FTTBHF &OEQPJOU 1PJOU UP 1PJOU $IBOOFM &WFOU %SJWFO $POTVNFS

:FT UIF +.4 CSPLFS JT PG DPVSTF FWFOU ESJWFO BOE POMZ SFBDUT XIFO UIF DMJFOU TFOET B NFTTBHF UP UIF TFSWFS.

8F VTF UIF GPMMPXJOH $BNFM DPNQPOFOUT: "LJMLKBKQ "DUJWF.2 #FBO 'JMF +.4 #BP@OFMQFLK 8F VTF "QBDIF "DUJWF.2 BT UIF +.4 CSPLFS PO UIF 4FSWFS TJEF 8F VTF UIF CFBO CJOEJOH UP FBTJMZ SPVUF UIF NFTTBHFT UP PVS CVTJOFTT TFSWJDF. 5IJT JT B WFSZ QPXFSGVM DPNQPOFOU JO $BNFM. *O UIF "01 FOBCMFE 4FSWFS XF TUPSF BVEJU USBJMT BT GJMFT. 6TFE GPS UIF +.4 NFTTBHJOH

"1$ 3$ 3'$ " ,$+ /1.)$"3


mvn archetype:create -DgroupId=org.example -DartifactId=CamelWithJmsAndSpring

4MA>QB QEB /., TFQE #BMBKABK@FBP 'JSTU XF OFFE UP IBWF EFQFOEFODJFT GPS UIF DPSF $BNFM KBST, JUT TQSJOH, KNT DPNQPOFOUT BOE GJOBMMZ "DUJWF.2 BT UIF NFTTBHF CSPLFS.
<!-- required by both client and server --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> </dependency>

5 65 0 3 *"-4

125

'PS UIF QVSQPTFT PG UIF UVUPSJBM B TJOHMF .BWFO QSPKFDU XJMM CF VTFE GPS CPUI UIF DMJFOU BOE TFSWFS. *EFBMMZ ZPV XPVME CSFBL ZPVS BQQMJDBUJPO EPXO JOUP UIF BQQSPQSJBUF DPNQPOFOUT.

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jms</artifactId> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-camel</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> </dependency>

"T XF VTF TQSJOH YNM DPOGJHVSBUJPO GPS UIF "DUJWF.2 +.4 CSPLFS XF OFFE UIJT EFQFOEFODZ:
<!-- xbean is required for ActiveMQ broker configuration in the spring xml file --> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-spring</artifactId> </dependency>

61(3(-& 3'$ 2$15$1


"OB>QB QEB 2MOFKD 2BOSF@B 'PS UIJT FYBNQMF UIF 4QSJOH TFSWJDF (= PVS CVTJOFTT TFSWJDF) PO UIF TFSWFS XJMM CF B TJNQMF NVMUJQMJFS XIJDI USFCMFT JO UIF SFDFJWFE WBMVF.
public interface Multiplier { /** * Multiplies the given number by a pre-defined constant. * * @param originalNumber The number to be multiplied * @return The result of the multiplication

126

56 50 3* " - 4

*/ int multiply(int originalNumber); }

"OE UIF JNQMFNFOUBUJPO PG UIJT TFSWJDF JT:


@Service(value = "multiplier") public class Treble implements Multiplier { public int multiply(final int originalNumber) { return originalNumber * 3; } }

/PUJDF UIBU UIJT DMBTT IBT CFFO BOOPUBUFE XJUI UIF !4FSWJDF TQSJOH BOOPUBUJPO. 5IJT FOTVSFT UIBU UIJT DMBTT JT SFHJTUFSFE BT B CFBO JO UIF SFHJTUSZ XJUI UIF HJWFO OBNF JRIQFMIFBO. #BCFKB QEB ">JBI 1LRQBP
public class ServerRoutes extends RouteBuilder { @Override public void configure() throws Exception { // route from the numbers queue to our business that is a spring bean registered with the id=multiplier // Camel will introspect the multiplier bean and find the best candidate of the method to invoke. // You can add annotations etc to help Camel find the method to invoke. // As our multiplier bean only have one method its easy for Camel to find the method to use. from("jms:queue:numbers").to("multiplier"); // Camel has several ways to configure the same routing, we have defined some of them here below // as above but with the bean: prefix //from("jms:queue:numbers").to("bean:multiplier"); // beanRef is using explicit bean bindings to lookup the multiplier bean and invoke the multiply method //from("jms:queue:numbers").beanRef("multiplier", "multiply"); // the same as above but expressed as a URI configuration //from("jms:queue:numbers").to("bean:multiplier?methodName=multiply"); } }

5 65 0 3 *"-4

127

5IJT EFGJOFT B $BNFM SPVUF from UIF +.4 RVFVF OBNFE KRJ?BOP to UIF 4QSJOH CFBO OBNFE JRIQFMIFBO. $BNFM XJMM DSFBUF B DPOTVNFS UP UIF +.4 RVFVF XIJDI GPSXBSET BMM SFDFJWFE NFTTBHFT POUP UIF UIF 4QSJOH CFBO, VTJOH UIF NFUIPE OBNFE JRIQFMIV. "LKCFDROB 2MOFKD 5IF 4QSJOH DPOGJH GJMF JT QMBDFE VOEFS META-INF/spring BT UIJT JT UIF EFGBVMU MPDBUJPO VTFE CZ UIF $BNFM .BWFO 1MVHJO, XIJDI XF XJMM MBUFS VTF UP SVO PVS TFSWFS. 'JSTU XF OFFE UP EP UIF TUBOEBSE TDIFNF EFDMBSBUJPOT JO UIF UPQ. *O UIF DBNFM-TFSWFS.YNM XF BSF VTJOH TQSJOH CFBOT BT UIF EFGBVMU ?B>K: OBNFTQBDF BOE TQSJOHT @LKQBUQ:. 'PS DPOGJHVSJOH "DUJWF.2 XF VTF ?OLHBO: BOE GPS $BNFM XF PG DPVSTF IBWF @>JBI:. /PUJDF UIBU XF EPO'U VTF WFSTJPO OVNCFST GPS UIF DBNFM-TQSJOH TDIFNB. "U SVOUJNF UIF TDIFNB JT SFTPMWFE JO UIF $BNFM CVOEMF. *G XF VTF B TQFDJGJD WFSTJPO OVNCFS TVDI BT 1.4 UIFO JUT *%& GSJFOEMZ BT JU XPVME CF BCMF UP JNQPSU JU BOE QSPWJEF TNBSU DPNQMFUJPO FUD. 4FF 9NM 3FGFSFODF GPS GVSUIFS EFUBJMT.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:broker="http://activemq.apache.org/schema/core" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/ schema/context/spring-context.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/ activemq-core.xsd">

8F VTF 4QSJOH BOOPUBUJPOT GPS EPJOH *P$ EFQFOEFODJFT BOE JUT DPNQPOFOU-TDBO GFBUVSFT DPNFT UP UIF SFTDVF BT JU TDBOT GPS TQSJOH BOOPUBUJPOT JO UIF HJWFO QBDLBHF OBNF:
<!-- let Spring do its IoC stuff in this package --> <context:component-scan base-package="org.apache.camel.example.server"/>

$BNFM XJMM PG DPVSTF OPU CF MFTT UIBO 4QSJOH JO UIJT SFHBSE TP JU TVQQPSUT B TJNJMBS GFBUVSF GPS TDBOOJOH PG 3PVUFT. 5IJT JT DPOGJHVSFE BT TIPXO CFMPX. /PUJDF UIBU XF BMTP IBWF FOBCMFE UIF +.9"HFOU TP XF XJMM CF BCMF UP JOUSPTQFDU UIF $BNFM 4FSWFS XJUI B +.9 $POTPMF.
<!-- declare a camel context that scans for classes that is RouteBuilder in the package org.apache.camel.example.server --> <camel:camelContext id="camel-server"> <camel:package>org.apache.camel.example.server</camel:package> <!-- enable JMX connector so we can connect to the server and browse mbeans --> <!-- Camel will log at INFO level the service URI to use for connecting with

128

56 50 3* " - 4

jconsole --> <camel:jmxAgent id="agent" createConnector="true"/> </camel:camelContext>

5IF "DUJWF.2 +.4 CSPLFS JT BMTP DPOGJHVSFE JO UIJT YNM GJMF. 8F TFU JU VQ UP MJTUFO PO 5$1 QPSU 61610.
<!-- lets configure the ActiveMQ JMS broker server --> <broker:broker useJmx="true" persistent="false" brokerName="myBroker"> <broker:transportConnectors> <!-- expose a VM transport for in-JVM transport between AMQ and Camel on the server side --> <broker:transportConnector name="vm" uri="vm://myBroker"/> <!-- expose a TCP transport for clients to use --> <broker:transportConnector name="tcp" uri="tcp://localhost:${tcp.port}"/> </broker:transportConnectors> </broker:broker>

"T UIJT FYBNQMFT VTFT +.4 UIFO $BNFM OFFET B +.4 DPNQPOFOU UIBU JT DPOOFDUFE XJUI UIF "DUJWF.2 CSPLFS. 5IJT JT DPOGJHVSFE BT TIPXO CFMPX:
<!-- lets configure the Camel ActiveMQ to use the embedded ActiveMQ broker declared above --> <bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="brokerURL" value="vm://myBroker"/> </bean>

-LQF@B: 5IF +.4 DPNQPOFOU JT DPOGJHVSFE JO TUBOEBSE 4QSJOH CFBOT, CVU UIF HFN JT UIBU UIF CFBO JE DBO CF SFGFSFODFE GSPN $BNFM SPVUFT - NFBOJOH XF DBO EP SPVUJOH VTJOH UIF +.4 $PNQPOFOU CZ KVTU VTJOH GJP: QSFGJY JO UIF SPVUF 63*. 8IBU IBQQFOT JT UIBU $BNFM XJMM GJOE JO UIF 4QSJOH 3FHJTUSZ GPS B CFBO XJUI UIF JE="KNT". 4JODF UIF CFBO JE DBO IBWF BSCJUSBSZ OBNF ZPV DPVME IBWF OBNFE JU JE="KNTCSPLFS" BOE UIFO SFGFSFODFE UP JU JO UIF SPVUJOH BT from="jmsbroker:queue:numbers).to("multiplier"); 8F VTF UIF WN QSPUPDPM UP DPOOFDU UP UIF "DUJWF.2 TFSWFS BT JUT FNCFEEFE JO UIJT BQQMJDBUJPO. DPNQPOFOUTDBO DBNFMDPOUFYU KNT CFBO %FGJOFT UIF QBDLBHF UP CF TDBOOFE GPS 4QSJOH TUFSFPUZQF BOOPUBUJPOT, JO UIJT DBTF, UP MPBE UIF "NVMUJQMJFS" CFBO %FGJOFT UIF QBDLBHF UP CF TDBOOFE GPS $BNFM SPVUFT. 8JMM GJOE UIF ServerRoutes DMBTT BOE DSFBUF UIF SPVUFT DPOUBJOFE XJUIJO JU $SFBUFT UIF $BNFM +.4 DPNQPOFOU

5 65 0 3 *"-4

129

1RK QEB 2BOSBO 5IF 4FSWFS JT TUBSUFE VTJOH UIF org.apache.camel.spring.Main DMBTT UIBU DBO TUBSU DBNFM-TQSJOH BQQMJDBUJPO PVU-PG-UIF-CPY. 5IF 4FSWFS DBO CF TUBSUFE JO TFWFSBM GMBWPST: BT B TUBOEBSE KBWB NBJO BQQMJDBUJPO - KVTU TUBSU UIF org.apache.camel.spring.Main DMBTT VTJOH NBWFO KBWF:FYFD VTJOH DBNFM:SVO *O UIJT TBNQMF BT UIFSF BSF UXP TFSWFST (XJUI BOE XJUIPVU "01) XF IBWF QSFQBSFE TPNF QSPGJMFT JO NBWFO UP TUBSU UIF 4FSWFS PG ZPVS DIPJDF. 5IF TFSWFS JT TUBSUFE XJUI: mvn compile exec:java -PCamelServer

61(3(-& 3'$ "+($-32


5IJT TBNQMF IBT UISFF DMJFOUT EFNPOTUSBUJOH EJGGFSFOU $BNFM UFDIOJRVFT GPS DPNNVOJDBUJPO $BNFM$MJFOU VTJOH UIF 1SPEVDFS5FNQMBUF GPS 4QSJOH UFNQMBUF TUZMF DPEJOH $BNFM3FNPUJOH VTJOH 4QSJOH 3FNPUJOH $BNFM&OEQPJOU VTJOH UIF .FTTBHF &OEQPJOU &*1 QBUUFSO VTJOH B OFVUSBM $BNFM "1* "IFBKQ 4PFKD 3EB /OLAR@BO3BJMI>QB 8F XJMM JOJUJBMMZ DSFBUF B DMJFOU CZ EJSFDUMZ VTJOH ProducerTemplate. 8F XJMM MBUFS DSFBUF B DMJFOU XIJDI VTFT 4QSJOH SFNPUJOH UP IJEF UIF GBDU UIBU NFTTBHJOH JT CFJOH VTFE.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/ schema/context/spring-context.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd">

<camel:camelContext id="camel-client"> <camel:template id="camelTemplate"/> </camel:camelContext>

<!-- Camel JMSProducer to be able to send messages to a remote Active MQ server --> <bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">

130

56 50 3* " - 4

<property name="brokerURL" value="tcp://localhost:${tcp.port}"/> </bean>

5IF DMJFOU XJMM OPU VTF UIF $BNFM .BWFO 1MVHJO TP UIF 4QSJOH 9.- IBT CFFO QMBDFE JO src/main/ resources UP OPU DPOGMJDU XJUI UIF TFSWFS DPOGJHT. DBNFM$POUFYU UFNQMBUF KNT CFBO 5IF $BNFM DPOUFYU JT EFGJOFE CVU EPFT OPU DPOUBJO BOZ SPVUFT 5IF ProducerTemplate JT VTFE UP QMBDF NFTTBHFT POUP UIF +.4 RVFVF 5IJT JOJUJBMJTFT UIF $BNFM +.4 DPNQPOFOU, BMMPXJOH VT UP QMBDF NFTTBHFT POUP UIF RVFVF

"OE UIF $BNFM$MJFOU TPVSDF DPEF:


public static void main(final String[] args) throws Exception { System.out.println("Notice this client requires that the CamelServer is already running!"); ApplicationContext context = new ClassPathXmlApplicationContext("camel-client.xml"); // get the camel template for Spring template style sending of messages (= producer) ProducerTemplate camelTemplate = context.getBean("camelTemplate", ProducerTemplate.class); System.out.println("Invoking the multiply with 22"); // as opposed to the CamelClientRemoting example we need to define the service URI in this java code int response = (Integer)camelTemplate.sendBody("jms:queue:numbers", ExchangePattern.InOut, 22); System.out.println("... the result is: " + response); System.exit(0); }

5IF ProducerTemplate JT SFUSJFWFE GSPN B 4QSJOH ApplicationContext BOE VTFE UP NBOVBMMZ QMBDF B NFTTBHF PO UIF "OVNCFST" +.4 RVFVF. 5IF requestBody NFUIPE XJMM VTF UIF FYDIBOHF QBUUFSO *O0VU, XIJDI TUBUFT UIBU UIF DBMM TIPVME CF TZODISPOPVT, BOE UIBU UIF DBMMFS FYQFDUT B SFTQPOTF. #FGPSF SVOOJOH UIF DMJFOU CF TVSF UIBU CPUI UIF "DUJWF.2 CSPLFS BOE UIF CamelServer BSF SVOOJOH. "IFBKQ 4PFKD 2MOFKD 1BJLQFKD 4QSJOH 3FNPUJOH "FBTFT UIF EFWFMPQNFOU PG SFNPUF-FOBCMFE TFSWJDFT". *U EPFT UIJT CZ BMMPXJOH ZPV UP JOWPLF SFNPUF TFSWJDFT UISPVHI ZPVS SFHVMBS +BWB JOUFSGBDF, NBTLJOH UIBU B SFNPUF TFSWJDF JT CFJOH DBMMFE.

5 65 0 3 *"-4

131

<!-- Camel proxy for a given service, in this case the JMS queue --> <camel:proxy id="multiplierProxy" serviceInterface="org.apache.camel.example.server.Multiplier" serviceUrl="jms:queue:numbers"/>

5IF TOJQQFU BCPWF POMZ JMMVTUSBUFT UIF EJGGFSFOU BOE IPX $BNFM FBTJMZ DBO TFUVQ BOE VTF 4QSJOH 3FNPUJOH JO POF MJOF DPOGJHVSBUJPOT. 5IF MOLUV XJMM DSFBUF B QSPYZ TFSWJDF CFBO GPS ZPV UP VTF UP NBLF UIF SFNPUF JOWPDBUJPOT. 5IF PBOSF@B(KQBOC>@B QSPQFSUZ EFUBJMT XIJDI +BWB JOUFSGBDF JT UP CF JNQMFNFOUFE CZ UIF QSPYZ. PBOSF@B4OI EFGJOFT XIFSF NFTTBHFT TFOU UP UIJT QSPYZ CFBO XJMM CF EJSFDUFE. )FSF XF EFGJOF UIF +.4 FOEQPJOU XJUI UIF "OVNCFST" RVFVF XF VTFE XIFO XPSLJOH XJUI $BNFM UFNQMBUF EJSFDUMZ. 5IF WBMVF PG UIF FA QSPQFSUZ JT UIF OBNF UIBU XJMM CF UIF HJWFO UP UIF CFBO XIFO JU JT FYQPTFE UISPVHI UIF 4QSJOH ApplicationContext. 8F XJMM VTF UIJT OBNF UP SFUSJFWF UIF TFSWJDF JO PVS DMJFOU. * IBWF OBNFE UIF CFBO multiplierProxy TJNQMZ UP IJHIMJHIU UIBU JU JT OPU UIF TBNF NVMUJQMJFS CFBO BT JT CFJOH VTFE CZ CamelServer. 5IFZ BSF JO DPNQMFUFMZ JOEFQFOEFOU DPOUFYUT BOE IBWF OP LOPXMFEHF PG FBDI PUIFS. "T ZPV BSF USZJOH UP NBTL UIF GBDU UIBU SFNPUJOH JT CFJOH VTFE JO B SFBM BQQMJDBUJPO ZPV XPVME HFOFSBMMZ OPU JODMVEF QSPYZ JO UIF OBNF. "OE UIF +BWB DMJFOU TPVSDF DPEF:
public static void main(final String[] args) { System.out.println("Notice this client requires that the CamelServer is already running!"); ApplicationContext context = new ClassPathXmlApplicationContext("camel-client-remoting.xml"); // just get the proxy to the service and we as the client can use the "proxy" as it was // a local object we are invoking. Camel will under the covers do the remote communication // to the remote ActiveMQ server and fetch the response. Multiplier multiplier = context.getBean("multiplierProxy", Multiplier.class); System.out.println("Invoking the multiply with 33"); int response = multiplier.multiply(33); System.out.println("... the result is: " + response); System.exit(0); }

"HBJO, UIF DMJFOU JT TJNJMBS UP UIF PSJHJOBM DMJFOU, CVU XJUI TPNF JNQPSUBOU EJGGFSFODFT. 1. 5IF 4QSJOH DPOUFYU JT DSFBUFE XJUI UIF OFX camel-client-remoting.xml 2. 8F SFUSJFWF UIF QSPYZ CFBO JOTUFBE PG B ProducerTemplate. *O B OPO-USJWJBM FYBNQMF ZPV XPVME IBWF UIF CFBO JOKFDUFE BT JO UIF TUBOEBSE 4QSJOH NBOOFS. 3. 5IF NVMUJQMZ NFUIPE JT UIFO DBMMFE EJSFDUMZ. *O UIF DMJFOU XF BSF OPX XPSLJOH UP BO JOUFSGBDF. 5IFSF JT OP NFOUJPO PG $BNFM PS +.4 JOTJEF PVS +BWB DPEF.

132

56 50 3* " - 4

"IFBKQ 4PFKD ,BPP>DB $KAMLFKQ $(/ />QQBOK 5IJT DMJFOU VTFT UIF .FTTBHF &OEQPJOU &*1 QBUUFSO UP IJEF UIF DPNQMFYJUZ UP DPNNVOJDBUF UP UIF 4FSWFS. 5IF $MJFOU VTFT UIF TBNF TJNQMF "1* UP HFU IPME PG UIF FOEQPJOU, DSFBUF BO FYDIBOHF UIBU IPMET UIF NFTTBHF, TFU UIF QBZMPBE BOE DSFBUF B QSPEVDFS UIBU EPFT UIF TFOE BOE SFDFJWF. "MM EPOF VTJOH UIF TBNF OFVUSBM $BNFM "1* GPS >II UIF DPNQPOFOUT JO $BNFM. 4P JG UIF DPNNVOJDBUJPO XBT TPDLFU 5$1 CBTFE ZPV KVTU HFU IPME PG B EJGGFSFOU FOEQPJOU BOE BMM UIF KBWB DPEF TUBZT UIF TBNF. 5IBU JT SFBMMZ QPXFSGVM. 0LBZ FOPVHI UBML, TIPX NF UIF DPEF!
public static void main(final String[] args) throws Exception { System.out.println("Notice this client requires that the CamelServer is already running!"); ApplicationContext context = new ClassPathXmlApplicationContext("camel-client.xml"); CamelContext camel = context.getBean("camel-client", CamelContext.class); // get the endpoint from the camel context Endpoint endpoint = camel.getEndpoint("jms:queue:numbers"); // create the exchange used for the communication // we use the in out pattern for a synchronized exchange where we expect a response Exchange exchange = endpoint.createExchange(ExchangePattern.InOut); // set the input on the in body // must be correct type to match the expected type of an Integer object exchange.getIn().setBody(11); // to send the exchange we need an producer to do it for us Producer producer = endpoint.createProducer(); // start the producer so it can operate producer.start(); // let the producer process the exchange where it does all the work in this oneline of code System.out.println("Invoking the multiply with 11"); producer.process(exchange); // get the response from the out body and cast it to an integer int response = exchange.getOut().getBody(Integer.class); System.out.println("... the result is: " + response); // stop and exit the client producer.stop(); System.exit(0); }

4XJUDIJOH UP B EJGGFSFOU DPNQPOFOU JT KVTU B NBUUFS PG VTJOH UIF DPSSFDU FOEQPJOU. 4P JG XF IBE EFGJOFE B 5$1 FOEQPJOU BT: "mina:tcp://localhost:61610" UIFO JUT KVTU B NBUUFS PG HFUUJOH IPME PG UIJT FOEQPJOU JOTUFBE PG UIF +.4 BOE BMM UIF SFTU PG UIF KBWB DPEF JT FYBDUMZ UIF TBNF.

5 65 0 3 *"-4

133

1RK QEB "IFBKQP 5IF $MJFOUT JT TUBSUFE VTJOH UIFJS NBJO DMBTT SFTQFDUJWFMZ. BT B TUBOEBSE KBWB NBJO BQQMJDBUJPO - KVTU TUBSU UIFJS NBJO DMBTT VTJOH NBWFO KBWF:FYFD *O UIJT TBNQMF XF TUBSU UIF DMJFOUT VTJOH NBWFO: mvn compile exec:java -PCamelClient mvn compile exec:java -PCamelClientRemoting mvn compile exec:java -PCamelClientEndpoint "MTP TFF UIF .BWFO pom.xml GJMF IPX UIF QSPGJMFT GPS UIF DMJFOUT JT EFGJOFE.

42(-& 3'$ " ,$+ , 5$- /+4&(5IF $BNFM .BWFO 1MVHJO BMMPXT ZPV UP SVO ZPVS $BNFM SPVUFT EJSFDUMZ GSPN .BWFO. 5IJT OFHBUFT UIF OFFE UP DSFBUF B IPTU BQQMJDBUJPO, BT XF EJE XJUI $BNFM TFSWFS, TJNQMZ UP TUBSU VQ UIF DPOUBJOFS. 5IJT DBO CF WFSZ VTFGVM EVSJOH EFWFMPQNFOU UP HFU $BNFM SPVUFT SVOOJOH RVJDLMZ.
Listing 1. pom.xml
<build> <plugins> <plugin> <groupId>org.apache.camel</groupId> <artifactId>camel-maven-plugin</artifactId> </plugin> </plugins> </build>

"MM UIBU JT SFRVJSFE JT B OFX QMVHJO EFGJOJUJPO JO ZPVS .BWFO 10.. "T XF IBWF BMSFBEZ QMBDFE PVS $BNFM DPOGJH JO UIF EFGBVMU MPDBUJPO (DBNFM-TFSWFS.YNM IBT CFFO QMBDFE JO .&5"-*/'/ TQSJOH/) XF EP OPU OFFE UP UFMM UIF QMVHJO XIFSF UIF SPVUF EFGJOJUJPOT BSF MPDBUFE. 4JNQMZ SVO mvn camel:run.

42(-& " ,$+ ),7


$BNFM IBT FYUFOTJWF TVQQPSU GPS +.9 BOE BMMPXT VT UP JOTQFDU UIF $BNFM 4FSWFS BU SVOUJNF. "T XF IBWF FOBCMFE UIF +.9"HFOU JO PVS UVUPSJBM XF DBO GJSF VQ UIF KDPOTPMF BOE DPOOFDU UP UIF GPMMPXJOH TFSWJDF 63*: service:jmx:rmi:///jndi/rmi://localhost:1099/ jmxrmi/camel. /PUJDF UIBU $BNFM XJMM MPH BU */'0 MFWFM UIF +.9 $POOFDUPS 63*:
... DefaultInstrumentationAgent INFO JMX connector thread started on service:jmx:rmi:///jndi/rmi://claus-acer:1099/jmxrmi/camel ...

134

56 50 3* " - 4

*O UIF TDSFFOTIPU CFMPX XF DBO TFF UIF SPVUF BOE JUT QFSGPSNBODF NFUSJDT:

2$$

+2.
` 4QSJOH 3FNPUJOH XJUI +.4 &YBNQMF PO "NJO "CCBTQPVS'T 8FCMPH

343.1( + - " ,$+-$7 ,/+$-1$/.13(-"(#$-3 (-31.#4"3(.$SFBUJOH UIJT UVUPSJBM XBT JOTQJSFE CZ B SFBM MJGF VTF-DBTF * EJTDVTTFE PWFS UIF QIPOF XJUI B DPMMFBHVF. )F XBT XPSLJOH BU B DMJFOU XIPN VTFT B IFBWZ-XFJHIU JOUFHSBUJPO QMBUGPSN GSPN B WFSZ MBSHF WFOEPS. )F XBT JO UBMLT XJUI EFWFMPQFS TIPQT UP JNQMFNFOU B OFX JOUFHSBUJPO PO UIJT QMBUGPSN. )JT USPVCMF XBT UIF TIPQ USJQMFE UIF QSJDF XIFO UIFZ SFBMJ[FE UIF QMBUGPSN PG DIPJDF. 4P * XBT XPOEFSJOH IPX XF DPVME EP UIJT JOUFHSBUJPO XJUI $BNFM. $BO JU CF EPOF, XJUIPVU USJQMJOH UIF DPTU . 5IJT UVUPSJBM JT XSJUUFO EVSJOH UIF EFWFMPQNFOU PG UIF JOUFHSBUJPO. * IBWF EFDJEFE UP TUBSU PGG XJUI B TBNQMF UIBU JTO'U $BNFM'T CVU TUBOEBSE +BWB BOE UIFO QMVHJO $BNFM BT XF HPFT. +VTU BT XIFO QFPQMF OFFEFE UP MFBSO 4QSJOH ZPV DPVME DPOTVNF JU QJFDF CZ QJFDF, UIF TBNF HPFT XJUI $BNFM. 5IF UBSHFU SFBEFS JT QFSTPO XIPN IBTO'U FYQFSJFODF PS KVTU TUBSUFE VTJOH $BNFM.

,.3(5 3(.- %.1 3'(2 343.1( +


* XSPUF UIJT UVUPSJBM NPUJWBUFE BT $BNFM MBDLFE BO FYBNQMF BQQMJDBUJPO UIBU XBT CBTFE PO UIF XFC BQQMJDBUJPO EFQMPZNFOU NPEFM. 5IF FOUJSF XPSME IBTO'U NPWFE UP QVSF 04(J EFQMPZNFOUT ZFU.

3'$ 42$-" 2$
5IF HPBM JT UP BMMPX TUBGG UP SFQPSU JODJEFOUT JOUP B DFOUSBM BENJOJTUSBUJPO. 'PS UIBU UIFZ VTF DMJFOU TPGUXBSF XIFSF UIFZ SFQPSU UIF JODJEFOU BOE TVCNJU JU UP UIF DFOUSBM BENJOJTUSBUJPO. "T UIJT JT BO JOUFHSBUJPO JO B USBOTJUJPO QIBTF UIF BENJOJTUSBUJPO TIPVME HFU UIFTF JODJEFOUT CZ FNBJM XIFSFBT UIFZ BSF NBOVBMMZ BEEFE UP UIF EBUBCBTF. 5IF DMJFOU TPGUXBSF TIPVME HBUIFS UIF JODJEFOU BOE TVCNJU UIF JOGPSNBUJPO UP UIF JOUFHSBUJPO QMBUGPSN UIBU JO UFSN XJMM USBOTGPSN UIF SFQPSU JOUP BO FNBJM BOE TFOE JU UP UIF DFOUSBM BENJOJTUSBUPS GPS NBOVBM QSPDFTTJOH. 5IF GJHVSF CFMPX JMMVTUSBUFT UIJT QSPDFTT. 5IF FOE VTFST SFQPSUT UIF JODJEFOUT VTJOH UIF DMJFOU BQQMJDBUJPOT. 5IF JODJEFOU JT TFOU UP UIF DFOUSBM JOUFHSBUJPO QMBUGPSN BT XFCTFSWJDF. 5IF

5 65 0 3 *"-4

135

5IF GVMM TPVSDF DPEF GPS UIJT UVUPSJBM BT DPNQMFUF JT QBSU PG UIF "QBDIF $BNFM EJTUSJCVUJPO JO UIF examples/camel-example-reportincident EJSFDUPSZ JOUFHSBUJPO QMBUGPSN XJMM QSPDFTT UIF JODJEFOU BOE TFOE BO 0, BDLOPXMFEHNFOU CBDL UP UIF DMJFOU. 5IFO UIF JOUFHSBUJPO XJMM USBOTGPSN UIF NFTTBHF UP BO FNBJM BOE TFOE JU UP UIF BENJOJTUSBUJPO NBJM TFSWFS. 5IF VTFST JO UIF BENJOJTUSBUJPO XJMM SFDFJWF UIF FNBJMT BOE UBLF JU GSPN UIFSF.

(K $(/ M>QQBOKP 8F EJTUJMM UIF VTF DBTF BT &*1 QBUUFSOT:

/ 132
5IJT UVUPSJBM JT EJWJEFE JOUP TFDUJPOT BOE QBSUT: 2B@QFLK : $UFPQFKD 2LIRQFLK, ELT QL PILTIV RPB ">JBI 1BSU 1 - 5IJT GJSTU QBSU FYQMBJO IPX UP TFUVQ UIF QSPKFDU BOE HFU B XFCTFSWJDF FYQPTFE VTJOH "QBDIF $9'. *O GBDU XF EPO'U UPVDI $BNFM ZFU. 1BSU 2 - /PX XF BSF SFBEZ UP JOUSPEVDF $BNFM QJFDF CZ QJFDF (XJUIPVU VTJOH 4QSJOH PS BOZ 9.- DPOGJHVSBUJPO GJMF) BOE DSFBUF UIF GVMM GFBUVSF JOUFHSBUJPO. 5IJT QBSU XJMM JOUSPEVDF EJGGFSFOU $BNFM'T DPODFQUT BOE )PX XF DBO CVJME PVS TPMVUJPO VTJOH UIFN MJLF : $BNFM$POUFYU &OEQPJOU, &YDIBOHF & 1SPEVDFS $PNQPOFOUT : -PH, 'JMF 1BSU 3 - $POUJOVFE GSPN QBSU 2 XIFSF XF JNQMFNFOU UIBU MBTU QBSU PG UIF TPMVUJPO XJUI UIF FWFOU ESJWFO DPOTVNFS BOE IPX UP TFOE UIF FNBJM UISPVHI UIF .BJM DPNQPOFOU. 2B@QFLK !: 3EB ">JBI 2LIRQFLK 1BSU 4 - 8F OPX UVSO JOUP UIF QBUI PG $BNFM XIFSF JU FYDFMT - UIF SPVUJOH. 1BSU 5 - *T BCPVU IPX FNCFE $BNFM XJUI 4QSJOH BOE VTJOH $9' FOEQPJOUT EJSFDUMZ JO $BNFM 1BSU 6 - 4IPXJOH B BMUFSOBUJWF TPMVUJPO QSJNBSJMZ VTJOH 9.- JOTUFBE PG +BWB DPEF

+(-*2
*OUSPEVDUJPO 1BSU 1 1BSU 2 1BSU 3

136

56 50 3* " - 4

4PFKD UFP 2 4FF UIJT CMPH FOUSZ CZ 4BHBSB EFNPOTUSBUJOH IPX UP VTF "QBDIF "YJT 2 JOTUFBE PG "QBDIF $9' BT UIF XFC TFSWJDF GSBNFXPSL. 1BSU 4 1BSU 5 1BSU 6

/ 13 1 /1$1$04(2(3$2
5IJT UVUPSJBM VTFT UIF GPMMPXJOH GSBNFXPSLT: ` .BWFO 3.0.4 ` "QBDIF $BNFM 2.10.0 ` "QBDIF $9' 2.6.1 ` 4QSJOH 3.0.7 -LQB: 5IF TBNQMF QSPKFDU DBO CF EPXOMPBEFE, TFF UIF SFTPVSDFT TFDUJPO.

(-(3( + /1.)$"3 2$34/


8F XBOU UIF JOUFHSBUJPO UP CF B TUBOEBSE .XBS BQQMJDBUJPO UIBU DBO CF EFQMPZFE JO BOZ XFC DPOUBJOFS TVDI BT 5PNDBU, +FUUZ PS FWFO IFBWZ XFJHIU BQQMJDBUJPO TFSWFST TVDI BT 8FC-PHJD PS 8FC4QIFSF. 5IFSF GPSF XF TUBSU PGG XJUI UIF TUBOEBSE .BWFO XFCBQQ QSPKFDU UIBU JT DSFBUFE XJUI UIF GPMMPXJOH MPOH BSDIFUZQF DPNNBOE:
mvn archetype:create -DgroupId=org.apache.camel -DartifactId=camel-example-reportincident -DarchetypeArtifactId=maven-archetype-webapp

/PUJDF UIBU UIF HSPVQ*E FUD. EPFOT'U IBWF UP CF PSH.BQBDIF.DBNFM JU DBO CF DPN.NZDPNQBOZ.XIBUFWFS. #VU * IBWF VTFE UIFTF QBDLBHF OBNFT BT UIF FYBNQMF JT BO PGGJDJBM QBSU PG UIF $BNFM EJTUSJCVUJPO. 5IFO XF IBWF UIF CBTJD NBWFO GPMEFS MBZPVU. 8F TUBSU PVU XJUI UIF XFCTFSWJDF QBSU XIFSF XF XBOU UP VTF "QBDIF $9' GPS UIF XFCTFSWJDF TUVGG. 4P XF BEE UIJT UP UIF QPN.YNM
<properties> <cxf-version>2.6.1</cxf-version> </properties>

5 65 0 3 *"-4

137

<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-core</artifactId> <version>${cxf-version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf-version}</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf-version}</version> </dependency>

#$5$+./(-& 3'$ 6$!2$15("$


"T XF XBOU UP EFWFMPQ XFCTFSWJDF XJUI UIF DPOUSBDU GJSTU BQQSPBDI XF DSFBUF PVS .XTEM GJMF. "T UIJT JT B FYBNQMF XF IBWF TJNQMJGJFE UIF NPEFM PG UIF JODJEFOU UP POMZ JODMVEF 8 GJFMET. *O SFBM MJGF UIF NPEFM XPVME CF B CJU NPSF DPNQMFY, CVU OPU UP NVDI. 8F QVU UIF XTEM GJMF JO UIF GPMEFS src/main/webapp/WEB-INF/wsdl BOE OBNF UIF GJMF report_incident.wsdl.
<?xml version="1.0" encoding="ISO-8859-1"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://reportincident.example.camel.apache.org" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://reportincident.example.camel.apache.org"> <!-- Type definitions for input- and output parameters for webservice --> <wsdl:types> <xs:schema targetNamespace="http://reportincident.example.camel.apache.org"> <xs:element name="inputReportIncident"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="incidentId"/> <xs:element type="xs:string" name="incidentDate"/> <xs:element type="xs:string" name="givenName"/> <xs:element type="xs:string" name="familyName"/> <xs:element type="xs:string" name="summary"/> <xs:element type="xs:string"

138

56 50 3* " - 4

name="details"/> <xs:element type="xs:string" name="email"/> <xs:element type="xs:string" name="phone"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="outputReportIncident"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="code"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> <!-- Message definitions for input and output --> <wsdl:message name="inputReportIncident"> <wsdl:part name="parameters" element="tns:inputReportIncident"/> </wsdl:message> <wsdl:message name="outputReportIncident"> <wsdl:part name="parameters" element="tns:outputReportIncident"/> </wsdl:message> <!-- Port (interface) definitions --> <wsdl:portType name="ReportIncidentEndpoint"> <wsdl:operation name="ReportIncident"> <wsdl:input message="tns:inputReportIncident"/> <wsdl:output message="tns:outputReportIncident"/> </wsdl:operation> </wsdl:portType> <!-- Port bindings to transports and encoding - HTTP, document literal encoding is used --> <wsdl:binding name="ReportIncidentBinding" type="tns:ReportIncidentEndpoint"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="ReportIncident"> <soap:operation soapAction="http://reportincident.example.camel.apache.org/ReportIncident" style="document"/> <wsdl:input> <soap:body parts="parameters" use="literal"/> </wsdl:input> <wsdl:output> <soap:body parts="parameters" use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <!-- Service definition -->

5 65 0 3 *"-4

139

<wsdl:service name="ReportIncidentService"> <wsdl:port name="ReportIncidentPort" binding="tns:ReportIncidentBinding"> <soap:address location="http://reportincident.example.camel.apache.org"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

"7% TPAI2G>S> 5IFO XF JOUFHSBUJPO UIF $9' XTEM2KBWB HFOFSBUPS JO UIF QPN.YNM TP XF IBWF $9' HFOFSBUF UIF OFFEFE 10+0 DMBTTFT GPS PVS XFCTFSWJDF DPOUSBDU. )PXFWFS BU GJSTU XF NVTU DPOGJHVSF NBWFO UP MJWF JO UIF NPEFSO XPSME PG +BWB 1.6 TP XF NVTU BEE UIJT UP UIF QPN.YNM
<!-- to compile with 1.6 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin>

"OE UIFO XF DBO BEE UIF $9' XTEM2KBWB DPEF HFOFSBUPS UIBU XJMM IPPL JOUP UIF DPNQJMF HPBM TP JUT BVUPNBUJD SVO BMM UIF UJNF:
<!-- CXF wsdl2java generator, will plugin to the compile goal --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>${cxf-version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <sourceRoot>${basedir}/target/ generated/src/main/java</sourceRoot> <wsdlOptions> <wsdlOption> <wsdl>${basedir}/src/main/webapp/WEB-INF/wsdl/report_incident.wsdl</wsdl> </wsdlOption> </wsdlOptions>

140

56 50 3* " - 4

</configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin>

:PV BSF OPX TFUVQ BOE TIPVME CF BCMF UP DPNQJMF UIF QSPKFDU. 4P SVOOJOH UIF mvn compile TIPVME SVO UIF $9' XTEM2KBWB BOE HFOFSBUF UIF TPVSDF DPEF JO UIF GPMEFS &{basedir}/target/generated/src/main/java UIBU XF TQFDJGJFE JO UIF QPN.YNM BCPWF. 4JODF JUT JO UIF target/generated/src/main/java NBWFO XJMM QJDL JU VQ BOE JODMVEF JU JO UIF CVJME QSPDFTT. "LKCFDRO>QFLK LC QEB TB?.UJI /FYU VQ JT UP DPOGJHVSF UIF XFC.YNM UP CF SFBEZ UP VTF $9' TP XF DBO FYQPTF UIF XFCTFSWJDF. "T 4QSJOH JT UIF DFOUFS PG UIF VOJWFSTF, PS BU MFBTU JT B WFSZ JNQPSUBOU GSBNFXPSL JO UPEBZ'T +BWB MBOE XF TUBSU XJUI UIF MJTUFOFS UIBU LJDL-TUBSUT 4QSJOH. 5IJT JT UIF VTVBM QJFDF PG DPEF:
<!-- the listener that kick-starts Spring --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>

"OE UIFO XF IBWF UIF $9' QBSU XIFSF XF EFGJOF UIF $9' TFSWMFU BOE JUT 63* NBQQJOHT UP XIJDI XF IBWF DIPTFO UIBU BMM PVS XFCTFSWJDFT TIPVME CF JO UIF QBUI /webservices/
<!-- CXF servlet --> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- all our webservices are mapped under this URI pattern --> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/webservices/*</url-pattern> </servlet-mapping>

5IFO UIF MBTU QJFDF PG UIF QV[[MF JT UP DPOGJHVSF $9', UIJT JT EPOF JO B TQSJOH 9.- UIBU XF MJOL UP GSPO UIF XFC.YNM CZ UIF TUBOEBSE 4QSJOH contextConfigLocation QSPQFSUZ JO UIF XFC.YNM

5 65 0 3 *"-4

141

<!-- location of spring xml files --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:cxf-config.xml</param-value> </context-param>

8F IBWF OBNFE PVS $9' DPOGJHVSBUJPO GJMF cxf-config.xml BOE JUT MPDBUFE JO UIF SPPU PG UIF DMBTTQBUI. *O .BWFO MBOE UIBU JT XF DBO IBWF UIF cxf-config.xml GJMF JO UIF src/ main/resources GPMEFS. 8F DPVME BMTP IBWF UIF GJMF MPDBUFE JO UIF 8&#-*/' GPMEFS GPS JOTUBODF <param-value>/WEB-INF/cxf-config.xml</param-value>. &BQQFKD OFA LC QEB LIA GPM TLOIA 5IF NBWFO BSDIFUZQF UIBU DSFBUFE UIF CBTJD GPMEFS TUSVDUVSF BMTP DSFBUFE B TBNQMF .KTQ GJMF JOEFY.KTQ. 5IJT GJMF src/main/webapp/index.jsp TIPVME CF EFMFUFE. "LKCFDRO>QFLK LC "7% 5IF DYG-DPOGJH.YNM JT BT GPMMPXT:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <!-- implementation of the webservice --> <bean id="reportIncidentEndpoint" class="org.apache.camel.example.reportincident.ReportIncidentEndpointImpl"/> <!-- export the webservice using jaxws --> <jaxws:endpoint id="reportIncident" implementor="#reportIncidentEndpoint" address="/incident" wsdlLocation="/WEB-INF/wsdl/report_incident.wsdl" endpointName="s:ReportIncidentPort" serviceName="s:ReportIncidentService" xmlns:s="http://reportincident.example.camel.apache.org"/> </beans>

5IF DPOGJHVSBUJPO JT TUBOEBSE $9' BOE JT EPDVNFOUFE BU UIF "QBDIF $9' XFCTJUF. 5IF 3 JNQPSU FMFNFOUT JT OFFEFE CZ $9' BOE UIFZ NVTU CF JO UIF GJMF.
142 56 50 3* " - 4

/PUJDFE UIBU XF IBWF B TQSJOH CFBO OBMLOQ(K@FABKQ$KAMLFKQ UIBU JT UIF JNQMFNFOUBUJPO PG UIF XFCTFSWJDF FOEQPJOU XF MFU $9' FYQPTF. *UT MJOLFE GSPN UIF KBYXT FMFNFOU XJUI UIF JNQMFNFOUBUPS BUUSJCVUF BT XF VTF UIF # NBSL UP JEFOUJGZ JUT B SFGFSFODF UP B TQSJOH CFBO. 8F DPVME IBWF TUBUFE UIF DMBTTOBNF EJSFDUMZ BT implementor="org.apache.camel.example.reportincident.ReportIncidentEndpoint CVU UIFO XF MPTF UIF BCJMJUZ UP MFU UIF 3FQPSU*ODJEFOU&OEQPJOU CF DPOGJHVSFE CZ TQSJOH. 5IF >AAOBPP BUUSJCVUF EFGJOFT UIF SFMBUJWF QBSU PG UIF 63- PG UIF FYQPTFE XFCTFSWJDF. TPAI+L@>QFLK JT BO PQUJPOBM QBSBNFUFS CVU GPS QFSTPOT MJLF NF UIBU MJLFT DPOUSBDU-GJSTU XF XBOU UP FYQPTF PVS PXO .XTEM DPOUSBDUT BOE OPU UIF BVUP HFOFSBUFE CZ UIF GSBNFXPSLT, TP XJUI UIJT BUUSJCVUF XF DBO MJOL UP UIF SFBM .XTEM GJMF. 5IF MBTU TUVGG JT OFFEFE CZ $9' BT ZPV DPVME IBWF TFWFSBM TFSWJDFT TP JU OFFET UP LOPX XIJDI UIJT POF JT. $POGJHVSJOH UIFTF JT RVJUF FBTZ BT BMM UIF JOGPSNBUJPO JT JO UIF XTEM BMSFBEZ. (JMIBJBKQFKD QEB 1BMLOQ(K@FABKQ$KAMLFKQ 1IFX BGUFS BMM UIFTF NFUB GJMFT JUT UJNF GPS TPNF KBWB DPEF TP XF TIPVME DPEF UIF JNQMFNFOUPS PG UIF XFCTFSWJDF. 4P XF GJSF VQ mvn compile UP MFU $9' HFOFSBUF UIF 10+0 DMBTTFT GPS PVS XFCTFSWJDF BOE XF BSF SFBEZ UP GJSF VQ B +BWB FEJUPS. :PV DBO VTF mvn idea:idea PS mvn eclipse:eclipse UP DSFBUF QSPKFDU GJMFT GPS UIFTF FEJUPST TP ZPV DBO MPBE UIF QSPKFDU. )PXFWFS *%&" IBT CFFO TNBSUFS MBUFMZ BOE DBO MPBE B QPN.YNM EJSFDUMZ. "T XF XBOU UP RVJDLMZ TFF PVS XFCTFSWJDF XF JNQMFNFOU KVTU B RVJDL BOE EJSUZ BT JU DBO HFU. "U GJSTU CFXBSF UIBU TJODF JUT KBYXT BOE +BWB 1.5 XF HFU BOOPUBUJPOT GPS UIF NPOFZ, CVU UIFZ SFTJEF PO UIF JOUFSGBDF TP XF DBO SFNPWF UIFN GSPN PVS JNQMFNFOUBUJPOT TP JUT B OJDF QMBJO 10+0 BHBJO:
package org.apache.camel.example.reportincident; /** * The webservice we have implemented. */ public class ReportIncidentEndpointImpl implements ReportIncidentEndpoint { public OutputReportIncident reportIncident(InputReportIncident parameters) { System.out.println("Hello ReportIncidentEndpointImpl is called from " + parameters.getGivenName()); OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; } }

8F KVTU PVUQVU UIF QFSTPO UIBU JOWPLFT UIJT XFCTFSWJDF BOE SFUVSOT B 0, SFTQPOTF. 5IJT DMBTT TIPVME CF JO UIF NBWFO TPVSDF SPPU GPMEFS src/main/java VOEFS UIF QBDLBHF OBNF

5 65 0 3 *"-4

143

org.apache.camel.example.reportincident. #FXBSF UIBU UIF NBWFO BSDIFUZQF UPPM EJEO'U DSFBUF UIF src/main/java folder, TP ZPV TIPVME DSFBUF JU NBOVBMMZ. 5P UFTU JG XF BSF IPNF GSFF XF SVO mvn clean compile. 1RKKFKD LRO TB?PBOSF@B /PX UIBU UIF DPEF DPNQJMFT XF XPVME MJLF UP SVO JU JOTJEF B XFC DPOUBJOFS, GPS UIJT QVSQPTF XF NBLF VTF PG +FUUZ XIJDI XF XJMM CPPUTUSBQ VTJOH JU'T QMVHJO org.mortbay.jetty:maven-jetty-plugin:
<build> <plugins> ... <!-- so we can run mvn jetty:run --> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <version>${jetty-version}</version> </plugin>

-LQF@B: 8F NBLF VTF PG UIF +FUUZ WFSTJPO CFJOH EFGJOFE JOTJEF UIF $BNFM'T 1BSFOU 10.. 4P UP TFF JG FWFSZUIJOH JT JO PSEFS XF GJSF VQ KFUUZ XJUI mvn jetty:run BOE JG FWFSZUIJOH JT PLBZ ZPV TIPVME CF BCMF UP BDDFTT http://localhost:8080. +FUUZ JT TNBSU UIBU JU XJMM MJTU UIF DPSSFDU 63* PO UIF QBHF UP PVS XFC BQQMJDBUJPO, TP KVTU DMJDL PO UIF MJOL. 5IJT JT TNBSU BT ZPV EPO'U IBWF UP SFNFNCFS UIF FYBDU XFC DPOUFYU 63* GPS ZPVS BQQMJDBUJPO - KVTU GJSF VQ UIF EFGBVMU QBHF BOE +FUUZ XJMM IFMQ ZPV. 4P XIFSF JT UIF EBNO XFCTFSWJDF UIFO 8FMM BT XF EJE DPOGJHVSF UIF XFC.YNM UP JOTUSVDU UIF $9' TFSWMFU UP BDDFQU UIF QBUUFSO /webservices/* XF TIPVME IJU UIJT 63- UP HFU UIF BUUFOUJPO PG $9': http://localhost:8080/camel-example-reportincident/ webservices. c 'FQQFKD QEB TB?PBOSF@B /PX XF IBWF UIF XFCTFSWJDF SVOOJOH JO B TUBOEBSE .XBS BQQMJDBUJPO JO B TUBOEBSE XFC DPOUBJOFS TVDI BT +FUUZ XF XPVME MJLF UP JOWPLF UIF XFCTFSWJDF BOE TFF JG XF HFU PVS DPEF FYFDVUFE. 6OGPSUVOBUFMZ UIJT JTO'U UIF FBTJFTU UBTL JO UIF XPSME - JUT OPU TP FBTZ BT B 3&45 63-, TP XF OFFE UPPMT GPS UIJT. 4P XF GJSF VQ PVS USVTUZ XFCTFSWJDF UPPM 4PBQ6* BOE MFU JU CF UIF POF UP GJSF UIF XFCTFSWJDF SFRVFTU BOE TFF UIF SFTQPOTF. 6TJOH 4PBQ6* XF TFOU B SFRVFTU UP PVS XFCTFSWJDF BOE XF HPU UIF FYQFDUFE 0, SFTQPOTF BOE UIF DPOTPMF PVUQVUT UIF 4ZTUFN.PVU TP XF BSF SFBEZ UP DPEF. c

144

56 50 3* " - 4

1BJLQB #B?RDDFKD 0LBZ B MJUUMF TJEFTUFQ CVU XPVMEO'U JU CF DPPM UP CF BCMF UP EFCVH ZPVS DPEF XIFO JUT GJSFE VQ VOEFS +FUUZ "T +FUUZ JT TUBSUFE GSPN NBWFO, XF OFFE UP JOTUSVDU NBWFO UP VTF EFCVH NPEF. 4F XF TFU UIF MAVEN_OPTS FOWJSPONFOU UP TUBSU JO EFCVH NPEF BOE MJTUFO PO QPSU 5005.
MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

5IFO ZPV OFFE UP SFTUBSU +FUUZ TP JUT TUPQQFE XJUI @QOI + @. 3FNFNCFS UP TUBSU B OFX TIFMM UP QJDLVQ UIF OFX FOWJSPONFOU TFUUJOHT. "OE TUBSU KFUUZ BHBJO. 5IFO XF DBO GSPN PVS *%& BUUBDI B SFNPUF EFCVHHFS BOE EFCVH BT XF XBOU. 'JSTU XF DPOGJHVSF *%&" UP BUUBDI UP B SFNPUF EFCVHHFS PO QPSU 5005: c 5IFO XF TFU B CSFBLQPJOU JO PVS DPEF ReportIncidentEndpoint BOE IJU UIF 4PBQ6* PODF BHBJO BOE XF BSF CSFBLFE BU UIF CSFBLQPJOU XIFSF XF DBO JOTQFDU UIF QBSBNFUFST: c AAFKD > RKFQ QBPQ 0I TP NVDI IBSE XPSL KVTU UP IJU B XFCTFSWJDF, XIZ DBO'U XF KVTU VTF BO VOJU UFTU UP JOWPLF PVS XFCTFSWJDF :FT PG DPVSTF XF DBO EP UIJT, BOE UIBU'T UIF OFYU TUFQ. 'JSTU XF DSFBUF UIF GPMEFS TUSVDUVSF src/test/java BOE src/test/resources. 8F UIFO DSFBUF UIF VOJU UFTU JO UIF src/test/java GPMEFS.
package org.apache.camel.example.reportincident; import junit.framework.TestCase; /** * Plain JUnit test of our webservice. */ public class ReportIncidentEndpointTest extends TestCase { }

)FSF XF IBWF B QMBJO PME +6OJU DMBTT. "T XF XBOU UP UFTU XFCTFSWJDFT XF OFFE UP TUBSU BOE FYQPTF PVS XFCTFSWJDF JO UIF VOJU UFTU CFGPSF XF DBO UFTU JU. "OE +"984 IBT QSFUUZ EFDFOU NFUIPET UP IFMQ VT IFSF, UIF DPEF JT TJNQMF BT:
import javax.xml.ws.Endpoint; ...

5 65 0 3 *"-4

145

private static String ADDRESS = "http://localhost:9090/unittest"; protected void startServer() throws Exception { // We need to start a server that exposes or webservice during the unit testing // We use jaxws to do this pretty simple ReportIncidentEndpointImpl server = new ReportIncidentEndpointImpl(); Endpoint.publish(ADDRESS, server); }

5IF &OEQPJOU DMBTT JT UIF javax.xml.ws.Endpoint UIBU VOEFS UIF DPWFST MPPLT GPS B QSPWJEFS BOE JO PVS DBTF JUT $9' - TP JUT $9' UIBU EPFT UIF IFBWZ MJGUJOH PG FYQPTJOH PVU XFCTFSWJDF PO UIF HJWFO 63- BEESFTT. 4JODF PVS DMBTT 3FQPSU*ODJEFOU&OEQPJOU*NQM JNQMFNFOUT UIF JOUFSGBDF 1BMLOQ(K@FABKQ$KAMLFKQ UIBU JT EFDPSBUFE XJUI BMM UIF KBYXT BOOPUBUJPOT JU HPU BMM UIF JOGPSNBUJPO JU OFFE UP FYQPTF UIF XFCTFSWJDF. #FMPX JT UIF $9' XTEM2KBWB HFOFSBUFE JOUFSGBDF:

/* * */ package org.apache.camel.example.reportincident; import import import import import import import javax.jws.WebMethod; javax.jws.WebParam; javax.jws.WebResult; javax.jws.WebService; javax.jws.soap.SOAPBinding; javax.jws.soap.SOAPBinding.ParameterStyle; javax.xml.bind.annotation.XmlSeeAlso;

/** * This class was generated by Apache CXF 2.1.1 * Wed Jul 16 12:40:31 CEST 2008 * Generated source version: 2.1.1 * */ /* * */

@WebService(targetNamespace = "http://reportincident.example.camel.apache.org", name = "ReportIncidentEndpoint") @XmlSeeAlso({ObjectFactory.class}) @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) public interface ReportIncidentEndpoint { /*

146

56 50 3* " - 4

* */ @SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) @WebResult(name = "outputReportIncident", targetNamespace = "http://reportincident.example.camel.apache.org", partName = "parameters") @WebMethod(operationName = "ReportIncident", action = "http://reportincident.example.camel.apache.org/ReportIncident") public OutputReportIncident reportIncident( @WebParam(partName = "parameters", name = "inputReportIncident", targetNamespace = "http://reportincident.example.camel.apache.org") InputReportIncident parameters ); }

/FYU VQ JT UP DSFBUF B XFCTFSWJDF DMJFOU TP XF DBO JOWPLF PVS XFCTFSWJDF. 'PS UIJT XF BDUVBMMZ VTF UIF $9' GSBNFXPSL EJSFDUMZ BT JUT B CJU NPSF FBTJFS UP DSFBUF B DMJFOU VTJOH UIJT GSBNFXPSL UIBO VTJOH UIF +"984 TUZMF. 8F DPVME IBWF EPOF UIF TBNF GPS UIF TFSWFS QBSU, BOE ZPV TIPVME EP UIJT JG ZPV OFFE NPSF QPXFS BOE BDDFTT NPSF BEWBODFE GFBUVSFT.
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; ... protected ReportIncidentEndpoint createCXFClient() { // we use CXF to create a client for us as its easier than JAXWS and works JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); factory.setServiceClass(ReportIncidentEndpoint.class); factory.setAddress(ADDRESS); return (ReportIncidentEndpoint) factory.create(); }

4P OPX XF BSF SFBEZ GPS DSFBUJOH B VOJU UFTU. 8F IBWF UIF TFSWFS BOE UIF DMJFOU. 4P XF KVTU DSFBUF B QMBJO TJNQMF VOJU UFTU NFUIPE BT UIF VTVBM KVOJU TUZMF:
public void testRendportIncident() throws Exception { startServer(); ReportIncidentEndpoint client = createCXFClient(); InputReportIncident input = new InputReportIncident(); input.setIncidentId("123"); input.setIncidentDate("2008-07-16"); input.setGivenName("Claus"); input.setFamilyName("Ibsen"); input.setSummary("bla bla"); input.setDetails("more bla bla"); input.setEmail("davsclaus@apache.org"); input.setPhone("+45 2962 7576"); OutputReportIncident out = client.reportIncident(input);

5 65 0 3 *"-4

147

assertEquals("Response code is wrong", "OK", out.getCode()); }

/PX XF BSF OFBSMZ UIFSF. #VU JG ZPV SVO UIF VOJU UFTU XJUI mvn test UIFO JU XJMM GBJM. 8IZ!!! 8FMM JUT CFDBVTF UIBU $9' OFFET JT NJTTJOH TPNF EFQFOEFODJFT EVSJOH VOJU UFTUJOH. *O GBDU JU OFFET UIF XFC DPOUBJOFS, TP XF OFFE UP BEE UIJT UP PVS MLJ.UJI.
<!-- cxf web container for unit testing --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>${cxf-version}</version> <scope>test</scope> </dependency>

8FMM XIBU JT UIBU, $9' BMTP VTFT +FUUZ GPS VOJU UFTU - XFMM JUT KVTU TIPXT IPX BHJMF, FNCFEBCMF BOE QPQVMBS +FUUZ JT. 4P MFUT SVO PVS KVOJU UFTU XJUI, BOE JU SFQPSUT:
mvn test Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 [INFO] BUILD SUCCESSFUL

:FQ UIBUT JU GPS OPX. 8F IBWF B CBTJD QSPKFDU TFUVQ.

$-# .% / 13 1
5IBOLT GPS CFJOH QBUJFOU BOE SFBEJOH BMM UIJT NPSF PS MFTT TUBOEBSE .BWFO, 4QSJOH, +"984 BOE "QBDIF $9' TUVGG. *UT TUVGG UIBU JT XFMM DPWFSFE PO UIF OFU, CVU * XBOUFE B GVMM GMFEHFE UVUPSJBM PO B NBWFO QSPKFDU TFUVQ UIBU JT XFC TFSWJDF SFBEZ XJUI "QBDIF $9'. 8F XJMM VTF UIJT BT B CBTF GPS UIF OFYU QBSU XIFSF XF EFNPOTUSBUF IPX $BNFM DBO CF EJHFTUFE TMPXMZ BOE QJFDF CZ QJFDF KVTU BT JU XBT CBDL JO UIF UJNFT XIFO XBT JOUSPEVDFE BOE XBT MFBSOJOH UIF 4QSJOH GSBNFXPSL UIBU XF UBLF GPS HSBOUFE UPEBZ.

1$2.41"$2
` "QBDIF $9' VTFS HVJEF

+(-*2
*OUSPEVDUJPO 1BSU 1

148

56 50 3* " - 4

1BSU 2 1BSU 3 1BSU 4 1BSU 5 1BSU 6

/ 13 2 ##(-& " ,$+


*O UIJT QBSU XF XJMM JOUSPEVDF $BNFM TP XF TUBSU CZ BEEJOH $BNFM UP PVS QPN.YNM:
<properties> ... <camel-version>1.4.0</camel-version> </properties> <!-- camel --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel-version}</version> </dependency>

5IBU'T JU, POMZ LKB EFQFOEFODZ GPS OPX. /PX XF UVSO UPXBSET PVS XFCTFSWJDF FOEQPJOU JNQMFNFOUBUJPO XIFSF XF XBOU UP MFU $BNFM IBWF B HP BU UIF JOQVU XF SFDFJWF. "T $BNFM JT WFSZ OPO JOWBTJWF JUT CBTJDBMMZ B .KBS GJMF UIFO XF DBO KVTU HSBQ $BNFM CVU DSFBUJOH B OFX JOTUBODF PG DefaultCamelContext UIBU JT UIF IFBSUI PG $BNFM JUT DPOUFYU.
CamelContext camel = new DefaultCamelContext();

*O GBDU XF DSFBUF B DPOTUSVDUPS JO PVS XFCTFSWJDF BOE BEE UIJT DPEF:


private CamelContext camel; public ReportIncidentEndpointImpl() throws Exception { // create the camel context that is the "heart" of Camel camel = new DefaultCamelContext(); // add the log component camel.addComponent("log", new LogComponent()); // start Camel

5 65 0 3 *"-4

149

2VK@EOLKFWB (#$ *G ZPV DPOUJOVF GSPN QBSU 1, SFNFNCFS UP VQEBUF ZPVS FEJUPS QSPKFDU TFUUJOHT TJODF XF IBWF JOUSPEVDF OFX .KBS GJMFT. 'PS JOTUBODF *%&" IBT B GFBUVSF UP TZODISPOJ[F XJUI .BWFO QSPKFDUT.

camel.start(); }

+.&&(-& 3'$ "'$++. 6.1+#"


)FSF BU GJSTU XF XBOU $BNFM UP MPH UIF DFSBK->JB BOE C>JFIV->JB QBSBNFUFST XF SFDFJWF, TP XF BEE UIF LogComponent XJUI UIF LFZ ILD. "OE XF NVTU PQ>OQ $BNFM CFGPSF JUT SFBEZ UP BDU. 5IFO XF DIBOHF UIF DPEF JO UIF NFUIPE UIBU JT JOWPLFE CZ "QBDIF $9' XIFO B XFCTFSWJDF SFRVFTU BSSJWFT. 8F HFU UIF OBNF BOE MFU $BNFM IBWF B HP BU JU JO UIF OFX NFUIPE XF DSFBUF PBKA3L">JBI:
public OutputReportIncident reportIncident(InputReportIncident parameters) { String name = parameters.getGivenName() + " " + parameters.getFamilyName(); // let Camel do something with the name sendToCamelLog(name); OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; }

/FYU JT UIF $BNFM DPEF. "U GJSTU JU MPPLT MJLF UIFSF BSF NBOZ DPEF MJOFT UP EP B TJNQMF UBTL PG MPHHJOH UIF OBNF - ZFT JU JT. #VU MBUFS ZPV XJMM JO GBDU SFBMJ[F UIJT JT POF PG $BNFMT USVF QPXFS. *UT DPODJTF "1*. )JOU: 5IF TBNF DPEF DBO CF VTFE GPS >KV DPNQPOFOU JO $BNFM.
private void sendToCamelLog(String name) { try { // get the log component Component component = camel.getComponent("log"); // // // // default Endpoint endpoint = component.createEndpoint("log:com.mycompany.part2"); create an endpoint and configure it. Notice the URI parameters this is a common pratice in Camel to configure endpoints based on URI. com.mycompany.part2 = the log category used. Will log at INFO level as

150

56 50 3* " - 4

"LJMLKBKQ #L@RJBKQ>QFLK 5IF -PH BOE 'JMF DPNQPOFOUT JT EPDVNFOUFE BT XFMM, KVTU DMJDL PO UIF MJOLT. +VTU SFUVSO UP UIJT EPDVNFOUBUJPO MBUFS XIFO ZPV NVTU VTF UIFTF DPNQPOFOUT GPS SFBM.

// create an Exchange that we want to send to the endpoint Exchange exchange = endpoint.createExchange(); // set the in message payload (=body) with the name parameter exchange.getIn().setBody(name); // now we want to send the exchange to this endpoint and we then need a producer // for this, so we create and start the producer. Producer producer = endpoint.createProducer(); producer.start(); // process the exchange will send the exchange to the log component, that will process // the exchange and yes log the payload producer.process(exchange); // stop the producer, we want to be nice and cleanup producer.stop();

} catch (Exception e) { // we ignore any exceptions and just rethrow as runtime throw new RuntimeException(e); } }

0LBZ UIFSF BSF DPEF DPNNFOUT JO UIF DPEF CMPDL BCPWF UIBU TIPVME FYQMBJO XIBU JT IBQQFOJOH. 8F SVO UIF DPEF CZ JOWPLJOH PVS VOJU UFTU XJUI NBWFO mvn test, BOE XF TIPVME HFU UIJT MPH MJOF:
INFO: Exchange[BodyType:String, Body:Claus Ibsen]

61(3$ 3. %(+$ - $ 28 6(3' 3'$ 2 ,$ ".#$ 238+$


0LBZ UIBU JTO'U UP JNQSFTTJWF, $BNFM DBO MPH 8FMM * QSPNJTFE UIBU UIF BCPWF DPEF TUZMF DBO CF VTFE GPS >KV DPNQPOFOU, TP MFU'T TUPSF UIF QBZMPBE JO B GJMF. 8F EP UIJT CZ BEEJOH UIF GJMF DPNQPOFOU UP UIF $BNFM DPOUFYU

5 65 0 3 *"-4

151

// add the file component camel.addComponent("file", new FileComponent());

"OE UIFO XF MFU DBNFM XSJUF UIF QBZMPBE UP UIF GJMF BGUFS XF IBWF MPHHFE, CZ DSFBUJOH B OFX NFUIPE PBKA3L">JBI%FIB. 8F XBOU UP TUPSF UIF QBZMPBE JO GJMFOBNF XJUI UIF JODJEFOU JE TP XF OFFE UIJT QBSBNFUFS BMTP:
// let Camel do something with the name sendToCamelLog(name); sendToCamelFile(parameters.getIncidentId(), name);

"OE UIFO UIF DPEF UIBU JT 99% JEFOUJDBM. 8F IBWF DIBOHF UIF 63* DPOGJHVSBUJPO XIFO XF DSFBUF UIF FOEQPJOU BT XF QBTT JO DPOGJHVSBUJPO QBSBNFUFST UP UIF GJMF DPNQPOFOU. "OE UIFO XF OFFE UP TFU UIF PVUQVU GJMFOBNF BOE UIJT JT EPOF CZ BEEJOH B TQFDJBM IFBEFS UP UIF FYDIBOHF. 5IBU'T UIF POMZ EJGGFSFODF:
private void sendToCamelFile(String incidentId, String name) { try { // get the file component Component component = camel.getComponent("file"); // create an endpoint and configure it. // Notice the URI parameters this is a common pratice in Camel to configure // endpoints based on URI. // file://target instructs the base folder to output the files. We put in the target folder // then its actumatically cleaned by mvn clean Endpoint endpoint = component.createEndpoint("file://target"); // create an Exchange that we want to send to the endpoint Exchange exchange = endpoint.createExchange(); // set the in message payload (=body) with the name parameter exchange.getIn().setBody(name); // now a special header is set to instruct the file component what the output filename // should be exchange.getIn().setHeader(FileComponent.HEADER_FILE_NAME, "incident-" + incidentId + ".txt"); // now we want to send the exchange to this endpoint and we then need a producer // for this, so we create and start the producer. Producer producer = endpoint.createProducer(); producer.start(); // process the exchange will send the exchange to the file component, that will process // the exchange and yes write the payload to the given filename producer.process(exchange);

152

56 50 3* " - 4

// stop the producer, we want to be nice and cleanup producer.stop(); } catch (Exception e) { // we ignore any exceptions and just rethrow as runtime throw new RuntimeException(e); } }

"GUFS SVOOJOH PVS VOJU UFTU BHBJO XJUI mvn test XF IBWF B PVUQVU GJMF JO UIF UBSHFU GPMEFS:
D:\demo\part-two>type target\incident-123.txt Claus Ibsen

%4++8 ) 5

! 2$# ".-%(&41 3(.- .% $-#/.(-32

*O UIF GJMF FYBNQMF BCPWF UIF DPOGJHVSBUJPO XBT 63* CBTFE. 8IBU JG ZPV XBOU 100% KBWB TFUUFS CBTFE TUZMF, XFMM UIJT JT PG DPVSTF BMTP QPTTJCMF. 8F KVTU OFFE UP DBTU UP UIF DPNQPOFOU TQFDJGJD FOEQPJOU BOE UIFO XF IBWF BMM UIF TFUUFST BWBJMBCMF:
// create the file endpoint, we cast to FileEndpoint because then we can do // 100% java settter based configuration instead of the URI sting based // must pass in an empty string, or part of the URI configuration if wanted FileEndpoint endpoint = (FileEndpoint)component.createEndpoint(""); endpoint.setFile(new File("target/subfolder")); endpoint.setAutoCreate(true);

5IBU'T JU. /PX XF IBWF VTFE UIF TFUUFST UP DPOGJHVSF UIF FileEndpoint UIBU JU TIPVME TUPSF UIF GJMF JO UIF GPMEFS UBSHFU/TVCGPMEFS. 0G DPVSTF $BNFM OPX TUPSFT UIF GJMF JO UIF TVCGPMEFS.
D:\demo\part-two>type target\subfolder\incident-123.txt Claus Ibsen

+$22.-2 +$ 1-$#
0LBZ * XBOUFE UP EFNPOTUSBUF IPX ZPV DBO CF JO 100% DPOUSPM PG UIF DPOGJHVSBUJPO BOE VTBHF PG $BNFM CBTFE PO QMBJO +BWB DPEF XJUI OP IJEEFO NBHJD PS TQFDJBM 7,+ PS PUIFS DPOGJHVSBUJPO GJMFT. +VTU BEE UIF DBNFM-DPSF.KBS BOE ZPV BSF SFBEZ UP HP. :PV NVTU IBWF OPUJDFE UIBU UIF DPEF GPS TFOEJOH B NFTTBHF UP B HJWFO FOEQPJOU JT UIF TBNF GPS CPUI UIF ILD BOE CFIB, JO GBDU >KV $BNFM FOEQPJOU. :PV BT UIF DMJFOU TIPVMEO'U CPUIFS XJUI DPNQPOFOU TQFDJGJD DPEF TVDI BT GJMF TUVGG GPS GJMF DPNQPOFOUT, KNT TUVGG GPS +.4 NFTTBHJOH FUD.

5 65 0 3 *"-4

153

5IJT JT XIBU UIF .FTTBHF &OEQPJOU &*1 QBUUFSO JT BMM BCPVU BOE $BNFM TPMWFT UIJT WFSZ WFSZ OJDF B LFZ QBUUFSO JO $BNFM.

1$#4"(-& ".#$ +(-$2


/PX UIBU ZPV IBWF CFFO JOUSPEVDFE UP $BNFM BOE POF PG JUT NBTUFSQJFDF QBUUFSOT TPMWFE FMFHBOUMZ XJUI UIF .FTTBHF &OEQPJOU JUT UJNF UP HJWF QSPEVDUJWF BOE TIPX B TPMVUJPO JO GFXFS DPEF MJOFT, JO GBDU XF DBO HFU JU EPXO UP 5, 4, 3, 2 .. ZFT POMZ 1 IFKB LC @LAB. 5IF LFZ JT UIF /OLAR@BO3BJMI>QB UIBU JT B 4QSJOH'JTI YYY5FNQMBUF CBTFE QSPEVDFS. .FBOJOH UIBU JU IBT NFUIPET UP TFOE NFTTBHFT UP BOZ $BNFM FOEQPJOUT. 'JSTU PG BMM XF OFFE UP HFU IPME PG TVDI B UFNQMBUF BOE UIJT JT EPOF GSPN UIF $BNFM$POUFYU
private ProducerTemplate template; public ReportIncidentEndpointImpl() throws Exception { ... // get the ProducerTemplate thst is a Spring'ish xxxTemplate based producer for very // easy sending exchanges to Camel. template = camel.createProducerTemplate(); // start Camel camel.start(); }

/PX XF DBO VTF QBJMI>QB GPS TFOEJOH QBZMPBET UP BOZ FOEQPJOU JO $BNFM. 4P BMM UIF MPHHJOH HBCCMF DBO CF SFEVDFE UP:
template.sendBody("log:com.mycompany.part2.easy", name);

"OE UIF TBNF HPFT GPS UIF GJMF, CVU XF NVTU BMTP TFOE UIF IFBEFS UP JOTUSVDU XIBU UIF PVUQVU GJMFOBNF TIPVME CF:
String filename = "easy-incident-" + incidentId + ".txt"; template.sendBodyAndHeader("file://target/subfolder", name, FileComponent.HEADER_FILE_NAME, filename);

1$#4"(-& $5$- ,.1$ ".#$ +(-$2


8FMM XF HPU UIF $BNFM DPEF EPXO UP 1-2 MJOFT GPS TFOEJOH UIF NFTTBHF UP UIF DPNQPOFOU UIBU EPFT BMM UIF IFBWZ XPSL PG XSJOH UIF NFTTBHF UP B GJMF FUD. #VU XF TUJMM HPU 5 MJOFT UP JOJUJBMJ[F $BNFM.

154

56 50 3* " - 4

camel = new DefaultCamelContext(); camel.addComponent("log", new LogComponent()); camel.addComponent("file", new FileComponent()); template = camel.createProducerTemplate(); camel.start();

5IJT DBO BMTP CF SFEVDFE. "MM UIF TUBOEBSE DPNQPOFOUT JO $BNFM JT BVUP EJTDPWFSFE PO-UIF-GMZ TP XF DBO SFNPWF UIFTF DPEF MJOFT BOE XF BSF EPXO UP 3 MJOFT. 0LBZ CBDL UP UIF 3 DPEF MJOFT:
camel = new DefaultCamelContext(); template = camel.createProducerTemplate(); camel.start();

-BUFS XJMM XF TFF IPX XF DBO SFEVDF UIJT UP ... JO GBDU 0 KBWB DPEF MJOFT. #VU UIF 3 MJOFT XJMM EP GPS OPX.

,$22 &$ 31 -2+ 3(.0LBZ MFUT IFBE CBDL UP UIF PWFS HPBM PG UIF JOUFHSBUJPO. -PPLJOH BU UIF &*1 EJBHSBNT BU UIF JOUSPEVDUJPO QBHF XF OFFE UP CF BCMF UP USBOTMBUF UIF JODPNJOH XFCTFSWJDF UP BO FNBJM. %PJOH TP XF OFFE UP DSFBUF UIF FNBJM CPEZ. 8IFO EPJOH UIF NFTTBHF USBOTMBUJPO XF DPVME QVU VQ PVS TMFFWFT BOE EP JU NBOVBMMZ JO QVSF KBWB XJUI B 4USJOH#VJMEFS TVDI BT:
private String createMailBody(InputReportIncident parameters) { StringBuilder sb = new StringBuilder(); sb.append("Incident ").append(parameters.getIncidentId()); sb.append(" has been reported on the ").append(parameters.getIncidentDate()); sb.append(" by ").append(parameters.getGivenName()); sb.append(" ").append(parameters.getFamilyName()); // and the rest of the mail body with more appends to the string builder return sb.toString(); }

#VU BT BMXBZT JU JT B IBSEDPEFE UFNQMBUF GPS UIF NBJM CPEZ BOE UIF DPEF HFUT LJOEB VHMZ JG UIF NBJM NFTTBHF IBT UP CF B CJU NPSF BEWBODFE. #VU PG DPVSTF JU KVTU XPSLT PVU-PG-UIF-CPY XJUI KVTU DMBTTFT BMSFBEZ JO UIF +%,. -FUT VTF B UFNQMBUF MBOHVBHF JOTUFBE TVDI BT "QBDIF 7FMPDJUZ. "T $BNFM IBWF B DPNQPOFOU GPS 7FMPDJUZ JOUFHSBUJPO XF XJMM VTF UIJT DPNQPOFOU. -PPLJOH BU UIF $PNQPOFOU -JTU PWFSWJFX XF DBO TFF UIBU DBNFM-WFMPDJUZ DPNQPOFOU VTFT UIF BSUJGBDU*E @>JBI-SBIL@FQV TP UIFSFGPSF XF OFFE UP BEE UIJT UP UIF MLJ.UJI

5 65 0 3 *"-4

155

"LJMLKBKQ >RQL AFP@LSBOV 8IFO BO FOEQPJOU JT SFRVFTUFE XJUI B TDIFNF UIBU $BNFM IBTO'U TFFO CFGPSF JU XJMM USZ UP MPPL GPS JU JO UIF DMBTTQBUI. *U XJMM EP TP CZ MPPLJOH GPS TQFDJBM $BNFM DPNQPOFOU NBSLFS GJMFT UIBU SFTJEF JO UIF GPMEFS META-INF/services/org/ apache/camel/component. *G UIFSF BSF GJMFT JO UIJT GPMEFS JU XJMM SFBE UIFN BT UIF GJMFOBNF JT UIF P@EBJB QBSU PG UIF 63-. 'PS JOTUBODF UIF ILD DPNQPOFOU JT EFGJOFE JO UIJT GJMF META-INF/services/org/apache/component/log BOE JUT DPOUFOU JT:
class=org.apache.camel.component.log.LogComponent

5IF DMBTT QSPQFSUZ EFGJOFT UIF DPNQPOFOU JNQMFNFOUBUJPO. 3FM: &OE-VTFST DBO DSFBUF UIFJS 3SE QBSUZ DPNQPOFOUT VTJOH UIF TBNF UFDIOJRVF BOE IBWF UIFN CFFO BVUP EJTDPWFSFE PO-UIF-GMZ.

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-velocity</artifactId> <version>${camel-version}</version> </dependency>

"OE OPX XF IBWF B 4QSJOH DPOGMJDU BT "QBDIF $9' JT EFQFOEFOU PO 4QSJOH 2.0.8 BOE DBNFMWFMPDJUZ JT EFQFOEFOU PO 4QSJOH 2.5.5. 5P SFNFEZ UIJT XF DPVME XSFTUMF XJUI UIF MLJ.UJI XJUI FYDMVEFT TFUUJOHT JO UIF EFQFOEFODJFT PS KVTU CSJOH JO BOPUIFS EFQFOEFODZ @>JBIPMOFKD:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel-version}</version> </dependency>

*O GBDU DBNFM-TQSJOH JT TVDI B WJUBM QBSU PG $BNFM UIBU ZPV XJMM FOE VQ VTJOH JU JO OFBSMZ BMM TJUVBUJPOT - XF XJMM MPPL JOUP IPX XFMM $BNFM JT TFBNMFTT JOUFHSBUJPO XJUI 4QSJOH JO QBSU 3. 'PS OPX JUT KVTU BOPUIFS EFQFOEFODZ. 8F DSFBUF UIF NBJM CPEZ XJUI UIF 7FMPDJUZ UFNQMBUF BOE DSFBUF UIF GJMF src/main/ resources/MailBody.vm. 5IF DPOUFOU JO UIF ,>FI!LAV.SJ GJMF JT:
Incident $body.incidentId has been reported on the $body.incidentDate by $body.givenName $body.familyName.

156

56 50 3* " - 4

The person can be contact by: - email: $body.email - phone: $body.phone Summary: $body.summary Details: $body.details This is an auto generated email. You can not reply.

-FUUJOH $BNFM DSFBUJOH UIF NBJM CPEZ BOE TUPSJOH JU BT B GJMF JT BT FBTZ BT UIF GPMMPXJOH 3 DPEF MJOFT:
private void generateEmailBodyAndStoreAsFile(InputReportIncident parameters) { // generate the mail body using velocity template // notice that we just pass in our POJO (= InputReportIncident) that we // got from Apache CXF to Velocity. Object response = template.sendBody("velocity:MailBody.vm", parameters); // Note: the response is a String and can be cast to String if needed // store the mail in a file String filename = "mail-incident-" + parameters.getIncidentId() + ".txt"; template.sendBodyAndHeader("file://target/subfolder", response, FileComponent.HEADER_FILE_NAME, filename); }

8IBU JT JNQSFTTJWF JT UIBU XF DBO KVTU QBTT JO PVS 10+0 PCKFDU XF HPU GSPN "QBDIF $9' UP 7FMPDJUZ BOE JU XJMM CF BCMF UP HFOFSBUF UIF NBJM CPEZ XJUI UIJT PCKFDU JO JUT DPOUFYU. 5IVT XF EPO'U OFFE UP QSFQBSF >KVQEFKD CFGPSF XF MFU 7FMPDJUZ MPPTF BOE HFOFSBUF PVS NBJM CPEZ. /PUJDF UIBU UIF QBJMI>QB NFUIPE SFUVSOT B PCKFDU XJUI PVU SFTQPOTF. 5IJT PCKFDU DPOUBJOT UIF NBJM CPEZ BT B 4USJOH PCKFDU. 8F DBO DBTU UP 4USJOH JG OFFEFE. *G XF SVO PVS VOJU UFTU XJUI mvn test XF DBO JO GBDU TFF UIBU $BNFM IBT QSPEVDFE UIF GJMF BOE XF DBO UZQF JUT DPOUFOU:
D:\demo\part-two>type target\subfolder\mail-incident-123.txt Incident 123 has been reported on the 2008-07-16 by Claus Ibsen. The person can be contact by: - email: davsclaus@apache.org - phone: +45 2962 7576 Summary: bla bla Details: more bla bla This is an auto generated email. You can not reply.

5 65 0 3 *"-4

157

%(123 / 13 .% 3'$ 2.+43(.8IBU XF IBWF TFFO IFSF JT BDUVBMMZ XIBU JU UBLFT UP CVJME UIF GJSTU QBSU PG UIF JOUFHSBUJPO GMPX. 3FDFJWJOH B SFRVFTU GSPN B XFCTFSWJDF, USBOTGPSN JU UP B NBJM CPEZ BOE TUPSF JU UP B GJMF, BOE SFUVSO BO 0, SFTQPOTF UP UIF XFCTFSWJDF. "MM QPTTJCMF XJUIJO 10 MJOFT PG DPEF. 4P MFUT XSBQ JU VQ IFSF JT XIBU JU UBLFT:
/** * The webservice we have implemented. */ public class ReportIncidentEndpointImpl implements ReportIncidentEndpoint { private CamelContext camel; private ProducerTemplate template; public ReportIncidentEndpointImpl() throws Exception { // create the camel context that is the "heart" of Camel camel = new DefaultCamelContext(); // get the ProducerTemplate thst is a Spring'ish xxxTemplate based producer for very // easy sending exchanges to Camel. template = camel.createProducerTemplate(); // start Camel camel.start(); } public OutputReportIncident reportIncident(InputReportIncident parameters) { // transform the request into a mail body Object mailBody = template.sendBody("velocity:MailBody.vm", parameters); // store the mail body in a file String filename = "mail-incident-" + parameters.getIncidentId() + ".txt"; template.sendBodyAndHeader("file://target/subfolder", mailBody, FileComponent.HEADER_FILE_NAME, filename); // return an OK reply OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; } }

0LBZ * NJTTFE CZ POF, JUT JO GBDU POMZ 9 IFKBP LC G>S> @LAB >KA 2 CFBIAP.

$-# .% / 13 2
* LOPX UIJT JT B CJU EJGGFSFOU JOUSPEVDUJPO UP $BNFM UP IPX ZPV DBO TUBSU VTJOH JU JO ZPVS QSPKFDUT KVTU BT B QMBJO KBWB .KBS GSBNFXPSL UIBU JTO'U JOWBTJWF BU BMM. * UPPL ZPV UISPVHI UIF

158

56 50 3* " - 4

DPEJOH QBSUT UIBU SFRVJSFT 6 - 10 MJOFT UP TFOE B NFTTBHF UP BO FOEQPJOU, CVUT JU'T JNQPSUBOU UP TIPX UIF .FTTBHF &OEQPJOU &*1 QBUUFSO JO BDUJPO BOE IPX JUT JNQMFNFOUFE JO $BNFM. :FT PG DPVSTF $BNFM BMTP IBT UP POF MJOFST UIBU ZPV DBO VTF, BOE XJMM VTF JO ZPVS QSPKFDUT GPS TFOEJOH NFTTBHFT UP FOEQPJOUT. 5IJT QBSU IBT CFFO BCPVU HPPE PME QMBJO KBWB, OPUIJOH GBODZ XJUI 4QSJOH, 9.- GJMFT, BVUP EJTDPWFSZ, 0(4J PS PUIFS OFX UFDIOPMPHJFT. * XBOUFE UP EFNPOTUSBUF UIF CBTJD CVJMEJOH CMPDLT JO $BNFM BOE IPX JUT TFUVQ JO QVSF HPE PME GBTIJPOFE +BWB. 5IFSF BSF QMFOUZ PG FZF DBUDIFS FYBNQMFT XJUI POF MJOFST UIBU EPFT NPSF UIBO ZPV DBO JNBHJOF - XF XJMM DPNF UIFSF JO UIF MBUFS QBSUT. 0LBZ QBSU 3 JT BCPVU CVJMEJOH UIF MBTU QJFDFT PG UIF TPMVUJPO BOE OPX JU HFUT JOUFSFTUJOH TJODF XF IBWF UP XSFTUMF XJUI UIF FWFOU ESJWFO DPOTVNFS. #SFX B DVQ PG DPGGFF, UVH UIF LJET BOE LJTT UIF XJGF, GPS OPX XF XJMM IBWF VT TPNF GVO XJUI UIF $BNFM. 4FF ZPV JO QBSU 3.

+(-*2
*OUSPEVDUJPO 1BSU 1 1BSU 2 1BSU 3 1BSU 4 1BSU 5 1BSU 6

/ 13 3 1$" /
-FUT KVTU SFDBQ PO UIF TPMVUJPO XF IBWF OPX:
public class ReportIncidentEndpointImpl implements ReportIncidentEndpoint { private CamelContext camel; private ProducerTemplate template; public ReportIncidentEndpointImpl() throws Exception { // create the camel context that is the "heart" of Camel camel = new DefaultCamelContext(); // get the ProducerTemplate thst is a Spring'ish xxxTemplate based producer for very // easy sending exchanges to Camel. template = camel.createProducerTemplate();

5 65 0 3 *"-4

159

// start Camel camel.start(); } /** * This is the last solution displayed that is the most simple */ public OutputReportIncident reportIncident(InputReportIncident parameters) { // transform the request into a mail body Object mailBody = template.sendBody("velocity:MailBody.vm", parameters); // store the mail body in a file String filename = "mail-incident-" + parameters.getIncidentId() + ".txt"; template.sendBodyAndHeader("file://target/subfolder", mailBody, FileComponent.HEADER_FILE_NAME, filename); // return an OK reply OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; } }

5IJT DPNQMFUFT UIF GJSTU QBSU PG UIF TPMVUJPO: SFDFJWJOH UIF NFTTBHF VTJOH XFCTFSWJDF, USBOTGPSN JU UP B NBJM CPEZ BOE TUPSF JU BT B UFYU GJMF. 8IBU JT NJTTJOH JT UIF MBTU QBSU UIBU QPMMT UIF UFYU GJMFT BOE TFOE UIFN BT FNBJMT. )FSF JT XIFSF TPNF GVO TUBSUT, BT UIJT SFRVJSFT VTBHF PG UIF &WFOU %SJWFO $POTVNFS &*1 QBUUFSO UP SFBDU XIFO OFX GJMFT BSSJWFT. 4P MFUT TFF IPX XF DBO EP UIJT JO $BNFM. 5IFSF JT B TBZJOH: .BOZ SPBET MFBE UP 3PNF, BOE UIBU JT BMTP USVF GPS $BNFM - UIFSF BSF NBOZ XBZT UP EP JU JO $BNFM.

##(-& 3'$ $5$-3 #1(5$- ".-24,$1


8F XBOU UP BEE UIF DPOTVNFS UP PVS JOUFHSBUJPO UIBU MJTUFO GPS OFX GJMFT, XF EP UIJT CZ DSFBUJOH B QSJWBUF NFUIPE XIFSF UIF DPOTVNFS DPEF MJWFT. 8F NVTU SFHJTUFS PVS DPOTVNFS JO $BNFM CFGPSF JUT TUBSUFE TP XF OFFE UP BEE, BOE UIFSF GPSF XF DBMM UIF NFUIPE >AA,>FI2BKABO"LKPRJBO JO UIF DPOTUSVDUPS CFMPX:
public ReportIncidentEndpointImpl() throws Exception { // create the camel context that is the "heart" of Camel camel = new DefaultCamelContext(); // get the ProducerTemplate thst is a Spring'ish xxxTemplate based producer for very // easy sending exchanges to Camel. template = camel.createProducerTemplate(); // add the event driven consumer that will listen for mail files and process

160

56 50 3* " - 4

them addMailSendConsumer(); // start Camel camel.start(); }

5IF DPOTVNFS OFFET UP CF DPOTVNJOH GSPN BO FOEQPJOU TP XF HSBC UIF FOEQPJOU GSPN $BNFM XF XBOU UP DPOTVNF. *U'T file://target/subfolder. %PO'U CF GPPMFE UIJT FOEQPJOU EPFTO'U IBWF UP 100% JEFOUJDBM UP UIF QSPEVDFS, J.F. UIF FOEQPJOU XF VTFE JO UIF QSFWJPVT QBSU UP DSFBUF BOE TUPSF UIF GJMFT. 8F DPVME DIBOHF UIF 63- UP JODMVEF TPNF PQUJPOT, BOE UP NBLF JU NPSF DMFBS UIBU JU'T QPTTJCMF XF TFUVQ B EFMBZ WBMVF UP 10 TFDPOET, BOE UIF GJSTU QPMM TUBSUT BGUFS 2 TFDPOET. 5IJT JT EPOF CZ BEEJOH ?consumer.delay=10000&consumer.initialDelay=2000 UP UIF 63-. 8IFO XF IBWF UIF FOEQPJOU XF DBO DSFBUF UIF DPOTVNFS (KVTU BT JO QBSU 1 XIFSF XF DSFBUFE B QSPEVDFS^. $SFBUJOH UIF DPOTVNFS SFRVJSFT B 1SPDFTTPS XIFSF XF JNQMFNFOU UIF KBWB DPEF XIBU TIPVME IBQQFO XIFO B NFTTBHF BSSJWFT. 5P HFU UIF NBJM CPEZ BT B 4USJOH PCKFDU XF DBO VTF UIF DBQ!LAV NFUIPE XIFSF XF DBO QSPWJEF UIF UZQF XF XBOU JO SFUVSO. 4FOEJOH UIF FNBJM JT TUJMM MFGU UP CF JNQMFNFOUFE, XF XJMM EP UIJT MBUFS. "OE GJOBMMZ XF NVTU SFNFNCFS UP TUBSU UIF DPOTVNFS PUIFSXJTF JUT OPU BDUJWF BOE XPO'U MJTUFO GPS OFX GJMFT.
private void addMailSendConsumer() throws Exception { // Grab the endpoint where we should consume. Option - the first poll starts after 2 seconds Endpoint endpint = camel.getEndpoint("file://target/ subfolder?consumer.initialDelay=2000"); // create the event driven consumer // the Processor is the code what should happen when there is an event // (think it as the onMessage method) Consumer consumer = endpint.createConsumer(new Processor() { public void process(Exchange exchange) throws Exception { // get the mail body as a String String mailBody = exchange.getIn().getBody(String.class); // okay now we are read to send it as an email System.out.println("Sending email..." + mailBody); } }); // star the consumer, it will listen for files consumer.start(); }

#FGPSF XF UFTU JU XF OFFE UP CF BXBSF UIBU PVS VOJU UFTU JT POMZ DBUFSJOH GPS UIF GJSTU QBSU PG UIF TPMVUJPO, SFDFJWJOH UIF NFTTBHF XJUI XFCTFSWJDF, USBOTGPSNJOH JU VTJOH 7FMPDJUZ BOE UIFO TUPSJOH JU BT B GJMF - JU EPFTO'U UFTU UIF &WFOU %SJWFO $POTVNFS XF KVTU BEEFE. "T XF BSF FBHFS UP TFF JU

5 65 0 3 *"-4

161

41+ "LKCFDRO>QFLK 5IF 63- DPOGJHVSBUJPO JO $BNFM FOEQPJOUT JT KVTU MJLF SFHVMBS 63- XF LOPX GSPN UIF *OUFSOFU. :PV VTF BOE & UP TFU UIF PQUJPOT.

">JBI 3VMB "LKSBOQBO 8IZ EPO'U XF KVTU DBTU JU BT XF BMXBZT EP JO +BWB 8FMM UIF CJHHFTU BEWBOUBHF XIFO ZPV QSPWJEF UIF UZQF BT B QBSBNFUFS ZPV UFMM $BNFM XIBU UZQF ZPV XBOU BOE $BNFM DBO BVUPNBUJDBMMZ DPOWFSU JU GPS ZPV, VTJOH JUT GMFYJCMF 5ZQF $POWFSUFS NFDIBOJTN. 5IJT JT B HSFBU BEWBOUBHF, BOE ZPV TIPVME USZ UP VTF UIJT JOTUFBE PG SFHVMBS UZQF DBTUJOH. JO BDUJPO, XF KVTU EP B DPNNPO USJDL BEEJOH TPNF TMFFQ JO PVS VOJU UFTU, UIBU HJWFT PVS &WFOU %SJWFO $POTVNFS UJNF UP SFBDU BOE QSJOU UP 4ZTUFN.PVU. 8F XJMM MBUFS SFGJOF UIF UFTU:
public void testRendportIncident() throws Exception { ... OutputReportIncident out = client.reportIncident(input); assertEquals("Response code is wrong", "OK", out.getCode()); // give the event driven consumer time to react Thread.sleep(10 * 1000); }

8F SVO UIF UFTU XJUI mvn clean test BOE IBWF FZFT GJYFE PO UIF DPOTPMF PVUQVU. %VSJOH BMM UIF PVUQVU JO UIF DPOTPMF, XF TFF UIBU PVS DPOTVNFS IBT CFFO USJHHFSFE, BT XF XBOU.
2008-07-19 12:09:24,140 [mponent@1f12c4e] DEBUG FileProcessStrategySupport - Locking the file: target\subfolder\mail-incident-123.txt ... Sending email...Incident 123 has been reported on the 2008-07-16 by Claus Ibsen. The person can be contact by: - email: davsclaus@apache.org - phone: +45 2962 7576 Summary: bla bla Details: more bla bla This is an auto generated email. You can not reply. 2008-07-19 12:09:24,156 [mponent@1f12c4e] DEBUG FileConsumer - Done processing file: target\subfolder\mail-incident-123.txt. Status is: OK

162

56 50 3* " - 4

2$-#(-& 3'$ $, (+
4FOEJOH UIF FNBJM SFRVJSFT BDDFTT UP B 4.51 NBJM TFSWFS, CVU UIF JNQMFNFOUBUJPO DPEF JT WFSZ TJNQMF:
private void sendEmail(String body) { // send the email to your mail server String url = "smtp://someone@localhost?password=secret&to=incident@mycompany.com"; template.sendBodyAndHeader(url, body, "subject", "New incident reported"); }

"OE KVTU JOWPLF UIF NFUIPE GSPN PVS DPOTVNFS:


// okay now we are read to send it as an email System.out.println("Sending email..."); sendEmail(mailBody); System.out.println("Email sent");

4-(3 3$23(-& , (+
'PS VOJU UFTUJOH UIF DPOTVNFS QBSU XF XJMM VTF B NPDL NBJM GSBNFXPSL, TP XF BEE UIJT UP PVS MLJ.UJI:
<!-- unit testing mail using mock --> <dependency> <groupId>org.jvnet.mock-javamail</groupId> <artifactId>mock-javamail</artifactId> <version>1.7</version> <scope>test</scope> </dependency>

5IFO XF QSFQBSF PVS JOUFHSBUJPO UP SVO XJUI PS XJUIPVU UIF DPOTVNFS FOBCMFE. 8F EP UIJT UP TFQBSBUF UIF SPVUF JOUP UIF UXP QBSUT: SFDFJWF UIF XFCTFSWJDF, USBOTGPSN BOE TBWF NBJM GJMF BOE SFUVSO 0, BT SFQPTF UIF DPOTVNFS UIBU MJTUFO GPS NBJM GJMFT BOE TFOE UIFN BT FNBJMT 4P XF DIBOHF UIF DPOTUSVDUPS DPEF B CJU:
public ReportIncidentEndpointImpl() throws Exception { init(true); } public ReportIncidentEndpointImpl(boolean enableConsumer) throws Exception { init(enableConsumer); }

5 65 0 3 *"-4

163

private void init(boolean enableConsumer) throws Exception { // create the camel context that is the "heart" of Camel camel = new DefaultCamelContext(); // get the ProducerTemplate thst is a Spring'ish xxxTemplate based producer for very // easy sending exchanges to Camel. template = camel.createProducerTemplate(); // add the event driven consumer that will listen for mail files and process them if (enableConsumer) { addMailSendConsumer(); } // start Camel camel.start(); }

5IFO SFNFNCFS UP DIBOHF UIF 1BMLOQ(K@FABKQ$KAMLFKQ3BPQ UP QBTT JO C>IPB JO UIF ReportIncidentEndpointImpl DPOTUSVDUPS. "OE BT BMXBZT SVO mvn clean test UP CF TVSF UIBU UIF MBUFTU DPEF DIBOHFT XPSLT.

##(-& -$6 4-(3 3$23


8F BSF OPX SFBEZ UP BEE B OFX VOJU UFTU UIBU UFTUT UIF DPOTVNFS QBSU TP XF DSFBUF B OFX UFTU DMBTT UIBU IBT UIF GPMMPXJOH DPEF TUSVDUVSF:
/** * Plain JUnit test of our consumer. */ public class ReportIncidentConsumerTest extends TestCase { private ReportIncidentEndpointImpl endpoint; public void testConsumer() throws Exception { // we run this unit test with the consumer, hence the true parameter endpoint = new ReportIncidentEndpointImpl(true); } }

"T XF XBOU UP UFTU UIF DPOTVNFS UIBU JU DBO MJTUFO GPS GJMFT, SFBE UIF GJMF DPOUFOU BOE TFOE JU BT BO FNBJM UP PVS NBJMCPY XF XJMM UFTU JU CZ BTTFSUJOH UIBU XF SFDFJWF 1 NBJM JO PVS NBJMCPY BOE UIBU UIF NBJM JT UIF POF XF FYQFDU. 5P EP TP XF OFFE UP HSBC UIF NBJMCPY XJUI UIF NPDLNBJM "1*. 5IJT JT EPOF BT TJNQMF BT:

164

56 50 3* " - 4

public void testConsumer() throws Exception { // we run this unit test with the consumer, hence the true parameter endpoint = new ReportIncidentEndpointImpl(true); // get the mailbox Mailbox box = Mailbox.get("incident@mycompany.com"); assertEquals("Should not have mails", 0, box.size());

)PX EP XF USJHHFS UIF DPOTVNFS 8FMM CZ DSFBUJOH B GJMF JO UIF GPMEFS JU MJTUFO GPS. 4P XF DPVME VTF QMBJO KBWB.JP.'JMF "1* UP DSFBUF UIF GJMF, CVU XBJU JTO'U UIFSF BO TNBSUFS TPMVUJPO ... ZFT $BNFM PG DPVSTF. $BNFM DBO EP BNB[JOH TUVGG JO POF MJOFS DPEFT XJUI JUT 1SPEVDFS5FNQMBUF, TP XF OFFE UP HFU B IPME PG UIJT CBCZ. 8F FYQPTF UIJT UFNQMBUF JO PVS 3FQPSU*ODJEFOU&OEQPJOU*NQM CVU BEEJOH UIJT HFUUFS:
protected ProducerTemplate getTemplate() { return template; }

5IFO XF DBO VTF UIF UFNQMBUF UP DSFBUF UIF GJMF JO LKB @LAB IFKB:
// drop a file in the folder that the consumer listen // here is a trick to reuse Camel! so we get the producer template and just // fire a message that will create the file for us endpoint.getTemplate().sendBodyAndHeader("file://target/ subfolder?append=false", "Hello World", FileComponent.HEADER_FILE_NAME, "mail-incident-test.txt");

5IFO XF KVTU OFFE UP XBJU B MJUUMF GPS UIF DPOTVNFS UP LJDL JO BOE EP JUT XPSL BOE UIFO XF TIPVME BTTFSU UIBU XF HPU UIF OFX NBJM. &BTZ BT KVTU:
// let the consumer have time to run Thread.sleep(3 * 1000); // get the mock mailbox and check if we got mail ;) assertEquals("Should have got 1 mail", 1, box.size()); assertEquals("Subject wrong", "New incident reported", box.get(0).getSubject()); assertEquals("Mail body wrong", "Hello World", box.get(0).getContent()); }

5IF GJOBM DMBTT GPS UIF VOJU UFTU JT:


/** * Plain JUnit test of our consumer. */ public class ReportIncidentConsumerTest extends TestCase {

5 65 0 3 *"-4

165

private ReportIncidentEndpointImpl endpoint; public void testConsumer() throws Exception { // we run this unit test with the consumer, hence the true parameter endpoint = new ReportIncidentEndpointImpl(true); // get the mailbox Mailbox box = Mailbox.get("incident@mycompany.com"); assertEquals("Should not have mails", 0, box.size()); // drop a file in the folder that the consumer listen // here is a trick to reuse Camel! so we get the producer template and just // fire a message that will create the file for us endpoint.getTemplate().sendBodyAndHeader("file://target/ subfolder?append=false", "Hello World", FileComponent.HEADER_FILE_NAME, "mail-incident-test.txt"); // let the consumer have time to run Thread.sleep(3 * 1000); // get the mock mailbox and check if we got mail ;) assertEquals("Should have got 1 mail", 1, box.size()); assertEquals("Subject wrong", "New incident reported", box.get(0).getSubject()); assertEquals("Mail body wrong", "Hello World", box.get(0).getContent()); } }

$-# .% / 13 3
0LBZ XF IBWF SFBDIFE UIF FOE PG QBSU 3. 'PS OPX XF IBWF POMZ TDSBUDIFE UIF TVSGBDF PG XIBU $BNFM JT BOE XIBU JU DBO EP. 8F IBWF JOUSPEVDFE $BNFM JOUP PVS JOUFHSBUJPO QJFDF CZ QJFDF BOE TMPXMZ BEEFE NPSF BOE NPSF BMPOH UIF XBZ. "OE UIF NPTU JNQPSUBOU JT: VLR >P QEB ABSBILMBO KBSBO ILPQ @LKQOLI. 8F IJU B TXFFU TQPU JO UIF XFCTFSWJDF JNQMFNFOUBUJPO XIFSF XF DPVME XSJUF PVS KBWB DPEF. "EEJOH $BNFM UP UIF NJY JT KVTU UP VTF JU BT B SFHVMBS KBWB DPEF, OPUIJOH NBHJD. 8F XFSF JO DPOUSPM PG UIF GMPX, XF EFDJEFE XIFO JU XBT UJNF UP USBOTMBUF UIF JOQVU UP B NBJM CPEZ, XF EFDJEFE XIFO UIF DPOUFOU TIPVME CF XSJUUFO UP B GJMF. 5IJT JT WFSZ JNQPSUBOU UP OPU MPTF DPOUSPM, UIBU UIF CJHHFS BOE IFBWJFS GSBNFXPSLT UFOE UP EP. /P OBNFT NFOUJPOFE, CVU CPZ EP EFWFMPQFST GSPN UJNF UP UJNF EJTMJLF UIFTF FMFQIBOUT. "OE $BNFM JT KL BIBME>KQ. * TVHHFTU ZPV EPXOMPBE UIF TBNQMFT GSPN QBSU 1 UP 3 BOE USZ UIFN PVU. *U JT HSFBU CBTJD LOPXMFEHF UP IBWF JO NJOE XIFO XF MPPL BU TPNF PG UIF GFBUVSFT XIFSF $BNFM SFBMMZ FYDFM QEB OLRQFKD ALJ>FK I>KDR>DB. 'SPN QBSU 1 UP 3 XF UPVDIFE DPODFQUT TVDI BT:: &OEQPJOU 63* DPOGJHVSBUJPO

166

56 50 3* " - 4

$POTVNFS 1SPEVDFS &WFOU %SJWFO $POTVNFS $PNQPOFOU $BNFM$POUFYU 1SPEVDFS5FNQMBUF 1SPDFTTPS 5ZQF $POWFSUFS

+(-*2
*OUSPEVDUJPO 1BSU 1 1BSU 2 1BSU 3 1BSU 4 1BSU 5 1BSU 6

/ 13 4 (-31.#4"3(.5IJT TFDUJPO JT BCPVU SFHVMBS $BNFM. 5IF FYBNQMFT QSFTFOUFE IFSF JO UIJT TFDUJPO JT NVDI NPSF JO DPNNPO PG BMM UIF FYBNQMFT XF IBWF JO UIF $BNFM EPDVNFOUBUJPO.

1.43(-&
$BNFM JT QBSUJDVMBS TUSPOH BT B MJHIU-XFJHIU BOE BHJMF OLRQFKD BOE JBAF>QFLK GSBNFXPSL. *O UIJT QBSU XF XJMM JOUSPEVDF UIF OLRQFKD DPODFQU BOE IPX XF DBO JOUSPEVDF UIJT JOUP PVS TPMVUJPO. -PPLJOH CBDL BU UIF GJHVSF GSPN UIF *OUSPEVDUJPO QBHF XF XBOU UP JNQMFNFOU UIJT SPVUJOH. $BNFM IBT TVQQPSU GPS FYQSFTTJOH UIJT SPVUJOH MPHJD VTJOH +BWB BT B %4- (%PNBJO 4QFDJGJD -BOHVBHF). *O GBDU $BNFM BMTP IBT %4- GPS 9.- BOE 4DBMB. *O UIJT QBSU XF VTF UIF +BWB %4- BT JUT UIF NPTU QPXFSGVM BOE BMM EFWFMPQFST LOPX +BWB. -BUFS XF XJMM JOUSPEVDF UIF 9.- WFSTJPO UIBU JT WFSZ XFMM JOUFHSBUFE XJUI 4QSJOH. #FGPSF XF KVNQ JOUP JU, XF XBOU UP TUBUF UIBU UIJT UVUPSJBM JT BCPVU #BSBILMBOP KLQ ILLPFKD @LKQOLI. *O NZ IVNCMF FYQFSJFODF POF PG UIF LFZ GFBST PG EFWFMPQFST JT UIBU UIFZ BSF GPSDFE JOUP B UPPM/GSBNFXPSL XIFSF UIFZ MPPTF DPOUSPM BOE/PS QPXFS, BOE UIF QPTTJCMF JT OPX JNQPTTJCMF. 4P JO UIJT QBSU XF TUBZ DMFBS XJUI UIJT WJTJPO BOE PVS TUBSUJOH QPJOU JT BT GPMMPXT:

5 65 0 3 *"-4

167

*G ZPV IBWF CFFO SFBEJOH UIF QSFWJPVT 3 QBSUT UIFO, UIJT RVPUF BQQMJFT:
ZPV NVTU VOMFBSO XIBU ZPV IBWF MFBSOFE Master Yoda, Star Wars IV 4P XF TUBSU BMM PWFS BHBJO!

8F IBWF HFOFSBUFE UIF XFCTFSWJDF TPVSDF DPEF VTJOH UIF $9' XTEM2KBWB HFOFSBUPS BOE XF IBWF PVS 3FQPSU*ODJEFOU&OEQPJOU*NQM.KBWB GJMF XIFSF XF BT B %FWFMPQFS GFFMT IPNF BOE IBWF UIF QPXFS. 4P UIF TUBSUJOH QPJOU JT:
/** * The webservice we have implemented. */ public class ReportIncidentEndpointImpl implements ReportIncidentEndpoint { /** * This is the last solution displayed that is the most simple */ public OutputReportIncident reportIncident(InputReportIncident parameters) { // WE ARE HERE !!! return null; } }

:FT XF IBWF B TJNQMF QMBJO +BWB DMBTT XIFSF XF IBWF UIF JNQMFNFOUBUJPO PG UIF XFCTFSWJDF. 5IF DVSTPS JT CMJOLJOH BU UIF 8& "3& )&3& CMPDL BOE UIJT JT XIFSF XF GFFM IPNF. .PSF PS MFTT BOZ +BWB %FWFMPQFST IBWF JNQMFNFOUFE XFCTFSWJDFT VTJOH B TUBDL TVDI BT: "QBDIF "9*4, "QBDIF $9' PS TPNF PUIFS RVJUF QPQVMBS GSBNFXPSL. 5IFZ BMM BMMPX UIF EFWFMPQFS UP CF JO DPOUSPM BOE JNQMFNFOU UIF DPEF MPHJD BT QMBJO +BWB DPEF. $BNFM PG DPVSTF EPFTO'U FOGPSDF UIJT UP CF BOZ EJGGFSFOU. 0LBZ UIF CPTT UPME VT UP JNQMFNFOU UIF TPMVUJPO GSPN UIF GJHVSF JO UIF *OUSPEVDUJPO QBHF BOE XF BSF OPX SFBEZ UP DPEF. 1LRQB!RFIABO 1LRQB!RFIABO JT UIF IFBSUI JO $BNFM PG UIF +BWB %4- SPVUJOH. 5IJT DMBTT EPFT BMM UIF IFBWZ MJGUJOH PG TVQQPSUJOH &*1 WFSCT GPS FOE-VTFST UP FYQSFTT UIF SPVUJOH. *U EPFT UBLF B MJUUMF XIJMF UP HFU TFUUMFE BOE VTFE UP, CVU XIFO ZPV IBWF XPSLFE XJUI JU GPS B XIJMF ZPV XJMM FOKPZ JUT QPXFS BOE SFBMJ[F JU JT JO GBDU B MJUUMF MBOHVBHF JOTJEF +BWB JUTFMG. $BNFM JT UIF LKIV JOUFHSBUJPO GSBNFXPSL XF BSF BXBSF PG UIBU IBT +BWB %4-, BMM UIF PUIFST BSF VTVBMMZ LKIV 9.- CBTFE. "T BO FOE-VTFS ZPV VTVBMMZ VTF UIF 1LRQB!RFIABO BT PG GPMMPXT: DSFBUF ZPVS PXO 3PVUF DMBTT UIBU FYUFOET 1LRQB!RFIABO

168

56 50 3* " - 4

JNQMFNFOU ZPVS SPVUJOH %4- JO UIF @LKCFDROB NFUIPE 4P XF DSFBUF B OFX DMBTT 3FQPSU*ODJEFOU3PVUFT BOE JNQMFNFOU UIF GJSTU QBSU PG UIF SPVUJOH:
import org.apache.camel.builder.RouteBuilder; public class ReportIncidentRoutes extends RouteBuilder { public void configure() throws Exception { // direct:start is a internal queue to kick-start the routing in our example // we use this as the starting point where you can send messages to direct:start from("direct:start") // to is the destination we send the message to our velocity endpoint // where we transform the mail body .to("velocity:MailBody.vm"); } }

8IBU UP OPUJDF IFSF JT UIF @LKCFDROB NFUIPE. )FSF JT XIFSF BMM UIF BDUJPO JT. )FSF XF IBWF UIF +BWB %4- MBOHBVHF, UIBU JT FYQSFTTFE VTJOH UIF CIRBKQ ?RFIABO PVKQ>U UIBU JT BMTP LOPXO GSPN )JCFSOBUF XIFO ZPV CVJME UIF EZOBNJD RVFSJFT FUD. 8IBU ZPV EP JT UIBU ZPV DBO TUBDL NFUIPET TFQBSBUJOH XJUI UIF EPU. *O UIF FYBNQMF BCPWF XF IBWF B WFSZ DPNNPO SPVUJOH, UIBU DBO CF EJTUJMMFE GSPN QTFVEP WFSCT UP BDUVBM DPEF XJUI: GSPN " UP # 'SPN &OEQPJOU " 5P &OEQPJOU # GSPN("FOEQPJOU"").UP("FOEQPJOU#") GSPN("EJSFDU:TUBSU").UP("WFMPDJUZ:.BJM#PEZ.WN"); COLJ("AFOB@Q:PQ>OQ") JT UIF DPOTVNFS UIBU JT LJDL-TUBSUJOH PVS SPVUJOH GMPX. *U XJMM XBJU GPS NFTTBHFT UP BSSJWF PO UIF EJSFDU RVFVF BOE UIFO EJTQBUDI UIF NFTTBHF. QL("SBIL@FQV:,>FI!LAV.SJ") JT UIF QSPEVDFS UIBU XJMM SFDFJWF B NFTTBHF BOE MFU 7FMPDJUZ HFOFSBUF UIF NBJM CPEZ SFTQPOTF. 4P XIBU XF IBWF JNQMFNFOUFE TP GBS XJUI PVS 3FQPSU*ODJEFOU3PVUFT 3PVUF#VJMEFS JT UIJT QBSU PG UIF QJDUVSF:

AAFKD QEB 1LRQB!RFIABO /PX XF IBWF PVS 3PVUF#VJMEFS XF OFFE UP BEE/DPOOFDU JU UP PVS $BNFM$POUFYU UIBU JT UIF IFBSUI PG $BNFM. 4P UVSOJOH CBDL UP PVS XFCTFSWJDF JNQMFNFOUBUJPO DMBTT 3FQPSU*ODJEFOU&OEQPJOU*NQM XF BEE UIJT DPOTUSVDUPS UP UIF DPEF, UP DSFBUF UIF $BNFM$POUFYU BOE BEE UIF SPVUFT GSPN PVS SPVUF CVJMEFS BOE GJOBMMZ UP TUBSU JU.

5 65 0 3 *"-4

169

private CamelContext context; public ReportIncidentEndpointImpl() throws Exception { // create the context context = new DefaultCamelContext(); // append the routes to the context context.addRoutes(new ReportIncidentRoutes()); // at the end start the camel context context.start(); }

0LBZ IPX EP ZPV VTF UIF SPVUFT UIFO 8FMM JUT KVTU BT CFGPSF XF VTF B 1SPEVDFS5FNQMBUF UP TFOE NFTTBHFT UP &OEQPJOUT, TP XF KVTU TFOE UP UIF AFOB@Q:PQ>OQ FOEQPJOU BOE JU XJMM UBLF JU GSPN UIFSF. 4P XF JNQMFNFOU UIF MPHJD JO PVS XFCTFSWJDF PQFSBUJPO:
/** * This is the last solution displayed that is the most simple */ public OutputReportIncident reportIncident(InputReportIncident parameters) { Object mailBody = context.createProducerTemplate().sendBody("direct:start", parameters); System.out.println("Body:" + mailBody); // return an OK reply OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; }

/PUJDF UIBU XF HFU UIF QSPEVDFS UFNQMBUF VTJOH UIF @OB>QB/OLAR@BO3BJMI>QB NFUIPE PO UIF $BNFM$POUFYU. 5IFO XF TFOE UIF JOQVU QBSBNFUFST UP UIF AFOB@Q:PQ>OQ FOEQPJOU BOE JU XJMM SPVUF JU QL UIF WFMPDJUZ FOEQPJOU UIBU XJMM HFOFSBUF UIF NBJM CPEZ. 4JODF XF VTF AFOB@Q BT UIF DPOTVNFS FOEQPJOU (=GSPN) BOE JUT B PVK@EOLKLRP FYDIBOHF XF XJMM HFU UIF SFTQPOTF CBDL GSPN UIF SPVUF. "OE UIF SFTQPOTF JT PG DPVSTF UIF PVUQVU GSPN UIF WFMPDJUZ FOEQPJOU. 8F IBWF OPX DPNQMFUFE UIJT QBSU PG UIF QJDUVSF:

4-(3 3$23(-&
/PX JT UIF UJNF XF XPVME MJLF UP VOJU UFTU XIBU XF HPU OPX. 4P XF DBMM GPS DBNFM BOE JUT HSFBU UFTU LJU. 'PS UIJT UP XPSL XF OFFE UP BEE JU UP UIF QPN.YNM

170

56 50 3* " - 4

?LRQ @OB>QFKD /OLAR@BO3BJMI>QB *O UIF FYBNQMF BCPWF XF DSFBUF B OFX ProducerTemplate XIFO UIF reportIncident NFUIPE JT JOWPLFE. )PXFWFS JO SFBMJUZ ZPV TIPVME POMZ DSFBUF UIF UFNQMBUF PODF BOE SF-VTF JU. 4FF UIJT '"2 FOUSZ.

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>1.4.0</version> <scope>test</scope> <type>test-jar</type> </dependency>

"GUFS BEEJOH JU UP UIF QPN.YNM ZPV TIPVME SFGSFTI ZPVS +BWB &EJUPS TP JU QJDLVQT UIF OFX KBS. 5IFO XF BSF SFBEZ UP DSFBUF PVU VOJU UFTU DMBTT. 8F DSFBUF UIJT VOJU UFTU TLFMFUPO, XIFSF XF BUQBKA UIJT DMBTT ContextTestSupport
package org.apache.camel.example.reportincident; import org.apache.camel.ContextTestSupport; import org.apache.camel.builder.RouteBuilder; /** * Unit test of our routes */ public class ReportIncidentRoutesTest extends ContextTestSupport { }

ContextTestSupport JT B TVQQPSUJOH VOJU UFTU DMBTT GPS NVDI FBTJFS VOJU UFTUJOH XJUI "QBDIF $BNFM. 5IF DMBTT JT FYUFOEJOH +6OJU 5FTU$BTF JUTFMG TP ZPV HFU BMM JUT HMPSZ. 8IBU XF OFFE UP EP OPX JT UP TPNFIPX UFMM UIJT VOJU UFTU DMBTT UIBU JU TIPVME VTF PVS SPVUF CVJMEFS BT UIJT JT UIF POF XF HPOOB UFTU. 4P XF EP UIJT CZ JNQMFNFOUJOH UIF createRouteBuilder NFUIPE.
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new ReportIncidentRoutes(); }

5IBU JT FBTZ KVTU SFUVSO BO JOTUBODF PG PVS SPVUF CVJMEFS BOE UIJT VOJU UFTU XJMM VTF PVS SPVUFT. 8F UIFO DPEF PVS VOJU UFTU NFUIPE UIBU TFOET B NFTTBHF UP UIF SPVUF BOE BTTFSU UIBU JUT USBOTGPSNFE UP UIF NBJM CPEZ VTJOH UIF 7FMPDJUZ UFNQMBUF.

5 65 0 3 *"-4

171

*U JT RVJUF DPNNPO JO $BNFM JUTFMG UP VOJU UFTU VTJOH SPVUFT EFGJOFE BT BO BOPOZNPVT JOOFS DMBTT, TVDI BT JMMVTUSBUFE CFMPX:
protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // TODO: Add your routes here, such as: from("jms:queue:inbox").to("file://target/out"); } }; }

5IF TBNF UFDIOJRVF JT PG DPVSTF BMTP QPTTJCMF GPS FOE-VTFST PG $BNFM UP DSFBUF QBSUT PG ZPVS SPVUFT BOE UFTU UIFN TFQBSBUFMZ JO NBOZ UFTU DMBTTFT. )PXFWFS JO UIJT UVUPSJBM XF UFTU UIF SFBM SPVUF UIBU JT UP CF VTFE GPS QSPEVDUJPO, TP XF KVTU SFUVSO BO JOTUBODF PG UIF SFBM POF.

public void testTransformMailBody() throws Exception { // create a dummy input with some input data InputReportIncident parameters = createInput(); // send the message (using the sendBody method that takes a parameters as the input body) // to "direct:start" that kick-starts the route // the response is returned as the out object, and its also the body of the response Object out = context.createProducerTemplate().sendBody("direct:start", parameters); // convert the response to a string using camel converters. However we could also have casted it to // a string directly but using the type converters ensure that Camel can convert it if it wasn't a string // in the first place. The type converters in Camel is really powerful and you will later learn to // appreciate them and wonder why its not build in Java out-of-the-box String body = context.getTypeConverter().convertTo(String.class, out); // do some simple assertions of the mail body assertTrue(body.startsWith("Incident 123 has been reported on the 2008-07-16 by Claus Ibsen.")); } /** * Creates a dummy request to be used for input */ protected InputReportIncident createInput() { InputReportIncident input = new InputReportIncident();

172

56 50 3* " - 4

input.setIncidentId("123"); input.setIncidentDate("2008-07-16"); input.setGivenName("Claus"); input.setFamilyName("Ibsen"); input.setSummary("bla bla"); input.setDetails("more bla bla"); input.setEmail("davsclaus@apache.org"); input.setPhone("+45 2962 7576"); return input; }

##(-& 3'$ %(+$ ! "*4/


5IF OFYU QJFDF PG QV[[MF UIBU JT NJTTJOH JT UP TUPSF UIF NBJM CPEZ BT B CBDLVQ GJMF. 4P XF UVSO CBDL UP PVS SPVUF BOE UIF &*1 QBUUFSOT. 8F VTF UIF 1JQFT BOE 'JMUFST QBUUFSO IFSF UP DIBJO UIF SPVUJOH BT:
public void configure() throws Exception { from("direct:start") .to("velocity:MailBody.vm") // using pipes-and-filters we send the output from the previous to the next .to("file://target/subfolder"); }

/PUJDF UIBU XF KVTU BEE B 2OE .QL PO UIF OFXMJOF. $BNFM XJMM EFGBVMU VTF UIF 1JQFT BOE 'JMUFST QBUUFSO IFSF XIFO UIFSF BSF NVMUJ FOEQPJOUT DIBJOFE MJLFE UIJT. 8F DPVME IBWF VTFE UIF MFMBIFKB WFSC UP MFU PVU TUBOE PVU UIBU JUT UIF 1JQFT BOE 'JMUFST QBUUFSO TVDI BT:
from("direct:start") // using pipes-and-filters we send the output from the previous to the next .pipeline("velocity:MailBody.vm", "file://target/subfolder");

#VU NPTU QFPQMF BSF VTJOH UIF NVMUJ .QL TUZMF JOTUFBE. 8F SF-SVO PVU VOJU UFTU BOE WFSJGJFT UIBU JU TUJMM QBTTFT:
Running org.apache.camel.example.reportincident.ReportIncidentRoutesTest Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.157 sec

#VU IFZ XF IBWF BEEFE UIF GJMF producer FOEQPJOU BOE UIVT B GJMF TIPVME BMTP CF DSFBUFE BT UIF CBDLVQ GJMF. *G XF MPPL JO UIF target/subfolder XF DBO TFF UIBU TPNFUIJOH IBQQFOFE. 0O NZ IVNCMF MBQUPQ JU DSFBUFE UIJT GPMEFS: Q>ODBQ;PR?CLIABO;(#-@I>RP->@BO. 4P UIF GJMF QSPEVDFS DSFBUF B TVC GPMEFS OBNFE ID-claus-acer XIBU JT UIJT 8FMM $BNFM BVUP HFOFSBUFT BO VOJRVF GJMFOBNF CBTFE PO UIF VOJRVF NFTTBHF JE JG OPU HJWFO JOTUSVDUJPOT UP VTF B GJYFE GJMFOBNF. *O GBDU JU DSFBUFT BOPUIFS TVC GPMEFS BOE OBNF UIF GJMF BT: UBSHFU=TVCGPMEFS=*%-

5 65 0 3 *"-4

173

DMBVT-BDFS=3750-1219148558921=1-0 XIFSF 1-0 JT UIF GJMF XJUI UIF NBJM CPEZ. 8IBU XF XBOU JT UP VTF PVS PXO GJMFOBNF JOTUFBE PG UIJT BVUP HFOFSBUFE GJMFOBNF. 5IJT JT BSDIJWFE CZ BEEJOH B IFBEFS UP UIF NFTTBHF XJUI UIF GJMFOBNF UP VTF. 4P XF OFFE UP BEE UIJT UP PVS SPVUF BOE DPNQVUF UIF GJMFOBNF CBTFE PO UIF NFTTBHF DPOUFOU. 2BQQFKD QEB CFIBK>JB 'PS TUBSUFST XF TIPX UIF TJNQMF TPMVUJPO BOE CVJME GSPN UIFSF. 8F TUBSU CZ TFUUJOH B DPOTUBOU GJMFOBNF, KVTU UP WFSJGZ UIBU XF BSF PO UIF SJHIU QBUI, UP JOTUSVDU UIF GJMF QSPEVDFS XIBU GJMFOBNF UP VTF. 5IF GJMF QSPEVDFS VTFT B TQFDJBM IFBEFS FileComponent.HEADER_FILE_NAME UP TFU UIF GJMFOBNF. 8IBU XF EP JT UP TFOE UIF IFBEFS XIFO XF "LJDL-TUBSU" UIF SPVUJOH BT UIF IFBEFS XJMM CF QSPQBHBUFE GSPN UIF EJSFDU RVFVF UP UIF GJMF QSPEVDFS. 8IBU XF OFFE UP EP JT UP VTF UIF ProducerTemplate.sendBodyAndHeader NFUIPE UIBU UBLFT ?LQE B CPEZ BOE B IFBEFS. 4P XF DIBOHF PVU XFCTFSWJDF DPEF UP JODMVEF UIF GJMFOBNF BMTP:
public OutputReportIncident reportIncident(InputReportIncident parameters) { // create the producer template to use for sending messages ProducerTemplate producer = context.createProducerTemplate(); // send the body and the filename defined with the special header key Object mailBody = producer.sendBodyAndHeader("direct:start", parameters, FileComponent.HEADER_FILE_NAME, "incident.txt"); System.out.println("Body:" + mailBody); // return an OK reply OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; }

)PXFWFS XF DPVME BMTP IBWF VTFE UIF SPVUF CVJMEFS JUTFMG UP DPOGJHVSF UIF DPOTUBOU GJMFOBNF BT TIPXO CFMPX:
public void configure() throws Exception { from("direct:start") .to("velocity:MailBody.vm") // set the filename to a constant before the file producer receives the message .setHeader(FileComponent.HEADER_FILE_NAME, constant("incident.txt")) .to("file://target/subfolder"); }

#VU $BNFM DBO CF TNBSUFS BOE XF XBOU UP EZOBNJD TFU UIF GJMFOBNF CBTFE PO TPNF PG UIF JOQVU QBSBNFUFST, IPX DBO XF EP UIJT 8FMM UIF PCWJPVT TPMVUJPO JT UP DPNQVUF BOE TFU UIF GJMFOBNF GSPN UIF XFCTFSWJDF JNQMFNFOUBUJPO, CVU UIFO UIF XFCTFSWJDF JNQMFNFOUBUJPO IBT TVDI MPHJD BOE XF XBOU UIJT EFDPVQMFE, TP XF DPVME DSFBUF PVS PXO 10+0 CFBO UIBU IBT B NFUIPE UP DPNQVUF UIF

174

56 50 3* " - 4

GJMFOBNF. 8F DPVME UIFO JOTUSVDU UIF SPVUJOH UP JOWPLF UIJT NFUIPE UP HFU UIF DPNQVUFE GJMFOBNF. 5IJT JT B TUSJOH GFBUVSF JO $BNFM, JUT #FBO CJOEJOH. 4P MFUT TIPX IPX UIJT DBO CF EPOF:

4PFKD !B>K +>KDR>DB QL @LJMRQB QEB CFIBK>JB


'JSTU XF DSFBUF PVS QMBJO KBWB DMBTT UIBU DPNQVUFT UIF GJMFOBNF, BOE JU IBT 100% OP EFQFOEFODJFT UP $BNFM XIBU TP FWFS.
/** * Plain java class to be used for filename generation based on the reported incident */ public class FilenameGenerator { public String generateFilename(InputReportIncident input) { // compute the filename return "incident-" + input.getIncidentId() + ".txt"; } }

5IF DMBTT JT WFSZ TJNQMF BOE XF DPVME FBTJMZ DSFBUF VOJU UFTUT GPS JU UP WFSJGZ UIBU JU XPSLT BT FYQFDUFE. 4P XIBU XF XBOU OPX JT UP MFU $BNFM JOWPLF UIJT DMBTT BOE JUT HFOFSBUF'JMFOBNF XJUI UIF JOQVU QBSBNFUFST BOE VTF UIF PVUQVU BT UIF GJMFOBNF. 1IFFFXX JT UIJT SFBMMZ QPTTJCMF PVU-PGUIF-CPY JO $BNFM :FT JU JT. 4P MFUT HFU PO XJUI UIF TIPX. 8F IBWF UIF DPEF UIBU DPNQVUFT UIF GJMFOBNF, XF KVTU OFFE UP DBMM JU GSPN PVS SPVUF VTJOH UIF #FBO -BOHVBHF:
public void configure() throws Exception { from("direct:start") // set the filename using the bean language and call the FilenameGenerator class. // the 2nd null parameter is optional methodname, to be used to avoid ambiguity. // if not provided Camel will try to figure out the best method to invoke, as we // only have one method this is very simple .setHeader(FileComponent.HEADER_FILE_NAME, BeanLanguage.bean(FilenameGenerator.class, null)) .to("velocity:MailBody.vm") .to("file://target/subfolder"); }

/PUJDF UIBU XF VTF UIF ?B>K MBOHVBHF XIFSF XF TVQQMZ UIF DMBTT XJUI PVS CFBO UP JOWPLF. $BNFM XJMM JOTUBOUJBUF BO JOTUBODF PG UIF DMBTT BOE JOWPLF UIF TVJUFE NFUIPE. 'PS DPNQMFUFOFTT BOE FBTF PG DPEF SFBEBCJMJUZ XF BEE UIF NFUIPE OBNF BT UIF 2OE QBSBNFUFS
.setHeader(FileComponent.HEADER_FILE_NAME, BeanLanguage.bean(FilenameGenerator.class, "generateFilename"))

5 65 0 3 *"-4

175

5IFO PUIFS EFWFMPQFST DBO VOEFSTUBOE XIBU UIF QBSBNFUFS JT, JOTUFBE PG null. /PX XF IBWF B OJDF TPMVUJPO, CVU BT B TJEFUSBDL * XBOU UP EFNPOTUSBUF UIF $BNFM IBT PUIFS MBOHVBHFT PVU-PG-UIF-CPY, BOE UIBU TDSJQUJOH MBOHVBHF JT B GJSTU DMBTT DJUJ[FO JO $BNFM XIFSF JU FUD. DBO CF VTFE JO DPOUFOU CBTFE SPVUJOH. )PXFWFS XF XBOU JU UP CF VTFE GPS UIF GJMFOBNF HFOFSBUJPO. 8IBUFWFS XPSLFE GPS ZPV XF IBWF OPX JNQMFNFOUFE UIF CBDLVQ PG UIF EBUB GJMFT:

2$-#(-& 3'$ $, (+
8IBU XF OFFE UP EP CFGPSF UIF TPMVUJPO JT DPNQMFUFE JT UP BDUVBMMZ TFOE UIF FNBJM XJUI UIF NBJM CPEZ XF HFOFSBUFE BOE TUPSFE BT B GJMF. *O UIF QSFWJPVT QBSU XF EJE UIJT XJUI B 'JMF DPOTVNFS, UIBU XF NBOVBMMZ BEEFE UP UIF $BNFM$POUFYU. 8F DBO EP UIJT RVJUF FBTJMZ XJUI UIF SPVUJOH.
import org.apache.camel.builder.RouteBuilder; public class ReportIncidentRoutes extends RouteBuilder { public void configure() throws Exception { // first part from the webservice -> file backup from("direct:start") .setHeader(FileComponent.HEADER_FILE_NAME, bean(FilenameGenerator.class, "generateFilename")) .to("velocity:MailBody.vm") .to("file://target/subfolder"); // second part from the file backup -> send email from("file://target/subfolder") // set the subject of the email .setHeader("subject", constant("new incident reported")) // send the email .to("smtp://someone@localhost?password=secret&to=incident@mycompany.com"); } }

5IF MBTU 3 MJOFT PG DPEF EPFT BMM UIJT. *U BEET B GJMF DPOTVNFS COLJ("CFIB://Q>ODBQ/ PR?CLIABO"), TFUT UIF NBJM TVCKFDU, BOE GJOBMMZ TFOE JU BT BO FNBJM. 5IF %4- JT SFBMMZ QPXFSGVM XIFSF ZPV DBO FYQSFTT ZPVS SPVUJOH JOUFHSBUJPO MPHJD. 4P XF DPNQMFUFE UIF MBTU QJFDF JO UIF QJDUVSF QV[[MF XJUI KVTU 3 MJOFT PG DPEF. 8F IBWF OPX DPNQMFUFE UIF JOUFHSBUJPO:

176

56 50 3* " - 4

4PFKD > P@OFMQ I>KDR>DB QL PBQ QEB CFIBK>JB


8F DPVME EP BT JO UIF QSFWJPVT QBSUT XIFSF XF TFOE UIF DPNQVUFE GJMFOBNF BT B NFTTBHF IFBEFS XIFO XF "LJDL-TUBSU" UIF SPVUF. #VU XF XBOU UP MFBSO OFX TUVGG TP XF MPPL GPS B EJGGFSFOU TPMVUJPO VTJOH TPNF PG $BNFMT NBOZ -BOHVBHFT. "T 0(/- JT B GBWPSJUF MBOHVBHF PG NJOF (VTFE CZ 8FC8PSL) TP XF QJDL UIJT CBCZ GPS B $BNFM SJEF. 'PS TUBSUFST XF NVTU BEE JU UP PVS QPN.YNM:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ognl</artifactId> <version>${camel-version}</version> </dependency>

"OE SFNFNCFS UP SFGSFTI ZPVS FEJUPS TP ZPV HPU UIF OFX .KBST. 8F XBOU UP DPOTUSVDU UIF GJMFOBNF CBTFE PO UIJT TZOUBY: mail-incident-#ID#.txt XIFSF #*%# JT UIF JODJEFOU JE GSPN UIF JOQVU QBSBNFUFST. "T 0(/- JT B MBOHVBHF UIBU DBO JOWPLF NFUIPET PO CFBO XF DBO JOWPLF UIF getIncidentId() PO UIF NFTTBHF CPEZ BOE UIFO DPODBU JU XJUI UIF GJYFE QSF BOE QPTUGJY TUSJOHT. *O 0(/- HMPSZ UIJT JT EPOF BT:
"'mail-incident-' + request.body.incidentId + '.txt'"

XIFSF request.body.incidentId DPNQVUFT UP:

OBNRBPQ JT UIF */ NFTTBHF. 4FF UIF 0(/- GPS PUIFS QSFEFGJOFE PCKFDUT BWBJMBCMF ?LAV JT UIF CPEZ PG UIF JO NFTTBHF FK@FABKQ(A XJMM JOWPLF UIF getIncidentId() NFUIPE PO UIF CPEZ. 5IF SFTU JT KVTU NPSF PS MFTT SFHVMBS QMBJO DPEF XIFSF XF DBO DPODBU TUSJOHT.
/PX XF HPU UIF FYQSFTTJPO UP EZOBNJD DPNQVUF UIF GJMFOBNF PO UIF GMZ XF OFFE UP TFU JU PO PVS SPVUF TP XF UVSO CBDL UP PVS SPVUF, XIFSF XF DBO BEE UIF 0(/- FYQSFTTJPO:
public void configure() throws Exception { from("direct:start") // we need to set the filename and uses OGNL for this .setHeader(FileComponent.HEADER_FILE_NAME, OgnlExpression.ognl("'mail-incident-' + request.body.incidentId + '.txt'"))

5 65 0 3 *"-4

177

// using pipes-and-filters we send the output from the previous to the next .pipeline("velocity:MailBody.vm", "file://target/subfolder"); }

"OE TJODF XF BSF PO +BWB 1.5 XF DBO VTF UIF TUBUJD JNQPSU PG LDKI TP XF IBWF:
import static org.apache.camel.language.ognl.OgnlExpression.ognl; ... .setHeader(FileComponent.HEADER_FILE_NAME, ognl("'mail-incident-' + request.body.incidentId + '.txt'"))

/PUJDF UIF JNQPSU TUBUJD BMTP BQQMJFT GPS BMM UIF PUIFS MBOHVBHFT, TVDI BT UIF #FBO -BOHVBHF XF VTFE QSFWJPVTMZ.

".-"+42(.8F IBWF KVTU CSJFGMZ UPVDIFE UIF OLRQFKD JO $BNFM BOE TIPXO IPX UP JNQMFNFOU UIFN VTJOH UIF CIRBKQ ?RFIABO TZOUBY JO +BWB. 5IFSF JT NVDI NPSF UP UIF SPVUJOH JO $BNFM UIBO TIPXO IFSF, CVU XF BSF MFBSOJOH TUFQ CZ TUFQ. 8F DPOUJOVF JO QBSU 5. 4FF ZPV UIFSF.

+(-*2
*OUSPEVDUJPO 1BSU 1 1BSU 2 1BSU 3 1BSU 4 1BSU 5 1BSU 6

!$33$1 ),2 31 -2/.13 %.1 "7% 6$!2$15("$ 42(-& / "'$ " ,$+
$POGJHVSJOH +.4 JO "QBDIF $9' CFGPSF 7FSTJPO 2.1.3 JT QPTTJCMF CVU OPU SFBMMZ FBTZ PS OJDF. 5IJT BSUJDMF TIPXT IPX UP VTF "QBDIF $BNFM UP QSPWJEF B CFUUFS +.4 5SBOTQPSU GPS $9'. 4MA>QB: 4JODF $9' 2.1.3 UIFSF JT B OFX XBZ PG DPOGJHVSJOH +.4 (6TJOH UIF +.4$POGJH'FBUVSF). *U NBLFT +.4 DPOGJH GPS $9' BT FBTZ BT XJUI $BNFM. 6TJOH $BNFM GPS +.4 JT TUJMM B HPPE JEFB JG ZPV XBOU UP VTF UIF SJDI GFBUVSF PG $BNFM GPS SPVUJOH BOE PUIFS *OUFHSBUJPO 4DFOBSJPT UIBU $9' EPFT OPU TVQQPSU.
178 56 50 3* " - 4

:PV DBO GJOE UIF PSJHJOBM BOOPVODFNFOU GPS UIJT 5VUPSJBM BOE TPNF BEEJUJPOBM JOGP PO $ISJTUJBO 4DIOFJEFSbT #MPH 2L ELT QL @LKKB@Q M>@EB ">JBI >KA "7%

5IF CFTU XBZ UP DPOOFDU $BNFM BOE $9' JT VTJOH UIF $BNFM USBOTQPSU GPS $9'. 5IJT JT B DBNFM NPEVMF UIBU SFHJTUFST XJUI DYG BT B OFX USBOTQPSU. *U JT RVJUF FBTZ UP DPOGJHVSF.
<bean class="org.apache.camel.component.cxf.transport.CamelTransportFactory"> <property name="bus" ref="cxf" /> <property name="camelContext" ref="camelContext" /> <property name="transportIds"> <list> <value>http://cxf.apache.org/transports/camel</value> </list> </property> </bean>

5IJT CFBO SFHJTUFST XJUI $9' BOE QSPWJEFT B OFX USBOTQPSU QSFGJY DBNFM:// UIBU DBO CF VTFE JO $9' BEESFTT DPOGJHVSBUJPOT. 5IF CFBO SFGFSFODFT B CFBO DYG XIJDI XJMM CF BMSFBEZ QSFTFOU JO ZPVS DPOGJH. 5IF PUIFS SFGSFODFJT B DBNFM DPOUFYU. 8F XJMM MBUFS EFGJOF UIJT CFBO UP QSPWJEF UIF SPVUJOH DPOGJH. 'LT FP ),2 @LKCFDROBA FK ">JBI *O DBNFM ZPV OFFE UXP UIJOHT UP DPOGJHVSF +.4. " $POOFDUJPO'BDUPSZ BOE B +.4$PNQPOFOU. "T $POOFDUJPO'BDUPSZ ZPV DBO TJNQMZ TFU VQ UIF OPSNBM 'BDUPSZ ZPVS +.4 QSPWJEFS PGGFST PS CJOE B +/%* $POOFDUJPO'BDUPSZ. *O UIJT FYBNQMF XF VTF UIF $POOFDUJPO'BDUPSZ QSPWJEFE CZ "DUJWF.2.
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean>

5IFO XF TFU VQ UIF +.4$PNQPOFOU. *U PGGFST B OFX USBOTQPSU QSFGJY UP DBNFM UIBU XF TJNQMZ DBMM KNT. *G XF OFFE TFWFSBM +.4$PNQPOFOUT XF DBO EJGGFSFOUJBUF UIFN CZ UIFJS OBNF.
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory" ref="jmsConnectionFactory" /> <property name="useMessageIDAsCorrelationID" value="true" /> </bean>

:PV DBO GJOE NPSF EFUBJMT BCPVU UIF +.4$PNQPOFOU BU UIF $BNFM 8JLJ. 'PS FYBNQMF ZPV GJOE UIF DPNQMFUF DPOGJHVSBUJPO PQUJPOT BOE B +/%* TBNQMF UIFSF.

5 65 0 3 *"-4

179

2BQQFKD RM QEB "7% @IFBKQ 8F XJMM DPOGJHVSF B TJNQMF $9' XFCTFSWJDF DMJFOU. *U XJMM VTF TUVC DPEF HFOFSBUFE GSPN B XTEM. 5IF XFCTFSWJDF DMJFOU XJMM CF DPOGJHVSFE UP VTF +.4 EJSFDUMZ. :PV DBO BMTP VTF B EJSFDU: &OEQPJOU BOE EP UIF SPVUJOH UP +.4 JO UIF $BNFM $POUFYU.
<client id="CustomerService" xmlns="http://cxf.apache.org/jaxws" xmlns:customer="http://customerservice.example.com/" serviceName="customer:CustomerServiceService" endpointName="customer:CustomerServiceEndpoint" address="camel:jms:queue:CustomerService" serviceClass="com.example.customerservice.CustomerService"> </client>

8F FYQMJDJUMZ DPOGJHVSF TFSWJDF/BNF BOE FOEQPJOU/BNF TP UIFZ BSF OPU SFBE GSPN UIF XTEM. 5IF OBNFT XF VTF BSF BSCJUSBSZ BOE IBWF OP GVSUIFS GVODUJPO CVU XF TFU UIFN UP MPPL OJDF. 5IF TFSWJDFDMBTT QPJOUT UP UIF TFSWJDF JOUFSGBDF UIBU XBT HFOFSBUFE GSPN UIF XTEM. /PX UIF JNQPSUBOU UIJOH JT BEESFTT. )FSF XF UFMM DYG UP VTF UIF DBNFM USBOTQPSU, VTF UIF +NT$PNQPOFOU XIP SFHJTUFSFE UIF QSFGJY "KNT" BOE VTF UIF RVFVF "$VTUPNFS4FSWJDF". 2BQQFKD RM QEB ">JBI"LKQBUQ "T XF EP OPU OFFE BEEJUJPOBM SPVUJOH BO FNQUZ $BNFM$POUFYU CFBO XJMM TVGGJDF.
<camelContext id="camelContext" xmlns="http://activemq.apache.org/camel/schema/spring"> </camelContext>

1RKKFKD QEB $U>JMIB ` %PXOMPBE UIF FYBNQMF QSPKFDU IFSF ` 'PMMPX UIF SFBENF.UYU "LK@IRPFLK "T ZPV IBWF TFFO JO UIJT FYBNQMF ZPV DBO VTF $BNFM UP DPOOFDU TFSWJDFT UP +.4 FBTJMZ XIJMF CFJOH BCMF UP BMTP VTF UIF SJDI JOUFHSBUJPO GFBUVSFT PG "QBDIF $BNFM.

343.1( + 42(-&
` ` ` ` `

7(2 1.4 6(3'

/ "'$ " ,$+

5VUPSJBM VTJOH "YJT 1.4 XJUI "QBDIF $BNFM 1SFSFRVJTJUFT %JTUSJCVUJPO *OUSPEVDUJPO 4FUUJOH VQ UIF QSPKFDU UP SVO "YJT

180

56 50 3* " - 4

1BJLSBA COLJ AFPQOF?RQFLK 5IJT FYBNQMF IBT CFFO SFNPWFE GSPN ">JBI 2.9 POXBSET. "QBDIF "YJT 1.4 JT B WFSZ PME BOE VOTVQQPSUFE GSBNFXPSL. 8F FODPVSBHF VTFST UP VTF $9' JOTUFBE PG "YJT. ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` .BWFO 2 XTEM $POGJHVSJOH "YJT 3VOOJOH UIF &YBNQMF *OUFHSBUJOH 4QSJOH 6TJOH 4QSJOH *OUFHSBUJOH $BNFM $BNFM$POUFYU 4UPSF B GJMF CBDLVQ 3VOOJOH UIF FYBNQMF 6OJU 5FTUJOH 4NBSUFS 6OJU 5FTUJOH XJUI 4QSJOH 6OJU 5FTU DBMMJOH 8FC4FSWJDF "OOPUBUJPOT 5IF &OE 4FF "MTP

/OBOBNRFPFQBP 5IJT UVUPSJBM VTFT .BWFO 2 UP TFUVQ UIF $BNFM QSPKFDU BOE GPS EFQFOEFODJFT GPS BSUJGBDUT. #FPQOF?RQFLK 5IJT TBNQMF JT EJTUSJCVUFE XJUI UIF $BNFM 1.5 EJTUSJCVUJPO BT examples/camel-exampleaxis. (KQOLAR@QFLK "QBDIF "YJT JT/XBT XJEFMZ VTFE BT B XFCTFSWJDF GSBNFXPSL. 4P JO MJOF XJUI TPNF PG UIF PUIFS UVUPSJBMT UP EFNPOTUSBUF IPX $BNFM JT OPU BO JOWBTJWF GSBNFXPSL CVU JT GMFYJCMF BOE JOUFHSBUFT XFMM XJUI FYJTUJOH TPMVUJPO. 8F IBWF BO FYJTUJOH TPMVUJPO UIBU FYQPTFT B XFCTFSWJDF VTJOH "YJT 1.4 EFQMPZFE BT XFC BQQMJDBUJPOT. 5IJT JT B DPNNPO TPMVUJPO. 8F VTF DPOUSBDU GJSTU TP XF IBWF "YJT HFOFSBUFE TPVSDF DPEF GSPN BO FYJTUJOH XTEM GJMF. 5IFO XF TIPX IPX XF JOUSPEVDF 4QSJOH BOE $BNFM UP JOUFHSBUF XJUI "YJT. 5IJT UVUPSJBM VTFT UIF GPMMPXJOH GSBNFXPSLT:

5 65 0 3 *"-4

181

` ` ` `

.BWFO 2.0.9 "QBDIF $BNFM 1.5.0 "QBDIF "YJT 1.4 4QSJOH 2.5.5 UFP

2BQQFKD RM QEB MOLGB@Q QL ORK

5IJT GJSTU QBSU JT BCPVU HFUUJOH UIF QSPKFDU VQ UP TQFFE XJUI "YJT. 8F BSF OPU UPVDIJOH $BNFM PS 4QSJOH BU UIJT UJNF.

,>SBK 2
"YJT EFQFOEFODJFT JT BWBJMBCMF GPS NBWFO 2 TP XF DPOGJHVSF PVS QPN.YNM BT:
<dependency> <groupId>org.apache.axis</groupId> <artifactId>axis</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.axis</groupId> <artifactId>axis-jaxrpc</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.axis</groupId> <artifactId>axis-saaj</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>axis</groupId> <artifactId>axis-wsdl4j</artifactId> <version>1.5.1</version> </dependency> <dependency> <groupId>commons-discovery</groupId> <artifactId>commons-discovery</artifactId> <version>0.4</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.14</version> </dependency>

182

56 50 3* " - 4

5IFO XF OFFE UP DPOGJHVSF NBWFO UP VTF +BWB 1.5 BOE UIF "YJT NBWFO QMVHJO UIBU HFOFSBUFT UIF TPVSDF DPEF CBTFE PO UIF XTEM GJMF:
<!-- to compile with 1.5 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>axistools-maven-plugin</artifactId> <configuration> <sourceDirectory>src/main/resources/</sourceDirectory> <packageSpace>com.mycompany.myschema</packageSpace> <testCases>false</testCases> <serverSide>true</serverSide> <subPackageByFileName>false</subPackageByFileName> </configuration> <executions> <execution> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin>

TPAI
8F VTF UIF TBNF .XTEM GJMF BT UIF 5VUPSJBM-&YBNQMF-3FQPSU*ODJEFOU BOE DPQZ JU UP src/main/ webapp/WEB-INF/wsdl
<?xml version="1.0" encoding="ISO-8859-1"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://reportincident.example.camel.apache.org" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://reportincident.example.camel.apache.org"> <!-- Type definitions for input- and output parameters for webservice --> <wsdl:types> <xs:schema targetNamespace="http://reportincident.example.camel.apache.org"> <xs:element name="inputReportIncident"> <xs:complexType>

5 65 0 3 *"-4

183

<xs:sequence> <xs:element type="xs:string" name="incidentId"/> <xs:element type="xs:string" name="incidentDate"/> <xs:element type="xs:string" name="givenName"/> <xs:element type="xs:string" name="familyName"/> <xs:element type="xs:string" name="summary"/> <xs:element type="xs:string" name="details"/> <xs:element type="xs:string" name="email"/> <xs:element type="xs:string" name="phone"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="outputReportIncident"> <xs:complexType> <xs:sequence> <xs:element type="xs:string" name="code"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> </wsdl:types> <!-- Message definitions for input and output --> <wsdl:message name="inputReportIncident"> <wsdl:part name="parameters" element="tns:inputReportIncident"/> </wsdl:message> <wsdl:message name="outputReportIncident"> <wsdl:part name="parameters" element="tns:outputReportIncident"/> </wsdl:message> <!-- Port (interface) definitions --> <wsdl:portType name="ReportIncidentEndpoint"> <wsdl:operation name="ReportIncident"> <wsdl:input message="tns:inputReportIncident"/> <wsdl:output message="tns:outputReportIncident"/> </wsdl:operation> </wsdl:portType> <!-- Port bindings to transports and encoding - HTTP, document literal encoding is used --> <wsdl:binding name="ReportIncidentBinding" type="tns:ReportIncidentEndpoint"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="ReportIncident"> <soap:operation

184

56 50 3* " - 4

soapAction="http://reportincident.example.camel.apache.org/ReportIncident" style="document"/> <wsdl:input> <soap:body parts="parameters" use="literal"/> </wsdl:input> <wsdl:output> <soap:body parts="parameters" use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <!-- Service definition --> <wsdl:service name="ReportIncidentService"> <wsdl:port name="ReportIncidentPort" binding="tns:ReportIncidentBinding"> <soap:address location="http://reportincident.example.camel.apache.org"/> </wsdl:port> </wsdl:service> </wsdl:definitions>

"LKCFDROFKD

UFP

0LBZ XF BSF OPX TFUVQ GPS UIF DPOUSBDU GJSTU EFWFMPQNFOU BOE DBO HFOFSBUF UIF TPVSDF GJMF. 'PS OPX XF BSF TUJMM POMZ VTJOH TUBOEBSE "YJT BOE OPU 4QSJOH OPS $BNFM. 8F TUJMM OFFE UP TFUVQ "YJT BT B XFC BQQMJDBUJPO TP XF DPOGJHVSF UIF XFC.YNM JO src/main/webapp/WEB-INF/ web.xml BT:
<servlet> <servlet-name>axis</servlet-name> <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>axis</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>

5IF XFC.YNM KVTU SFHJTUFST "YJT TFSWMFU UIBU JT IBOEMJOH UIF JODPNJOH XFC SFRVFTUT UP JUT TFSWMFU NBQQJOH. 8F TUJMM OFFE UP DPOGJHVSF "YJT JUTFMG BOE UIJT JT EPOF VTJOH JUT TQFDJBM DPOGJHVSBUJPO GJMF server-config.wsdd. 8F OFBSMZ HFU UIJT GJMF GPS GSFF JG XF MFU "YJT HFOFSBUF UIF TPVSDF DPEF TP XF SVO UIF NBWFO HPBM:
mvn axistools:wsdl2java

5 65 0 3 *"-4

185

5IF UPPM XJMM HFOFSBUF UIF TPVSDF DPEF CBTFE PO UIF XTEM BOE TBWF UIF GJMFT UP UIF GPMMPXJOH GPMEFS:
.\target\generated-sources\axistools\wsdl2java\org\apache\camel\example\reportincident deploy.wsdd InputReportIncident.java OutputReportIncident.java ReportIncidentBindingImpl.java ReportIncidentBindingStub.java ReportIncidentService_PortType.java ReportIncidentService_Service.java ReportIncidentService_ServiceLocator.java undeploy.wsdd

5IJT JT TUBOEBSE "YJT BOE TP GBS OP $BNFM PS 4QSJOH IBT CFFO UPVDIFE. 5P JNQMFNFOU PVS XFCTFSWJDF XF XJMM BEE PVS DPEF, TP XF DSFBUF B OFX DMBTT AxisReportIncidentService UIBU JNQMFNFOUT UIF QPSU UZQF JOUFSGBDF XIFSF XF DBO JNQMFNFOU PVS DPEF MPHJD XIBU IBQQFOT XIFO UIF XFCTFSWJDF JT JOWPLFE.
package org.apache.camel.example.axis; import org.apache.camel.example.reportincident.InputReportIncident; import org.apache.camel.example.reportincident.OutputReportIncident; import org.apache.camel.example.reportincident.ReportIncidentService_PortType; import java.rmi.RemoteException; /** * Axis webservice */ public class AxisReportIncidentService implements ReportIncidentService_PortType { public OutputReportIncident reportIncident(InputReportIncident parameters) throws RemoteException { System.out.println("Hello AxisReportIncidentService is called from " + parameters.getGivenName()); OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; } }

/PX XF OFFE UP DPOGJHVSF "YJT JUTFMG BOE UIJT JT EPOF VTJOH JUT server-config.wsdd GJMF. 8F OFBSMZ HFU UIJT GPS GPS GSFF GSPN UIF BVUP HFOFSBUFE DPEF, XF DPQZ UIF TUVGG GSPN deploy.wsdd BOE NBEF B GFX NPEJGJDBUJPOT:
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/

186

56 50 3* " - 4

axis/wsdd/providers/java"> <!-- global configuration --> <globalConfiguration> <parameter name="sendXsiTypes" value="true"/> <parameter name="sendMultiRefs" value="true"/> <parameter name="sendXMLDeclaration" value="true"/> <parameter name="axis.sendMinimizedElements" value="true"/> </globalConfiguration> <handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/> <!-- this service is from deploy.wsdd --> <service name="ReportIncidentPort" provider="java:RPC" style="document" use="literal"> <parameter name="wsdlTargetNamespace" value="http://reportincident.example.camel.apache.org"/> <parameter name="wsdlServiceElement" value="ReportIncidentService"/> <parameter name="schemaUnqualified" value="http://reportincident.example.camel.apache.org"/> <parameter name="wsdlServicePort" value="ReportIncidentPort"/> <parameter name="className" value="org.apache.camel.example.reportincident.ReportIncidentBindingImpl"/> <parameter name="wsdlPortType" value="ReportIncidentService"/> <parameter name="typeMappingVersion" value="1.2"/> <operation name="reportIncident" qname="ReportIncident" returnQName="retNS:outputReportIncident" xmlns:retNS="http://reportincident.example.camel.apache.org" returnType="rtns:>outputReportIncident" xmlns:rtns="http://reportincident.example.camel.apache.org" soapAction="http://reportincident.example.camel.apache.org/ ReportIncident" > <parameter qname="pns:inputReportIncident" xmlns:pns="http://reportincident.example.camel.apache.org" type="tns:>inputReportIncident" xmlns:tns="http://reportincident.example.camel.apache.org"/> </operation> <parameter name="allowedMethods" value="reportIncident"/> <typeMapping xmlns:ns="http://reportincident.example.camel.apache.org" qname="ns:>outputReportIncident" type="java:org.apache.camel.example.reportincident.OutputReportIncident" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="" /> <typeMapping xmlns:ns="http://reportincident.example.camel.apache.org" qname="ns:>inputReportIncident" type="java:org.apache.camel.example.reportincident.InputReportIncident" serializer="org.apache.axis.encoding.ser.BeanSerializerFactory" deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory" encodingStyle="" /> </service>

5 65 0 3 *"-4

187

<!-- part of Axis configuration --> <transport name="http"> <requestFlow> <handler type="URLMapper"/> <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/> </requestFlow> </transport> </deployment>

5IF DIL?>I"LKCFDRO>QFLK BOE QO>KPMLOQ JT OPU JO UIF EFQMPZ.XTEE GJMF TP ZPV HPUUB XSJUF UIBU ZPVSTFMG. 5IF PBOSF@B JT B 100% DPQZ GSPN EFQMPZ.XTEE. "YJT IBT NPSF DPOGJHVSBUJPO UP JU UIBO TIPXO IFSF, CVU UIFO ZPV TIPVME DIFDL UIF "YJT EPDVNFOUBUJPO. 8IBU XF OFFE UP EP OPX JT JNQPSUBOU, BT XF OFFE UP NPEJGZ UIF BCPWF DPOGJHVSBUJPO UP VTF PVS XFCTFSWJDF DMBTT UIBO UIF EFGBVMU POF, TP XF DIBOHF UIF DMBTTOBNF QBSBNFUFS UP PVS DMBTT UFP1BMLOQ(K@FABKQ2BOSF@B:
<parameter name="className" value="org.apache.camel.example.axis.AxisReportIncidentService"/>

1RKKFKD QEB $U>JMIB


/PX XF BSF SFBEZ UP SVO PVS FYBNQMF GPS UIF GJSTU UJNF, TP XF VTF +FUUZ BT UIF RVJDL XFC DPOUBJOFS VTJOH JUT NBWFO DPNNBOE:
mvn jetty:run

5IFO XF DBO IJU UIF XFC CSPXTFS BOE FOUFS UIJT 63-: http://localhost:8080/ camel-example-axis/services BOE ZPV TIPVME TFF UIF GBNPVT "YJT TUBSU QBHF XJUI UIF UFYU KA KLT... 2LJB 2BOSF@BP. $MJDLJOH PO UIF .XTEM MJOL TIPXT UIF XTEM GJMF, CVU XIBU. *U'T BO BVUP HFOFSBUFE POF BOE OPU PVS PSJHJOBM .XTEM GJMF. 4P XF OFFE UP GJY UIJT "4"1 BOE UIJT JT EPOF CZ DPOGJHVSJOH "YJT JO UIF TFSWFS-DPOGJH.XTEE GJMF:
<service name="ReportIncidentPort" provider="java:RPC" style="document" use="literal"> <wsdlFile>/WEB-INF/wsdl/report_incident.wsdl</wsdlFile> ...

8F EP UIJT CZ BEEJOH UIF XTEM'JMF UBH JO UIF TFSWJDF FMFNFOU XIFSF XF DBO QPJOU UP UIF SFBM .XTEM GJMF.

188

56 50 3* " - 4

(KQBDO>QFKD 2MOFKD 'JSTU XF OFFE UP BEE JUT EFQFOEFODJFT UP UIF MLJ.UJI.


<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>2.5.5</version> </dependency>

4QSJOH JT JOUFHSBUFE KVTU BT JU XPVME MJLF UP, XF BEE JUT MJTUFOFS UP UIF XFC.YNM BOE B DPOUFYU QBSBNFUFS UP CF BCMF UP DPOGJHVSF QSFDJTFMZ XIBU TQSJOH YNM GJMFT UP VTF:
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:axis-example-context.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>

/FYU JT UP BEE B QMBJO TQSJOH 9.- GJMF OBNFE >UFP-BU>JMIB-@LKQBUQ.UJI JO UIF TSD/NBJO/ SFTPVSDFT GPMEFS.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans-2.5.xsd"> </beans>

5IF TQSJOH 9.- GJMF JT DVSSFOUMZ FNQUZ. 8F IJU KFUUZ BHBJO XJUI mvn jetty:run KVTU UP NBLF TVSF 4QSJOH XBT TFUVQ DPSSFDUMZ.

4PFKD 2MOFKD
8F XPVME MJLF UP CF BCMF UP HFU IPME PG UIF 4QSJOH "QQMJDBUJPO$POUFYU GSPN PVS XFCTFSWJDF TP XF DBO HFU BDDFTT UP UIF HMPSZ TQSJOH, CVU IPX EP XF EP UIJT "OE PVS XFCTFSWJDF DMBTT "YJT3FQPSU*ODJEFOU4FSWJDF JT DSFBUFE BOE NBOBHFE CZ "YJT XF XBOU UP MFU 4QSJOH EP UIJT. 4P XF IBWF UXP QSPCMFNT.

5 65 0 3 *"-4

189

8F TPMWF UIFTF QSPCMFNT CZ DSFBUJOH B EFMFHBUF DMBTT UIBU "YJT DSFBUFT, BOE UIJT EFMFHBUF DMBTT HFUT IPME PO 4QSJOH BOE UIFO HFUT PVS SFBM XFCTFSWJDF BT B TQSJOH CFBO BOE JOWPLF UIF TFSWJDF. 'JSTU XF DSFBUF B OFX DMBTT UIBU JT 100% JOEFQFOEFOU GSPN "YJT BOE KVTU B QMBJO 10+0. 5IJT JT PVS SFBM TFSWJDF.
package org.apache.camel.example.axis; import org.apache.camel.example.reportincident.InputReportIncident; import org.apache.camel.example.reportincident.OutputReportIncident; /** * Our real service that is not tied to Axis */ public class ReportIncidentService { public OutputReportIncident reportIncident(InputReportIncident parameters) { System.out.println("Hello ReportIncidentService is called from " + parameters.getGivenName()); OutputReportIncident out = new OutputReportIncident(); out.setCode("OK"); return out; } }

4P OPX XF OFFE UP HFU GSPN "YJT3FQPSU*ODJEFOU4FSWJDF UP UIJT POF 3FQPSU*ODJEFOU4FSWJDF VTJOH 4QSJOH. 8FMM GJSTU PG BMM XF BEE PVS SFBM TFSWJDF UP TQSJOH 9.- DPOGJHVSBUJPO GJMF TP 4QSJOH DBO IBOEMF JUT MJGFDZDMF:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans-2.5.xsd"> <bean id="incidentservice" class="org.apache.camel.example.axis.ReportIncidentService"/> </beans>

"OE UIFO XF OFFE UP NPEJGZ "YJT3FQPSU*ODJEFOU4FSWJDF UP VTF 4QSJOH UP MPPLVQ UIF TQSJOH CFBO FA="FK@FABKQPBOSF@B" BOE EFMFHBUF UIF DBMM. 8F EP UIJT CZ FYUFOEJOH UIF TQSJOH DMBTT org.springframework.remoting.jaxrpc.ServletEndpointSupport TP UIF SFGBDUPSFE DPEF JT:

190

56 50 3* " - 4

package org.apache.camel.example.axis; import import import import org.apache.camel.example.reportincident.InputReportIncident; org.apache.camel.example.reportincident.OutputReportIncident; org.apache.camel.example.reportincident.ReportIncidentService_PortType; org.springframework.remoting.jaxrpc.ServletEndpointSupport;

import java.rmi.RemoteException; /** * Axis webservice */ public class AxisReportIncidentService extends ServletEndpointSupport implements ReportIncidentService_PortType { public OutputReportIncident reportIncident(InputReportIncident parameters) throws RemoteException { // get hold of the spring bean from the application context ReportIncidentService service = (ReportIncidentService) getApplicationContext().getBean("incidentservice"); // delegate to the real service return service.reportIncident(parameters); } }

5P TFF JG FWFSZUIJOH JT PLBZ XF SVO mvn jetty:run. *O UIF DPEF BCPWF XF HFU IPME PG PVS TFSWJDF BU FBDI SFRVFTU CZ MPPLJOH VQ JO UIF BQQMJDBUJPO DPOUFYU. )PXFWFS 4QSJOH BMTP TVQQPSUT BO FKFQ NFUIPE XIFSF XF DBO EP UIJT PODF. 4P XF DIBOHF UIF DPEF UP:
public class AxisReportIncidentService extends ServletEndpointSupport implements ReportIncidentService_PortType { private ReportIncidentService service; @Override protected void onInit() throws ServiceException { // get hold of the spring bean from the application context service = (ReportIncidentService) getApplicationContext().getBean("incidentservice"); } public OutputReportIncident reportIncident(InputReportIncident parameters) throws RemoteException { // delegate to the real service return service.reportIncident(parameters); } }

5 65 0 3 *"-4

191

4P OPX XF IBWF JOUFHSBUFE "YJT XJUI 4QSJOH BOE XF BSF SFBEZ GPS $BNFM. (KQBDO>QFKD ">JBI "HBJO UIF GJSTU TUFQ JT UP BEE UIF EFQFOEFODJFT UP UIF NBWFO MLJ.UJI GJMF:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>1.5.0</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>1.5.0</version> </dependency>

/PX UIBU XF IBWF JOUFHSBUFE XJUI 4QSJOH UIFO XF FBTJMZ JOUFHSBUF XJUI $BNFM BT $BNFM XPSLT XFMM XJUI 4QSJOH. 8F DIPPTF UP JOUFHSBUF $BNFM JO UIF 4QSJOH 9.- GJMF TP XF BEE UIF DBNFM OBNFTQBDF BOE UIF TDIFNB MPDBUJPO:
xmlns:camel="http://activemq.apache.org/camel/schema/spring" http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/ spring/camel-spring.xsd"

">JBI"LKQBUQ
$BNFM$POUFYU JT UIF IFBSU PG $BNFM JUT XIFSF BMM UIF SPVUFT, FOEQPJOUT, DPNQPOFOUT, FUD. JT SFHJTUFSFE. 4P XF TFUVQ B $BNFM$POUFYU BOE UIF TQSJOH 9.- GJMFT MPPLT MJLF:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://activemq.apache.org/camel/schema/spring" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans-2.5.xsd http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/ camel/schema/spring/camel-spring.xsd"> <bean id="incidentservice" class="org.apache.camel.example.axis.ReportIncidentService"/> <camel:camelContext id="camel"> <!-- TODO: Here we can add Camel stuff -->

192

56 50 3* " - 4

">JBI ALBP KLQ OBNRFOB 2MOFKD $BNFM EPFT OPU SFRVJSF 4QSJOH, XF DPVME FBTJMZ IBWF VTFE $BNFM XJUIPVU 4QSJOH, CVU NPTU VTFST QSFGFS UP VTF 4QSJOH BMTP.

</camel:camelContext> </beans>

2QLOB > CFIB ?>@HRM


8F XBOU UP TUPSF UIF XFC TFSWJDF SFRVFTU BT B GJMF CFGPSF XF SFUVSO B SFTQPOTF. 5P EP UIJT XF XBOU UP TFOE UIF GJMF DPOUFOU BT B NFTTBHF UP BO FOEQPJOU UIBU QSPEVDFT UIF GJMF. 4P XF OFFE UP EP UXP TUFQT: DPOGJHVSF UIF GJMF CBDLVQ FOEQPJOU TFOE UIF NFTTBHF UP UIF FOEQPJOU 5IF FOEQPJOU JT DPOGJHVSFE JO TQSJOH 9.- TP XF KVTU BEE JU BT:
<camel:camelContext id="camelContext"> <!-- endpoint named backup that is configued as a file component --> <camel:endpoint id="backup" uri="file://target?append=false"/> </camel:camelContext>

*O UIF $BNFM$POUFYU XF IBWF EFGJOFE PVS FOEQPJOU XJUI UIF JE backup BOE DPOGJHVSFE JU VTF UIF 63- OPUBUJPO UIBU XF LOPX GSPN UIF JOUFSOFU. *UT B file TDIFNF UIBU BDDFQUT B DPOUFYU BOE TPNF PQUJPOT. 5IF DPOUFTU JT target BOE JUT UIF GPMEFS UP TUPSF UIF GJMF. 5IF PQUJPO JT KVTU BT UIF JOUFSOFU XJUI BOE & GPS TVCTFRVFOU PQUJPOT. 8F DPOGJHVSF JU UP OPU BQQFOE, NFBOJOH UIBO BOZ FYJTUJOH GJMF XJMM CF PWFSXSJUUFO. 4FF UIF 'JMF DPNQPOFOU GPS PQUJPOT BOE IPX UP VTF UIF DBNFM GJMF FOEQPJOU. /FYU VQ JT UP CF BCMF UP TFOE B NFTTBHF UP UIJT FOEQPJOU. 5IF FBTJFTU XBZ JT UP VTF B 1SPEVDFS5FNQMBUF. " 1SPEVDFS5FNQMBUF JT JOTQJSFE CZ 4QSJOH UFNQMBUF QBUUFSO XJUI GPS JOTUBODF +NT5FNQMBUF PS +ECD5FNQMBUF JO NJOE. 5IF UFNQMBUF UIBU BMM UIF HSVOU XPSL BOE FYQPTFT B TJNQMF JOUFSGBDF UP UIF FOE-VTFS XIFSF IF/TIF DBO TFU UIF QBZMPBE UP TFOE. 5IFO UIF UFNQMBUF XJMM EP QSPQFS SFTPVSDF IBOEMJOH BOE BMM SFMBUFE JTTVFT JO UIBU SFHBSE. #VU IPX EP XF HFU IPME PG TVDI B UFNQMBUF 8FMM UIF $BNFM$POUFYU JT BCMF UP QSPWJEF POF. 5IJT JT EPOF CZ DPOGJHVSJOH UIF UFNQMBUF PO UIF DBNFM DPOUFYU JO UIF TQSJOH 9.- BT:
<camel:camelContext id="camelContext"> <!-- producer template exposed with this id --> <camel:template id="camelTemplate"/>

5 65 0 3 *"-4

193

<!-- endpoint named backup that is configued as a file component --> <camel:endpoint id="backup" uri="file://target?append=false"/> </camel:camelContext>

5IFO XF DBO FYQPTF B 1SPEVDFS5FNQMBUF QSPQFSUZ PO PVS TFSWJDF XJUI B TFUUFS JO UIF +BWB DPEF BT:
public class ReportIncidentService { private ProducerTemplate template; public void setTemplate(ProducerTemplate template) { this.template = template; }

"OE UIFO MFU 4QSJOH IBOEMF UIF EFQFOEFODZ JOKFDU BT CFMPX:


<bean id="incidentservice" class="org.apache.camel.example.axis.ReportIncidentService"> <!-- set the producer template to use from the camel context below --> <property name="template" ref="camelTemplate"/> </bean>

/PX XF BSF SFBEZ UP VTF UIF QSPEVDFS UFNQMBUF JO PVS TFSWJDF UP TFOE UIF QBZMPBE UP UIF FOEQPJOU. 5IF UFNQMBUF IBT NBOZ PBKA777 NFUIPET GPS UIJT QVSQPTF. #VU CFGPSF XF TFOE UIF QBZMPBE UP UIF GJMF FOEQPJOU XF NVTU BMTP TQFDJGZ XIBU GJMFOBNF UP TUPSF UIF GJMF BT. 5IJT JT EPOF CZ TFOEJOH NFUB EBUB XJUI UIF QBZMPBE. *O $BNFM NFUBEBUB JT TFOU BT IFBEFST. )FBEFST JT KVTU B QMBJO Map<String, Object>. 4P JG XF OFFEFE UP TFOE TFWFSBM NFUBEBUB UIFO XF DPVME DPOTUSVDU BO PSEJOBSZ )BTI.BQ BOE QVU UIF WBMVFT JO UIFSF. #VU BT XF KVTU OFFE UP TFOE POF IFBEFS XJUI UIF GJMFOBNF $BNFM IBT B DPOWFOJFOU TFOE NFUIPE sendBodyAndHeader TP XF DIPPTF UIJT POF.
public OutputReportIncident reportIncident(InputReportIncident parameters) { System.out.println("Hello ReportIncidentService is called from " + parameters.getGivenName()); String data = parameters.getDetails(); // store the data as a file String filename = parameters.getIncidentId() + ".txt"; // send the data to the endpoint and the header contains what filename it should be stored as template.sendBodyAndHeader("backup", data, "org.apache.camel.file.name", filename); OutputReportIncident out = new OutputReportIncident(); out.setCode("OK");

194

56 50 3* " - 4

return out; }

5IF UFNQMBUF JO UIF DPEF BCPWF VTFT 4 QBSBNFUFST: UIF FOEQPJOU OBNF, JO UIJT DBTF UIF JE SFGFSSJOH UP UIF FOEQPJOU EFGJOFE JO 4QSJOH 9.JO UIF DBNFM$POUFYU FMFNFOU. UIF QBZMPBE, DBO CF BOZ LJOE PG PCKFDU UIF LFZ GPS UIF IFBEFS, JO UIJT DBTF B $BNFM LFZXPSE UP TFU UIF GJMFOBNF BOE UIF WBMVF GPS UIF IFBEFS 1RKKFKD QEB BU>JMIB 8F TUBSU PVS JOUFHSBUJPO XJUI NBWFO VTJOH mvn jetty:run. 5IFO XF PQFO B CSPXTFS BOE IJU http://localhost:8080. +FUUZ JT TP TNBSU UIBU JU EJTQMBZ B GSPOUQBHF XJUI MJOLT UP UIF EFQMPZFE BQQMJDBUJPO TP KVTU IJU UIF MJOL BOE ZPV HFU PVS BQQMJDBUJPO. /PX XF IJU BQQFOE /TFSWJDFT UP UIF 63- UP BDDFTT UIF "YJT GSPOUQBHF. 5IF 63- TIPVME CF http://localhost:8080/camel-example-axis/services. :PV DBO UIFO UFTU JU VTJOH B XFC TFSWJDF UFTU UPPMT TVDI BT 4PBQ6*. )JUUJOH UIF TFSWJDF XJMM PVUQVU UP UIF DPOTPMF
2008-09-06 15:01:41.718::INFO: Started SelectChannelConnector @ 0.0.0.0:8080 [INFO] Started Jetty Server Hello ReportIncidentService is called from Ibsen

"OE UIFSF TIPVME CF B GJMF JO UIF UBSHFU TVCGPMEFS.


dir target /b 123.txt

4KFQ 3BPQFKD 8F XPVME MJLF UP CF BCMF UP VOJU UFTU PVS 1BMLOQ(K@FABKQ2BOSF@B DMBTT. 4P XF BEE KVOJU UP UIF NBWFO EFQFOEFODZ:
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.2</version> <scope>test</scope> </dependency>

"OE UIFO XF DSFBUF B QMBJO KVOJU UFTUDBTF GPS PVS TFSWJDF DMBTT.

5 65 0 3 *"-4

195

package org.apache.camel.example.axis; import junit.framework.TestCase; import org.apache.camel.example.reportincident.InputReportIncident; import org.apache.camel.example.reportincident.OutputReportIncident; /** * Unit test of service */ public class ReportIncidentServiceTest extends TestCase { public void testIncident() { ReportIncidentService service = new ReportIncidentService(); InputReportIncident input = createDummyIncident(); OutputReportIncident output = service.reportIncident(input); assertEquals("OK", output.getCode()); } protected InputReportIncident createDummyIncident() { InputReportIncident input = new InputReportIncident(); input.setEmail("davsclaus@apache.org"); input.setIncidentId("12345678"); input.setIncidentDate("2008-07-13"); input.setPhone("+45 2962 7576"); input.setSummary("Failed operation"); input.setDetails("The wrong foot was operated."); input.setFamilyName("Ibsen"); input.setGivenName("Claus"); return input; } }

5IFO XF DBO SVO UIF UFTU XJUI NBWFO VTJOH: mvn test. #VU XF XJMM HFU B GBJMVSF:
Running org.apache.camel.example.axis.ReportIncidentServiceTest Hello ReportIncidentService is called from Claus Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.235 sec <<< FAILURE! Results : Tests in error: testIncident(org.apache.camel.example.axis.ReportIncidentServiceTest) Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

8IBU JT UIF QSPCMFN 8FMM PVS TFSWJDF VTFT B $BNFM1SPEVDFS (UIF UFNQMBUF) UP TFOE B NFTTBHF UP UIF GJMF FOEQPJOU TP UIF NFTTBHF XJMM CF TUPSFE JO B GJMF. 8IBU XF OFFE JT UP HFU IPME PG TVDI B QSPEVDFS BOE JOKFDU JU PO PVS TFSWJDF, CZ DBMMJOH UIF TFUUFS.

196

56 50 3* " - 4

4JODF $BNFM JT WFSZ MJHIU XFJHIU BOE FNCFEBCMF XF BSF BCMF UP DSFBUF B $BNFM$POUFYU BOE BEE UIF FOEQPJOU JO PVS VOJU UFTU DPEF EJSFDUMZ. 8F EP UIJT UP TIPX IPX UIJT JT QPTTJCMF:
private CamelContext context; @Override protected void setUp() throws Exception { super.setUp(); // CamelContext is just created like this context = new DefaultCamelContext(); // then we can create our endpoint and set the options FileEndpoint endpoint = new FileEndpoint(); // the endpoint must have the camel context set also endpoint.setCamelContext(context); // our output folder endpoint.setFile(new File("target")); // and the option not to append endpoint.setAppend(false); // then we add the endpoint just in java code just as the spring XML, we register it with the "backup" id. context.addSingletonEndpoint("backup", endpoint); // finally we need to start the context so Camel is ready to rock context.start(); } @Override protected void tearDown() throws Exception { super.tearDown(); // and we are nice boys so we stop it to allow resources to clean up context.stop(); }

4P OPX XF BSF SFBEZ UP TFU UIF 1SPEVDFS5FNQMBUF PO PVS TFSWJDF, BOE XF HFU B IPME PG UIBU CBCZ GSPN UIF $BNFM$POUFYU BT:
public void testIncident() { ReportIncidentService service = new ReportIncidentService(); // get a producer template from the camel context ProducerTemplate template = context.createProducerTemplate(); // inject it on our service using the setter service.setTemplate(template); InputReportIncident input = createDummyIncident(); OutputReportIncident output = service.reportIncident(input); assertEquals("OK", output.getCode()); }

"OE UIJT UJNF XIFO XF SVO UIF VOJU UFTU JUT B TVDDFTT:

5 65 0 3 *"-4

197

Results : Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

8F XPVME MJLF UP UFTU UIBU UIF GJMF FYJTUT TP XF BEE UIFTF UXP MJOFT UP PVS UFTU NFUIPE:
// should generate a file also File file = new File("target/" + input.getIncidentId() + ".txt"); assertTrue("File should exists", file.exists());

2J>OQBO 4KFQ 3BPQFKD TFQE 2MOFKD


5IF VOJU UFTU BCPWF SFRVJSFT VT UP BTTFNCMF UIF $BNFM QJFDFT NBOVBMMZ JO KBWB DPEF. 8IBU JG XF XPVME MJLF PVS VOJU UFTU UP VTF PVS TQSJOH DPOGJHVSBUJPO GJMF >UFP-BU>JMIB-@LKQBUQ.UJI XIFSF XF BMSFBEZ IBWF TFUVQ UIF FOEQPJOU. "OE PG DPVSTF XF XPVME MJLF UP UFTU VTJOH UIJT DPOGJHVSBUJPO GJMF BT UIJT JT UIF SFBM GJMF XF XJMM VTF. 8FMM IFZ QSFTUP UIF YNM GJMF JT B TQSJOH "QQMJDBUJPO$POUFYU GJMF BOE TQSJOH JT BCMF UP MPBE JU, TP XF HP UIF TQSJOH QBUI GPS VOJU UFTUJOH. 'JSTU XF BEE UIF TQSJOH-UFTU KBS UP PVS NBWFO EFQFOEFODZ:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> </dependency>

"OE UIFO XF SFGBDUPS PVS VOJU UFTU UP CF B TUBOEBSE TQSJOH VOJU DMBTT. 8IBU XF OFFE UP EP JT UP FYUFOE AbstractJUnit38SpringContextTests JOTUFBE PG TestCase JO PVS VOJU UFTU. 4JODF 4QSJOH 2.5 FNCSBDFT BOOPUBUJPOT XF XJMM VTF POF BT XFMM UP JOTUSVDU XIBU PVS YNM DPOGJHVSBUJPO GJMF JT MPDBUFE:
@ContextConfiguration(locations = "classpath:axis-example-context.xml") public class ReportIncidentServiceTest extends AbstractJUnit38SpringContextTests {

8IBU XF NVTU SFNFNCFS UP BEE JT UIF @I>PPM>QE: QSFGJY BT PVS YNM GJMF JT MPDBUFE JO src/ main/resources. *G XF PNJU UIF QSFGJY UIFO 4QSJOH XJMM CZ EFGBVMU USZ UP MPDBUF UIF YNM GJMF JO UIF DVSSFOU QBDLBHF BOE UIBU JT PSH.BQBDIF.DBNFM.FYBNQMF.BYJT. *G UIF YNM GJMF JT MPDBUFE PVUTJEF UIF DMBTTQBUI ZPV DBO VTF GJMF: QSFGJY JOTUFBE. 4P XJUI UIFTF UXP NPEJGJDBUJPOT XF DBO HFU SJE PG BMM UIF TFUVQ BOE UFBSEPXO DPEF XF IBE CFGPSF BOE OPX XF XJMM UFTU PVS SFBM DPOGJHVSBUJPO. 5IF MBTU DIBOHF JT UP HFU IPME PG UIF QSPEVDFS UFNQMBUF BOE OPX XF DBO KVTU SFGFS UP UIF CFBO JE JU IBT JO UIF TQSJOH YNM GJMF:

198

56 50 3* " - 4

<!-- producer template exposed with this id --> <camel:template id="camelTemplate"/>

4P XF HFU IPME PG JU CZ KVTU HFUUJOH JU GSPN UIF TQSJOH "QQMJDBUJPO$POUFYU BT BMM TQSJOH VTFST JT VTFE UP EP:
// get a producer template from the the spring context ProducerTemplate template = (ProducerTemplate) applicationContext.getBean("camelTemplate"); // inject it on our service using the setter service.setTemplate(template);

/PX PVS VOJU UFTU JT NVDI CFUUFS, BOE B SFBM QPXFS PG $BNFM JT UIBU JT GJUT OJDFMZ XJUI 4QSJOH BOE ZPV DBO VTF TUBOEBSE 4QSJOH'JTI VOJU UFTU UP UFTU ZPVS $BNFM BQQMJDBUJPOT BT XFMM. 4KFQ 3BPQ @>IIFKD 6B?2BOSF@B 8IBU JG ZPV XPVME MJLF UP FYFDVUF B VOJU UFTU XIFSF ZPV TFOE B XFCTFSWJDF SFRVFTU UP UIF UFP1BMLOQ(K@FABKQ2BOSF@B IPX EP XF VOJU UFTU UIJT POF 8FMM GJSTU PG BMM UIF DPEF JT NFSFMZ KVTU B EFMFHBUF UP PVS SFBM TFSWJDF UIBU XF IBWF KVTU UFTUFE, CVU OFWFSUIFMFTT JUT B HPPE RVFTUJPO BOE XF XPVME MJLF UP LOPX IPX. 8FMM UIF BOTXFS JT UIBU XF DBO FYQMPJU UIBU GBDU UIBU +FUUZ JT BMTP B TMJN XFC DPOUBJOFS UIBU DBO CF FNCFEEFE BOZXIFSF KVTU BT $BNFM DBO. 4P XF BEE UIJT UP PVS QPN.YNM:
<dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <version>${jetty-version}</version> <scope>test</scope> </dependency>

5IFO XF DBO DSFBUF B OFX DMBTT UFP1BMLOQ(K@FABKQ2BOSF@B3BPQ UP VOJU UFTU XJUI +FUUZ. 5IF DPEF UP TFUVQ +FUUZ JT TIPXO CFMPX XJUI DPEF DPNNFOUT:
public class AxisReportIncidentServiceTest extends TestCase { private Server server; private void startJetty() throws Exception { // create an embedded Jetty server server = new Server(); // add a listener on port 8080 on localhost (127.0.0.1) Connector connector = new SelectChannelConnector(); connector.setPort(8080); connector.setHost("127.0.0.1");

5 65 0 3 *"-4

199

server.addConnector(connector); // add our web context path WebAppContext wac = new WebAppContext(); wac.setContextPath("/unittest"); // set the location of the exploded webapp where WEB-INF is located // this is a nice feature of Jetty where we can point to src/main/webapp wac.setWar("./src/main/webapp"); server.setHandler(wac); // then start Jetty server.setStopAtShutdown(true); server.start(); } @Override protected void setUp() throws Exception { super.setUp(); startJetty(); } @Override protected void tearDown() throws Exception { super.tearDown(); server.stop(); } }

/PX XF KVTU OFFE UP TFOE UIF JODJEFOU BT B XFCTFSWJDF SFRVFTU VTJOH "YJT. 4P XF BEE UIF GPMMPXJOH DPEF:
public void testReportIncidentWithAxis() throws Exception { // the url to the axis webservice exposed by jetty URL url = new URL("http://localhost:8080/unittest/services/ ReportIncidentPort"); // Axis stuff to get the port where we can send the webservice request ReportIncidentService_ServiceLocator locator = new ReportIncidentService_ServiceLocator(); ReportIncidentService_PortType port = locator.getReportIncidentPort(url); // create input to send InputReportIncident input = createDummyIncident(); // send the webservice and get the response OutputReportIncident output = port.reportIncident(input); assertEquals("OK", output.getCode()); // should generate a file also File file = new File("target/" + input.getIncidentId() + ".txt"); assertTrue("File should exists", file.exists()); }

200

56 50 3* " - 4

protected InputReportIncident createDummyIncident() { InputReportIncident input = new InputReportIncident(); input.setEmail("davsclaus@apache.org"); input.setIncidentId("12345678"); input.setIncidentDate("2008-07-13"); input.setPhone("+45 2962 7576"); input.setSummary("Failed operation"); input.setDetails("The wrong foot was operated."); input.setFamilyName("Ibsen"); input.setGivenName("Claus"); return input; }

"OE OPX XF IBWF BO VOJUUFTU UIBU TFOET B XFCTFSWJDF SFRVFTU VTJOH HPPE PME "YJT. KKLQ>QFLKP #PUI $BNFM BOE 4QSJOH IBT BOOPUBUJPOT UIBU DBO CF VTFE UP DPOGJHVSF BOE XJSF USJWJBM TFUUJOHT NPSF FMFHBOUMZ. $BNFM IBT UIF FOEQPJOU BOOPUBUJPO @EndpointInjected UIBU JT KVTU XIBU XF OFFE. 8JUI UIJT BOOPUBUJPO XF DBO JOKFDU UIF FOEQPJOU JOUP PVS TFSWJDF. 5IF BOOPUBUJPO UBLFT FJUIFS B OBNF PS VSJ QBSBNFUFS. 5IF OBNF JT UIF CFBO JE JO UIF 3FHJTUSZ. 5IF VSJ JT UIF 63* DPOGJHVSBUJPO GPS UIF FOEQPJOU. 6TJOH UIJT ZPV DBO BDUVBMMZ JOKFDU BO FOEQPJOU UIBU ZPV IBWF OPU EFGJOFE JO UIF DBNFM DPOUFYU. "T XF IBWF EFGJOFE PVS FOEQPJOU XJUI UIF JE ?>@HRM XF VTF UIF OBNF QBSBNFUFS.
@EndpointInject(name = "backup") private ProducerTemplate template;

$BNFM JT TNBSU BT @EndpointInjected TVQQPSUT EJGGFSFOU LJOET PG PCKFDU UZQFT. 8F MJLF UIF 1SPEVDFS5FNQMBUF TP XF KVTU LFFQ JU BT JU JT. 4JODF XF VTF BOOPUBUJPOT PO UIF GJFME EJSFDUMZ XF EP OPU OFFE UP TFU UIF QSPQFSUZ JO UIF TQSJOH YNM GJMF TP XF DIBOHF PVS TFSWJDF CFBO:
<bean id="incidentservice" class="org.apache.camel.example.axis.ReportIncidentService"/>

3VOOJOH UIF VOJU UFTU XJUI mvn test SFWFBMT UIBU JU XPSLT OJDFMZ. "OE TJODF XF VTF UIF @EndpointInjected UIBU SFGFST UP UIF FOEQPJOU XJUI UIF JE CBDLVQ EJSFDUMZ XF DBO MPPTF UIF UFNQMBUF UBH JO UIF YNM, TP JUT TIPSUFS:
<bean id="incidentservice" class="org.apache.camel.example.axis.ReportIncidentService"/> <camel:camelContext id="camelContext">

5 65 0 3 *"-4

201

<!-- producer template exposed with this id --> <camel:template id="camelTemplate"/> <!-- endpoint named backup that is configued as a file component --> <camel:endpoint id="backup" uri="file://target?append=false"/> </camel:camelContext>

"OE UIF GJOBM UPVDI XF DBO EP JT UIBU TJODF UIF FOEQPJOU JT JOKFDUFE XJUI DPODSFUF FOEQPJOU UP VTF XF DBO SFNPWF UIF "backup" OBNF QBSBNFUFS XIFO XF TFOE UIF NFTTBHF. 4P XF DIBOHF GSPN:
// send the data to the endpoint and the header contains what filename it should be stored as template.sendBodyAndHeader("backup", data, "org.apache.camel.file.name", filename);

5P XJUIPVU UIF OBNF:


// send the data to the endpoint and the header contains what filename it should be stored as template.sendBodyAndHeader(data, "org.apache.camel.file.name", filename);

5IFO XF BWPJE UP EVQMJDBUF UIF OBNF BOE JG XF SFOBNF UIF FOEQPJOU OBNF UIFO XF EPO'U GPSHFU UP DIBOHF JU JO UIF DPEF BMTP. 3EB $KA 5IJT UVUPSJBM IBTO'U SFBMMZ UPVDIFE UIF POF PG UIF LFZ DPODFQU PG $BNFM BT B QPXFSGVM SPVUJOH BOE NFEJBUJPO GSBNFXPSL. #VU XF XBOUFE UP EFNPOTUSBUF JUT GMFYJCJMJUZ BOE UIBU JU JOUFHSBUFT XFMM XJUI FWFO PMEFS GSBNFXPSLT TVDI BT "QBDIF "YJT 1.4. $IFDL PVU UIF PUIFS UVUPSJBMT PO $BNFM BOE UIF PUIFS FYBNQMFT. /PUF UIBU UIF DPEF TIPXO IFSF BMTP BQQMJFT UP $BNFM 1.4 TP BDUVBMMZ ZPV DBO HFU TUBSUFE SJHIU BXBZ XJUI UIF SFMFBTFE WFSTJPO PG $BNFM. "T UIJT UJNF PG XSJUJOH $BNFM 1.5 JT XPSL JO QSPHSFTT. 2BB IPL 5VUPSJBMT &YBNQMFT

202

56 50 3* " - 4

343.1( + .- 42(-& " ,$+ (-

6$!

//+(" 3(.-

$BNFM IBT CFFO EFTJHOFE UP XPSL HSFBU XJUI UIF 4QSJOH GSBNFXPSL; TP JG ZPV BSF BMSFBEZ B 4QSJOH VTFS ZPV DBO UIJOL PG $BNFM BT KVTU B GSBNFXPSL GPS BEEJOH UP ZPVS 4QSJOH 9.- GJMFT. 4P ZPV DBO GPMMPX UIF VTVBM 4QSJOH BQQSPBDI UP XPSLJOH XJUI XFC BQQMJDBUJPOT; OBNFMZ UP BEE UIF TUBOEBSE 4QSJOH IPPL UP MPBE B /6$!-(-%/>MMIF@>QFLK"LKQBUQ.UJI GJMF. *O UIBU GJMF ZPV DBO JODMVEF ZPVS VTVBM $BNFM 9.- DPOGJHVSBUJPO. 2QBM1: $AFQ VLRO TB?.UJI 5P FOBCMF TQSJOH BEE B DPOUFYU MPBEFS MJTUFOFS UP ZPVS /6$!-(-%/TB?.UJI GJMF
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ ns/javaee/web-app_2_5.xsd" version="2.5"> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>

5IJT XJMM DBVTF 4QSJOH UP CPPU VQ BOE MPPL GPS UIF /6$!-(-%/>MMIF@>QFLK"LKQBUQ.UJI GJMF. 2QBM 2: "OB>QB > /6$!-(-%/>MMIF@>QFLK"LKQBUQ.UJI CFIB /PX ZPV KVTU OFFE UP DSFBUF ZPVS 4QSJOH 9.- GJMF BOE BEE ZPVS DBNFM SPVUFT PS DPOGJHVSBUJPO. 'PS FYBNQMF
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route>

5 65 0 3 *"-4

203

<from uri="seda:foo"/> <to uri="mock:results"/> </route> </camelContext> </beans>

5IFO CPPU VQ ZPVS XFC BQQMJDBUJPO BOE ZPV'SF HPPE UP HP! 'FKQP >KA 3FMP *G ZPV VTF .BWFO UP CVJME ZPVS BQQMJDBUJPO ZPVS EJSFDUPSZ USFF XJMM MPPL MJLF UIJT...
src/main/webapp/WEB-INF web.xml applicationContext.xml

:PV TIPVME VQEBUF ZPVS .BWFO QPN.YNM UP FOBCMF 8"3 QBDLBHJOH/OBNJOH MJLF UIJT...
<project> ... <packaging>war</packaging> ... <build> <finalName>[desired WAR file name]</finalName> ... </build>

5P FOBCMF NPSF SBQJE EFWFMPQNFOU XF IJHIMZ SFDPNNFOE UIF KFUUZ:SVO NBWFO QMVHJO. 1MFBTF SFGFS UP UIF IFMQ GPS NPSF JOGPSNBUJPO PO VTJOH KFUUZ:SVO - CVU CSJFGMZ JG ZPV BEE UIF GPMMPXJOH UP ZPVS QPN.YNM
<build> <plugins> <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <configuration> <webAppConfig> <contextPath>/</contextPath> </webAppConfig> <scanIntervalSeconds>10</scanIntervalSeconds> </configuration> </plugin> </plugins> </build>

5IFO ZPV DBO SVO ZPVS XFC BQQMJDBUJPO BT GPMMPXT

204

56 50 3* " - 4

mvn jetty:run

5IFO +FUUZ XJMM BMTP NPOJUPS ZPVS UBSHFU/DMBTTFT EJSFDUPSZ BOE ZPVS TSD/NBJO/XFCBQQ EJSFDUPSZ TP UIBU JG ZPV NPEJGZ ZPVS TQSJOH 9.-, ZPVS XFC.YNM PS ZPVS KBWB DPEF UIF XFC BQQMJDBUJPO XJMM CF SFTUBSUFE, SF-DSFBUJOH ZPVS $BNFM SPVUFT. *G ZPVS VOJU UFTUT UBLF B XIJMF UP SVO, ZPV DPVME NJTT UIFN PVU XIFO SVOOJOH ZPVS XFC BQQMJDBUJPO WJB
mvn -Dtest=false jetty:run

343.1( + !42(-$22 / 13-$12 ! "*&1.4-#


!RPFKBPP !>@HDOLRKA 4P UIFSF'T B DPNQBOZ, XIJDI XF'MM DBMM "DNF. "DNF TFMMT XJEHFUT, JO B GBJSMZ VOVTVBM XBZ. 5IFJS DVTUPNFST BSF SFTQPOTJCMF GPS UFMMJOH "DNF XIBU UIFZ QVSDIBTFE. 5IF DVTUPNFS FOUFST JOUP UIFJS PXO TZTUFNT (&31 PS XIBUFWFS) XIJDI XJEHFUT UIFZ CPVHIU GSPN "DNF. 5IFO BU TPNF QPJOU, UIFJS TZTUFNT FNJU B SFDPSE PG UIF TBMF XIJDI OFFET UP HP UP "DNF TP "DNF DBO CJMM UIFN GPS JU. 0CWJPVTMZ, FWFSZPOF XBOUT UIJT UP CF BT BVUPNBUFE BT QPTTJCMF, TP UIFSF OFFET UP CF JOUFHSBUJPO CFUXFFO UIF DVTUPNFS'T TZTUFN BOE "DNF. 4BEMZ, "DNF'T TBMFT QFPQMF BSF, UFDIOJDBMMZ TQFBLJOH, EPPSNBUT. 5IFZ UFMM BMM UIFJS QSPTQFDUT, "ZPV DBO TFOE VT UIF EBUB JO XIBUFWFS GPSNBU, VTJOH XIBUFWFS QSPUPDPMT, XIBUFWFS. :PV KVTU DBO'U DIBOHF PODF JU'T VQ BOE SVOOJOH." 5IF SFTVMU JT QSFUUZ NVDI XIBU ZPV'E FYQFDU. 5BLJOH B SBOEPN TBNQMF PG 3 DVTUPNFST: ` $VTUPNFS 1: 7,+ LSBO %3/ ` $VTUPNFS 2: "25 LSBO '33/ ` $VTUPNFS 3: $U@BI SF> B-J>FI /PX PO UIF "DNF TJEF, BMM UIJT IBT UP CF DPOWFSUFE UP B DBOPOJDBM 9.- GPSNBU BOE TVCNJUUFE UP UIF "DNF BDDPVOUJOH TZTUFN WJB +.4. 5IFO UIF "DNF BDDPVOUJOH TZTUFN EPFT JUT TUVGG BOE TFOET BO 9.- SFQMZ WJB +.4, XJUI B TVNNBSZ PG XIBU JU QSPDFTTFE (F.H. 3 MJOF JUFNT BDDFQUFE, MJOF JUFN #2 JO FSSPS, UPUBM JOWPJDF $123.45). 'JOBMMZ, UIBU EBUB OFFET UP CF GPSNBUUFE JOUP BO FNBJM, BOE TFOU UP B DPOUBDU BU UIF DVTUPNFS JO RVFTUJPO ("%FBS +PZDF, XF SFDFJWFE BO JOWPJDF PO 1/2/08. 8F BDDFQUFE 3 MJOF JUFNT UPUBMJOH $123.45, UIPVHI UIFSF XBT BO FSSPS XJUI MJOF JUFNT #2 <JOWBMJE RVBOUJUZ PSEFSFE>. 5IBOL ZPV GPS ZPVS CVTJOFTT. -PWF, "DNF."). 4P JU UVSOT PVU $BNFM DBO IBOEMF BMM UIJT: ` -JTUFO GPS )551, F-NBJM, BOE '51 GJMFT ` (SBC BUUBDINFOUT GSPN UIF F-NBJM NFTTBHFT

-# (-31.#4"3(.-

5 65 0 3 *"-4

205

4KABO "LKPQOR@QFLK 5IJT UVUPSJBM JT B XPSL JO QSPHSFTT. ` ` ` ` ` $POWFSU 9.-, 9-4, BOE $47 GJMFT UP B DBOPOJDBM 9.- GPSNBU SFBE BOE XSJUF +.4 NFTTBHFT SPVUF CBTFE PO DPNQBOZ *% GPSNBU F-NBJMT VTJOH 7FMPDJUZ UFNQMBUFT TFOE PVUHPJOH F-NBJM NFTTBHFT

3RQLOF>I !>@HDOLRKA 5IJT UVUPSJBM XJMM DPWFS BMM UIBU, QMVT TFUUJOH VQ UFTUT BMPOH UIF XBZ. #FGPSF TUBSUJOH, ZPV TIPVME CF GBNJMJBS XJUI: ` $BNFM DPODFQUT JODMVEJOH UIF $BNFM$POUFYU, 3PVUFT, $PNQPOFOUT BOE &OEQPJOUT, BOE &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT ` $POGJHVSJOH $BNFM XJUI UIF 9.- PS +BWB %4:PV'MM MFBSO: ` )PX UP TFU VQ B .BWFO CVJME GPS B $BNFM QSPKFDU ` )PX UP USBOTGPSN 9.-, $47, BOE &YDFM EBUB JOUP B TUBOEBSE 9.- GPSNBU XJUI $BNFM )PX UP XSJUF 10+0T (1MBJO 0ME +BWB 0CKFDUT), 7FMPDJUZ UFNQMBUFT, BOE 94-5 TUZMFTIFFUT UIBU BSF JOWPLFE CZ $BNFM SPVUFT GPS NFTTBHF USBOTGPSNBUJPO ` )PX UP DPOGJHVSF TJNQMF BOE DPNQMFY 3PVUFT JO $BNFM, VTJOH FJUIFS UIF 9.- PS UIF +BWB %4- GPSNBU ` )PX UP TFU VQ VOJU UFTUT UIBU MPBE B $BNFM DPOGJHVSBUJPO BOE UFTU $BNFM SPVUFT ` )PX UP VTF $BNFM'T %BUB 'PSNBUT UP BVUPNBUJDBMMZ DPOWFSU EBUB CFUXFFO +BWB PCKFDUT BOE 9.-, $47 GJMFT, FUD. ` )PX UP TFOE BOE SFDFJWF F-NBJM GSPN $BNFM ` )PX UP TFOE BOE SFDFJWF +.4 NFTTBHFT GSPN $BNFM ` )PX UP VTF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT JODMVEJOH .FTTBHF 3PVUFS BOE 1JQFT BOE 'JMUFST )PX UP VTF WBSJPVT MBOHVBHFT UP FYQSFTT DPOUFOU-CBTFE SPVUJOH SVMFT JO $BNFM ` )PX UP EFBM XJUI $BNFM NFTTBHFT, IFBEFST, BOE BUUBDINFOUT :PV NBZ DIPPTF UP USFBU UIJT BT B IBOET-PO UVUPSJBM, BOE XPSL UISPVHI CVJMEJOH UIF DPEF BOE DPOGJHVSBUJPO GJMFT ZPVSTFMG. &BDI PG UIF TFDUJPOT HJWFT EFUBJMFE EFTDSJQUJPOT PG UIF TUFQT UIBU OFFE UP CF UBLFO UP HFU UIF DPNQPOFOUT BOE SPVUFT XPSLJOH JO $BNFM, BOE UBLFT ZPV UISPVHI UFTUT UP NBLF TVSF UIFZ BSF XPSLJOH BT FYQFDUFE. #VU FBDI TFDUJPO BMTP MJOLT UP XPSLJOH DPQJFT PG UIF TPVSDF BOE DPOGJHVSBUJPO GJMFT, TP JG ZPV EPO'U XBOU UIF IBOET-PO BQQSPBDI, ZPV DBO TJNQMZ SFWJFX BOE/PS EPXOMPBE UIF GJOJTIFE GJMFT.

206

56 50 3* " - 4

'FDE-+BSBI #F>DO>J )FSF'T NPSF PS MFTT XIBU UIF JOUFHSBUJPO QSPDFTT MPPLT MJLF. 'JSTU, UIF JOQVU GSPN UIF DVTUPNFST UP "DNF: "OE UIFO, UIF PVUQVU GSPN "DNF UP UIF DVTUPNFST:

3RQLOF>I 3>PHP 5P HFU UISPVHI UIJT TDFOBSJP, XF'SF HPJOH UP CSFBL JU EPXO JOUP TNBMMFS QJFDFT, JNQMFNFOU BOE UFTU UIPTF, BOE UIFO USZ UP BTTFNCMF UIF CJH TDFOBSJP BOE UFTU UIBU. )FSF'T XIBU XF'MM USZ UP BDDPNQMJTI: 1. $SFBUF B .BWFO CVJME GPS UIF QSPKFDU 2. (FU TBNQMF GJMFT GPS UIF DVTUPNFS &YDFM, $47, BOE 9.- JOQVU 3. (FU B TBNQMF GJMF GPS UIF DBOPOJDBM 9.- GPSNBU UIBU "DNF'T BDDPVOUJOH TZTUFN VTFT 4. $SFBUF BO 94% GPS UIF DBOPOJDBM 9.- GPSNBU 5. $SFBUF +"9# 10+0T DPSSFTQPOEJOH UP UIF DBOPOJDBM 94% 6. $SFBUF BO 94-5 TUZMFTIFFU UP DPOWFSU UIF $VTUPNFS 1 (9.- PWFS '51) NFTTBHFT UP UIF DBOPOJDBM GPSNBU 7. $SFBUF B VOJU UFTU UP FOTVSF UIBU B TJNQMF $BNFM SPVUF JOWPLJOH UIF 94-5 TUZMFTIFFU XPSLT 8. $SFBUF B 10+0 UIBU DPOWFSUT B List<List<String>> UP UIF BCPWF +"9# 10+0T /PUF UIBU $BNFM DBO BVUPNBUJDBMMZ DPOWFSU $47 JOQVU UP B -JTU PG -JTUT PG 4USJOHT SFQSFTFOUJOH UIF SPXT BOE DPMVNOT PG UIF $47, TP XF'MM VTF UIJT 10+0 UP IBOEMF $VTUPNFS 2 ($47 PWFS )551) 9. $SFBUF B VOJU UFTU UP FOTVSF UIBU B TJNQMF $BNFM SPVUF JOWPLJOH UIF $47 QSPDFTTJOH XPSLT 10. $SFBUF B 10+0 UIBU DPOWFSUT B $VTUPNFS 3 &YDFM GJMF UP UIF BCPWF +"9# 10+0T (VTJOH 10* UP SFBE &YDFM) 11. $SFBUF B VOJU UFTU UP FOTVSF UIBU B TJNQMF $BNFM SPVUF JOWPLJOH UIF &YDFM QSPDFTTJOH XPSLT 12. $SFBUF B 10+0 UIBU SFBET BO JOQVU NFTTBHF, UBLFT BO BUUBDINFOU PGG UIF NFTTBHF, BOE SFQMBDFT UIF CPEZ PG UIF NFTTBHF XJUI UIF BUUBDINFOU 5IJT JT BTTVNJOH GPS $VTUPNFS 3 (&YDFM PWFS F-NBJM) UIBU UIF F-NBJM DPOUBJOT B TJOHMF &YDFM GJMF BT BO BUUBDINFOU, BOE UIF BDUVBM F-NBJM CPEZ JT UISPXBXBZ 13. #VJME B TFU PG $BNFM SPVUFT UP IBOEMF UIF FOUJSF JOQVU ($VTUPNFS -> "DNF) TJEF PG UIF TDFOBSJP. 14. #VJME VOJU UFTUT GPS UIF $BNFM JOQVU. 15. 3.#.: 5BTLT GPS UIF PVUQVU ("DNF -> $VTUPNFS) TJEF PG UIF TDFOBSJP

5 65 0 3 *"-4

207

+$3'2 &$3 23 13$#!


2QBM 1: (KFQF>I ,>SBK ?RFIA 8F'MM VTF .BWFO GPS UIJT QSPKFDU BT UIFSF XJMM FWFOUVBMMZ CF RVJUF B GFX EFQFOEFODJFT BOE JU'T OJDF UP IBWF .BWFO IBOEMF UIFN GPS VT. :PV TIPVME IBWF B DVSSFOU WFSTJPO PG .BWFO (F.H. 2.0.9) JOTUBMMFE. :PV DBO TUBSU XJUI B QSFUUZ FNQUZ QSPKFDU EJSFDUPSZ BOE B .BWFO 10. GJMF, PS VTF B TJNQMF +"3 BSDIFUZQF UP DSFBUF POF. )FSF'T B TBNQMF 10.. 8F'WF BEEFE B EFQFOEFODZ PO @>JBI-@LOB, BOE TFU UIF DPNQJMF WFSTJPO UP 1.5 (TP XF DBO VTF BOOPUBUJPOT):
Listing 1. pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"> <modelVersion>4.0.0</modelVersion> <groupId>org.apache.camel.tutorial</groupId> <artifactId>business-partners</artifactId> <version>1.0-SNAPSHOT</version> <name>Camel Business Partners Tutorial</name> <dependencies> <dependency> <artifactId>camel-core</artifactId> <groupId>org.apache.camel</groupId> <version>1.4.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> </plugins> </build> </project>

2QBM 2: &BQ 2>JMIB %FIBP :PV DBO NBLF VQ ZPVS PXO JG ZPV MJLF, CVU IFSF BSF UIF "PGG UIF TIFMG" POFT. :PV DBO TBWF ZPVSTFMG TPNF UJNF CZ EPXOMPBEJOH UIFTF UP src/test/resources JO ZPVS .BWFO QSPKFDU. ` $VTUPNFS 1 (9.-): JOQVU-DVTUPNFS1.YNM ` $VTUPNFS 2 ($47): JOQVU-DVTUPNFS2.DTW ` $VTUPNFS 3 (&YDFM): JOQVU-DVTUPNFS3.YMT

208

56 50 3* " - 4

` $BOPOJDBM "DNF 9.- 3FRVFTU: DBOPOJDBM-BDNF-SFRVFTU.YNM ` $BOPOJDBM "DNF 9.- 3FTQPOTF: 3.#. *G ZPV MPPL BU UIFTF GJMFT, ZPV'MM TFF UIBU UIF EJGGFSFOU JOQVU GPSNBUT VTF EJGGFSFOU GJFME OBNFT BOE/ PS PSEFSJOH, CFDBVTF PG DPVSTF UIF TBMFT HVZT XFSF UPUBMMZ 0, XJUI UIBU. 4JHI. 2QBM 3: 72# >KA ) 7! !B>KP CLO QEB ">KLKF@>I 7,+ %LOJ>Q )FSF'T UIF TBNQMF PG UIF DBOPOJDBM 9.- GJMF:
<?xml version="1.0" encoding="UTF-8"?> <invoice xmlns="http://activemq.apache.org/camel/tutorial/partners/invoice"> <partner-id>2</partner-id> <date-received>9/12/2008</date-received> <line-item> <product-id>134</product-id> <description>A widget</description> <quantity>3</quantity> <item-price>10.45</item-price> <order-date>6/5/2008</order-date> </line-item> <!-- // more line-item elements here --> <order-total>218.82</order-total> </invoice>

*G ZPV'SF BNCJUJPOT, ZPV DBO XSJUF ZPVS PXO 94% (9.- 4DIFNB) GPS GJMFT UIBU MPPL MJLF UIJT, BOE TBWF JU UP src/main/xsd. 2LIRQFLK: *G OPU, ZPV DBO EPXOMPBE NJOF, BOE TBWF UIBU UP TBWF JU UP src/main/xsd.

&BKBO>QFKD ) 7! !B>KP
%PXO UIF SPBE XF'MM XBOU UP EFBM XJUI UIF 9.- BT +BWB 10+0T. 8F'MM UBLF B NPNFOU OPX UP TFU VQ UIPTF 9.- CJOEJOH 10+0T. 4P XF'MM VQEBUF UIF .BWFO 10. UP HFOFSBUF +"9# CFBOT GSPN UIF 94% GJMF. 8F OFFE B EFQFOEFODZ:
<dependency> <artifactId>camel-jaxb</artifactId> <groupId>org.apache.camel</groupId> <version>1.4.0</version> </dependency>

"OE B QMVHJO DPOGJHVSFE:


<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId>

5 65 0 3 *"-4

209

<executions> <execution> <goals> <goal>xjc</goal> </goals> </execution> </executions> </plugin>

5IBU TIPVME EP JU (JU BVUPNBUJDBMMZ MPPLT GPS 9.- 4DIFNBT JO src/main/xsd UP HFOFSBUF CFBOT GPS). 3VO JSK FKPQ>II BOE JU TIPVME FNJU UIF CFBOT JOUP target/generatedsources/jaxb. :PVS *%& TIPVME TFF UIFN UIFSF, UIPVHI ZPV NBZ OFFE UP VQEBUF UIF QSPKFDU UP SFGMFDU UIF OFX TFUUJOHT JO UIF .BWFO 10.. 2QBM 4: (KFQF>I 6LOH LK "RPQLJBO 1 (KMRQ (7,+ LSBO %3/) 5P HFU B TUBSU PO $VTUPNFS 1, XF'MM DSFBUF BO 94-5 UFNQMBUF UP DPOWFSU UIF $VTUPNFS 1 TBNQMF GJMF JOUP UIF DBOPOJDBM 9.- GPSNBU, XSJUF B TNBMM $BNFM SPVUF UP UFTU JU, BOE CVJME UIBU JOUP B VOJU UFTU. *G XF HFU UISPVHI UIJT, XF DBO CF QSFUUZ TVSF UIBU UIF 94-5 UFNQMBUF JT WBMJE BOE DBO CF SVO TBGFMZ JO $BNFM.

"OB>QB >K 72+3 QBJMI>QB


4UBSU XJUI UIF $VTUPNFS 1 TBNQMF JOQVU. :PV XBOU UP DSFBUF BO 94-5 UFNQMBUF UP HFOFSBUF 9.- MJLF UIF DBOPOJDBM 9.- TBNQMF BCPWF f BO invoice FMFNFOU XJUI line-item FMFNFOUT (POF QFS JUFN JO UIF PSJHJOBM 9.- EPDVNFOU). *G ZPV'SF FTQFDJBMMZ DMFWFS, ZPV DBO QPQVMBUF UIF DVSSFOU EBUF BOE PSEFS UPUBM FMFNFOUT UPP. 2LIRQFLK: .Z TBNQMF 94-5 UFNQMBUF JTO'U UIBU TNBSU, CVU JU'MM HFU ZPV HPJOH JG ZPV EPO'U XBOU UP XSJUF POF PG ZPVS PXO.

"OB>QB > RKFQ QBPQ


)FSF'T XIFSF XF HFU UP TPNF NFBUZ $BNFM XPSL. 8F OFFE UP: ` 4FU VQ B VOJU UFTU ` 5IBU MPBET B $BNFM DPOGJHVSBUJPO ` 5IBU IBT B SPVUF JOWPLJOH PVS 94-5 ` 8IFSF UIF UFTU TFOET B NFTTBHF UP UIF SPVUF ` "OE FOTVSFT UIBU TPNF 9.- DPNFT PVU UIF FOE PG UIF SPVUF 5IF FBTJFTU XBZ UP EP UIJT JT UP TFU VQ B 4QSJOH DPOUFYU UIBU EFGJOFT UIF $BNFM TUVGG, BOE UIFO VTF B CBTF VOJU UFTU DMBTT GSPN 4QSJOH UIBU LOPXT IPX UP MPBE B 4QSJOH DPOUFYU UP SVO UFTUT BHBJOTU. 4P, UIF QSPDFEVSF JT:

210

56 50 3* " - 4

2BQ 4M > 2HBIBQ>I ">JBI/2MOFKD 4KFQ 3BPQ 1. "EE EFQFOEFODJFT PO $BNFM-4QSJOH, BOE UIF 4QSJOH UFTU +"3 (XIJDI XJMM BVUPNBUJDBMMZ CSJOH JO +6OJU 3.8.Y) UP ZPVS 10.:
<dependency> <artifactId>camel-spring</artifactId> <groupId>org.apache.camel</groupId> <version>1.4.0</version> </dependency> <dependency> <artifactId>spring-test</artifactId> <groupId>org.springframework</groupId> <version>2.5.5</version> <scope>test</scope> </dependency>

2. $SFBUF B OFX VOJU UFTU DMBTT JO src/test/java/your-package-here, QFSIBQT DBMMFE XMLInputTest.java 3. .BLF UIF UFTU FYUFOE 4QSJOH'T "CTUSBDU+6OJU384QSJOH$POUFYU5FTUT DMBTT, TP JU DBO MPBE B 4QSJOH DPOUFYU GPS UIF UFTU 4. $SFBUF B 4QSJOH DPOUFYU DPOGJHVSBUJPO GJMF JO src/test/resources, QFSIBQT DBMMFE XMLInputTest-context.xml 5. *O UIF VOJU UFTU DMBTT, VTF UIF DMBTT-MFWFM !$POUFYU$POGJHVSBUJPO BOOPUBUJPO UP JOEJDBUF UIBU B 4QSJOH DPOUFYU TIPVME CF MPBEFE #Z EFGBVMU, UIJT MPPLT GPS B $POUFYU DPOGJHVSBUJPO GJMF DBMMFE TestClassName-context.xml JO B TVCEJSFDUPSZ DPSSFTQPOEJOH UP UIF QBDLBHF PG UIF UFTU DMBTT. 'PS JOTUBODF, JG ZPVS UFTU DMBTT XBT org.apache.camel.tutorial.XMLInputTest, JU XPVME MPPL GPS org/apache/camel/tutorial/XMLInputTest-context.xml 5P PWFSSJEF UIJT EFGBVMU, VTF UIF IL@>QFLKP BUUSJCVUF PO UIF !$POUFYU$POGJHVSBUJPO BOOPUBUJPO UP QSPWJEF TQFDJGJD DPOUFYU GJMF MPDBUJPOT (TUBSUJOH FBDI QBUI XJUI B / JG ZPV EPO'U XBOU JU UP CF SFMBUJWF UP UIF QBDLBHF EJSFDUPSZ). .Z TPMVUJPO EPFT UIJT TP * DBO QVU UIF DPOUFYU GJMF EJSFDUMZ JO src/test/resources JOTUFBE PG JO B QBDLBHF EJSFDUPSZ VOEFS UIFSF. 6. "EE B $BNFM$POUFYU JOTUBODF WBSJBCMF UP UIF UFTU DMBTT, XJUI UIF !"VUPXJSFE BOOPUBUJPO. 5IBU XBZ 4QSJOH XJMM BVUPNBUJDBMMZ QVMM UIF $BNFM$POUFYU PVU PG UIF 4QSJOH DPOUFYU BOE JOKFDU JU JOUP PVS UFTU DMBTT. 7. "EE B 1SPEVDFS5FNQMBUF JOTUBODF WBSJBCMF BOE B setUp NFUIPE UIBU JOTUBOUJBUFT JU GSPN UIF $BNFM$POUFYU. 8F'MM VTF UIF 1SPEVDFS5FNQMBUF MBUFS UP TFOE NFTTBHFT UP UIF SPVUF.
protected ProducerTemplate<Exchange> template;

5 65 0 3 *"-4

211

protected void setUp() throws Exception { super.setUp(); template = camelContext.createProducerTemplate(); }

8. 1VU JO BO FNQUZ UFTU NFUIPE KVTU GPS UIF NPNFOU (TP XIFO XF SVO UIJT XF DBO TFF UIBU "1 UFTU TVDDFFEFE") 9. "EE UIF 4QSJOH <CFBOT> FMFNFOU (JODMVEJOH UIF $BNFM /BNFTQBDF) XJUI BO FNQUZ <DBNFM$POUFYU> FMFNFOU UP UIF 4QSJOH DPOUFYU, MJLF UIJT:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ spring-beans-2.5.xsd http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/ camel-spring-1.4.0.xsd"> <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/ spring"> </camelContext> </beans>

5FTU JU CZ SVOOJOH JSK FKPQ>II BOE NBLF TVSF UIFSF BSF OP CVJME FSSPST. 4P GBS JU EPFTO'U UFTU NVDI; KVTU UIBU ZPVS QSPKFDU BOE UFTU BOE TPVSDF GJMFT BSF BMM PSHBOJ[FE DPSSFDUMZ, BOE UIF POF FNQUZ UFTU NFUIPE DPNQMFUFT TVDDFTTGVMMZ. 2LIRQFLK: :PVS UFTU DMBTT NJHIU MPPL TPNFUIJOH MJLF UIJT: ` TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/9.-*OQVU5FTU.KBWB ` TSD/UFTU/SFTPVSDFT/9.-*OQVU5FTU-DPOUFYU.YNM (TBNF BT KVTU BCPWF) %IBPE .RQ QEB 4KFQ 3BPQ 4P OPX XF'SF HPJOH UP XSJUF B $BNFM SPVUF UIBU BQQMJFT UIF 94-5 UP UIF TBNQMF $VTUPNFS 1 JOQVU GJMF, BOE NBLFT TVSF UIBU TPNF 9.- PVUQVU DPNFT PVU: 1. 4BWF UIF JOQVU-DVTUPNFS1.YNM GJMF UP src/test/resources 2. 4BWF ZPVS 94-5 GJMF (DSFBUFE JO UIF QSFWJPVT TUFQ) UP src/main/resources 3. 8SJUF B $BNFM 3PVUF, FJUIFS SJHIU JO UIF 4QSJOH 9.-, PS VTJOH UIF +BWB %4- (JO BOPUIFS DMBTT VOEFS src/test/java TPNFXIFSF). 5IJT SPVUF TIPVME VTF UIF 1JQFT BOE 'JMUFST JOUFHSBUJPO QBUUFSO UP: 1. 4UBSU GSPN UIF FOEQPJOU EJSFDU:TUBSU (XIJDI MFUT UIF UFTU DPOWFOJFOUMZ QBTT NFTTBHFT JOUP UIF SPVUF) 2. $BMM UIF FOEQPJOU YTMU::PVS94-5'JMF.YTM (UP USBOTGPSN UIF NFTTBHF XJUI UIF TQFDJGJFE 94-5 UFNQMBUF)

212

56 50 3* " - 4

3. 4FOE UIF SFTVMU UP UIF FOEQPJOU NPDL:GJOJTI (XIJDI MFUT UIF UFTU WFSJGZ UIF SPVUF PVUQVU) 4. "EE B UFTU NFUIPE UP UIF VOJU UFTU DMBTT UIBU: 1. (FU B SFGFSFODF UP UIF .PDL FOEQPJOU mock:finish VTJOH DPEF MJLF UIJT:
MockEndpoint finish = MockEndpoint.resolve(camelContext, "mock:finish");

2. 4FU UIF FYQFDUFE.FTTBHF$PVOU PO UIBU FOEQPJOU UP 1 3. (FU B SFGFSFODF UP UIF $VTUPNFS 1 JOQVU GJMF, VTJOH DPEF MJLF UIJT:
InputStream in = XMLInputTest.class.getResourceAsStream("/input-partner1.xml"); assertNotNull(in);

4. 4FOE UIBU *OQVU4USFBN BT B NFTTBHF UP UIF direct:start FOEQPJOU, VTJOH DPEF MJLF UIJT:
template.sendBody("direct:start", in);

/PUF UIBU XF DBO TFOE UIF TBNQMF GJMF CPEZ JO TFWFSBM GPSNBUT ('JMF, *OQVU4USFBN, 4USJOH, FUD.) CVU JO UIJT DBTF BO *OQVU4USFBN JT QSFUUZ DPOWFOJFOU. 5. &OTVSF UIBU UIF NFTTBHF NBEF JU UISPVHI UIF SPVUF UP UIF GJOBM FOEQPJOU, CZ UFTUJOH BMM DPOGJHVSFE .PDL FOEQPJOUT MJLF UIJT:
MockEndpoint.assertIsSatisfied(camelContext);

6. *G ZPV MJLF, JOTQFDU UIF GJOBM NFTTBHF CPEZ VTJOH TPNF DPEF MJLF finish.getExchanges().get(0).getIn().getBody(). *G ZPV EP UIJT, ZPV'MM OFFE UP LOPX XIBU GPSNBU UIBU CPEZ JT f 4USJOH, CZUF BSSBZ, *OQVU4USFBN, FUD. 5. 3VO ZPVS UFTU XJUI JSK FKPQ>II BOE NBLF TVSF UIF CVJME DPNQMFUFT TVDDFTTGVMMZ. 2LIRQFLK: :PVS GJOJTIFE UFTU NJHIU MPPL TPNFUIJOH MJLF UIJT: ` TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/9.-*OQVU5FTU.KBWB ` 'PS 9.- $POGJHVSBUJPO: TSD/UFTU/SFTPVSDFT/9.-*OQVU5FTU-DPOUFYU.YNM ` 0S, GPS +BWB %4- $POGJHVSBUJPO: TSD/UFTU/SFTPVSDFT/9.-*OQVU5FTU-ETM-DPOUFYU.YNM TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/SPVUFT/9.-*OQVU5FTU3PVUF.KBWB

5 65 0 3 *"-4

213

3BPQ !>PB "I>PP 0ODF ZPVS UFTU DMBTT JT XPSLJOH, ZPV NJHIU XBOU UP FYUSBDU UIJOHT MJLF UIF !"VUPXJSFE $BNFM$POUFYU, UIF 1SPEVDFS5FNQMBUF, BOE UIF TFU6Q NFUIPE UP B DVTUPN CBTF DMBTT UIBU ZPV FYUFOE XJUI ZPVS PUIFS UFTUT. 2QBM 5: (KFQF>I 6LOH LK "RPQLJBO 2 (KMRQ ("25 LSBO '33/) 5P HFU B TUBSU PO $VTUPNFS 2, XF'MM DSFBUF B 10+0 UP DPOWFSU UIF $VTUPNFS 2 TBNQMF $47 EBUB JOUP UIF +"9# 10+0T SFQSFTFOUJOH UIF DBOPOJDBM 9.- GPSNBU, XSJUF B TNBMM $BNFM SPVUF UP UFTU JU, BOE CVJME UIBU JOUP B VOJU UFTU. *G XF HFU UISPVHI UIJT, XF DBO CF QSFUUZ TVSF UIBU UIF $47 DPOWFSTJPO BOE +"9# IBOEMJOH JT WBMJE BOE DBO CF SVO TBGFMZ JO $BNFM.

"OB>QB > "25-E>KAIFKD /.).


5P CFHJO XJUI, $47 JT B LOPXO EBUB GPSNBU JO $BNFM. $BNFM DBO DPOWFSU B $47 GJMF UP B -JTU (SFQSFTFOUJOH SPXT JO UIF $47) PG -JTUT (SFQSFTFOUJOH DFMMT JO UIF SPX) PG 4USJOHT (UIF EBUB GPS FBDI DFMM). 5IBU NFBOT PVS 10+0 DBO KVTU BTTVNF UIF EBUB DPNJOH JO JT PG UZQF List<List<String>>, BOE XF DBO EFDMBSF B NFUIPE XJUI UIBU BT UIF BSHVNFOU. -PPLJOH BU UIF +"9# DPEF JO target/generated-sources/jaxb, JU MPPLT MJLF BO Invoice PCKFDU SFQSFTFOUT UIF XIPMF EPDVNFOU, XJUI B OFTUFE MJTU PG -JOF*UFN5ZQF PCKFDUT GPS UIF MJOF JUFNT. 5IFSFGPSF PVS 10+0 NFUIPE XJMM SFUVSO BO Invoice (B EPDVNFOU JO UIF DBOPOJDBM 9.- GPSNBU). 4P UP JNQMFNFOU UIF $47-UP-+"9# 10+0, XF OFFE UP EP TPNFUIJOH MJLF UIJT: 1. $SFBUF B OFX DMBTT VOEFS src/main/java, QFSIBQT DBMMFE CSVConverterBean. 2. "EE B NFUIPE, XJUI POF BSHVNFOU PG UZQF List<List<String>> BOE UIF SFUVSO UZQF Invoice :PV NBZ BOOPUBUF UIF BSHVNFOU XJUI !#PEZ UP TQFDJGJDBMMZ EFTJHOBUF JU BT UIF CPEZ PG UIF JODPNJOH NFTTBHF 3. *O UIF NFUIPE, UIF MPHJD TIPVME MPPL SPVHIMZ MJLF UIJT: 1. $SFBUF B OFX Invoice, VTJOH UIF NFUIPE PO UIF HFOFSBUFE ObjectFactory DMBTT 2. -PPQ UISPVHI BMM UIF SPXT JO UIF JODPNJOH $47 (UIF PVUFS List) 3. 4LJQ UIF GJSTU SPX, XIJDI DPOUBJOT IFBEFST (DPMVNO OBNFT) 4. 'PS UIF PUIFS SPXT: 1. $SFBUF B OFX LineItemType (VTJOH UIF ObjectFactory BHBJO) 2. 1JDL PVU BMM UIF DFMM WBMVFT (UIF 4USJOHT JO UIF JOOFS List) BOE QVU UIFN JOUP UIF DPSSFDU GJFMET PG UIF LineItemType /PU BMM PG UIF WBMVFT XJMM BDUVBMMZ HP JOUP UIF MJOF JUFN JO UIJT FYBNQMF

214

56 50 3* " - 4

:PV NBZ IBSEDPEF UIF DPMVNO PSEFSJOH CBTFE PO UIF TBNQMF EBUB GJMF, PS FMTF USZ UP SFBE JU EZOBNJDBMMZ GSPN UIF IFBEFST JO UIF GJSTU MJOF /PUF UIBU ZPV'MM OFFE UP VTF B +"9# DatatypeFactory UP DSFBUF UIF XMLGregorianCalendar WBMVFT UIBU +"9# VTFT GPS UIF date GJFMET JO UIF 9.- f XIJDI QSPCBCMZ NFBOT VTJOH B SimpleDateFormat UP QBSTF UIF EBUF BOE TFUUJOH UIBU EBUF PO B GregorianCalendar 3. "EE UIF MJOF JUFN UP UIF JOWPJDF 5. 1PQVMBUF UIF QBSUOFS *%, EBUF PG SFDFJQU, BOE PSEFS UPUBM PO UIF Invoice 6. 5ISPX BOZ FYDFQUJPOT PVU PG UIF NFUIPE, TP $BNFM LOPXT TPNFUIJOH XFOU XSPOH 7. 3FUVSO UIF GJOJTIFE Invoice 2LIRQFLK: )FSF'T BO FYBNQMF PG XIBU UIF $47$POWFSUFS#FBO NJHIU MPPL MJLF.

"OB>QB > RKFQ QBPQ


4UBSU XJUI B TJNQMF UFTU DMBTT BOE UFTU 4QSJOH DPOUFYU MJLF MBTU UJNF, QFSIBQT CBTFE PO UIF OBNF CSVInputTest:
Listing 1. CSVInputTest.java
/** * A test class the ensure we can convert Partner 2 CSV input files to the * canonical XML output format, using JAXB POJOs. */ @ContextConfiguration(locations = "/CSVInputTest-context.xml") public class CSVInputTest extends AbstractJUnit38SpringContextTests { @Autowired protected CamelContext camelContext; protected ProducerTemplate<Exchange> template; protected void setUp() throws Exception { super.setUp(); template = camelContext.createProducerTemplate(); } public void testCSVConversion() { // TODO } }

Listing 1. CSVInputTest-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

5 65 0 3 *"-4

215

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/ spring-beans-2.5.xsd http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/ camel-spring-1.4.0.xsd"> <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring"> <!-- TODO --> </camelContext> </beans>

/PX UIF NFBUZ QBSU JT UP GMFTI PVU UIF UFTU DMBTT BOE XSJUF UIF $BNFM SPVUFT. 1. 6QEBUF UIF .BWFO 10. UP JODMVEF $47 %BUB 'PSNBU TVQQPSU:
<dependency> <artifactId>camel-csv</artifactId> <groupId>org.apache.camel</groupId> <version>1.4.0</version> </dependency>

2. 8SJUF UIF SPVUFT (SJHIU JO UIF 4QSJOH 9.- DPOUFYU, PS VTJOH UIF +BWB %4-) GPS UIF $47 DPOWFSTJPO QSPDFTT, BHBJO VTJOH UIF 1JQFT BOE 'JMUFST QBUUFSO: 1. 4UBSU GSPN UIF FOEQPJOU EJSFDU:$47TUBSU (XIJDI MFUT UIF UFTU DPOWFOJFOUMZ QBTT NFTTBHFT JOUP UIF SPVUF). 8F'MM OBNF UIJT EJGGFSFOUMZ UIBO UIF TUBSUJOH QPJOU GPS UIF QSFWJPVT UFTU, JO DBTF ZPV VTF UIF +BWB %4- BOE QVU BMM ZPVS SPVUFT JO UIF TBNF QBDLBHF (XIJDI XPVME NFBO UIBU FBDI UFTU XPVME MPBE UIF %4- SPVUFT GPS TFWFSBM UFTUT.) 2. 5IJT UJNF, UIFSF'T B MJUUMF QSFQBSBUJPO UP CF EPOF. $BNFM EPFTO'U LOPX UIBU UIF JOJUJBM JOQVU JT B $47, TP JU XPO'U CF BCMF UP DPOWFSU JU UP UIF FYQFDUFE List<List<String>> XJUIPVU B MJUUMF IJOU. 'PS UIBU, XF OFFE BO VONBSTIBM USBOTGPSNBUJPO JO UIF SPVUF. 5IF unmarshal NFUIPE (JO UIF %4-) PS FMFNFOU (JO UIF 9.-) UBLFT B DIJME JOEJDBUJOH UIF GPSNBU UP VONBSTIBM; JO UIJT DBTF UIBU TIPVME CF csv. 3. /FYU JOWPLF UIF 10+0 UP USBOTGPSN UIF NFTTBHF XJUI B CFBO:$47$POWFSUFS FOEQPJOU 4. "T CFGPSF, TFOE UIF SFTVMU UP UIF FOEQPJOU NPDL:GJOJTI (XIJDI MFUT UIF UFTU WFSJGZ UIF SPVUF PVUQVU) 5. 'JOBMMZ, XF OFFE B 4QSJOH <bean> FMFNFOU JO UIF 4QSJOH DPOUFYU 9.- GJMF (CVU PVUTJEF UIF <camelContext> FMFNFOU) UP EFGJOF UIF 4QSJOH CFBO UIBU PVS SPVUF JOWPLFT. 5IJT 4QSJOH CFBO TIPVME IBWF B name BUUSJCVUF UIBU NBUDIFT UIF OBNF VTFE JO UIF bean FOEQPJOU (CSVConverter JO UIF FYBNQMF BCPWF), BOE B class BUUSJCVUF UIBU QPJOUT UP UIF $47-UP-+"9# 10+0 DMBTT ZPV XSPUF BCPWF (TVDI BT, org.apache.camel.tutorial.CSVConverterBean). 8IFO

216

56 50 3* " - 4

4QSJOH JT JO UIF QJDUVSF, BOZ bean FOEQPJOUT MPPL VQ 4QSJOH CFBOT XJUI UIF TQFDJGJFE OBNF. 3. 8SJUF B UFTU NFUIPE JO UIF UFTU DMBTT, XIJDI TIPVME MPPL WFSZ TJNJMBS UP UIF QSFWJPVT UFTU DMBTT: 1. (FU UIF .PDL&OEQPJOU GPS UIF GJOBM FOEQPJOU, BOE UFMM JU UP FYQFDU POF NFTTBHF 2. -PBE UIF 1BSUOFS 2 TBNQMF $47 GJMF GSPN UIF $MBTT1BUI, BOE TFOE JU BT UIF CPEZ PG B NFTTBHF UP UIF TUBSUJOH FOEQPJOU 3. 7FSJGZ UIBU UIF GJOBM .PDL&OEQPJOU JT TBUJTGJFE (UIBU JT, JU SFDFJWFE POF NFTTBHF) BOE FYBNJOF UIF NFTTBHF CPEZ JG ZPV MJLF /PUF UIBU XF EJEO'U NBSTIBM UIF +"9# 10+0T UP 9.- JO UIJT UFTU, TP UIF GJOBM NFTTBHF TIPVME DPOUBJO BO Invoice BT UIF CPEZ. :PV DPVME XSJUF B TJNQMF MJOF PG DPEF UP HFU UIF &YDIBOHF (BOE .FTTBHF) GSPN UIF .PDL&OEQPJOU UP DPOGJSN UIBU. 4. 3VO UIJT OFX UFTU XJUI JSK FKPQ>II BOE NBLF TVSF JU QBTTFT BOE UIF CVJME DPNQMFUFT TVDDFTTGVMMZ. 2LIRQFLK: :PVS GJOJTIFE UFTU NJHIU MPPL TPNFUIJOH MJLF UIJT: ` TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/$47*OQVU5FTU.KBWB ` 'PS 9.- $POGJHVSBUJPO: TSD/UFTU/SFTPVSDFT/$47*OQVU5FTU-DPOUFYU.YNM ` 0S, GPS +BWB %4- $POGJHVSBUJPO: TSD/UFTU/SFTPVSDFT/$47*OQVU5FTU-ETM-DPOUFYU.YNM TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/SPVUFT/$47*OQVU5FTU3PVUF.KBWB 2QBM 6: (KFQF>I 6LOH LK "RPQLJBO 3 (KMRQ ($U@BI LSBO B-J>FI) 5P HFU B TUBSU PO $VTUPNFS 3, XF'MM DSFBUF B 10+0 UP DPOWFSU UIF $VTUPNFS 3 TBNQMF &YDFM EBUB JOUP UIF +"9# 10+0T SFQSFTFOUJOH UIF DBOPOJDBM 9.- GPSNBU, XSJUF B TNBMM $BNFM SPVUF UP UFTU JU, BOE CVJME UIBU JOUP B VOJU UFTU. *G XF HFU UISPVHI UIJT, XF DBO CF QSFUUZ TVSF UIBU UIF &YDFM DPOWFSTJPO BOE +"9# IBOEMJOH JT WBMJE BOE DBO CF SVO TBGFMZ JO $BNFM.

"OB>QB >K $U@BI-E>KAIFKD /.).


$BNFM EPFT OPU IBWF B EBUB GPSNBU IBOEMFS GPS &YDFM CZ EFGBVMU. 8F IBWF UXP PQUJPOT f DSFBUF BO &YDFM %BUB'PSNBU (TP $BNFM DBO DPOWFSU &YDFM TQSFBETIFFUT UP TPNFUIJOH MJLF UIF $47 List<List<String>> BVUPNBUJDBMMZ), PS DSFBUF B 10+0 UIBU DBO USBOTMBUF &YDFM EBUB NBOVBMMZ. 'PS OPX, UIF TFDPOE BQQSPBDI JT FBTJFS (JG XF HP UIF DataFormat SPVUF, XF OFFE DPEF UP CPUI SFBE BOE XSJUF &YDFM GJMFT, XIFSFBT PUIFSXJTF SFBE-POMZ XJMM EP). 4P, XF OFFE B 10+0 XJUI B NFUIPE UIBU UBLFT TPNFUIJOH MJLF BO InputStream PS byte[] BT BO BSHVNFOU, BOE SFUVSOT JO Invoice BT CFGPSF. 5IF QSPDFTT TIPVME MPPL TPNFUIJOH MJLF UIJT: 1. 6QEBUF UIF .BWFO 10. UP JODMVEF 10* TVQQPSU:

5 65 0 3 *"-4

217

<dependency> <artifactId>poi</artifactId> <groupId>org.apache.poi</groupId> <version>3.1-FINAL</version> </dependency>

2. $SFBUF B OFX DMBTT VOEFS src/main/java, QFSIBQT DBMMFE ExcelConverterBean. 3. "EE B NFUIPE, XJUI POF BSHVNFOU PG UZQF InputStream BOE UIF SFUVSO UZQF Invoice :PV NBZ BOOPUBUF UIF BSHVNFOU XJUI !#PEZ UP TQFDJGJDBMMZ EFTJHOBUF JU BT UIF CPEZ PG UIF JODPNJOH NFTTBHF 4. *O UIF NFUIPE, UIF MPHJD TIPVME MPPL SPVHIMZ MJLF UIJT: 1. $SFBUF B OFX Invoice, VTJOH UIF NFUIPE PO UIF HFOFSBUFE ObjectFactory DMBTT 2. $SFBUF B OFX )44'8PSLCPPL GSPN UIF InputStream, BOE HFU UIF GJSTU TIFFU GSPN JU 3. -PPQ UISPVHI BMM UIF SPXT JO UIF TIFFU 4. 4LJQ UIF GJSTU SPX, XIJDI DPOUBJOT IFBEFST (DPMVNO OBNFT) 5. 'PS UIF PUIFS SPXT: 1. $SFBUF B OFX LineItemType (VTJOH UIF ObjectFactory BHBJO) 2. 1JDL PVU BMM UIF DFMM WBMVFT BOE QVU UIFN JOUP UIF DPSSFDU GJFMET PG UIF LineItemType (ZPV'MM OFFE TPNF EBUB UZQF DPOWFSTJPO MPHJD) /PU BMM PG UIF WBMVFT XJMM BDUVBMMZ HP JOUP UIF MJOF JUFN JO UIJT FYBNQMF :PV NBZ IBSEDPEF UIF DPMVNO PSEFSJOH CBTFE PO UIF TBNQMF EBUB GJMF, PS FMTF USZ UP SFBE JU EZOBNJDBMMZ GSPN UIF IFBEFST JO UIF GJSTU MJOF /PUF UIBU ZPV'MM OFFE UP VTF B +"9# DatatypeFactory UP DSFBUF UIF XMLGregorianCalendar WBMVFT UIBU +"9# VTFT GPS UIF date GJFMET JO UIF 9.- f XIJDI QSPCBCMZ NFBOT TFUUJOH UIF EBUF GSPN B EBUF DFMM PO B GregorianCalendar 3. "EE UIF MJOF JUFN UP UIF JOWPJDF 6. 1PQVMBUF UIF QBSUOFS *%, EBUF PG SFDFJQU, BOE PSEFS UPUBM PO UIF Invoice 7. 5ISPX BOZ FYDFQUJPOT PVU PG UIF NFUIPE, TP $BNFM LOPXT TPNFUIJOH XFOU XSPOH 8. 3FUVSO UIF GJOJTIFE Invoice 2LIRQFLK: )FSF'T BO FYBNQMF PG XIBU UIF &YDFM$POWFSUFS#FBO NJHIU MPPL MJLF.

218

56 50 3* " - 4

"OB>QB > RKFQ QBPQ


5IF VOJU UFTUT TIPVME CF QSFUUZ GBNJMJBS OPX. 5IF UFTU DMBTT BOE DPOUFYU GPS UIF &YDFM CFBO TIPVME CF RVJUF TJNJMBS UP UIF $47 CFBO. 1. $SFBUF UIF CBTJD UFTU DMBTT BOE DPSSFTQPOEJOH 4QSJOH $POUFYU 9.- DPOGJHVSBUJPO GJMF 2. 5IF 9.- DPOGJH TIPVME MPPL B MPU MJLF UIF $47 UFTU, FYDFQU: 3FNFNCFS UP VTF B EJGGFSFOU TUBSU FOEQPJOU OBNF JG ZPV'SF VTJOH UIF +BWB %4- BOE OPU VTF TFQBSBUF QBDLBHFT QFS UFTU :PV EPO'U OFFE UIF unmarshal TUFQ TJODF UIF &YDFM 10+0 UBLFT UIF SBX InputStream GSPN UIF TPVSDF FOEQPJOU :PV'MM EFDMBSF B <bean> BOE FOEQPJOU GPS UIF &YDFM CFBO QSFQBSFE BCPWF JOTUFBE PG UIF $47 CFBO 3. 5IF UFTU DMBTT TIPVME MPPL B MPU MJLF UIF $47 UFTU, FYDFQU VTF UIF SJHIU JOQVU GJMF OBNF BOE TUBSU FOEQPJOU OBNF. 2LIRQFLK: :PVS GJOJTIFE UFTU NJHIU MPPL TPNFUIJOH MJLF UIJT: ` TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/&YDFM*OQVU5FTU.KBWB ` 'PS 9.- $POGJHVSBUJPO: TSD/UFTU/SFTPVSDFT/&YDFM*OQVU5FTU-DPOUFYU.YNM ` 0S, GPS +BWB %4- $POGJHVSBUJPO: TSD/UFTU/SFTPVSDFT/&YDFM*OQVU5FTU-ETM-DPOUFYU.YNM TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/UVUPSJBM/SPVUFT/&YDFM*OQVU5FTU3PVUF.KBWB 2QBM 7: /RQ QEFP >II QLDBQEBO FKQL ">JBI OLRQBP CLO QEB "RPQLJBO (KMRQ 8JUI BMM UIF EBUB UZQF DPOWFSTJPOT XPSLJOH, UIF OFYU TUFQ JT UP XSJUF UIF SFBM SPVUFT UIBU MJTUFO GPS )551, '51, PS F-NBJM JOQVU, BOE XSJUF UIF GJOBM 9.- PVUQVU UP BO "DUJWF.2 RVFVF. "MPOH UIF XBZ UIFTF SPVUFT XJMM VTF UIF EBUB DPOWFSTJPOT XF'WF EFWFMPQFE BCPWF. 4P XF'MM DSFBUF 3 SPVUFT UP TUBSU XJUI, BT TIPXO JO UIF EJBHSBN CBDL BU UIF CFHJOOJOH: 1. "DDFQU 9.- PSEFST PWFS '51 GSPN $VTUPNFS 1 (XF'MM BTTVNF UIF '51 TFSWFS EVNQT GJMFT JO B MPDBM EJSFDUPSZ PO UIF $BNFM NBDIJOF) 2. "DDFQU $47 PSEFST PWFS )551 GSPN $VTUPNFS 2 3. "DDFQU &YDFM PSEFST WJB F-NBJM GSPN $VTUPNFS 3 (XF'MM BTTVNF UIF NFTTBHFT BSF TFOU UP BO BDDPVOU XF DBO BDDFTT WJB *."1) ... 2QBM 8: "OB>QB > RKFQ QBPQ CLO QEB "RPQLJBO (KMRQ 1LRQBP

5 65 0 3 *"-4

219

+LDDFKD :PV NBZ OPUJDF UIBU ZPVS UFTUT FNJU B MPU MFTT PVUQVU BMM PG B TVEEFO. 5IF EFQFOEFODZ PO 10* CSPVHIU JO -PH4+ BOE DPOGJHVSFE DPNNPOT-MPHHJOH UP VTF JU, TP OPX XF OFFE B MPH4K.QSPQFSUJFT GJMF UP DPOGJHVSF MPH PVUQVU. :PV DBO VTF UIF BUUBDIFE POF (TOBSGFE GSPN "DUJWF.2) PS XSJUF ZPVS PXO; FJUIFS XBZ TBWF JU UP src/main/resources UP FOTVSF ZPV DPOUJOVF UP TFF MPH PVUQVU.

220

56 50 3* " - 4

+>KDR>DBP 2RMMLOQBA

MMBKAFU

5P TVQQPSU GMFYJCMF BOE QPXFSGVM &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT $BNFM TVQQPSUT WBSJPVT -BOHVBHFT UP DSFBUF BO &YQSFTTJPO PS 1SFEJDBUF XJUIJO FJUIFS UIF 3PVUJOH %PNBJO 4QFDJGJD -BOHVBHF PS UIF 9NM $POGJHVSBUJPO. 5IF GPMMPXJOH MBOHVBHFT BSF TVQQPSUFE

!$ - + -&4 &$
5IF QVSQPTF PG UIF #FBO -BOHVBHF JT UP CF BCMF UP JNQMFNFOU BO &YQSFTTJPO PS 1SFEJDBUF VTJOH B TJNQMF NFUIPE PO B CFBO. 4P UIF JEFB JT ZPV TQFDJGZ B CFBO OBNF XIJDI XJMM UIFO CF SFTPMWFE JO UIF 3FHJTUSZ TVDI BT UIF 4QSJOH "QQMJDBUJPO$POUFYU UIFO B NFUIPE JT JOWPLFE UP FWBMVBUF UIF &YQSFTTJPO PS 1SFEJDBUF. *G OP NFUIPE OBNF JT QSPWJEFE UIFO POF JT BUUFNQUFE UP CF DIPTFO VTJOH UIF SVMFT GPS #FBO #JOEJOH; VTJOH UIF UZQF PG UIF NFTTBHF CPEZ BOE VTJOH BOZ BOOPUBUJPOT PO UIF CFBO NFUIPET. 5IF #FBO #JOEJOH SVMFT BSF VTFE UP CJOE UIF .FTTBHF &YDIBOHF UP UIF NFUIPE QBSBNFUFST; TP ZPV DBO BOOPUBUF UIF CFBO UP FYUSBDU IFBEFST PS PUIFS FYQSFTTJPOT TVDI BT 91BUI PS 92VFSZ GSPN UIF NFTTBHF. 4PFKD !B>K $UMOBPPFLKP COLJ QEB )>S> #2+
from("activemq:topic:OrdersTopic"). filter().method("myBean", "isGoldCustomer"). to("activemq:BigSpendersQueue");

4PFKD !B>K $UMOBPPFLKP COLJ 7,+


<route> <from uri="activemq:topic:OrdersTopic"/> <filter> <method bean="myBean" method="isGoldCustomer"/> <to uri="activemq:BigSpendersQueue"/> </filter> </route>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

221

6OFQFKD QEB BUMOBPPFLK ?B>K 5IF CFBO JO UIF BCPWF FYBNQMFT JT KVTU BOZ PME +BWB #FBO XJUI B NFUIPE DBMMFE JT(PME$VTUPNFS() UIBU SFUVSOT TPNF PCKFDU UIBU JT FBTJMZ DPOWFSUFE UP B ?LLIB>K WBMVF JO UIJT DBTF, BT JUT VTFE BT B QSFEJDBUF. 4P XF DPVME JNQMFNFOU JU MJLF UIJT...
public class MyBean { public boolean isGoldCustomer(Exchange exchange) { ... } }

8F DBO BMTP VTF UIF #FBO *OUFHSBUJPO BOOPUBUJPOT. 'PS FYBNQMF ZPV DPVME EP...
public boolean isGoldCustomer(String body) {...}

PS
public boolean isGoldCustomer(@Header(name = "foo") Integer fooHeader) {...}

4P ZPV DBO CJOE QBSBNFUFST PG UIF NFUIPE UP UIF &YDIBOHF, UIF .FTTBHF PS JOEJWJEVBM IFBEFST, QSPQFSUJFT, UIF CPEZ PS PUIFS FYQSFTTJPOT. -LK OBDFPQOV ?B>KP 5IF #FBO -BOHVBHF BMTP TVQQPSUT JOWPLJOH CFBOT UIBU JTO'U SFHJTUFSFE JO UIF 3FHJTUSZ. 5IJT JT VTBCMF GPS RVJDLMZ UP JOWPLF B CFBO GSPN +BWB %4- XIFSF ZPV EPO'U OFFE UP SFHJTUFS UIF CFBO JO UIF 3FHJTUSZ TVDI BT UIF 4QSJOH "QQMJDBUJPO$POUFYU. $BNFM DBO JOTUBOUJBUF UIF CFBO BOE JOWPLF UIF NFUIPE JG HJWFO B DMBTT PS JOWPLF BO BMSFBEZ FYJTUJOH JOTUBODF. 5IJT JT JMMVTUSBUFE GSPN UIF FYBNQMF CFMPX:
from("activemq:topic:OrdersTopic"). filter().expression(BeanLanguage(MyBean.class, "isGoldCustomer")). to("activemq:BigSpendersQueue");

5IF 2OE QBSBNFUFS isGoldCustomer JT BO PQUJPOBM QBSBNFUFS UP FYQMJDJU TFU UIF NFUIPE OBNF UP JOWPLF. *G OPU QSPWJEFE $BNFM XJMM USZ UP JOWPLF UIF CFTU TVJUFE NFUIPE. *G DBTF PG BNCJHVJUZ $BNFM XJMM UISPXO BO &YDFQUJPO. *O UIFTF TJUVBUJPOT UIF 2OE QBSBNFUFS DBO TPMWF UIJT QSPCMFN. "MTP UIF DPEF JT NPSF SFBEBCMF JG UIF NFUIPE OBNF JT QSPWJEFE. 5IF 1TU QBSBNFUFS DBO BMTP CF BO FYJTUJOH JOTUBODF PG B #FBO TVDI BT:
private MyBean my;

222

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

from("activemq:topic:OrdersTopic"). filter().expression(BeanLanguage.bean(my, "isGoldCustomer")). to("activemq:BigSpendersQueue");

*O $BNFM 2.2 POXBSET ZPV DBO BWPJE UIF BeanLanguage BOE IBWF JU KVTU BT:
private MyBean my; from("activemq:topic:OrdersTopic"). filter().expression(bean(my, "isGoldCustomer")). to("activemq:BigSpendersQueue");

8IJDI BMTP DBO CF EPOF JO B CJU TIPSUFS BOE OJDF XBZ:


private MyBean my; from("activemq:topic:OrdersTopic"). filter().method(my, "isGoldCustomer"). to("activemq:BigSpendersQueue");

.QEBO BU>JMIBP 8F IBWF TPNF UFTU DBTFT ZPV DBO MPPL BU JG JU'MM IFMQ ` .FUIPE'JMUFS5FTU JT B +6OJU UFTU DBTF TIPXJOH UIF +BWB %4- VTF PG UIF CFBO FYQSFTTJPO CFJOH VTFE JO B GJMUFS ` BHHSFHBUPS.YNM JT B 4QSJOH 9.- UFTU DBTF GPS UIF "HHSFHBUPS XIJDI VTFT B CFBO NFUIPE DBMM UP UFTU GPS UIF DPNQMFUJPO PG UIF BHHSFHBUJPO. #BMBKABK@FBP 5IF #FBO MBOHVBHF JT QBSU PG @>JBI-@LOB.

".-23 -3 $7/1$22(.- + -&4 &$


5IF $POTUBOU &YQSFTTJPO -BOHVBHF JT SFBMMZ KVTU B XBZ UP TQFDJGZ DPOTUBOU TUSJOHT BT B UZQF PG FYQSFTTJPO. $U>JMIB RP>DB 5IF TFU)FBEFS FMFNFOU PG UIF 4QSJOH %4- DBO VUJMJ[F B DPOTUBOU FYQSFTTJPO MJLF:
<route> <from uri="seda:a"/>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

223

<setHeader headerName="theHeader"> <constant>the value</constant> </setHeader> <to uri="mock:b"/> </route>

JO UIJT DBTF, UIF .FTTBHF DPNJOH GSPN UIF TFEB:B &OEQPJOU XJMM IBWF 'UIF)FBEFS' IFBEFS TFU UP UIF DPOTUBOU WBMVF 'UIF WBMVF'. "OE UIF TBNF FYBNQMF VTJOH +BWB %4-:
from("seda:a").setHeader("theHeader", constant("the value")).to("mock:b");

#BMBKABK@FBP 5IF $POTUBOU MBOHVBHF JT QBSU PG @>JBI-@LOB.

$+
$BNFM TVQQPSUT UIF VOJGJFE +41 BOE +4' &YQSFTTJPO -BOHVBHF WJB UIF +6&- UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 'PS FYBNQMF ZPV DPVME VTF &- JOTJEF B .FTTBHF 'JMUFS JO 9.<route> <from uri="seda:foo"/> <filter> <el>${in.headers.foo == 'bar'}</el> <to uri="seda:bar"/> </filter> </route>

:PV DPVME BMTP VTF TMJHIUMZ EJGGFSFOU TZOUBY, F.H. JG UIF IFBEFS OBNF JT OPU B WBMJE JEFOUJGJFS:
<route> <from uri="seda:foo"/> <filter> <el>${in.headers['My Header'] == 'bar'}</el> <to uri="seda:bar"/> </filter> </route>

:PV DPVME VTF &- UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU

224

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

5>OF>?IBP 5>OF>?IB FYDIBOHF JO PVU 3VMB &YDIBOHF .FTTBHF .FTTBHF #BP@OFMQFLK UIF &YDIBOHF PCKFDU UIF FYDIBOHF.JO NFTTBHF UIF FYDIBOHF.PVU NFTTBHF

2>JMIBP :PV DBO VTF &- EPU OPUBUJPO UP JOWPLF PQFSBUJPOT. *G ZPV GPS JOTUBODF IBWF B CPEZ UIBU DPOUBJOT B 10+0 UIBU IBT B getFamiliyName NFUIPE UIFO ZPV DBO DPOTUSVDU UIF TZOUBY BT GPMMPXT:
"$in.body.familyName"

#BMBKABK@FBP 5P VTF &- JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-GRBI XIJDI JNQMFNFOUT UIF &- MBOHVBHF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-juel</artifactId> <version>x.x.x</version> </dependency>

0UIFSXJTF ZPV'MM BMTP OFFE UP JODMVEF +6&-.

'$ #$1 $7/1$22(.- + -&4 &$


5IF )FBEFS &YQSFTTJPO -BOHVBHF BMMPXT ZPV UP FYUSBDU WBMVFT PG OBNFE IFBEFST. $U>JMIB RP>DB 5IF SFDJQJFOU-JTU FMFNFOU PG UIF 4QSJOH %4- DBO VUJMJ[F B IFBEFS FYQSFTTJPO MJLF:
<route> <from uri="direct:a" /> <!-- use comma as a delimiter for String based values --> <recipientList delimiter=",">

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

225

<header>myHeader</header> </recipientList> </route>

*O UIJT DBTF, UIF MJTU PG SFDJQJFOUT BSF DPOUBJOFE JO UIF IFBEFS 'NZ)FBEFS'. "OE UIF TBNF FYBNQMF JO +BWB %4-:
from("direct:a").recipientList(header("myHeader"));

"OE XJUI B TMJHIUMZ EJGGFSFOU TZOUBY XIFSF ZPV VTF UIF CVJMEFS UP UIF GVMMFTU (J.F. BWPJE VTJOH QBSBNFUFST CVU VTJOH TUBDLFE PQFSBUJPOT, OPUJDF UIBU IFBEFS JT OPU B QBSBNFUFS CVU B TUBDLFE NFUIPE DBMM)
from("direct:a").recipientList().header("myHeader");

#BMBKABK@FBP 5IF )FBEFS MBOHVBHF JT QBSU PG @>JBI-@LOB.

)7/ 3'
$BNFM TVQQPSUT +91BUI UP BMMPX 91BUI FYQSFTTJPOT UP CF VTFE PO CFBOT JO BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 'PS FYBNQMF ZPV DPVME VTF +91BUI UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU. :PV DBO VTF 91BUI FYQSFTTJPOT EJSFDUMZ VTJOH TNBSU DPNQMFUJPO JO ZPVS *%& BT GPMMPXT
from("queue:foo").filter(). jxpath("/in/body/foo"). to("queue:bar")

5>OF>?IBP 5>OF>?IB QEFP JO PVU 3VMB &YDIBOHF .FTTBHF .FTTBHF #BP@OFMQFLK UIF &YDIBOHF PCKFDU UIF FYDIBOHF.JO NFTTBHF UIF FYDIBOHF.PVU NFTTBHF

226

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

.MQFLKP .MQFLK 3VMB #BP@OFMQFLK ">JBI 2.11/2.10.5: "MMPXT UP UVSO MFOJFOU PO UIF +91BUI$POUFYU. 8IFO UVSOFE PO UIJT BMMPXT UIF +91BUI FYQSFTTJPO UP FWBMVBUF BHBJOTU FYQSFTTJPOT BOE NFTTBHF CPEJFT XIJDI NBZ CF JOWBMJE / NJTTJOH EBUB. 4FF NPSF EFUBJMT BU UIF +91BUI %PDVNFOUBUJPO 5IJT PQUJPO JT CZ EFGBVMU GBMTF.

MFOJFOU

CPPMFBO

4PFKD 7,+ @LKCFDRO>QFLK *G ZPV QSFGFS UP DPOGJHVSF ZPVS SPVUFT JO ZPVS 4QSJOH 9.- GJMF UIFO ZPV DBO VTF +91BUI FYQSFTTJPOT BT GPMMPXT
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd"> <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="activemq:MyQueue"/> <filter> <jxpath>in/body/name = 'James'</xpath> <to uri="mqseries:SomeOtherQueue"/> </filter> </route> </camelContext> </beans>

$U>JMIBP )FSF JT B TJNQMF FYBNQMF VTJOH B +91BUI FYQSFTTJPO BT B QSFEJDBUF JO B .FTTBHF 'JMUFS
from("direct:start"). filter().jxpath("in/body/name='James'"). to("mock:result");

)7/ 3' (-)$"3(.:PV DBO VTF #FBO *OUFHSBUJPO UP JOWPLF B NFUIPE PO B CFBO BOE VTF WBSJPVT MBOHVBHFT TVDI BT +91BUI UP FYUSBDU B WBMVF GSPN UIF NFTTBHF BOE CJOE JU UP B NFUIPE QBSBNFUFS.

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

227

'PS FYBNQMF
public class Foo { @MessageDriven(uri = "activemq:my.queue") public void doSomething(@JXPath("in/body/foo") String correlationID, @Body String body) { // process the inbound message here } }

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").jxpath("resource:classpath:myjxpath.txt")

#BMBKABK@FBP 5P VTF +9QBUI JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-GUM>QE XIJDI JNQMFNFOUT UIF +9QBUI MBOHVBHF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jxpath</artifactId> <version>x.x.x</version> </dependency>

0UIFSXJTF, ZPV'MM BMTP OFFE $PNNPOT +91BUI.

,5$+
$BNFM BMMPXT .WFM UP CF VTFE BT BO &YQSFTTJPO PS 1SFEJDBUF UIF %4- PS 9NM $POGJHVSBUJPO. :PV DPVME VTF .WFM UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU

228

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

:PV DBO VTF .WFM EPU OPUBUJPO UP JOWPLF PQFSBUJPOT. *G ZPV GPS JOTUBODF IBWF B CPEZ UIBU DPOUBJOT B 10+0 UIBU IBT B getFamiliyName NFUIPE UIFO ZPV DBO DPOTUSVDU UIF TZOUBY BT GPMMPXT:
"request.body.familyName" // or "getRequest().getBody().getFamilyName()"

5>OF>?IBP 5>OF>?IB QEFP FYDIBOHF FYDFQUJPO FYDIBOHF*E GBVMU SFRVFTU SFTQPOTF QSPQFSUJFT QSPQFSUZ(OBNF) QSPQFSUZ(OBNF, UZQF) 3VMB &YDIBOHF &YDIBOHF 5ISPXBCMF 4USJOH .FTTBHF .FTTBHF .FTTBHF .BQ 0CKFDU 5ZQF #BP@OFMQFLK UIF &YDIBOHF JT UIF SPPU PCKFDU UIF &YDIBOHF PCKFDU UIF &YDIBOHF FYDFQUJPO (JG BOZ) UIF FYDIBOHF JE UIF 'BVMU NFTTBHF (JG BOZ) UIF FYDIBOHF.JO NFTTBHF UIF FYDIBOHF.PVU NFTTBHF (JG BOZ) UIF FYDIBOHF QSPQFSUJFT UIF QSPQFSUZ CZ UIF HJWFO OBNF UIF QSPQFSUZ CZ UIF HJWFO OBNF BT UIF HJWFO UZQF

2>JMIBP 'PS FYBNQMF ZPV DPVME VTF .WFM JOTJEF B .FTTBHF 'JMUFS JO 9.<route> <from uri="seda:foo"/> <filter> <mvel>request.headers.foo == 'bar'</mvel> <to uri="seda:bar"/> </filter> </route>

"OE UIF TBNQMF VTJOH +BWB %4-:


from("seda:foo").filter().mvel("request.headers.foo == 'bar'").to("seda:bar");

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

229

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").mvel("resource:classpath:script.mvel")

#BMBKABK@FBP 5P VTF .WFM JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-JSBI XIJDI JNQMFNFOUT UIF .WFM MBOHVBHF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-mvel</artifactId> <version>x.x.x</version> </dependency>

0UIFSXJTF, ZPV'MM BMTP OFFE .7&-

.&-+
$BNFM BMMPXT 0(/- UP CF VTFE BT BO &YQSFTTJPO PS 1SFEJDBUF UIF %4- PS 9NM $POGJHVSBUJPO. :PV DPVME VTF 0(/- UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU :PV DBO VTF 0(/- EPU OPUBUJPO UP JOWPLF PQFSBUJPOT. *G ZPV GPS JOTUBODF IBWF B CPEZ UIBU DPOUBJOT B 10+0 UIBU IBT B getFamiliyName NFUIPE UIFO ZPV DBO DPOTUSVDU UIF TZOUBY BT GPMMPXT:
"request.body.familyName" // or "getRequest().getBody().getFamilyName()"

5>OF>?IBP 5>OF>?IB 3VMB #BP@OFMQFLK

230

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

QEFP FYDIBOHF FYDFQUJPO FYDIBOHF*E GBVMU SFRVFTU SFTQPOTF QSPQFSUJFT QSPQFSUZ(OBNF) QSPQFSUZ(OBNF, UZQF)

&YDIBOHF &YDIBOHF 5ISPXBCMF 4USJOH .FTTBHF .FTTBHF .FTTBHF .BQ 0CKFDU 5ZQF

UIF &YDIBOHF JT UIF SPPU PCKFDU UIF &YDIBOHF PCKFDU UIF &YDIBOHF FYDFQUJPO (JG BOZ) UIF FYDIBOHF JE UIF 'BVMU NFTTBHF (JG BOZ) UIF FYDIBOHF.JO NFTTBHF UIF FYDIBOHF.PVU NFTTBHF (JG BOZ) UIF FYDIBOHF QSPQFSUJFT UIF QSPQFSUZ CZ UIF HJWFO OBNF UIF QSPQFSUZ CZ UIF HJWFO OBNF BT UIF HJWFO UZQF

2>JMIBP 'PS FYBNQMF ZPV DPVME VTF 0(/- JOTJEF B .FTTBHF 'JMUFS JO 9.<route> <from uri="seda:foo"/> <filter> <ognl>request.headers.foo == 'bar'</ognl> <to uri="seda:bar"/> </filter> </route>

"OE UIF TBNQMF VTJOH +BWB %4-:


from("seda:foo").filter().ognl("request.headers.foo == 'bar'").to("seda:bar");

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").ognl("resource:classpath:myognl.txt")

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

231

#BMBKABK@FBP 5P VTF 0(/- JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-LDKI XIJDI JNQMFNFOUT UIF 0(/- MBOHVBHF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ognl</artifactId> <version>x.x.x</version> </dependency>

0UIFSXJTF, ZPV'MM BMTP OFFE 0(/-

/1./$138 $7/1$22(.- + -&4 &$


5IF 1SPQFSUZ &YQSFTTJPO -BOHVBHF BMMPXT ZPV UP FYUSBDU WBMVFT PG OBNFE FYDIBOHF QSPQFSUJFT. $U>JMIB RP>DB 5IF SFDJQJFOU-JTU FMFNFOU PG UIF 4QSJOH %4- DBO VUJMJ[F B QSPQFSUZ FYQSFTTJPO MJLF:
<route> <from uri="direct:a" /> <recipientList> <property>myProperty</property> </recipientList> </route>

*O UIJT DBTF, UIF MJTU PG SFDJQJFOUT BSF DPOUBJOFE JO UIF QSPQFSUZ 'NZ1SPQFSUZ'. "OE UIF TBNF FYBNQMF JO +BWB %4-:
from("direct:a").recipientList(property("myProperty"));

"OE XJUI B TMJHIUMZ EJGGFSFOU TZOUBY XIFSF ZPV VTF UIF CVJMEFS UP UIF GVMMFTU (J.F. BWPJE VTJOH QBSBNFUFST CVU VTJOH TUBDLFE PQFSBUJPOT, OPUJDF UIBU QSPQFSUZ JT OPU B QBSBNFUFS CVU B TUBDLFE NFUIPE DBMM)
from("direct:a").recipientList().property("myProperty");

#BMBKABK@FBP 5IF 1SPQFSUZ MBOHVBHF JT QBSU PG @>JBI-@LOB.

232

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

2"1(/3(-& + -&4 &$2


$BNFM TVQQPSUT B OVNCFS PG TDSJQUJOH MBOHVBHFT XIJDI DBO CF VTFE UP DSFBUF BO &YQSFTTJPO PS 1SFEJDBUF WJB UIF TUBOEBSE +43 223 XIJDI JT B TUBOEBSE QBSU PG +BWB 6. 5IF GPMMPXJOH TDSJQUJOH MBOHVBHFT BSF JOUFHSBUFE JOUP UIF %4-: +>KDR>DB &(SPPWZ +BWB4DSJQU +P42+91BUI .7&0(/1)1 1ZUIPO 3VCZ 91BUI 92VFSZ #2+ HBVTLOA el groovy javaScript sql jxpath mvel ognl php python ruby xpath xquery

)PXFWFS BOZ +43 223 TDSJQUJOH MBOHVBHF DBO CF VTFE VTJOH UIF HFOFSJD %4- NFUIPET. 2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU 5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF

FYDIBOHF

org.apache.camel.Exchange

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

233

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.
from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:
from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):

234

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:
public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar"); arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

235

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

236

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

2$$

+2.
` -BOHVBHFT ` %4` 9NM $POGJHVSBUJPO

!$ -2'$++
$BNFM TVQQPSUT #FBO4IFMM BNPOH PUIFS 4DSJQUJOH -BOHVBHFT UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 5P VTF B #FBO4IFMM FYQSFTTJPO VTF UIF GPMMPXJOH +BWB DPEF:
...choice() .when(script("beanshell", "request.getHeaders().get(\"foo\").equals(\"bar\")")) .to("...")

0S UIF TPNFUIJOH MJLF UIJT JO ZPVS 4QSJOH 9.-:


<filter> <language language="beanshell">request.getHeaders().get("Foo") == null</language> ...

:PV DPVME GPMMPX UIF FYBNQMFT BCPWF UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU 2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU 5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF

FYDIBOHF

org.apache.camel.Exchange

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

237

!B>K2EBII (PPRBP :PV NVTU VTF #FBO4IFMM 2.0C5 PS HSFBUFS. /PUF UIBU BT PG 2.0C5 #FBO4IFMM DBOOPU DPNQJMF TDSJQUT, XIJDI DBVTFT $BNFM SFMFBTFT CFGPSF 2.6 UP GBJM XIFO DPOGJHVSFE XJUI #FBO4IFMM FYQSFTTJPOT.

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.
from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:

238

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):
<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:
public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar");

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

239

arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).

240

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

) 5 2"1(/3
$BNFM TVQQPSUT +BWB4DSJQU/&$."4DSJQU BNPOH PUIFS 4DSJQUJOH -BOHVBHFT UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 5P VTF B +BWB4DSJQU FYQSFTTJPO VTF UIF GPMMPXJOH +BWB DPEF
... javaScript("someJavaScriptExpression") ...

'PS FYBNQMF ZPV DPVME VTF UIF G>S>2@OFMQ GVODUJPO UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU $U>JMIB *O UIF TBNQMF CFMPX XF VTF +BWB4DSJQU UP DSFBUF B 1SFEJDBUF VTF JO UIF SPVUF QBUI, UP SPVUF FYDIBOHFT GSPN BENJO VTFST UP B TQFDJBM RVFVF.
from("direct:start") .choice() .when().javaScript("request.headers.get('user') == 'admin'").to("seda:adminQueue") .otherwise() .to("seda:regularQueue");

"OE B 4QSJOH %4- TBNQMF BT XFMM:


<route> <from uri="direct:start"/> <choice> <when> <javaScript>request.headers.get('user') == 'admin'</javaScript> <to uri="seda:adminQueue"/> </when> <otherwise> <to uri="seda:regularQueue"/> </otherwise> </choice> </route>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

241

2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU 5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF ">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

FYDIBOHF

org.apache.camel.Exchange

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.

242

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:
from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):
<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

243

public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar"); arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:

244

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

&1..58
$BNFM TVQQPSUT (SPPWZ BNPOH PUIFS 4DSJQUJOH -BOHVBHFT UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 5P VTF B (SPPWZ FYQSFTTJPO VTF UIF GPMMPXJOH +BWB DPEF
... groovy("someGroovyExpression") ...

'PS FYBNQMF ZPV DPVME VTF UIF DOLLSV GVODUJPO UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU $U>JMIB
// lets route if a line item is over $100 from("queue:foo").filter(groovy("request.lineItems.any { i -> i.value > 100 }")).to("queue:bar")

"OE UIF 4QSJOH %4-:


<route> <from uri="queue:foo"/> <filter> <groovy>request.lineItems.any { i -> i.value > 100 }</groovy> <to uri="queue:bar"/> </filter> </route>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

245

2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU 5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF ">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

FYDIBOHF

org.apache.camel.Exchange

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.

246

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:
from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):
<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

247

public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar"); arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:

248

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

/83'.$BNFM TVQQPSUT 1ZUIPO BNPOH PUIFS 4DSJQUJOH -BOHVBHFT UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 5P VTF B 1ZUIPO FYQSFTTJPO VTF UIF GPMMPXJOH +BWB DPEF
... python("somePythonExpression") ...

'PS FYBNQMF ZPV DPVME VTF UIF MVQELK GVODUJPO UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU $U>JMIB *O UIF TBNQMF CFMPX XF VTF 1ZUIPO UP DSFBUF B 1SFEJDBUF VTF JO UIF SPVUF QBUI, UP SPVUF FYDIBOHFT GSPN BENJO VTFST UP B TQFDJBM RVFVF.
from("direct:start") .choice() .when().python("request.headers['user'] == 'admin'").to("seda:adminQueue") .otherwise() .to("seda:regularQueue");

"OE B 4QSJOH %4- TBNQMF BT XFMM:


<route> <from uri="direct:start"/>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

249

<choice> <when> <python>request.headers['user'] == 'admin'</python> <to uri="seda:adminQueue"/> </when> <otherwise> <to uri="seda:regularQueue"/> </otherwise> </choice> </route>

2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU 5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF

FYDIBOHF

org.apache.camel.Exchange

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

250

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.
from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:
from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

251

<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:
public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar"); arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

252

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

253

/'/
$BNFM TVQQPSUT 1)1 BNPOH PUIFS 4DSJQUJOH -BOHVBHFT UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 5P VTF B 1)1 FYQSFTTJPO VTF UIF GPMMPXJOH +BWB DPEF
... php("somePHPExpression") ...

'PS FYBNQMF ZPV DPVME VTF UIF MEM GVODUJPO UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU 2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU 5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF

FYDIBOHF

org.apache.camel.Exchange

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

254

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.
from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:
from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

255

<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:
public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar"); arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

256

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

257

14!8
$BNFM TVQQPSUT 3VCZ BNPOH PUIFS 4DSJQUJOH -BOHVBHFT UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 5P VTF B 3VCZ FYQSFTTJPO VTF UIF GPMMPXJOH +BWB DPEF
... ruby("someRubyExpression") ...

'PS FYBNQMF ZPV DPVME VTF UIF OR?V GVODUJPO UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU $U>JMIB *O UIF TBNQMF CFMPX XF VTF 3VCZ UP DSFBUF B 1SFEJDBUF VTF JO UIF SPVUF QBUI, UP SPVUF FYDIBOHFT GSPN BENJO VTFST UP B TQFDJBM RVFVF.
from("direct:start") .choice() .when().ruby("$request.headers['user'] == 'admin'").to("seda:adminQueue") .otherwise() .to("seda:regularQueue");

"OE B 4QSJOH %4- TBNQMF BT XFMM:


<route> <from uri="direct:start"/> <choice> <when> <ruby>$request.headers['user'] == 'admin'</ruby> <to uri="seda:adminQueue"/> </when> <otherwise> <to uri="seda:regularQueue"/> </otherwise> </choice> </route>

2@OFMQ"LKQBUQ 5IF +43-223 TDSJQUJOH MBOHVBHFT 4DSJQU$POUFYU JT QSF DPOGJHVSFE XJUI UIF GPMMPXJOH BUUSJCVUFT BMM TFU BU ENGINE_SCOPE: QQOF?RQB DPOUFYU 3VMB org.apache.camel.CamelContext 5>IRB 5IF $BNFM $POUFYU

258

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

FYDIBOHF

org.apache.camel.Exchange

5IF DVSSFOU &YDIBOHF 5IF */ NFTTBHF 5IF 065 NFTTBHF ">JBI 2.9: 'VODUJPO XJUI B resolve NFUIPE UP NBLF JU FBTJFS UP VTF $BNFMT 1SPQFSUJFT DPNQPOFOU GSPN TDSJQUT. 4FF GVSUIFS CFMPX GPS FYBNQMF.

SFRVFTU SFTQPOTF

org.apache.camel.Message org.apache.camel.Message

QSPQFSUJFT

org.apache.camel.builder.script.PropertiesFunction

QQOF?RQBP :PV DBO BEE ZPVS PXO BUUSJCVUFT XJUI UIF attribute(name, value) %4- NFUIPE, TVDI BT: *O UIF TBNQMF CFMPX XF BEE BO BUUSJCVUF user UIBU JT BO PCKFDU XF BMSFBEZ IBWF JOTUBOUJBUFE BT NZ6TFS. 5IJT PCKFDU IBT B HFU'JSTU/BNF() NFUIPE UIBU XF XBOU UP TFU BT IFBEFS PO UIF NFTTBHF. 8F VTF UIF HSPPWZ MBOHVBHF UP DPODBU UIF GJSTU BOE MBTU OBNF JOUP B TJOHMF TUSJOH UIBU JT SFUVSOFE.
from("direct:in").setHeader("name").groovy("'$user.firstName $user.lastName'").attribute("user", myUser).to("seda:users");

KV P@OFMQFKD I>KDR>DB $BNFM DBO SVO BOZ +43-223 TDSJQUJOH MBOHVBHFT VTJOH UIF script %4- NFUIPE TVDI BT:

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

259

from("direct:in").setHeader("firstName").script("jaskel", "user.firstName").attribute("user", myUser).to("seda:users");

5IJT JT B CJU EJGGFSFOU VTJOH UIF 4QSJOH %4- XIFSF ZPV VTF UIF BUMOBPPFLK FMFNFOU UIBU EPFTO'U TVQQPSU TFUUJOH BUUSJCVUFT (ZFU):
<from uri="direct:in"/> <setHeader headerName="firstName"> <expression language="jaskel">user.firstName</expression> </setHeader> <to uri="seda:users"/>

:PV DBO BMTP VTF QSFEJDBUFT F.H. JO B 'JMUFS:


<filter> <language language="beanshell">request.getHeaders().get("Foo").equals("Bar")</language> <to uri="direct:next" /> </filter>

4FF 4DSJQUJOH -BOHVBHFT GPS UIF MJTU PG MBOHVBHFT XJUI FYQMJDJU %4- TVQQPSU. 4PNF MBOHVBHFT XJUIPVU TQFDJGJD %4- TVQQPSU CVU LOPXO UP XPSL XJUI UIFTF HFOFSJD NFUIPET JODMVEF: +>KDR>DB #FBO4IFMM (JMIBJBKQ>QFLK #FBO4IFMM 2.0C5 I>KDR>DB="..." S>IRB beanshell PS bsh

AAFQFLK>I >ODRJBKQP QL 2@OFMQFKD$KDFKB S>FI>?IB >P LC ">JBI 2.8 :PV DBO QSPWJEF BEEJUJPOBM BSHVNFOUT UP UIF ScriptingEngine VTJOH B IFBEFS PO UIF $BNFM NFTTBHF XJUI UIF LFZ CamelScriptArguments. 4FF UIJT FYBNQMF:
public void testArgumentsExample() throws Exception { if (!ScriptTestHelper.canRunTestOnThisPlatform()) { return; } getMockEndpoint("mock:result").expectedMessageCount(0); getMockEndpoint("mock:unmatched").expectedMessageCount(1); // additional arguments to ScriptEngine Map<String, Object> arguments = new HashMap<String, Object>(); arguments.put("foo", "bar");

260

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

arguments.put("baz", 7); // those additional arguments is provided as a header on the Camel Message template.sendBodyAndHeader("direct:start", "hello", ScriptBuilder.ARGUMENTS, arguments); assertMockEndpointsSatisfied(); }

4PFKD MOLMBOQFBP CRK@QFLK S>FI>?IB >P LC ">JBI 2.9 *G ZPV OFFE UP VTF UIF 1SPQFSUJFT DPNQPOFOU GSPN B TDSJQU UP MPPLVQ QSPQFSUZ QMBDFIPMEFST, UIFO JUT B CJU DVNCFSTPNF UP EP TP. 'PS FYBNQMF UP TFU B IFBEFS OBNF NZ)FBEFS XJUI B WBMVF GSPN B QSPQFSUZ QMBDFIPMEFS, XIJDI LFZ JT QSPWJEFE JO B IFBEFS OBNFE "GPP".
.setHeader("myHeader").groovy("context.resolvePropertyPlaceholders('{{' + request.headers.get('foo') + '}}')")

'SPN $BNFM 2.9 POXBSET ZPV DBO OPX VTF UIF QSPQFSUJFT GVODUJPO BOE UIF TBNF FYBNQMF JT TJNQMFS:
.setHeader("myHeader").groovy("properties.resolve(request.headers.get('foo'))")

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").groovy("resource:classpath:mygroovy.groovy")

#BMBKABK@FBP 5P VTF TDSJQUJOH MBOHVBHFT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIP@OFMQ XIJDI JOUFHSBUFT UIF +43-223 TDSJQUJOH FOHJOF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

261

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <version>x.x.x</version> </dependency>

2(,/+$ $7/1$22(.- + -&4 &$


5IF 4JNQMF &YQSFTTJPO -BOHVBHF XBT B SFBMMZ TJNQMF MBOHVBHF ZPV DBO VTF, CVU IBT TJODF HSPXO NPSF QPXFSGVM. *UT QSJNBSJMZ JOUFOEFE GPS CFJOH B SFBMMZ TNBMM BOE TJNQMF MBOHVBHF GPS FWBMVBUJOH &YQSFTTJPO BOE 1SFEJDBUF XJUIPVU SFRVJSJOH BOZ OFX EFQFOEFODJFT PS LOPXMFEHF PG 91BUI; TP JUT JEFBM GPS UFTUJOH JO DBNFM-DPSF. *UT JEFBM UP DPWFS 95% PG UIF DPNNPO VTF DBTFT XIFO ZPV OFFE B MJUUMF CJU PG FYQSFTTJPO CBTFE TDSJQU JO ZPVS $BNFM SPVUFT. )PXFWFS GPS NVDI NPSF DPNQMFY VTF DBTFT ZPV BSF HFOFSBMMZ SFDPNNFOEFE UP DIPPTF B NPSF FYQSFTTJWF BOE QPXFSGVM MBOHVBHF TVDI BT: ` 4Q&` .WFM ` (SPPWZ ` +BWB4DSJQU ` &` 0(/` POF PG UIF TVQQPSUFE 4DSJQUJOH -BOHVBHFT 5IF TJNQMF MBOHVBHF VTFT ${body^ QMBDFIPMEFST GPS DPNQMFY FYQSFTTJPOT XIFSF UIF FYQSFTTJPO DPOUBJOT DPOTUBOU MJUFSBMT. 5IF $\ ^ QMBDFIPMEFST DBO CF PNJUUFE JG UIF FYQSFTTJPO JT POMZ UIF UPLFO JUTFMG. 5P HFU UIF CPEZ PG UIF JO NFTTBHF: "body", PS "in.body" PS "${body}". " DPNQMFY FYQSFTTJPO NVTU VTF $\ ^ QMBDFIPMEFST, TVDI BT: "Hello ${in.header.name} how are you?". :PV DBO IBWF NVMUJQMF GVODUJPOT JO UIF TBNF FYQSFTTJPO: "Hello ${in.header.name} this is ${in.header.me} speaking". )PXFWFS ZPV DBO KLQ OFTU GVODUJPOT JO $BNFM 2.8.Y PS PMEFS (J.F. IBWJOH BOPUIFS $\ ^ QMBDFIPMEFS JO BO FYJTUJOH, JT OPU BMMPXFE). 'SPN ">JBI 2.9 POXBSET ZPV DBO OFTU GVODUJPOT. 5>OF>?IBP
5>OF>?IB
DBNFM*E DBNFM$POUFYU..&-+ FYDIBOHF*E JE CPEZ

3VMB
4USJOH 0CKFDU 4USJOH 4USJOH 0CKFDU

#BP@OFMQFLK
">JBI 2.10: UIF $BNFM$POUFYU OBNF ">JBI 2.11: UIF $BNFM$POUFYU JOWPLFE VTJOH B $BNFM 0(/- FYQSFTTJPO. ">JBI 2.3: UIF FYDIBOHF JE UIF JOQVU NFTTBHF JE UIF JOQVU CPEZ

262

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

IQBOK>QFSB PVKQ>U 'SPN $BNFM 2.5 POXBSET ZPV DBO BMTP VTF UIF BMUFSOBUJWF TZOUBY XIJDI VTFT $TJNQMF\ ^ BT QMBDFIPMEFST. 5IJT DBO CF VTFE JO TJUVBUJPOT UP BWPJE DMBTIFT XIFO VTJOH GPS FYBNQMF 4QSJOH QSPQFSUZ QMBDFIPMEFS UPHFUIFS XJUI $BNFM.

"LKCFDROFKD OBPRIQ QVMB 'SPN $BNFM 2.8 POXBSET ZPV DBO DPOGJHVSF UIF SFTVMU UZQF PG UIF 4JNQMF FYQSFTTJPO. 'PS FYBNQMF UP TFU UIF UZQF BT B java.lang.Boolean PS B java.lang.Integer FUD.

%FIB I>KDR>DB FP KLT JBODBA TFQE 2FJMIB I>KDR>DB 'SPN $BNFM 2.2 POXBSET, UIF 'JMF -BOHVBHF JT OPX NFSHFE XJUI 4JNQMF MBOHVBHF XIJDI NFBOT ZPV DBO VTF BMM UIF GJMF TZOUBY EJSFDUMZ XJUIJO UIF TJNQMF MBOHVBHF.

2FJMIB +>KDR>DB "E>KDBP FK ">JBI 2.9 LKT>OAP 5IF 4JNQMF MBOHVBHF IBWF CFFO JNQSPWFE GSPN $BNFM 2.9 POXBSET UP VTF B CFUUFS TZOUBY QBSTFS, XIJDI DBO EP JOEFY QSFDJTF FSSPS NFTTBHFT, TP ZPV LOPX FYBDUMZ XIBU JT XSPOH BOE XIFSF UIF QSPCMFN JT. 'PS FYBNQMF JG ZPV IBWF NBEF B UZQP JO POF PG UIF PQFSBUPST, UIFO QSFWJPVTMZ UIF QBSTFS XPVME OPU CF BCMF UP EFUFDU UIJT, BOE DBVTF UIF FWBMVBUJPO UP CF USVF. 5IFSF JT B GFX DIBOHFT JO UIF TZOUBY XIJDI BSF OP MPOHFS CBDLXBSET DPNQBUJCMF. 8IFO VTJOH 4JNQMF MBOHVBHF BT B 1SFEJDBUF UIFO UIF MJUFSBM UFYU JRPQ CF FODMPTFE JO FJUIFS TJOHMF PS EPVCMF RVPUFT. 'PS FYBNQMF: "${body} == 'Camel'". /PUJDF IPX XF IBWF TJOHMF RVPUFT BSPVOE UIF MJUFSBM. 5IF PME TUZMF PG VTJOH "body" BOE "header.foo" UP SFGFS UP UIF NFTTBHF CPEZ BOE IFBEFS JT !EFQSFDBUFE, BOE JUT FODPVSBHFE UP BMXBZT VTF $\ ^ UPLFOT GPS UIF CVJMU-JO GVODUJPOT. 5IF SBOHF PQFSBUPS OPX SFRVJSFT UIF SBOHF UP CF JO TJOHMF RVPUF BT XFMM BT TIPXO: "${header.zip} between '30000..39999'".
JO.CPEZ CPEZ..&-+ JO.CPEZ..&-+ CPEZ"T(type) NBOEBUPSZ#PEZ"T(type) 0CKFDU 0CKFDU 0CKFDU 5ZQF 5ZQF UIF JOQVU CPEZ ">JBI 2.3: UIF JOQVU CPEZ JOWPLFE VTJOH B $BNFM 0(/- FYQSFTTJPO. ">JBI 2.3: UIF JOQVU CPEZ JOWPLFE VTJOH B $BNFM 0(/- FYQSFTTJPO. ">JBI 2.3: $POWFSUT UIF CPEZ UP UIF HJWFO UZQF EFUFSNJOFE CZ JUT DMBTTOBNF. 5IF DPOWFSUFE CPEZ DBO CF OVMM. ">JBI 2.5: $POWFSUT UIF CPEZ UP UIF HJWFO UZQF EFUFSNJOFE CZ JUT DMBTTOBNF, BOE FYQFDUT UIF CPEZ UP CF OPU OVMM.

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

263

PVU.CPEZ IFBEFS.GPP IFBEFS<GPP> IFBEFST.GPP IFBEFST<GPP> JO.IFBEFS.GPP JO.IFBEFS<GPP> JO.IFBEFST.GPP JO.IFBEFST<GPP> IFBEFS.GPP<CBS> JO.IFBEFS.GPP<CBS> JO.IFBEFST.GPP<CBS> IFBEFS.GPP..&-+ JO.IFBEFS.GPP..&-+ JO.IFBEFST.GPP..&-+ PVU.IFBEFS.GPP PVU.IFBEFS<GPP> PVU.IFBEFST.GPP PVU.IFBEFST<GPP> IFBEFS"T(key,type) IFBEFST JO.IFBEFST QSPQFSUZ.GPP QSPQFSUZ<GPP> QSPQFSUZ.GPP..&-+ TZT.GPP TZTFOW.GPP FYDFQUJPO FYDFQUJPO..&-+ FYDFQUJPO.NFTTBHF FYDFQUJPO.TUBDLUSBDF

0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 0CKFDU 5ZQF .BQ .BQ 0CKFDU 0CKFDU 0CKFDU 4USJOH 4USJOH 0CKFDU 0CKFDU 4USJOH 4USJOH

UIF PVUQVU CPEZ SFGFS UP UIF JOQVU GPP IFBEFS ">JBI 2.9.2: SFGFS UP UIF JOQVU GPP IFBEFS SFGFS UP UIF JOQVU GPP IFBEFS ">JBI 2.9.2: SFGFS UP UIF JOQVU GPP IFBEFS SFGFS UP UIF JOQVU GPP IFBEFS ">JBI 2.9.2: SFGFS UP UIF JOQVU GPP IFBEFS SFGFS UP UIF JOQVU GPP IFBEFS ">JBI 2.9.2: SFGFS UP UIF JOQVU GPP IFBEFS ">JBI 2.3: SFHBSE JOQVU GPP IFBEFS BT B NBQ BOE QFSGPSN MPPLVQ PO UIF NBQ XJUI CBS BT LFZ ">JBI 2.3: SFHBSE JOQVU GPP IFBEFS BT B NBQ BOE QFSGPSN MPPLVQ PO UIF NBQ XJUI CBS BT LFZ ">JBI 2.3: SFHBSE JOQVU GPP IFBEFS BT B NBQ BOE QFSGPSN MPPLVQ PO UIF NBQ XJUI CBS BT LFZ ">JBI 2.3: SFGFS UP UIF JOQVU GPP IFBEFS BOE JOWPLF JUT WBMVF VTJOH B $BNFM 0(/- FYQSFTTJPO. ">JBI 2.3: SFGFS UP UIF JOQVU GPP IFBEFS BOE JOWPLF JUT WBMVF VTJOH B $BNFM 0(/- FYQSFTTJPO. ">JBI 2.3: SFGFS UP UIF JOQVU GPP IFBEFS BOE JOWPLF JUT WBMVF VTJOH B $BNFM 0(/- FYQSFTTJPO. SFGFS UP UIF PVU IFBEFS GPP ">JBI 2.9.2: SFGFS UP UIF PVU IFBEFS GPP SFGFS UP UIF PVU IFBEFS GPP ">JBI 2.9.2: SFGFS UP UIF PVU IFBEFS GPP ">JBI 2.5: $POWFSUT UIF IFBEFS UP UIF HJWFO UZQF EFUFSNJOFE CZ JUT DMBTTOBNF ">JBI 2.9: SFGFS UP UIF JOQVU IFBEFST ">JBI 2.9: SFGFS UP UIF JOQVU IFBEFST SFGFS UP UIF GPP QSPQFSUZ PO UIF FYDIBOHF ">JBI 2.9.2: SFGFS UP UIF GPP QSPQFSUZ PO UIF FYDIBOHF ">JBI 2.8: SFGFS UP UIF GPP QSPQFSUZ PO UIF FYDIBOHF BOE JOWPLF JUT WBMVF VTJOH B $BNFM 0(/- FYQSFTTJPO. SFGFS UP UIF TZTUFN QSPQFSUZ ">JBI 2.3: SFGFS UP UIF TZTUFN FOWJSPONFOU ">JBI 2.4: 3FGFS UP UIF FYDFQUJPO PCKFDU PO UIF FYDIBOHF, JT KRII JG OP FYDFQUJPO TFU PO FYDIBOHF. 8JMM GBMMCBDL BOE HSBC DBVHIU FYDFQUJPOT (Exchange.EXCEPTION_CAUGHT) JG UIF &YDIBOHF IBT BOZ. ">JBI 2.4: 3FGFS UP UIF FYDIBOHF FYDFQUJPO JOWPLFE VTJOH B $BNFM 0(/- FYQSFTTJPO PCKFDU 3FGFS UP UIF FYDFQUJPO.NFTTBHF PO UIF FYDIBOHF, JT KRII JG OP FYDFQUJPO TFU PO FYDIBOHF. 8JMM GBMMCBDL BOE HSBC DBVHIU FYDFQUJPOT (Exchange.EXCEPTION_CAUGHT) JG UIF &YDIBOHF IBT BOZ. ">JBI 2.6. 3FGFS UP UIF FYDFQUJPO.TUSBDLUSBDF PO UIF FYDIBOHF, JT KRII JG OP FYDFQUJPO TFU PO FYDIBOHF. 8JMM GBMMCBDL BOE HSBC DBVHIU FYDFQUJPOT (Exchange.EXCEPTION_CAUGHT) JG UIF &YDIBOHF IBT BOZ. %BUF GPSNBUUJOH VTJOH UIF java.text.SimpleDataFormat QBUUFSOT. 4VQQPSUFE DPNNBOET BSF: KLT GPS DVSSFOU UJNFTUBNQ, FK.EB>ABO.UUU PS EB>ABO.UUU UP VTF UIF %BUF PCKFDU JO UIF */ IFBEFS XJUI UIF LFZ YYY. LRQ.EB>ABO.UUU UP VTF UIF %BUF PCKFDU JO UIF 065 IFBEFS XJUI UIF LFZ YYY. *OWPLJOH B CFBO FYQSFTTJPO VTJOH UIF #FBO MBOHVBHF. 4QFDJGZJOH B NFUIPE OBNF ZPV NVTU VTF EPU BT TFQBSBUPS. 8F BMTP TVQQPSU UIF NFUIPE=NFUIPEOBNF TZOUBY UIBU JT VTFE CZ UIF #FBO DPNQPOFOU. ">JBI 2.3: -PPLVQ B QSPQFSUZ XJUI UIF HJWFO LFZ. 5IF locations PQUJPO JT PQUJPOBM. 4FF NPSF BU 6TJOH 1SPQFSUZ1MBDFIPMEFS. ">JBI 2.11: 3FUVSOT UIF JE PG UIF DVSSFOU SPVUF UIF &YDIBOHF JT CFJOH SPVUFE. ">JBI 2.3: 3FUVSOT UIF OBNF PG UIF DVSSFOU UISFBE. $BO CF VTFE GPS MPHHJOH QVSQPTF. ">JBI 2.6: 5P MPPLVQ B CFBO GSPN UIF 3FHJTUSZ XJUI UIF HJWFO JE. ">JBI 2.11: 5P SFGFS UP B UZQF PS GJFME CZ JUT '2/ OBNF. 5P SFGFS UP B GJFME ZPV DBO BQQFOE .'*&-%@/".&. 'PS FYBNQMF ZPV DBO SFGFS UP UIF DPOTUBOU GJFME GSPN &YDIBOHF BT: org.apache.camel.Exchange.FILE_NAME .

EBUF:command:pattern

4USJOH

CFBO:bean expression QSPQFSUJFT:locations:key SPVUF*E UISFBE/BNF SFG:YYY UZQF:OBNF.GJFME

0CKFDU 4USJOH 4USJOH 4USJOH 0CKFDU 0CKFDU

.&-+ BUMOBPPFLK PRMMLOQ S>FI>?IB >P LC ">JBI 2.3 5IF 4JNQMF BOE #FBO MBOHVBHF OPX TVQQPSUT B $BNFM 0(/- OPUBUJPO GPS JOWPLJOH CFBOT JO B DIBJO MJLF GBTIJPO. 4VQQPTF UIF .FTTBHF */ CPEZ DPOUBJOT B 10+0 XIJDI IBT B getAddress() NFUIPE.

264

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

5IFO ZPV DBO VTF $BNFM 0(/- OPUBUJPO UP BDDFTT UIF BEESFTT PCKFDU:
simple("${body.address}") simple("${body.address.street}") simple("${body.address.zip}")

$BNFM VOEFSTUBOET UIF TIPSUIBOE OBNFT GPS HFUUFST, CVU ZPV DBO JOWPLF BOZ NFUIPE PS VTF UIF SFBM OBNF TVDI BT:
simple("${body.address}") simple("${body.getAddress.getStreet}") simple("${body.address.getZip}") simple("${body.doSomething}")

:PV DBO BMTP VTF UIF OVMM TBGF PQFSBUPS (?.) UP BWPJE /1& JG GPS FYBNQMF UIF CPEZ EPFT /05 IBWF BO BEESFTT
simple("${body?.address?.street}")

*UT BMTP QPTTJCMF UP JOEFY JO Map PS List UZQFT, TP ZPV DBO EP:
simple("${body[foo].name}")

5P BTTVNF UIF CPEZ JT Map CBTFE BOE MPPLVQ UIF WBMVF XJUI foo BT LFZ, BOE JOWPLF UIF getName NFUIPE PO UIBU WBMVF. :PV DBO BDDFTT UIF Map PS List PCKFDUT EJSFDUMZ VTJOH UIFJS LFZ OBNF (XJUI PS XJUIPVU EPUT) :
simple("${body[foo]}") simple("${body[this.is.foo]}")

4VQQPTF UIFSF XBT OP WBMVF XJUI UIF LFZ foo UIFO ZPV DBO VTF UIF OVMM TBGF PQFSBUPS UP BWPJE UIF /1& BT TIPXO:
simple("${body[foo]?.name}")

:PV DBO BMTP BDDFTT List UZQFT, GPS FYBNQMF UP HFU MJOFT GSPN UIF BEESFTT ZPV DBO EP:
simple("${body.address.lines[0]}") simple("${body.address.lines[1]}") simple("${body.address.lines[2]}")

5IFSF JT B TQFDJBM last LFZXPSE XIJDI DBO CF VTFE UP HFU UIF MBTU WBMVF GSPN B MJTU.

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

265

*G UIF LFZ IBT TQBDF, UIFO ZPV JRPQ FODMPTF UIF LFZ XJUI RVPUFT, GPS FYBNQMF 'GPP CBS':
simple("${body['foo bar'].name}")

simple("${body.address.lines[last]}")

"OE UP HFU UIF 2OE MBTU ZPV DBO TVCUSBDU B OVNCFS, TP XF DBO VTF last-1 UP JOEJDBUF UIJT:
simple("${body.address.lines[last-1]}")

"OE UIF 3SE MBTU JT PG DPVSTF:


simple("${body.address.lines[last-2]}")

"OE ZFT ZPV DBO DPNCJOF UIJT XJUI UIF PQFSBUPS TVQQPSU BT TIPXO CFMPX:
simple("${body.address.zip} > 1000")

.MBO>QLO PRMMLOQ 5IF QBSTFS JT MJNJUFE UP POMZ TVQQPSU B TJOHMF PQFSBUPS. 5P FOBCMF JU UIF MFGU WBMVF NVTU CF FODMPTFE JO $\ ^. 5IF TZOUBY JT:
${leftValue} OP rightValue

8IFSF UIF rightValue DBO CF B 4USJOH MJUFSBM FODMPTFE JO ' ', null, B DPOTUBOU WBMVF PS BOPUIFS FYQSFTTJPO FODMPTFE JO $\ ^. $BNFM XJMM BVUPNBUJDBMMZ UZQF DPOWFSU UIF SJHIU7BMVF UZQF UP UIF MFGU7BMVF UZQF, TP JUT BCMF UP FH. DPOWFSU B TUSJOH JOUP B OVNFSJD TP ZPV DBO VTF > DPNQBSJTPO GPS OVNFSJD WBMVFT. 5IF GPMMPXJOH PQFSBUPST BSF TVQQPSUFE: .MBO>QLO == > >= #BP@OFMQFLK FRVBMT HSFBUFS UIBO HSFBUFS UIBO PS FRVBMT

266

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

(JMLOQ>KQ 5IFSF JRPQ CF TQBDFT BSPVOE UIF PQFSBUPS.

< <= != DPOUBJOT OPU DPOUBJOT SFHFY OPU SFHFY JO OPU JO JT OPU JT SBOHF

MFTT UIBO MFTT UIBO PS FRVBMT OPU FRVBMT 'PS UFTUJOH JG DPOUBJOT JO B TUSJOH CBTFE WBMVF 'PS UFTUJOH JG OPU DPOUBJOT JO B TUSJOH CBTFE WBMVF 'PS NBUDIJOH BHBJOTU B HJWFO SFHVMBS FYQSFTTJPO QBUUFSO EFGJOFE BT B 4USJOH WBMVF 'PS OPU NBUDIJOH BHBJOTU B HJWFO SFHVMBS FYQSFTTJPO QBUUFSO EFGJOFE BT B 4USJOH WBMVF 'PS NBUDIJOH JG JO B TFU PG WBMVFT, FBDI FMFNFOU NVTU CF TFQBSBUFE CZ DPNNB. 'PS NBUDIJOH JG OPU JO B TFU PG WBMVFT, FBDI FMFNFOU NVTU CF TFQBSBUFE CZ DPNNB. 'PS NBUDIJOH JG UIF MFGU IBOE TJEF UZQF JT BO JOTUBODFPG UIF WBMVF. 'PS NBUDIJOH JG UIF MFGU IBOE TJEF UZQF JT OPU BO JOTUBODFPG UIF WBMVF. 'PS NBUDIJOH JG UIF MFGU IBOE TJEF JT XJUIJO B SBOHF PG WBMVFT EFGJOFE BT OVNCFST: from..to. 'SPN ">JBI 2.9 POXBSET UIF SBOHF WBMVFT NVTU CF FODMPTFE JO TJOHMF RVPUFT. 'PS NBUDIJOH JG UIF MFGU IBOE TJEF JT OPU XJUIJO B SBOHF PG WBMVFT EFGJOFE BT OVNCFST: from..to. 'SPN ">JBI 2.9 POXBSET UIF SBOHF WBMVFT NVTU CF FODMPTFE JO TJOHMF RVPUFT. #BP@OFMQFLK ">JBI 2.9: 5P JODSFNFOU B OVNCFS CZ POF. 5IF MFGU IBOE TJEF NVTU CF B GVODUJPO, PUIFSXJTF QBSTFE BT MJUFSBM. ">JBI 2.9: 5P EFDSFNFOU B OVNCFS CZ POF. 5IF MFGU IBOE TJEF NVTU CF B GVODUJPO, PUIFSXJTF QBSTFE BT MJUFSBM.

OPU SBOHF

"OE UIF GPMMPXJOH VOBSZ PQFSBUPST DBO CF VTFE: .MBO>QLO ++ --

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

267

">JBI 2.9.3 QL 2.10.U 5P FTDBQF B WBMVF, FH =$, UP JOEJDBUF B $ TJHO. 4QFDJBM: 6TF =O GPS OFX MJOF, =U GPS UBC, BOE =S GPS DBSSJBHF SFUVSO. -LQF@B: &TDBQJOH JT KLQ TVQQPSUFE VTJOH UIF 'JMF -BOHVBHF. -LQF@B: 'SPN $BNFM 2.11 POXBSET UIF FTDBQF DIBSBDUFS JT OP MPOHFS TVQQPSU, CVU SFQMBDFE XJUI UIF GPMMPXJOH UISFF TQFDJBM FTDBQJOH. ">JBI 2.11: 5P VTF OFXMJOF DIBSBDUFS. ">JBI 2.11: 5P VTF UBC DIBSBDUFS. ">JBI 2.11: 5P VTF DBSSJBHF SFUVSO DIBSBDUFS. #BP@OFMQFLK ABMOB@>QBA VTF && JOTUFBE. 5IF MPHJDBM BOE PQFSBUPS JT VTFE UP HSPVQ UXP FYQSFTTJPOT. ABMOB@>QBA VTF ]] JOTUFBE. 5IF MPHJDBM PS PQFSBUPS JT VTFE UP HSPVQ UXP FYQSFTTJPOT. ">JBI 2.9: 5IF MPHJDBM BOE PQFSBUPS JT VTFE UP HSPVQ UXP FYQSFTTJPOT. ">JBI 2.9: 5IF MPHJDBM PS PQFSBUPS JT VTFE UP HSPVQ UXP FYQSFTTJPOT.

=O =U =S .MBO>QLO BOE PS && ]]

"OE UIF GPMMPXJOH MPHJDBM PQFSBUPST DBO CF VTFE UP HSPVQ FYQSFTTJPOT:

5IF TZOUBY GPS "/% JT:


${leftValue} OP rightValue and ${leftValue} OP rightValue

"OE UIF TZOUBY GPS 03 JT:


${leftValue} OP rightValue or ${leftValue} OP rightValue

4PNF FYBNQMFT:
simple("${in.header.foo} == 'foo'") // here Camel will type convert '100' into the type of in.header.bar and if its an Integer '100' will also be converter to an Integer simple("${in.header.bar} == '100'") simple("${in.header.bar} == 100") // 100 will be converter to the type of in.header.bar so we can do > comparison simple("${in.header.bar} > 100")

// testing for null simple("${in.header.baz} == null")

268

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

4PFKD >KA,LO LMBO>QLOP *O ">JBI 2.4 LO LIABO UIF and PS or DBO POMZ CF VTFE LK@B JO B TJNQMF MBOHVBHF FYQSFTTJPO. 'SPN ">JBI 2.5 POXBSET ZPV DBO VTF UIFTF PQFSBUPST NVMUJQMF UJNFT.

"LJM>OFKD TFQE AFCCBOBKQ QVMBP 8IFO ZPV DPNQBSF XJUI EJGGFSFOU UZQFT TVDI BT 4USJOH BOE JOU, UIFO ZPV IBWF UP UBLF B CJU DBSF. $BNFM XJMM VTF UIF UZQF GSPN UIF MFGU IBOE TJEF BT 1TU QSJPSJUZ. "OE GBMMCBDL UP UIF SJHIU IBOE TJEF UZQF JG CPUI WBMVFT DPVMEO'U CF DPNQBSFE CBTFE PO UIBU UZQF. 5IJT NFBOT ZPV DBO GMJQ UIF WBMVFT UP FOGPSDF B TQFDJGJD UZQF. 4VQQPTF UIF CBS WBMVF BCPWF JT B 4USJOH. 5IFO ZPV DBO GMJQ UIF FRVBUJPO:
simple("100 < ${in.header.bar}")

XIJDI UIFO FOTVSFT UIF JOU UZQF JT VTFE BT 1TU QSJPSJUZ. 5IJT NBZ DIBOHF JO UIF GVUVSF JG UIF $BNFM UFBN JNQSPWFT UIF CJOBSZ DPNQBSJTPO PQFSBUJPOT UP QSFGFS OVNFSJD UZQFT PWFS 4USJOH CBTFE. *U'T NPTU PGUFO UIF 4USJOH UZQF XIJDI DBVTFT QSPCMFN XIFO DPNQBSJOH XJUI OVNCFST.

// testing for not null simple("${in.header.baz} != null")

"OE B CJU NPSF BEWBODFE FYBNQMF XIFSF UIF SJHIU WBMVF JT BOPUIFS FYQSFTTJPO
simple("${in.header.date} == ${date:now:yyyyMMdd}") simple("${in.header.type} == ${bean:orderService?method=getOrderType}")

"OE BO FYBNQMF XJUI DPOUBJOT, UFTUJOH JG UIF UJUMF DPOUBJOT UIF XPSE $BNFM
simple("${in.header.title} contains 'Camel'")

"OE BO FYBNQMF XJUI SFHFY, UFTUJOH JG UIF OVNCFS IFBEFS JT B 4 EJHJU WBMVF:
simple("${in.header.number} regex '\\d{4}'")

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

269

"OE GJOBMMZ BO FYBNQMF JG UIF IFBEFS FRVBMT BOZ PG UIF WBMVFT JO UIF MJTU. &BDI FMFNFOU NVTU CF TFQBSBUFE CZ DPNNB, BOE OP TQBDF BSPVOE. 5IJT BMTP XPSLT GPS OVNCFST FUD, BT $BNFM XJMM DPOWFSU FBDI FMFNFOU JOUP UIF UZQF PG UIF MFGU IBOE TJEF.
simple("${in.header.type} in 'gold,silver'")

"OE GPS BMM UIF MBTU 3 XF BMTP TVQQPSU UIF OFHBUF UFTU VTJOH OPU:
simple("${in.header.type} not in 'gold,silver'")

"OE ZPV DBO UFTU JG UIF UZQF JT B DFSUBJO JOTUBODF, FH GPS JOTUBODF B 4USJOH
simple("${in.header.type} is 'java.lang.String'")

8F IBWF BEEFE B TIPSUIBOE GPS BMM java.lang UZQFT TP ZPV DBO XSJUF JU BT:
simple("${in.header.type} is 'String'")

3BOHFT BSF BMTP TVQQPSUFE. 5IF SBOHF JOUFSWBM SFRVJSFT OVNCFST BOE CPUI GSPN BOE FOE BSF JODMVTJWF. 'PS JOTUBODF UP UFTU XIFUIFS B WBMVF JT CFUXFFO 100 BOE 199:
simple("${in.header.number} range 100..199")

/PUJDF XF VTF .. JO UIF SBOHF XJUIPVU TQBDFT. *UT CBTFE PO UIF TBNF TZOUBY BT (SPPWZ. 'SPN ">JBI 2.9 POXBSET UIF SBOHF WBMVF NVTU CF JO TJOHMF RVPUFT
simple("${in.header.number} range '100..199'")

4PFKD >KA / LO
*G ZPV IBWF UXP FYQSFTTJPOT ZPV DBO DPNCJOF UIFN XJUI UIF and PS or PQFSBUPS. 'PS JOTUBODF:
simple("${in.header.title} contains 'Camel' and ${in.header.type'} == 'gold'")

"OE PG DPVSTF UIF or JT BMTP TVQQPSUFE. 5IF TBNQMF XPVME CF:


simple("${in.header.title} contains 'Camel' or ${in.header.type'} == 'gold'")

270

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

">K ?B RPBA FK 2MOFKD 7,+ "T UIF 4QSJOH 9.- EPFT OPU IBWF BMM UIF QPXFS BT UIF +BWB %4- XJUI BMM JUT WBSJPVT CVJMEFS NFUIPET, ZPV IBWF UP SFTPSU UP VTF TPNF PUIFS MBOHVBHFT GPS UFTUJOH XJUI TJNQMF PQFSBUPST. /PX ZPV DBO EP UIJT XJUI UIF TJNQMF MBOHVBHF. *O UIF TBNQMF CFMPX XF XBOU UP UFTU JG UIF IFBEFS JT B XJEHFU PSEFS:
<from uri="seda:orders"> <filter> <simple>${in.header.type} == 'widget'</simple> <to uri="bean:orderService?method=handleWidget"/> </filter> </from>

">JBI 2.9 LKT>OAP 6TF && PS ]] GSPN $BNFM 2.9 POXBSET. -LQF@B: $VSSFOUMZ and PS or DBO POMZ CF VTFE LK@B JO B TJNQMF MBOHVBHF FYQSFTTJPO. 5IJT NJHIU DIBOHF JO UIF GVUVSF. 4P ZPV @>KKLQ EP:
simple("${in.header.title} contains 'Camel' and ${in.header.type'} == 'gold' and ${in.header.number} range 100..200")

2>JMIBP *O UIF 4QSJOH 9.- TBNQMF CFMPX XF GJMUFS CBTFE PO B IFBEFS WBMVF:
<from uri="seda:orders"> <filter> <simple>${in.header.foo}</simple> <to uri="mock:fooOrders"/> </filter> </from>

5IF 4JNQMF MBOHVBHF DBO CF VTFE GPS UIF QSFEJDBUF UFTU BCPWF JO UIF .FTTBHF 'JMUFS QBUUFSO, XIFSF XF UFTU JG UIF JO NFTTBHF IBT B foo IFBEFS (B IFBEFS XJUI UIF LFZ foo FYJTUT). *G UIF FYQSFTTJPO FWBMVBUFT UP QORB UIFO UIF NFTTBHF JT SPVUFE UP UIF mock:fooOrders FOEQPJOU, PUIFSXJTF JUT MPTU JO UIF EFFQ CMVF TFB . 5IF TBNF FYBNQMF JO +BWB %4-:

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

271

from("seda:orders") .filter().simple("${in.header.foo}").to("seda:fooOrders");

:PV DBO BMTP VTF UIF TJNQMF MBOHVBHF GPS TJNQMF UFYU DPODBUFOBUJPOT TVDI BT:
from("direct:hello").transform().simple("Hello ${in.header.user} how are you?").to("mock:reply");

/PUJDF UIBU XF NVTU VTF $\ ^ QMBDFIPMEFST JO UIF FYQSFTTJPO OPX UP BMMPX $BNFM UP QBSTF JU DPSSFDUMZ. "OE UIJT TBNQMF VTFT UIF EBUF DPNNBOE UP PVUQVU DVSSFOU EBUF.
from("direct:hello").transform().simple("The today is ${date:now:yyyyMMdd} and its a great day.").to("mock:reply");

"OE JO UIF TBNQMF CFMPX XF JOWPLF UIF CFBO MBOHVBHF UP JOWPLF B NFUIPE PO B CFBO UP CF JODMVEFE JO UIF SFUVSOFE TUSJOH:
from("direct:order").transform().simple("OrderId: ${bean:orderIdGenerator}").to("mock:reply");

8IFSF orderIdGenerator JT UIF JE PG UIF CFBO SFHJTUFSFE JO UIF 3FHJTUSZ. *G VTJOH 4QSJOH UIFO JUT UIF 4QSJOH CFBO JE. *G XF XBOU UP EFDMBSF XIJDI NFUIPE UP JOWPLF PO UIF PSEFS JE HFOFSBUPS CFBO XF NVTU QSFQFOE .method name TVDI BT CFMPX XIFSF XF JOWPLF UIF generateId NFUIPE.
from("direct:order").transform().simple("OrderId: ${bean:orderIdGenerator.generateId}").to("mock:reply");

8F DBO VTF UIF ?method=methodname PQUJPO UIBU XF BSF GBNJMJBS XJUI UIF #FBO DPNQPOFOU JUTFMG:
from("direct:order").transform().simple("OrderId: ${bean:orderIdGenerator?method=generateId}").to("mock:reply");

"OE GSPN $BNFM 2.3 POXBSET ZPV DBO BMTP DPOWFSU UIF CPEZ UP B HJWFO UZQF, GPS FYBNQMF UP FOTVSF JUT B 4USJOH ZPV DBO EP:
<transform> <simple>Hello ${bodyAs(String)} how are you?</simple> </transform>

272

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

5IFSF BSF B GFX UZQFT XIJDI IBWF B TIPSUIBOE OPUBUJPO, TP XF DBO VTF String JOTUFBE PG java.lang.String. 5IFTF BSF: byte[], String, Integer, Long. "MM PUIFS UZQFT NVTU VTF UIFJS '2/ OBNF, F.H. org.w3c.dom.Document. *UT BMTP QPTTJCMF UP MPPLVQ B WBMVF GSPN B IFBEFS Map JO ">JBI 2.3 POXBSET:
<transform> <simple>The gold value is ${header.type[gold]}</simple> </transform>

*O UIF DPEF BCPWF XF MPPLVQ UIF IFBEFS XJUI OBNF type BOE SFHBSE JU BT B java.util.Map BOE XF UIFO MPPLVQ XJUI UIF LFZ gold BOE SFUVSO UIF WBMVF. *G UIF IFBEFS JT OPU DPOWFSUJCMF UP .BQ BO FYDFQUJPO JT UISPXO. *G UIF IFBEFS XJUI OBNF type EPFT OPU FYJTU null JT SFUVSOFE. 'SPN $BNFM 2.9 POXBSET ZPV DBO OFTU GVODUJPOT, TVDI BT TIPXO CFMPX:
<setHeader headerName="myHeader"> <simple>${properties:${header.someKey}}</simple> </setHeader>

1BCBOOFKD QL @LKPQ>KQP LO BKRJP


S>FI>?IB >P LC ">JBI 2.11 4VQQPTF ZPV IBWF BO FOVN GPS DVTUPNFST
public enum Customer { GOLD, SILVER, BRONZE }

"OE JO B $POUFOU #BTFE 3PVUFS XF DBO VTF UIF 4JNQMF MBOHVBHF UP SFGFS UP UIJT FOVN, UP DIFDL UIF NFTTBHF XIJDI FOVN JU NBUDIFT.
from("direct:start") .choice() .when().simple("${header.customer} == ${type:org.apache.camel.processor.Customer.GOLD}") .to("mock:gold") .when().simple("${header.customer} == ${type:org.apache.camel.processor.Customer.SILVER}") .to("mock:silver") .otherwise() .to("mock:other");

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

273

4PFKD KBT IFKBP LO Q>?P FK 7,+ #2+P S>FI>?IB >P LC ">JBI 2.9.3 'SPN $BNFM 2.9.3 POXBSET JUT FBTJFS UP TQFDJGZ OFX MJOFT PS UBCT JO 9.- %4-T BT ZPV DBO FTDBQF UIF WBMVF OPX
<transform> <simple>The following text\nis on a new line</simple> </transform>

2BQQFKD OBPRIQ QVMB S>FI>?IB >P LC ">JBI 2.8 :PV DBO OPX QSPWJEF B SFTVMU UZQF UP UIF 4JNQMF FYQSFTTJPO, XIJDI NFBOT UIF SFTVMU PG UIF FWBMVBUJPO XJMM CF DPOWFSUFE UP UIF EFTJSFE UZQF. 5IJT JT NPTU VTFBCMF UP EFGJOF UZQFT TVDI BT CPPMFBOT, JOUFHFST, FUD. 'PS FYBNQMF UP TFU B IFBEFS BT B CPPMFBO UZQF ZPV DBO EP:
.setHeader("cool", simple("true", Boolean.class))

"OE JO 9.- %4<setHeader headerName="cool"> <!-- use resultType to indicate that the type should be a java.lang.Boolean --> <simple resultType="java.lang.Boolean">true</simple> </setHeader>

"E>KDFKD CRK@QFLK PQ>OQ >KA BKA QLHBKP S>FI>?IB >P LC ">JBI 2.9.1 :PV DBO DPOGJHVSF UIF GVODUJPO TUBSU BOE FOE UPLFOT - $\ ^ VTJOH UIF TFUUFST changeFunctionStartToken BOE changeFunctionEndToken PO SimpleLanguage, VTJOH +BWB DPEF. 'SPN 4QSJOH 9.- ZPV DBO EFGJOF B <CFBO> UBH XJUI UIF OFX DIBOHFE UPLFOT JO UIF QSPQFSUJFT BT TIPXO CFMPX:
<!-- configure Simple to use custom prefix/suffix tokens --> <bean id="simple" class="org.apache.camel.language.simple.SimpleLanguage"> <property name="functionStartToken" value="["/> <property name="functionEndToken" value="]"/> </bean>

*O UIF FYBNQMF BCPWF XF VTF < > BT UIF DIBOHFE UPLFOT.

274

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

/PUJDF CZ DIBOHJOH UIF TUBSU/FOE UPLFO ZPV DIBOHF UIPTF JO BMM UIF $BNFM BQQMJDBUJPOT XIJDI TIBSF UIF TBNF @>JBI-@LOB PO UIFJS DMBTTQBUI. 'PS FYBNQMF JO BO 04(J TFSWFS UIJT NBZ BGGFDU NBOZ BQQMJDBUJPOT, XIFSF BT B 8FC "QQMJDBUJPO BT B 8"3 GJMF JU POMZ BGGFDUT UIF 8FC "QQMJDBUJPO. +L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").simple("resource:classpath:mysimple.txt")

#BMBKABK@FBP 5IF 4JNQMF MBOHVBHF JT QBSU PG @>JBI-@LOB.

%(+$ $7/1$22(.- + -&4 &$


5IF 'JMF &YQSFTTJPO -BOHVBHF JT BO FYUFOTJPO UP UIF 4JNQMF MBOHVBHF, BEEJOH GJMF SFMBUFE DBQBCJMJUJFT. 5IFTF DBQBCJMJUJFT BSF SFMBUFE UP DPNNPO VTF DBTFT XPSLJOH XJUI GJMF QBUI BOE OBNFT. 5IF HPBM JT UP BMMPX FYQSFTTJPOT UP CF VTFE XJUI UIF 'JMF BOE '51 DPNQPOFOUT GPS TFUUJOH EZOBNJD GJMF QBUUFSOT GPS CPUI DPOTVNFS BOE QSPEVDFS. 2VKQ>U 5IJT MBOHVBHF JT BO BUQBKPFLK UP UIF 4JNQMF MBOHVBHF TP UIF 4JNQMF TZOUBY BQQMJFT BMTP. 4P UIF UBCMF CFMPX POMZ MJTUT UIF BEEJUJPOBM. "T PQQPTFE UP 4JNQMF MBOHVBHF 'JMF -BOHVBHF BMTP TVQQPSUT $POTUBOU FYQSFTTJPOT TP ZPV DBO FOUFS B GJYFE GJMFOBNF. "MM UIF GJMF UPLFOT VTF UIF TBNF FYQSFTTJPO OBNF BT UIF NFUIPE PO UIF java.io.File PCKFDU, GPS JOTUBODF file:absolute SFGFST UP UIF java.io.File.getAbsolute() NFUIPE. /PUJDF UIBU OPU BMM FYQSFTTJPOT BSF TVQQPSUFE CZ UIF DVSSFOU &YDIBOHF. 'PS JOTUBODF UIF '51 DPNQPOFOU TVQQPSUT TPNF PG UIF PQUJPOT, XIFSF BT UIF 'JMF DPNQPOFOU TVQQPSUT BMM PG UIFN.
$UMOBPPFLK
GJMF:OBNF

3VMB
4USJOH

%FIB "LKPRJBO
ZFT

%FIB /OLAR@BO
OP

%3/ "LKPRJBO
ZFT

%3/ /OLAR@BO
OP

#BP@OFMQFLK
SFGFST UP UIF GJMF OBNF (JT SFMBUJWF UP UIF TUBSUJOH EJSFDUPSZ, TFF OPUF CFMPX)

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

275

%FIB I>KDR>DB FP KLT JBODBA TFQE 2FJMIB I>KDR>DB 'SPN $BNFM 2.2 POXBSET, UIF GJMF MBOHVBHF JT OPX NFSHFE XJUI 4JNQMF MBOHVBHF XIJDI NFBOT ZPV DBO VTF BMM UIF GJMF TZOUBY EJSFDUMZ XJUIJO UIF TJNQMF MBOHVBHF.
">JBI 2.3: SFGFST UP UIF GJMF FYUFOTJPO POMZ SFGFST UP UIF GJMF OBNF XJUI OP FYUFOTJPO (JT SFMBUJWF UP UIF TUBSUJOH EJSFDUPSZ, TFF OPUF CFMPX) SFGFST UP UIF GJMF OBNF POMZ XJUI OP MFBEJOH QBUIT. SFGFST UP UIF GJMF OBNF POMZ XJUI OP FYUFOTJPO BOE XJUI OP MFBEJOH QBUIT. SFGFST UP UIF GJMF FYUFOTJPO POMZ SFGFST UP UIF GJMF QBSFOU SFGFST UP UIF GJMF QBUI SFGFST UP XIFUIFS UIF GJMF JT SFHBSEFE BT BCTPMVUF PS SFMBUJWF SFGFST UP UIF BCTPMVUF GJMF QBUI SFGFST UP UIF GJMF MFOHUI SFUVSOFE BT B -POH UZQF ">JBI 2.5: SFGFST UP UIF GJMF MFOHUI SFUVSOFE BT B -POH UZQF FGFST UP UIF GJMF MBTU NPEJGJFE SFUVSOFE BT B %BUF UZQF GPS EBUF GPSNBUUJOH VTJOH UIF java.text.SimepleDataFormat QBUUFSOT. *T BO BUQBKPFLK UP UIF 4JNQMF MBOHVBHF. "EEJUJPOBM DPNNBOE JT: CFIB (DPOTVNFST POMZ) GPS UIF MBTU NPEJGJFE UJNFTUBNQ PG UIF GJMF. /PUJDF: BMM UIF DPNNBOET GSPN UIF 4JNQMF MBOHVBHF DBO BMTP CF VTFE.

GJMF:OBNF.FYU

4USJOH

ZFT

OP

ZFT

OP

GJMF:OBNF.OPFYU

4USJOH

ZFT

OP

ZFT

OP

GJMF:POMZOBNF GJMF:POMZOBNF.OPFYU GJMF:FYU GJMF:QBSFOU GJMF:QBUI GJMF:BCTPMVUF GJMF:BCTPMVUF.QBUI GJMF:MFOHUI GJMF:TJ[F GJMF:NPEJGJFE

4USJOH 4USJOH 4USJOH 4USJOH 4USJOH #PPMFBO 4USJOH -POH -POH %BUF

ZFT ZFT ZFT ZFT ZFT ZFT ZFT ZFT ZFT ZFT

OP OP OP OP OP OP OP OP OP OP

ZFT ZFT ZFT ZFT ZFT OP OP ZFT ZFT ZFT

OP OP OP OP OP OP OP OP OP OP

EBUF:command:pattern

4USJOH

ZFT

ZFT

ZFT

ZFT

%FIB QLHBK BU>JMIB

1BI>QFSB M>QEP
8F IBWF B java.io.File IBOEMF GPS UIF GJMF hello.txt JO UIF GPMMPXJOH OBI>QFSB EJSFDUPSZ: .\filelanguage\test. "OE XF DPOGJHVSF PVS FOEQPJOU UP VTF UIJT TUBSUJOH EJSFDUPSZ .\filelanguage. 5IF GJMF UPLFOT XJMM SFUVSO BT: $UMOBPPFLK GJMF:OBNF GJMF:OBNF.FYU GJMF:OBNF.OPFYU GJMF:POMZOBNF 1BQROKP UFTU=IFMMP.UYU UYU UFTU=IFMMP IFMMP.UYU

276

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

GJMF:POMZOBNF.OPFYU GJMF:FYU GJMF:QBSFOU GJMF:QBUI GJMF:BCTPMVUF GJMF:BCTPMVUF.QBUI

IFMMP UYU GJMFMBOHVBHF=UFTU GJMFMBOHVBHF=UFTU=IFMMP.UYU GBMTF =XPSLTQBDF=DBNFM=DBNFM-DPSF=UBSHFU=GJMFMBOHVBHF=UFTU=IFMMP.UYU

?PLIRQB M>QEP
8F IBWF B java.io.File IBOEMF GPS UIF GJMF hello.txt JO UIF GPMMPXJOH >?PLIRQB EJSFDUPSZ: \workspace\camel\camel-core\target\filelanguage\test. "OE XF DPOGJHVSF PVU FOEQPJOU UP VTF UIF BCTPMVUF TUBSUJOH EJSFDUPSZ \workspace\camel\ camel-core\target\filelanguage. 5IF GJMF UPLFOT XJMM SFUVSO BT: $UMOBPPFLK GJMF:OBNF GJMF:OBNF.FYU GJMF:OBNF.OPFYU GJMF:POMZOBNF GJMF:POMZOBNF.OPFYU GJMF:FYU GJMF:QBSFOU GJMF:QBUI GJMF:BCTPMVUF GJMF:BCTPMVUF.QBUI 1BQROKP UFTU=IFMMP.UYU UYU UFTU=IFMMP IFMMP.UYU IFMMP UYU =XPSLTQBDF=DBNFM=DBNFM-DPSF=UBSHFU=GJMFMBOHVBHF=UFTU =XPSLTQBDF=DBNFM=DBNFM-DPSF=UBSHFU=GJMFMBOHVBHF=UFTU=IFMMP.UYU USVF =XPSLTQBDF=DBNFM=DBNFM-DPSF=UBSHFU=GJMFMBOHVBHF=UFTU=IFMMP.UYU

2>JMIBP :PV DBO FOUFS B GJYFE $POTUBOU FYQSFTTJPO TVDI BT myfile.txt:


fileName="myfile.txt"

-FUT BTTVNF XF VTF UIF GJMF DPOTVNFS UP SFBE GJMFT BOE XBOU UP NPWF UIF SFBE GJMFT UP CBDLVQ GPMEFS XJUI UIF DVSSFOU EBUF BT B TVC GPMEFS. 5IJT DBO CF BSDIJFWFE VTJOH BO FYQSFTTJPO MJLF:

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

277

fileName="backup/${date:now:yyyyMMdd}/${file:name.noext}.bak"

SFMBUJWF GPMEFS OBNFT BSF BMTP TVQQPSUFE TP TVQQPTF UIF CBDLVQ GPMEFS TIPVME CF B TJCMJOH GPMEFS UIFO ZPV DBO BQQFOE .. BT:
fileName="../backup/${date:now:yyyyMMdd}/${file:name.noext}.bak"

"T UIJT JT BO FYUFOTJPO UP UIF 4JNQMF MBOHVBHF XF IBWF BDDFTT UP BMM UIF HPPEJFT GSPN UIJT MBOHVBHF BMTP, TP JO UIJT VTF DBTF XF XBOU UP VTF UIF JO.IFBEFS.UZQF BT B QBSBNFUFS JO UIF EZOBNJD FYQSFTTJPO:
fileName="../backup/${date:now:yyyyMMdd}/type-${in.header.type}/backup-of-${file:name.noext}.bak"

*G ZPV IBWF B DVTUPN %BUF ZPV XBOU UP VTF JO UIF FYQSFTTJPO UIFO $BNFM TVQQPSUT SFUSJFWJOH EBUFT GSPN UIF NFTTBHF IFBEFS.
fileName="orders/ order-${in.header.customerId}-${date:in.header.orderDate:yyyyMMdd}.xml"

"OE GJOBMMZ XF DBO BMTP VTF B CFBO FYQSFTTJPO UP JOWPLF B 10+0 DMBTT UIBU HFOFSBUFT TPNF 4USJOH PVUQVU (PS DPOWFSUJCMF UP 4USJOH) UP CF VTFE:
fileName="uniquefile-${bean:myguidgenerator.generateid}.txt"

"OE PG DPVSTF BMM UIJT DBO CF DPNCJOFE JO POF FYQSFTTJPO XIFSF ZPV DBO VTF UIF 'JMF -BOHVBHF, 4JNQMF BOE UIF #FBO MBOHVBHF JO POF DPNCJOFE FYQSFTTJPO. 5IJT JT QSFUUZ QPXFSGVM GPS UIPTF DPNNPO GJMF QBUI QBUUFSOT. 4PFKD 2MOFKD /OLMBOQV/I>@BELIABO"LKCFDROBO QLDBQEBO TFQE QEB %FIB @LJMLKBKQ *O $BNFM ZPV DBO VTF UIF 'JMF -BOHVBHF EJSFDUMZ GSPN UIF 4JNQMF MBOHVBHF XIJDI NBLFT B $POUFOU #BTFE 3PVUFS FBTJFS UP EP JO 4QSJOH 9.-, XIFSF XF DBO SPVUF CBTFE PO GJMF FYUFOTJPOT BT TIPXO CFMPX:
<from uri="file://input/orders"/> <choice> <when> <simple>${file:ext} == 'txt'</simple> <to uri="bean:orderService?method=handleTextFiles"/> </when> <when> <simple>${file:ext} == 'xml'</simple>

278

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

<to uri="bean:orderService?method=handleXmlFiles"/> </when> <otherwise> <to uri="bean:orderService?method=handleOtherFiles"/> </otherwise> </choice>

*G ZPV VTF UIF fileName PQUJPO PO UIF 'JMF FOEQPJOU UP TFU B EZOBNJD GJMFOBNF VTJOH UIF 'JMF -BOHVBHF UIFO NBLF TVSF ZPV VTF UIF BMUFSOBUJWF TZOUBY (BWBJMBCMF GSPN $BNFM 2.5 POXBSET) UP BWPJE DMBTIJOH XJUI 4QSJOHT PropertyPlaceholderConfigurer.
Listing 1. bundle-context.xml
<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:bundle-context.cfg" /> </bean> <bean id="sampleRoute" class="SampleRoute"> <property name="fromEndpoint" value="${fromEndpoint}" /> <property name="toEndpoint" value="${toEndpoint}" /> </bean>

Listing 1. bundle-context.cfg
fromEndpoint=activemq:queue:test toEndpoint=file://fileRoute/out?fileName=test-$simple{date:now:yyyyMMdd}.txt

/PUJDF IPX XF VTF UIF $TJNQMF\ ^ TZOUBY JO UIF toEndpoint BCPWF. *G ZPV EPO'U EP UIJT, UIFSF JT B DMBTI BOE 4QSJOH XJMM UISPX BO FYDFQUJPO MJLF
org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'sampleRoute' defined in class path resource [bundle-context.xml]: Could not resolve placeholder 'date:now:yyyyMMdd'

#BMBKABK@FBP 5IF 'JMF MBOHVBHF JT QBSU PG @>JBI-@LOB.

20+ + -&4 &$


5IF 42- TVQQPSU JT BEEFE CZ +P42- BOE JT QSJNBSJMZ VTFE GPS QFSGPSNJOH 42- RVFSJFT PO JONFNPSZ PCKFDUT. *G ZPV QSFGFS UP QFSGPSN BDUVBM EBUBCBTF RVFSJFT UIFO DIFDL PVU UIF +1" DPNQPOFOU.

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

279

+LLHFKD CLO QEB 20+ @LJMLKBKQ $BNFM IBT CPUI B 42- MBOHVBHF BOE B 42- $PNQPOFOU. 5IJT QBHF JT BCPVU UIF 42MBOHVBHF. $MJDL PO 42- $PNQPOFOU JG ZPV BSF MPPLJOH GPS UIF DPNQPOFOU JOTUFBE. 5P VTF 42- JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-GLPNI XIJDI JNQMFNFOUT UIF 42- MBOHVBHF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-josql</artifactId> <version>2.5.0</version> </dependency>

$BNFM TVQQPSUT 42- UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 'PS FYBNQMF ZPV DPVME VTF 42- UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU.
from("queue:foo").setBody().sql("select * from MyType").to("queue:bar")

"OE UIF TQSJOH %4-:


<from uri="queue:foo"/> <setBody> <sql>select * from MyType</sql> </setBody> <to uri="queue:bar"/>

5>OF>?IBP 5>OF>?IB FYDIBOHF JO PVU UIF QSPQFSUZ LFZ UIF IFBEFS LFZ 3VMB &YDIBOHF .FTTBHF .FTTBHF 0CKFDU 0CKFDU #BP@OFMQFLK UIF &YDIBOHF PCKFDU UIF FYDIBOHF.JO NFTTBHF UIF FYDIBOHF.PVU NFTTBHF UIF &YDIBOHF QSPQFSUJFT UIF FYDIBOHF.JO IFBEFST

280

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

UIF WBSJBCMF LFZ

0CKFDU

JG BOZ BEEJUJPOBM WBSJBCMFT JT BEEFE VTJOH setVariables NFUIPE

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").sql("resource:classpath:mysql.sql")

7/ 3'
$BNFM TVQQPSUT 91BUI UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 'PS FYBNQMF ZPV DPVME VTF 91BUI UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU.
from("queue:foo"). filter().xpath("//foo")). to("queue:bar")

from("queue:foo"). choice().xpath("//foo")).to("queue:bar"). otherwise().to("queue:others");

->JBPM>@BP :PV DBO FBTJMZ VTF OBNFTQBDFT XJUI 91BUI FYQSFTTJPOT VTJOH UIF /BNFTQBDFT IFMQFS DMBTT.
Namespaces ns = new Namespaces("c", "http://acme.com/cheese"); from("direct:start").filter(). xpath("/c:person[@name='James']", ns). to("mock:result");

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

281

5>OF>?IBP 7BSJBCMFT JO 91BUI JT EFGJOFE JO EJGGFSFOU OBNFTQBDFT. 5IF EFGBVMU OBNFTQBDF JT http://camel.apache.org/schema/spring. ->JBPM>@B 41( IUUQ://DBNFM.BQBDIF.PSH/YNM/JO/ IUUQ://DBNFM.BQBDIF.PSH/YNM/PVU/ IUUQ://DBNFM.BQBDIF.PSH/YNM/GVODUJPO/ IUUQ://DBNFM.BQBDIF.PSH/YNM/WBSJBCMFT/ FOWJSPONFOU-WBSJBCMFT IUUQ://DBNFM.BQBDIF.PSH/YNM/WBSJBCMFT/ TZTUFN-QSPQFSUJFT IUUQ://DBNFM.BQBDIF.PSH/YNM/WBSJBCMFT/ FYDIBOHF-QSPQFSUZ +L@>I M>OQ JO PVU GVODUJPOT FOW TZTUFN c 3VMB .FTTBHF .FTTBHF 0CKFDU 0CKFDU 0CKFDU 0CKFDU #BP@OFMQFLK UIF FYDIBOHF.JO NFTTBHF UIF FYDIBOHF.PVU NFTTBHF ">JBI 2.5: "EEJUJPOBM GVODUJPOT 04 FOWJSPONFOU WBSJBCMFT +BWB 4ZTUFN QSPQFSUJFT UIF FYDIBOHF QSPQFSUZ

$BNFM XJMM SFTPMWF WBSJBCMFT BDDPSEJOH UP FJUIFS: OBNFTQBDF HJWFO OP OBNFTQBDF HJWFO

->JBPM>@B DFSBK
*G UIF OBNFTQBDF JT HJWFO UIFO $BNFM JT JOTUSVDUFE FYBDUMZ XIBU UP SFUVSO. )PXFWFS XIFO SFTPMWJOH FJUIFS FK PS LRQ $BNFM XJMM USZ UP SFTPMWF B IFBEFS XJUI UIF HJWFO MPDBM QBSU GJSTU, BOE SFUVSO JU. *G UIF MPDBM QBSU IBT UIF WBMVF ?LAV UIFO UIF CPEZ JT SFUVSOFE JOTUFBE.

-L K>JBPM>@B DFSBK
*G UIFSF JT OP OBNFTQBDF HJWFO UIFO $BNFM SFTPMWFT POMZ CBTFE PO UIF MPDBM QBSU. $BNFM XJMM USZ UP SFTPMWF B WBSJBCMF JO UIF GPMMPXJOH TUFQT: GSPN variables UIBU IBT CFFO TFU VTJOH UIF variable(name, value) GMVFOU CVJMEFS GSPN NFTTBHF.JO.IFBEFS JG UIFSF JT B IFBEFS XJUI UIF HJWFO LFZ GSPN FYDIBOHF.QSPQFSUJFT JG UIFSF JT B QSPQFSUZ XJUI UIF HJWFO LFZ

282

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

%RK@QFLKP $BNFM BEET UIF GPMMPXJOH 91BUI GVODUJPOT UIBU DBO CF VTFE UP BDDFTT UIF FYDIBOHF: %RK@QFLK JO:CPEZ JO:IFBEFS PVU:CPEZ PVU:IFBEFS ODRJBKQ OPOF UIF IFBEFS OBNF OPOF UIF IFBEFS OBNF LFZ GPS QSPQFSUZ TJNQMF FYQSFTTJPO 3VMB 0CKFDU 0CKFDU 0CKFDU 0CKFDU #BP@OFMQFLK 8JMM SFUVSO UIF FK NFTTBHF CPEZ. 8JMM SFUVSO UIF FK NFTTBHF IFBEFS. 8JMM SFUVSO UIF LRQ NFTTBHF CPEZ. 8JMM SFUVSO UIF LRQ NFTTBHF IFBEFS. ">JBI 2.5: 5P MPPLVQ B QSPQFSUZ VTJOH UIF 1SPQFSUJFT DPNQPOFOU (QSPQFSUZ QMBDFIPMEFST). ">JBI 2.5: 5P FWBMVBUF B 4JNQMF FYQSFTTJPO.

GVODUJPO:QSPQFSUJFT

4USJOH

GVODUJPO:TJNQMF

0CKFDU

-LQF@B: function:properties BOE function:simple JT OPU TVQQPSUFE XIFO UIF SFUVSO UZQF JT B NodeSet, TVDI BT XIFO VTJOH XJUI B 4QMJUUFS &*1. )FSF'T BO FYBNQMF TIPXJOH TPNF PG UIFTF GVODUJPOT JO VTF.
from("direct:start").choice() .when().xpath("in:header('foo') = 'bar'").to("mock:x") .when().xpath("in:body() = '<two/>'").to("mock:y") .otherwise().to("mock:z");

"OE UIF OFX GVODUJPOT JOUSPEVDFE JO $BNFM 2.5:


// setup properties component PropertiesComponent properties = new PropertiesComponent(); properties.setLocation("classpath:org/apache/camel/builder/xml/myprop.properties"); context.addComponent("properties", properties); // myprop.properties contains the following properties // foo=Camel // bar=Kong from("direct:in").choice() // $type is a variable for the header with key type // here we use the properties function to lookup foo from the properties files // which at runtime will be evaluted to 'Camel' .when().xpath("$type = function:properties('foo')") .to("mock:camel") // here we use the simple language to evaluate the expression // which at runtime will be evaluated to 'Donkey Kong' .when().xpath("//name = function:simple('Donkey ${properties:bar}')")

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

283

.to("mock:donkey") .otherwise() .to("mock:other") .end();

4PFKD 7,+ @LKCFDRO>QFLK *G ZPV QSFGFS UP DPOGJHVSF ZPVS SPVUFT JO ZPVS 4QSJOH 9.- GJMF UIFO ZPV DBO VTF 91BUI FYQSFTTJPOT BT GPMMPXT
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd"> <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring" xmlns:foo="http://example.com/person"> <route> <from uri="activemq:MyQueue"/> <filter> <xpath>/foo:person[@name='James']</xpath> <to uri="mqseries:SomeOtherQueue"/> </filter> </route> </camelContext> </beans>

/PUJDF IPX XF DBO SFVTF UIF OBNFTQBDF QSFGJYFT, CLL JO UIJT DBTF, JO UIF 91BUI FYQSFTTJPO GPS FBTJFS OBNFTQBDF CBTFE 91BUI FYQSFTTJPOT! 4FF BMTP UIJT EJTDVTTJPO PO UIF NBJMJOHMJTU BCPVU VTJOH ZPVS PXO OBNFTQBDFT XJUI YQBUI 2BQQFKD OBPRIQ QVMB 5IF 91BUI FYQSFTTJPO XJMM SFUVSO B SFTVMU UZQF VTJOH OBUJWF 9.- PCKFDUT TVDI BT org.w3c.dom.NodeList. #VU NBOZ UJNFT ZPV XBOU B SFTVMU UZQF UP CF B 4USJOH. 5P EP UIJT ZPV IBWF UP JOTUSVDU UIF 91BUI XIJDI SFTVMU UZQF UP VTF. *O +BWB %4-:
xpath("/foo:person/@id", String.class)

*O 4QSJOH %4- ZPV VTF UIF OBPRIQ3VMB BUUSJCVUF UP QSPWJEF B GVMMZ RVBMJGJFE DMBTTOBNF:

284

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

<xpath resultType="java.lang.String">/foo:person/@id</xpath>

*O !91BUI: S>FI>?IB >P LC ">JBI 2.1


@XPath(value = "concat('foo-',//order/name/)", resultType = String.class) String name)

8IFSF XF VTF UIF YQBUI GVODUJPO DPODBU UP QSFGJY UIF PSEFS OBNF XJUI foo-. *O UIJT DBTF XF IBWF UP TQFDJGZ UIBU XF XBOU B 4USJOH BT SFTVMU UZQF TP UIF DPODBU GVODUJPO XPSLT. 4PFKD 7/>QE LK 'B>ABOP S>FI>?IB >P LC ">JBI 2.11 4PNF VTFST NBZ IBWF 9.- TUPSFE JO B IFBEFS. 5P BQQMZ BO 91BUI UP B IFBEFS'T WBMVF ZPV DBO EP UIJT CZ EFGJOJOH UIF 'IFBEFS/BNF' BUUSJCVUF. *O 9.- %4-:
<camelContext id="xpathHeaderNameTest" xmlns="http://camel.apache.org/schema/ blueprint"> <route> <from uri="direct:in"/> <choice> <when> <!-- use headerName attribute to refer to a header --> <xpath headerName="invoiceDetails">/invoice/@orderType = 'premium'</xpath> <to uri="mock:premium"/> </when> <when> <!-- use headerName attribute to refer to a header --> <xpath headerName="invoiceDetails">/invoice/@orderType = 'standard'</xpath> <to uri="mock:standard"/> </when> <otherwise> <to uri="mock:unknown"/> </otherwise> </choice> </route> </camelContext>

$U>JMIBP )FSF JT B TJNQMF FYBNQMF VTJOH BO 91BUI FYQSFTTJPO BT B QSFEJDBUF JO B .FTTBHF 'JMUFS

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

285

from("direct:start"). filter().xpath("/person[@name='James']"). to("mock:result");

*G ZPV IBWF B TUBOEBSE TFU PG OBNFTQBDFT ZPV XJTI UP XPSL XJUI BOE XJTI UP TIBSF UIFN BDSPTT NBOZ EJGGFSFOU 91BUI FYQSFTTJPOT ZPV DBO VTF UIF /BNFTQBDF#VJMEFS BT TIPXO JO UIJT FYBNQMF
// lets define the namespaces we'll need in our filters Namespaces ns = new Namespaces("c", "http://acme.com/cheese") .add("xsd", "http://www.w3.org/2001/XMLSchema"); // now lets create an xpath based Message Filter from("direct:start"). filter(ns.xpath("/c:person[@name='James']")). to("mock:result");

*O UIJT TBNQMF XF IBWF B DIPJDF DPOTUSVDU. 5IF GJSTU DIPJDF FWBVMBUFT JG UIF NFTTBHF IBT B IFBEFS LFZ QVMB UIBU IBT UIF WBMVF ">JBI. 5IF 2OE DIPJDF FWBMVBUFT JG UIF NFTTBHF CPEZ IBT B OBNF UBH <K>JB> XIJDI WBMVFT JT *LKD. *G OFJUIFS JT USVF UIF NFTTBHF JT SPVUFE JO UIF PUIFSXJTF CMPDL:
from("direct:in").choice() // using $headerName is special notation in Camel to get the header key .when().xpath("$type = 'Camel'") .to("mock:camel") // here we test for the body name tag .when().xpath("//name = 'Kong'") .to("mock:donkey") .otherwise() .to("mock:other") .end();

"OE UIF TQSJOH 9.- FRVJWBMFOU PG UIF SPVUF:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:in"/> <choice> <when> <xpath>$type = 'Camel'</xpath> <to uri="mock:camel"/> </when> <when> <xpath>//name = 'Kong'</xpath> <to uri="mock:donkey"/> </when> <otherwise> <to uri="mock:other"/> </otherwise>

286

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

</choice> </route> </camelContext>

7/ 3' (-)$"3(.:PV DBO VTF #FBO *OUFHSBUJPO UP JOWPLF B NFUIPE PO B CFBO BOE VTF WBSJPVT MBOHVBHFT TVDI BT 91BUI UP FYUSBDU B WBMVF GSPN UIF NFTTBHF BOE CJOE JU UP B NFUIPE QBSBNFUFS. 5IF EFGBVMU 91BUI BOOPUBUJPO IBT 40"1 BOE 9.- OBNFTQBDFT BWBJMBCMF. *G ZPV XBOU UP VTF ZPVS PXO OBNFTQBDF 63*T JO BO 91BUI FYQSFTTJPO ZPV DBO VTF ZPVS PXO DPQZ PG UIF 91BUI BOOPUBUJPO UP DSFBUF XIBUFWFS OBNFTQBDF QSFGJYFT ZPV XBOU UP VTF.
import import import import java.lang.annotation.ElementType; java.lang.annotation.Retention; java.lang.annotation.RetentionPolicy; java.lang.annotation.Target;

import org.w3c.dom.NodeList; import org.apache.camel.component.bean.XPathAnnotationExpressionFactory; import org.apache.camel.language.LanguageAnnotation; import org.apache.camel.language.NamespacePrefix; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) @LanguageAnnotation(language = "xpath", factory = XPathAnnotationExpressionFactory.class) public @interface MyXPath { String value(); // You can add the namespaces as the default value of the annotation NamespacePrefix[] namespaces() default { @NamespacePrefix(prefix = "n1", uri = "http://example.org/ns1"), @NamespacePrefix(prefix = "n2", uri = "http://example.org/ns2")}; Class<?> resultType() default NodeList.class; }

J.F. DVU BOE QBTUF VQQFS DPEF UP ZPVS PXO QSPKFDU JO B EJGGFSFOU QBDLBHF BOE/PS BOOPUBUJPO OBNF UIFO BEE XIBUFWFS OBNFTQBDF QSFGJY/VSJT ZPV XBOU JO TDPQF XIFO ZPV VTF ZPVS BOOPUBUJPO PO B NFUIPE QBSBNFUFS. 5IFO XIFO ZPV VTF ZPVS BOOPUBUJPO PO B NFUIPE QBSBNFUFS BMM UIF OBNFTQBDFT ZPV XBOU XJMM CF BWBJMBCMF GPS VTF JO ZPVS 91BUI FYQSFTTJPO. 'PS FYBNQMF
public class Foo {

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

287

@MessageDriven(uri = "activemq:my.queue") public void doSomething(@MyXPath("/ns1:foo/ns2:bar/text()") String correlationID, @Body String body) { // process the inbound message here } }

4PFKD 7/>QE!RFIABO TFQELRQ >K $U@E>KDB S>FI>?IB >P LC ">JBI 2.3 :PV DBO OPX VTF UIF org.apache.camel.builder.XPathBuilder XJUIPVU UIF OFFE GPS BO &YDIBOHF. 5IJT DPNFT IBOEZ JG ZPV XBOU UP VTF JU BT B IFMQFS UP EP DVTUPN YQBUI FWBMVBUJPOT. *U SFRVJSFT UIBU ZPV QBTT JO B $BNFM$POUFYU TJODF B MPU PG UIF NPWJOH QBSUT JOTJEF UIF 91BUI#VJMEFS SFRVJSFT BDDFTT UP UIF $BNFM 5ZQF $POWFSUFS BOE IFODF XIZ $BNFM$POUFYU JT OFFEFE. 'PS FYBNQMF ZPV DBO EP TPNFUIJOH MJLF UIJT:
boolean matches = XPathBuilder.xpath("/foo/bar/@xyz").matches(context, "<foo><bar xyz='cheese'/></foo>"));

5IJT XJMM NBUDI UIF HJWFO QSFEJDBUF. :PV DBO BMTP FWBMVBUF GPS FYBNQMF BT TIPXO JO UIF GPMMPXJOH UISFF FYBNQMFT:
String name = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>cheese</bar></foo>", String.class); Integer number = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>123</bar></foo>", Integer.class); Boolean bool = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>true</bar></foo>", Boolean.class);

&WBMVBUJOH XJUI B 4USJOH SFTVMU JT B DPNNPO SFRVJSFNFOU BOE UIVT ZPV DBO EP JU B CJU TJNQMFS:
String name = XPathBuilder.xpath("foo/bar").evaluate(context, "<foo><bar>cheese</bar></foo>");

4PFKD 2>ULK TFQE 7/>QE!RFIABO S>FI>?IB >P LC ">JBI 2.3 :PV OFFE UP BEE @>JBI-P>ULK BT EFQFOEFODZ UP ZPVS QSPKFDU.

288

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

*UT OPX FBTJFS UP VTF 4BYPO XJUI UIF 91BUI#VJMEFS XIJDI DBO CF EPOF JO TFWFSBM XBZT BT TIPXO CFMPX. 8IFSF BT UIF MBUUFS POFT BSF UIF FBTJFTU POFT. 6TJOH B GBDUPSZ
// create a Saxon factory XPathFactory fac = new net.sf.saxon.xpath.XPathFactoryImpl(); // create a builder to evaluate the xpath using the saxon factory XPathBuilder builder = XPathBuilder.xpath("tokenize(/foo/bar, '_')[2]").factory(fac); // evaluate as a String result String result = builder.evaluate(context, "<foo><bar>abc_def_ghi</bar></foo>"); assertEquals("def", result);

6TJOH 0CKFDU.PEFM
// create a builder to evaluate the xpath using saxon based on its object model uri XPathBuilder builder = XPathBuilder.xpath("tokenize(/foo/bar, '_')[2]").objectModel("http://saxon.sf.net/jaxp/xpath/om"); // evaluate as a String result String result = builder.evaluate(context, "<foo><bar>abc_def_ghi</bar></foo>"); assertEquals("def", result);

5IF FBTZ POF


// create a builder to evaluate the xpath using saxon XPathBuilder builder = XPathBuilder.xpath("tokenize(/foo/bar, '_')[2]").saxon(); // evaluate as a String result String result = builder.evaluate(context, "<foo><bar>abc_def_ghi</bar></foo>"); assertEquals("def", result);

2BQQFKD > @RPQLJ 7/>QE%>@QLOV RPFKD 2VPQBJ /OLMBOQV S>FI>?IB >P LC ">JBI 2.3 $BNFM OPX TVQQPSUT SFBEJOH UIF +7. TZTUFN QSPQFSUZ javax.xml.xpath.XPathFactory UIBU DBO CF VTFE UP TFU B DVTUPN 91BUI'BDUPSZ UP VTF. 5IJT VOJU UFTU TIPXT IPX UIJT DBO CF EPOF UP VTF 4BYPO JOTUFBE:
// set system property with the XPath factory to use which is Saxon System.setProperty(XPathFactory.DEFAULT_PROPERTY_NAME + ":" + "http://saxon.sf.net/ jaxp/xpath/om", "net.sf.saxon.xpath.XPathFactoryImpl");

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

289

// create a builder to evaluate the xpath using saxon XPathBuilder builder = XPathBuilder.xpath("tokenize(/foo/bar, '_')[2]"); // evaluate as a String result String result = builder.evaluate(context, "<foo><bar>abc_def_ghi</bar></foo>"); assertEquals("def", result);

$BNFM XJMM MPH BU INFO MFWFM JG JU VTFT B OPO EFGBVMU 91BUI'BDUPSZ TVDI BT:
XPathBuilder INFO Using system property javax.xml.xpath.XPathFactory:http://saxon.sf.net/jaxp/xpath/om with value: net.sf.saxon.xpath.XPathFactoryImpl when creating XPathFactory

5P VTF "QBDIF 9FSDFT ZPV DBO DPOGJHVSF UIF TZTUFN QSPQFSUZ


-Djavax.xml.xpath.XPathFactory=org.apache.xpath.jaxp.XPathFactoryImpl

$K>?IFKD 2>ULK COLJ 2MOFKD #2+ S>FI>?IB >P LC ">JBI 2.10 4JNJMBSMZ UP +BWB %4-, UP FOBCMF 4BYPO GSPN 4QSJOH %4- ZPV IBWF UISFF PQUJPOT: 4QFDJGZJOH UIF GBDUPSZ
<xpath factoryRef="saxonFactory" resultType="java.lang.String">current-dateTime()</xpath>

4QFDJGZJOH UIF PCKFDU NPEFM


<xpath objectModel="http://saxon.sf.net/jaxp/xpath/om" resultType="java.lang.String">current-dateTime()</xpath>

4IPSUDVU
<xpath saxon="true" resultType="java.lang.String">current-dateTime()</xpath>

->JBPM>@B >RAFQFKD QL >FA AB?RDDFKD S>FI>?IB >P LC ">JBI 2.10 " MBSHF OVNCFS PG 91BUI-SFMBUFE JTTVFT UIBU VTFST GSFRVFOUMZ GBDF BSF MJOLFE UP UIF VTBHF PG OBNFTQBDFT. :PV NBZ IBWF TPNF NJTBMJHONFOU CFUXFFO UIF OBNFTQBDFT QSFTFOU JO ZPVS NFTTBHF BOE UIPTF UIBU ZPVS 91BUI FYQSFTTJPO JT BXBSF PG PS SFGFSFODJOH. 91BUI QSFEJDBUFT PS FYQSFTTJPOT UIBU BSF VOBCMF UP MPDBUF UIF 9.- FMFNFOUT BOE BUUSJCVUFT EVF UP OBNFTQBDFT

290

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

JTTVFT NBZ TJNQMZ MPPL MJLF "UIFZ BSF OPU XPSLJOH", XIFO JO SFBMJUZ BMM UIFSF JT UP JU JT B MBDL PG OBNFTQBDF EFGJOJUJPO. /BNFTQBDFT JO 9.- BSF DPNQMFUFMZ OFDFTTBSZ, BOE XIJMF XF XPVME MPWF UP TJNQMJGZ UIFJS VTBHF CZ JNQMFNFOUJOH TPNF NBHJD PS WPPEPP UP XJSF OBNFTQBDFT BVUPNBUJDBMMZ, USVUI JT UIBU BOZ BDUJPO EPXO UIJT QBUI XPVME EJTBHSFF XJUI UIF TUBOEBSET BOE XPVME HSFBUMZ IJOEFS JOUFSPQFSBCJMJUZ. 5IFSFGPSF, UIF VUNPTU XF DBO EP JT BTTJTU ZPV JO EFCVHHJOH TVDI JTTVFT CZ BEEJOH UXP OFX GFBUVSFT UP UIF 91BUI &YQSFTTJPO -BOHVBHF BOE BSF UIVT BDDFTJCMF GSPN CPUI QSFEJDBUFT BOE FYQSFTTJPOT.

+LDDFKD QEB ->JBPM>@B "LKQBUQ LC VLRO 7/>QE BUMOBPPFLK/ MOBAF@>QB


&WFSZ UJNF B OFX 91BUI FYQSFTTJPO JT DSFBUFE JO UIF JOUFSOBM QPPM, $BNFM XJMM MPH UIF OBNFTQBDF DPOUFYU PG UIF FYQSFTTJPO VOEFS UIF org.apache.camel.builder.xml.XPathBuilder MPHHFS. 4JODF $BNFM SFQSFTFOUT /BNFTQBDF $POUFYUT JO B IJFSBSDIJDBM GBTIJPO (QBSFOU-DIJME SFMBUJPOTIJQT), UIF FOUJSF USFF JT PVUQVU JO B SFDVSTJWF NBOOFS XJUI UIF GPMMPXJOH GPSNBU:
[me: {prefix -> namespace}, {prefix -> namespace}], [parent: [me: {prefix -> namespace}, {prefix -> namespace}], [parent: [me: {prefix -> namespace}]]]

"OZ PG UIFTF PQUJPOT DBO CF VTFE UP BDUJWBUF UIJT MPHHJOH: 1. &OBCMF 53"$& MPHHJOH PO UIF org.apache.camel.builder.xml.XPathBuilder MPHHFS, PS TPNF QBSFOU MPHHFS TVDI BT org.apache.camel PS UIF SPPU MPHHFS 2. &OBCMF UIF logNamespaces PQUJPO BT JOEJDBUFE JO "VEJUJOH /BNFTQBDFT, JO XIJDI DBTF UIF MPHHJOH XJMM PDDVS PO UIF */'0 MFWFM

RAFQFKD K>JBPM>@BP
$BNFM JT BCMF UP EJTDPWFS BOE EVNQ BMM OBNFTQBDFT QSFTFOU PO FWFSZ JODPNJOH NFTTBHF CFGPSF FWBMVBUJOH BO 91BUI FYQSFTTJPO, QSPWJEJOH BMM UIF SJDIOFTT PG JOGPSNBUJPO ZPV OFFE UP IFMQ ZPV BOBMZTF BOE QJOQPJOU QPTTJCMF OBNFTQBDF JTTVFT. 5P BDIJFWF UIJT, JU JO UVSO JOUFSOBMMZ VTFT BOPUIFS TQFDJBMMZ UBJMPSFE 91BUI FYQSFTTJPO UP FYUSBDU BMM OBNFTQBDF NBQQJOHT UIBU BQQFBS JO UIF NFTTBHF, EJTQMBZJOH UIF QSFGJY BOE UIF GVMM OBNFTQBDF 63*(T) GPS FBDI JOEJWJEVBM NBQQJOH. 4PNF QPJOUT UP UBLF JOUP BDDPVOU: ` 5IF JNQMJDJU 9.- OBNFTQBDF (YNMOT:YNM="IUUQ://XXX.X3.PSH/9.-/1998/OBNFTQBDF") JT TVQQSFTTFE GSPN UIF PVUQVU CFDBVTF JU BEET OP WBMVF ` %FGBVMU OBNFTQBDFT BSF MJTUFE VOEFS UIF %&'"6-5 LFZXPSE JO UIF PVUQVU

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

291

` ,FFQ JO NJOE UIBU OBNFTQBDFT DBO CF SFNBQQFE VOEFS EJGGFSFOU TDPQFT. 5IJOL PG B UPQ-MFWFM 'B' QSFGJY XIJDI JO JOOFS FMFNFOUT DBO CF BTTJHOFE B EJGGFSFOU OBNFTQBDF, PS UIF EFGBVMU OBNFTQBDF DIBOHJOH JO JOOFS TDPQFT. 'PS FBDI EJTDPWFSFE QSFGJY, BMM BTTPDJBUFE 63*T BSF MJTUFE. :PV DBO FOBCMF UIJT PQUJPO JO +BWB %4- BOE 4QSJOH %4-. +BWB %4-:
XPathBuilder.xpath("/foo:person/@id", String.class).logNamespaces()

4QSJOH %4-:
<xpath logNamespaces="true" resultType="String">/foo:person/@id</xpath>

5IF SFTVMU PG UIF BVEJUJOH XJMM CF BQQFBS BU UIF */'0 MFWFM VOEFS UIF org.apache.camel.builder.xml.XPathBuilder MPHHFS BOE XJMM MPPL MJLF UIF GPMMPXJOH:
2012-01-16 13:23:45,878 [stSaxonWithFlag] INFO XPathBuilder - Namespaces discovered in message: {xmlns:a=[http://apache.org/camel], DEFAULT=[http://apache.org/default], xmlns:b=[http://apache.org/camelA, http://apache.org/camelB]}

+L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").xpath("resource:classpath:myxpath.txt", String.class)

#BMBKABK@FBP 5IF 91BUI MBOHVBHF JT QBSU PG DBNFM-DPSF.

704$18
$BNFM TVQQPSUT 92VFSZ UP BMMPX BO &YQSFTTJPO PS 1SFEJDBUF UP CF VTFE JO UIF %4- PS 9NM $POGJHVSBUJPO. 'PS FYBNQMF ZPV DPVME VTF 92VFSZ UP DSFBUF BO 1SFEJDBUF JO B .FTTBHF 'JMUFS PS BT BO &YQSFTTJPO GPS B 3FDJQJFOU -JTU.

292

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

.MQFLKP
->JB
allowStAX

#BC>RIQ 5>IRB
false

#BP@OFMQFLK
">JBI 2.8.3/2.9: 8IFUIFS UP BMMPX VTJOH 4U"9 BT UIF javax.xml.transform.Source.

$U>JMIBP
from("queue:foo").filter(). xquery("//foo"). to("queue:bar")

:PV DBO BMTP VTF GVODUJPOT JOTJEF ZPVS RVFSZ, JO XIJDI DBTF ZPV OFFE BO FYQMJDJU UZQF DPOWFSTJPO (PS ZPV XJMM HFU B PSH.X3D.EPN.%0.&YDFQUJPO: )*&3"3$):@3&26&45@&33) CZ QBTTJOH UIF $MBTT BT B TFDPOE BSHVNFOU UP UIF UNRBOV() NFUIPE.
from("direct:start"). recipientList().xquery("concat('mock:foo.', /person/@city)", String.class);

5>OF>?IBP 5IF */ NFTTBHF CPEZ XJMM CF TFU BT UIF contextItem. #FTJEFT UIJT UIFTF 7BSJBCMFT JT BMTP BEEFE BT QBSBNFUFST: 5>OF>?IB FYDIBOHF JO.CPEZ PVU.CPEZ JO.IFBEFST.* PVU.IFBEFST.* 3VMB &YDIBOHF 0CKFDU 0CKFDU 0CKFDU 0CKFDU #BP@OFMQFLK 5IF DVSSFOU &YDIBOHF 5IF *O NFTTBHF'T CPEZ 5IF 065 NFTTBHF'T CPEZ (JG BOZ) :PV DBO BDDFTT UIF WBMVF PG FYDIBOHF.JO.IFBEFST XJUI LFZ CLL CZ VTJOH UIF WBSJBCMF XIJDI OBNF JT JO.IFBEFST.GPP :PV DBO BDDFTT UIF WBMVF PG FYDIBOHF.PVU.IFBEFST XJUI LFZ CLL CZ VTJOH UIF WBSJBCMF XIJDI OBNF JT PVU.IFBEFST.GPP WBSJBCMF "OZ FYDIBOHF.QSPQFSUJFT BOE FYDIBOHF.JO.IFBEFST BOE BOZ BEEJUJPOBM QBSBNFUFST TFU VTJOH setParameters(Map). 5IFTF QBSBNFUFST JT BEEFE XJUI UIFZ PXO LFZ OBNF, GPS JOTUBODF JG UIFSF JT BO */ IFBEFS XJUI UIF LFZ OBNF CLL UIFO JUT BEEFE BT CLL.

HBV K>JB

0CKFDU

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

293

4PFKD 7,+ @LKCFDRO>QFLK *G ZPV QSFGFS UP DPOGJHVSF ZPVS SPVUFT JO ZPVS 4QSJOH 9.- GJMF UIFO ZPV DBO VTF 91BUI FYQSFTTJPOT BT GPMMPXT
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:foo="http://example.com/person" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd"> <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="activemq:MyQueue"/> <filter> <xquery>/foo:person[@name='James']</xquery> <to uri="mqseries:SomeOtherQueue"/> </filter> </route> </camelContext> </beans>

/PUJDF IPX XF DBO SFVTF UIF OBNFTQBDF QSFGJYFT, CLL JO UIJT DBTF, JO UIF 91BUI FYQSFTTJPO GPS FBTJFS OBNFTQBDF CBTFE 92VFSZ FYQSFTTJPOT! 8IFO ZPV VTF GVODUJPOT JO ZPVS 92VFSZ FYQSFTTJPO ZPV OFFE BO FYQMJDJU UZQF DPOWFSTJPO XIJDI JT EPOF JO UIF YNM DPOGJHVSBUJPO WJB UIF @QVMB BUUSJCVUF:
<xquery type="java.lang.String">concat('mock:foo.', /person/@city)</xquery>

4PFKD 70RBOV >P >K BKAMLFKQ 4PNFUJNFT BO 92VFSZ FYQSFTTJPO DBO CF RVJUF MBSHF; JU DBO FTTFOUBMMZ CF VTFE GPS 5FNQMBUJOH. 4P ZPV NBZ XBOU UP VTF BO 92VFSZ &OEQPJOU TP ZPV DBO SPVUF VTJOH 92VFSZ UFNQMBUFT. 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP UBLF B NFTTBHF PG BO "DUJWF.2 RVFVF (.Z2VFVF) BOE USBOTGPSN JU VTJOH 92VFSZ BOE TFOE JU UP .24FSJFT.
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="activemq:MyQueue"/> <to uri="xquery:com/acme/someTransform.xquery"/> <to uri="mqseries:SomeOtherQueue"/> </route> </camelContext>

294

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

$U>JMIBP )FSF JT B TJNQMF FYBNQMF VTJOH BO 92VFSZ FYQSFTTJPO BT B QSFEJDBUF JO B .FTTBHF 'JMUFS
from("direct:start").filter().xquery("/person[@name='James']").to("mock:result");

5IJT FYBNQMF VTFT 92VFSZ XJUI OBNFTQBDFT BT B QSFEJDBUF JO B .FTTBHF 'JMUFS


Namespaces ns = new Namespaces("c", "http://acme.com/cheese"); from("direct:start"). filter().xquery("/c:person[@name='James']", ns). to("mock:result");

+B>OKFKD 70RBOV 92VFSZ JT B WFSZ QPXFSGVM MBOHVBHF GPS RVFSZJOH, TFBSDIJOH, TPSUJOH BOE SFUVSOJOH 9.-. 'PS IFMQ MFBSOJOH 92VFSZ USZ UIFTF UVUPSJBMT ` .JLF ,BZ'T 92VFSZ 1SJNFS ` UIF 834DIPPMT 92VFSZ 5VUPSJBM :PV NJHIU BMTP GJOE UIF 92VFSZ GVODUJPO SFGFSFODF VTFGVM +L>AFKD P@OFMQ COLJ BUQBOK>I OBPLRO@B S>FI>?IB >P LC ">JBI 2.11 :PV DBO FYUFSOBMJ[F UIF TDSJQU BOE IBWF $BNFM MPBE JU GSPN B SFTPVSDF TVDI BT "classpath:", "file:", PS "http:". 5IJT JT EPOF VTJOH UIF GPMMPXJOH TZOUBY: "resource:scheme:location", FH UP SFGFS UP B GJMF PO UIF DMBTTQBUI ZPV DBO EP:
.setHeader("myHeader").xquery("resource:classpath:myxquery.txt", String.class)

#BMBKABK@FBP 5P VTF 92VFSZ JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-P>ULK XIJDI JNQMFNFOUT UIF 92VFSZ MBOHVBHF. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-saxon</artifactId>

-"/ (6"(&4 46110 3 5 &% "11&/ %*9

295

<version>x.x.x</version> </dependency>

296

- " / ( 6 " ( & 4 4 6 1 1 03 5 & % " 1 1 & /% * 9

#>Q> %LOJ>Q

MMBKAFU

# 3

%.1, 3

$BNFM TVQQPSUT B QMVHHBCMF %BUB'PSNBU UP BMMPX NFTTBHFT UP CF NBSTIBMMFE UP BOE GSPN CJOBSZ PS UFYU GPSNBUT UP TVQQPSU B LJOE PG .FTTBHF 5SBOTMBUPS. 5IF GPMMPXJOH EBUB GPSNBUT BSF DVSSFOUMZ TVQQPSUFE: ` 4UBOEBSE +7. PCKFDU NBSTIBMMJOH 4FSJBMJ[BUJPO 4USJOH ` 0CKFDU NBSTIBMMJOH "WSP +40/ 1SPUPCVG ` 0CKFDU/9.- NBSTIBMMJOH $BTUPS +"9# 9NM#FBOT 94USFBN +J#9 ` 0CKFDU/9.-/8FCTFSWJDF NBSTIBMMJOH 40"1 ` %JSFDU +40/ / 9.- NBSTIBMMJOH 9NM+TPO ` 'MBU EBUB TUSVDUVSF NBSTIBMMJOH #FBO*0 #JOEZ $47 &%* 'MBUQBDL %BUB'PSNBU ` %PNBJO TQFDJGJD NBSTIBMMJOH )-7 %BUB'PSNBU ` $PNQSFTTJPO (;JQ EBUB GPSNBU ;JQ %BUB'PSNBU ;JQ 'JMF %BUB'PSNBU ` 4FDVSJUZ $SZQUP 1(1 9.-4FDVSJUZ %BUB'PSNBU

%"5 " '0 3 . "5 "11&/ %*9

297

` .JTD. #BTF64 $VTUPN %BUB'PSNBU - UP VTF ZPVS PXO DVTUPN JNQMFNFOUBUJPO 344 5JEZ.BSLVQ 4ZTMPH "OE SFMBUFE JT UIF GPMMPXJOH 5ZQF $POWFSUFST: %P[FS 5ZQF $POWFSTJPO 4KJ>OPE>IIFKD *G ZPV SFDFJWF B NFTTBHF GSPN POF PG UIF $BNFM $PNQPOFOUT TVDI BT 'JMF, )551 PS +.4 ZPV PGUFO XBOU UP VONBSTIBM UIF QBZMPBE JOUP TPNF CFBO TP UIBU ZPV DBO QSPDFTT JU VTJOH TPNF #FBO *OUFHSBUJPO PS QFSGPSN 1SFEJDBUF FWBMVBUJPO BOE TP GPSUI. 5P EP UIJT VTF UIF RKJ>OPE>I XPSE JO UIF %4- JO +BWB PS UIF 9NM $POGJHVSBUJPO. 'PS FYBNQMF
DataFormat jaxb = new JaxbDataFormat("com.acme.model"); from("activemq:My.Queue"). unmarshal(jaxb). to("mqseries:Another.Queue");

5IF BCPWF VTFT B OBNFE %BUB'PSNBU PG jaxb XIJDI JT DPOGJHVSFE XJUI B OVNCFS PG +BWB QBDLBHF OBNFT. :PV DBO JG ZPV QSFGFS VTF B OBNFE SFGFSFODF UP B EBUB GPSNBU XIJDI DBO UIFO CF EFGJOFE JO ZPVS 3FHJTUSZ TVDI BT WJB ZPVS 4QSJOH 9.- GJMF. :PV DBO BMTP VTF UIF %4- JUTFMG UP EFGJOF UIF EBUB GPSNBU BT ZPV VTF JU. 'PS FYBNQMF UIF GPMMPXJOH VTFT +BWB TFSJBMJ[BUJPO UP VONBSTIBM B CJOBSZ GJMF UIFO TFOE JU BT BO 0CKFDU.FTTBHF UP "DUJWF.2
from("file://foo/bar"). unmarshal().serialization(). to("activemq:Some.Queue");

,>OPE>IIFKD .BSTIBMMJOH JT UIF PQQPTJUF PG VONBSTIBMMJOH, XIFSF B CFBO JT NBSTIBMMFE JOUP TPNF CJOBSZ PS UFYUVBM GPSNBU GPS USBOTNJTTJPO PWFS TPNF USBOTQPSU WJB B $BNFM $PNQPOFOU. .BSTIBMMJOH JT VTFE JO UIF TBNF XBZ BT VONBSTIBMMJOH BCPWF; JO UIF %4- ZPV DBO VTF B %BUB'PSNBU JOTUBODF, ZPV DBO DPOGJHVSF UIF %BUB'PSNBU EZOBNJDBMMZ VTJOH UIF %4- PS ZPV DBO SFGFS UP B OBNFE JOTUBODF PG UIF GPSNBU JO UIF 3FHJTUSZ. 5IF GPMMPXJOH FYBNQMF VONBSTIBMT WJB TFSJBMJ[BUJPO UIFO NBSTIBMT VTJOH B OBNFE +"9# EBUB GPSNBU UP QFSGPSN B LJOE PG .FTTBHF 5SBOTMBUPS

298

% " 5" '0 3 . " 5 " 1 1 & /% * 9

from("file://foo/bar"). unmarshal().serialization(). marshal("jaxb"). to("activemq:Some.Queue");

4PFKD 2MOFKD 7,+ 5IJT FYBNQMF TIPXT IPX UP DPOGJHVSF UIF EBUB UZQF KVTU PODF BOE SFVTF JU PO NVMUJQMF SPVUFT
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <jaxb id="myJaxb" prettyPrint="true" contextPath="org.apache.camel.example"/> </dataFormats> <route> <from uri="direct:start"/> <marshal ref="myJaxb"/> <to uri="direct:marshalled"/> </route> <route> <from uri="direct:marshalled"/> <unmarshal ref="myJaxb"/> <to uri="mock:result"/> </route> </camelContext>

:PV DBO BMTP EFGJOF SFVTBCMF EBUB GPSNBUT BT 4QSJOH CFBOT


<bean id="myJaxb" class="org.apache.camel.model.dataformat.JaxbDataFormat"> <property name="prettyPrint" value="true"/> <property name="contextPath" value="org.apache.camel.example"/> </bean>

2$1( +(9 3(.4FSJBMJ[BUJPO JT B %BUB 'PSNBU XIJDI VTFT UIF TUBOEBSE +BWB 4FSJBMJ[BUJPO NFDIBOJTN UP VONBSTIBM B CJOBSZ QBZMPBE JOUP +BWB PCKFDUT PS UP NBSTIBM +BWB PCKFDUT JOUP B CJOBSZ CMPC. 'PS FYBNQMF UIF GPMMPXJOH VTFT +BWB TFSJBMJ[BUJPO UP VONBSTIBM B CJOBSZ GJMF UIFO TFOE JU BT BO 0CKFDU.FTTBHF UP "DUJWF.2
from("file://foo/bar"). unmarshal().serialization(). to("activemq:Some.Queue");

%"5 " '0 3 . "5 "11&/ %*9

299

#BMBKABK@FBP 5IJT EBUB GPSNBU JT QSPWJEFE JO @>JBI-@LOB TP OP BEEJUJPOBM EFQFOEFODJFT JT OFFEFE.

) 7!
+"9# JT B %BUB 'PSNBU XIJDI VTFT UIF +"9#2 9.- NBSTIBMMJOH TUBOEBSE XIJDI JT JODMVEFE JO +BWB 6 UP VONBSTIBM BO 9.- QBZMPBE JOUP +BWB PCKFDUT PS UP NBSTIBM +BWB PCKFDUT JOUP BO 9.QBZMPBE. 4PFKD QEB )>S> #2+ 'PS FYBNQMF UIF GPMMPXJOH VTFT B OBNFE %BUB'PSNBU PG jaxb XIJDI JT DPOGJHVSFE XJUI B OVNCFS PG +BWB QBDLBHF OBNFT UP JOJUJBMJ[F UIF +"9#$POUFYU.
DataFormat jaxb = new JaxbDataFormat("com.acme.model"); from("activemq:My.Queue"). unmarshal(jaxb). to("mqseries:Another.Queue");

:PV DBO JG ZPV QSFGFS VTF B OBNFE SFGFSFODF UP B EBUB GPSNBU XIJDI DBO UIFO CF EFGJOFE JO ZPVS 3FHJTUSZ TVDI BT WJB ZPVS 4QSJOH 9.- GJMF. F.H.
from("activemq:My.Queue"). unmarshal("myJaxbDataType"). to("mqseries:Another.Queue");

4PFKD 2MOFKD 7,+ 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP VTF +"9# UP VONBSTIBM VTJOH 4QSJOH DPOGJHVSJOH UIF KBYC EBUB UZQF
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <unmarshal> <jaxb prettyPrint="true" contextPath="org.apache.camel.example"/> </unmarshal> <to uri="mock:result"/> </route> </camelContext>

5IJT FYBNQMF TIPXT IPX UP DPOGJHVSF UIF EBUB UZQF KVTU PODF BOE SFVTF JU PO NVMUJQMF SPVUFT.

300

% " 5" '0 3 . " 5 " 1 1 & /% * 9

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <jaxb id="myJaxb" prettyPrint="true" contextPath="org.apache.camel.example"/> </dataFormats> <route> <from uri="direct:start"/> <marshal ref="myJaxb"/> <to uri="direct:marshalled"/> </route> <route> <from uri="direct:marshalled"/> <unmarshal ref="myJaxb"/> <to uri="mock:result"/> </route> </camelContext>

/>OQF>I J>OPE>IIFKD/RKJ>OPE>IIFKD 3EFP CB>QROB FP KBT QL ">JBI 2.2.0. +"9# 2 TVQQPSUT NBSTIBMMJOH BOE VONBSTIBMMJOH 9.- USFF GSBHNFOUT. #Z EFGBVMU +"9# MPPLT GPS @XmlRootElement BOOPUBUJPO PO HJWFO DMBTT UP PQFSBUF PO XIPMF 9.- USFF. 5IJT JT VTFGVM CVU OPU BMXBZT - TPNFUJNFT HFOFSBUFE DPEF EPFT OPU IBWF !9NM3PPU&MFNFOU BOOPUBUJPO, TPNFUJNFT ZPV OFFE VONBSTIBMM POMZ QBSU PG USFF. *O UIBU DBTF ZPV DBO VTF QBSUJBM VONBSTIBMMJOH. 5P FOBCMF UIJT CFIBWJPVST ZPV OFFE TFU QSPQFSUZ partClass. $BNFM XJMM QBTT UIJT DMBTT UP +"9#'T VONBSTIBMFS.
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:marshal"/> <marshal> <jaxb prettyPrint="false" contextPath="org.apache.camel.example" partClass="org.apache.camel.example.PurchaseOrder" fragment="true" partNamespace="{http://example.camel.org/apache}po" /> </marshal> <to uri="mock:marshal"/> </route> <route> <from uri="direct:unmarshal"/> <unmarshal> <jaxb prettyPrint="false" contextPath="org.apache.camel.example" partClass="org.apache.camel.example.Partial" /> </unmarshal> <to uri="mock:unmarshal"/> </route> </camelContext>

%"5 " '0 3 . "5 "11&/ %*9

301

,RIQFMIB @LKQBUQ M>QEP *U JT QPTTJCMF UP VTF UIJT EBUB GPSNBU XJUI NPSF UIBO POF DPOUFYU QBUI. :PV DBO TQFDJGZ DPOUFYU QBUI VTJOH : BT TFQBSBUPS, GPS FYBNQMF com.mycompany:com.mycompany2. /PUF UIBU UIJT JT IBOEMFE CZ +"9# JNQMFNFOUBUJPO BOE NJHIU DIBOHF JG ZPV VTF EJGGFSFOU WFOEPS UIBO 3*. 'PS NBSTIBMMJOH ZPV IBWF UP BEE partNamespace BUUSJCVUF XJUI 2/BNF PG EFTUJOBUJPO OBNFTQBDF. &YBNQMF PG 4QSJOH %4- ZPV DBO GJOE BCPWF. %O>DJBKQ 3EFP CB>QROB FP KBT QL ">JBI 2.8.0. +BYC%BUB'PSNBU IBT OFX QSPQFSUZ GSBHNFOU XIJDI DBO TFU UIF UIF Marshaller.JAXB_FRAGMENT FODPEJOH QSPQFSUZ PO UIF +"9# .BSTIBMMFS. *G ZPV EPO'U XBOU UIF +"9# .BSTIBMMFS UP HFOFSBUF UIF 9.- EFDMBSBUJPO, ZPV DBO TFU UIJT PQUJPO UP CF USVF. 5IF EFGBVMU WBMVF PG UIJT QSPQFSUZ JT GBMFT. (DKLOFKD QEB -LK7,+ "E>O>@QBO 3EFP CB>QROB FP KBT QL ">JBI 2.2.0. +BYC%BUB'SPNBU TVQQPSUT UP JHOPSF UIF /PO9.- $IBSBDUFS, ZPV KVTU OFFE UP TFU UIF GJMUFS/PO9NM$IBST QSPQFSUZ UP CF USVF, +BYC%BUB'PSNBU XJMM SFQMBDF UIF /PO9.- DIBSBDUFS XJUI " " XIFO JU JT NBSTIBMJOH PS VONBSTIBMJOH UIF NFTTBHF. :PV DBO BMTP EP JU CZ TFUUJOH UIF &YDIBOHF QSPQFSUZ Exchange.FILTER_NON_XML_CHARS. c %FIQBOFKD FK RPB %FIQBOFKD KLQ FK RPB )#* 1.5 4U"9 "1* BOE JNQMFNFOUBUJPO 4U"9 "1* POMZ )#* 1.6+ /P /P

5IJT GFBUVSF IBT CFFO UFTUFE XJUI 8PPETUPY 3.2.9 BOE 4VO +%, 1.6 4U"9 JNQMFNFOUBUJPO. 6LOHFKD TFQE QEB .?GB@Q%>@QLOV *G ZPV VTF 9+$ UP DSFBUF UIF KBWB DMBTT GSPN UIF TDIFNB, ZPV XJMM HFU BO 0CKFDU'BDUPSZ GPS ZPV +"9# DPOUFYU. 4JODF UIF 0CKFDU'BDUPSZ VTFT +"9#&MFNFOU UP IPME UIF SFGFSFODF PG UIF TDIFNB BOE FMFNFOU JOTUBODF WBMVF, KBYC%BUBGPSNBU XJMM JHOPSF UIF +"9#&MFNFOU CZ EFGBVMU BOE ZPV XJMM HFU UIF FMFNFOU JOTUBODF WBMVF JOTUFBE PG UIF +"9#&MFNFOU PCKFDU GPSN UIF VONBSTIBMFE NFTTBHF CPEZ. *G ZPV XBOU UP HFU UIF +"9#&MFNFOU PCKFDU GPSN UIF VONBSTIBMFE NFTTBHF CPEZ, ZPV OFFE UP TFU UIF +BYC%BUB'PSNBU PCKFDU'T JHOPSF+"9#&MFNFOU QSPQFSUZ UP CF GBMTF.

302

% " 5" '0 3 . " 5 " 1 1 & /% * 9

2BQQFKD BK@LAFKD :PV DBO TFU UIF BK@LAFKD PQUJPO UP VTF XIFO NBSTIBMMJOH. *UT UIF Marshaller.JAXB_ENCODING FODPEJOH QSPQFSUZ PO UIF +"9# .BSTIBMMFS. :PV DBO TFUVQ XIJDI FODPEJOH UP VTF XIFO ZPV EFDMBSF UIF +"9# EBUB GPSNBU. :PV DBO BMTP QSPWJEF UIF FODPEJOH JO UIF &YDIBOHF QSPQFSUZ Exchange.CHARSET_NAME. 5IJT QSPQFSUZ XJMM PWFSSVMF UIF FODPEJOH TFU PO UIF +"9# EBUB GPSNBU. *O UIJT 4QSJOH %4- XF IBWF EFGJOFE UP VTF iso-8859-1 BT UIF FODPEJOH:
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <marshal> <jaxb prettyPrint="false" encoding="iso-8859-1" contextPath="org.apache.camel.example"/> </marshal> <to uri="mock:result"/> </route> </camelContext>

"LKQOLIIFKD K>JBPM>@B MOBCFU J>MMFKD S>FI>?IB >P LC ">JBI 2.11 8IFO NBSTIBMMJOH VTJOH +"9# PS 40"1 UIFO UIF +"9# JNQMFNFOUBUJPO XJMM BVUPNBUJD BTTJHO OBNFTQBDF QSFGJYFT, TVDI BT OT2, OT3, OT4 FUD. 5P DPOUSPM UIJT NBQQJOH, $BNFM BMMPXT ZPV UP SFGFS UP B NBQ XIJDI DPOUBJOT UIF EFTJSFE NBQQJOH. /PUJDF UIJT SFRVJSFT IBWJOH +"9#-3* 2.1 PS CFUUFS (GSPN 46/) PO UIF DMBTTQBUI, BT UIF NBQQJOH GVODUJPOBMJUZ JT EFQFOEFOU PO UIF JNQMFNFOUBUJPO PG +"9#, XIFUIFS JUT TVQQPSUFE. 'PS FYBNQMF JO 4QSJOH 9.- XF DBO EFGJOF B .BQ XJUI UIF NBQQJOH. *O UIF NBQQJOH GJMF CFMPX, XF NBQ 40"1 UP VTF TPBQ BT QSFGJY. 8IJMF PVS DVTUPN OBNFTQBDF "IUUQ://XXX.NZDPNQBOZ.DPN/GPP/2" JT OPU VTJOH BOZ QSFGJY.
<util:map id="myMap"> <entry key="http://www.w3.org/2003/05/soap-envelope" value="soap"/> <!-- we dont want any prefix for our namespace --> <entry key="http://www.mycompany.com/foo/2" value=""/> </util:map>

5P VTF UIJT JO +"9# PS 40"1 ZPV SFGFS UP UIJT NBQ, VTJOH UIF namespacePrefixRef BUUSJCVUF BT TIPXO CFMPX. 5IFO $BNFM XJMM MPPLVQ JO UIF 3FHJTUSZ B java.util.Map XJUI UIF JE "NZ.BQ", XIJDI XBT XIBU XF EFGJOFE BCPWF.
<marshal> <soapjaxb version="1.2" contextPath="com.mycompany.foo"

%"5 " '0 3 . "5 "11&/ %*9

303

namespacePrefixRef="myMap"/> </marshal>

2@EBJ> S>IFA>QFLK S>FI>?IB >P LC ">JBI 2.11 5IF +"9# %BUB 'PSNBU TVQQPSUT WBMJEBUJPO CZ NBSTIBMMJOH BOE VONBSTIBMMJOH GSPN/UP 9.-. :PVS DBO VTF UIF QSFGJY @I>PPM>QE:, CFIB:* LO *EQQM: UP TQFDJGZ IPX UIF SFTPVSDF TIPVME CZ SFTPMWFE. :PV DBO TFQBSBUF NVMUJQMF TDIFNB GJMFT CZ VTJOH UIF ',' DIBSBDUFS. 6TJOH UIF +BWB %4-, ZPV DBO DPOGJHVSF JU JO UIF GPMMPXJOH XBZ:
JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(); jaxbDataFormat.setContextPath(Person.class.getPackage().getName()); jaxbDataFormat.setSchema("classpath:person.xsd,classpath:address.xsd");

:PV DBO EP UIF TBNF VTJOH UIF 9.- %4-:


<marshal> <jaxb id="jaxb" schema="classpath:person.xsd,classpath:address.xsd"/> </marshal>

#BMBKABK@FBP 5P VTF +"9# JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-G>U? XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jaxb</artifactId> <version>x.x.x</version> </dependency>

7,+!$ -2
9NM#FBOT JT B %BUB 'PSNBU XIJDI VTFT UIF 9NM#FBOT MJCSBSZ UP VONBSTIBM BO 9.- QBZMPBE JOUP +BWB PCKFDUT PS UP NBSTIBM +BWB PCKFDUT JOUP BO 9.- QBZMPBE.

304

% " 5" '0 3 . " 5 " 1 1 & /% * 9

from("activemq:My.Queue"). unmarshal().xmlBeans(). to("mqseries:Another.Queue");

#BMBKABK@FBP 5P VTF 9NM#FBOT JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF EFQFOEFODZ PO @>JBIUJI?B>KP XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-xmlbeans</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

7231$ ,
94USFBN JT B %BUB 'PSNBU XIJDI VTFT UIF 94USFBN MJCSBSZ UP NBSTIBM BOE VONBSTIBM +BWB PCKFDUT UP BOE GSPN 9.-.
// lets turn Object messages into XML then send to MQSeries from("activemq:My.Queue"). marshal().xstream(). to("mqseries:Another.Queue");

7,+(KMRQ%>@QLOV >KA 7,+.RQMRQ%>@QLOV 5IF 94USFBN MJCSBSZ VTFT UIF javax.xml.stream.XMLInputFactory BOE javax.xml.stream.XMLOutputFactory, ZPV DBO DPOUSPM XIJDI JNQMFNFOUBUJPO PG UIJT GBDUPSZ TIPVME CF VTFE. 5IF 'BDUPSZ JT EJTDPWFSFE VTJOH UIJT BMHPSJUIN: 1. 6TF UIF javax.xml.stream.XMLInputFactory , javax.xml.stream.XMLOutputFactory TZTUFN QSPQFSUZ. 2. 6TF UIF lib/xml.stream.properties GJMF JO UIF JRE_HOME EJSFDUPSZ. 3. 6TF UIF 4FSWJDFT "1*, JG BWBJMBCMF, UP EFUFSNJOF UIF DMBTTOBNF CZ MPPLJOH JO UIF META-INF/ services/javax.xml.stream.XMLInputFactory, META-INF/services/ javax.xml.stream.XMLOutputFactory GJMFT JO KBST BWBJMBCMF UP UIF +3&. 4. 6TF UIF QMBUGPSN EFGBVMU 9.-*OQVU'BDUPSZ,9.-0VUQVU'BDUPSZ JOTUBODF.

%"5 " '0 3 . "5 "11&/ %*9

305

'LT QL PBQ QEB 7,+ BK@LAFKD FK 7PQOB>J #>Q>%LOJ>Q? 'SPN $BNFM 2.2.0, ZPV DBO TFU UIF FODPEJOH PG 9.- JO 9TUSFBN %BUB'PSNBU CZ TFUUJOH UIF &YDIBOHF'T QSPQFSUZ XJUI UIF LFZ Exchange.CHARSET_NAME, PS TFUUJOH UIF FODPEJOH QSPQFSUZ PO 9TUSFBN GSPN %4- PS 4QSJOH DPOGJH.
from("activemq:My.Queue"). marshal().xstream("UTF-8"). to("mqseries:Another.Queue");

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <!-- we define the json xstream data formats to be used (xstream is default) --> <dataFormats> <xstream id="xstream-utf8" encoding="UTF-8"/> <xstream id="xstream-default"/> </dataFormats> <route> <from uri="direct:in"/> <marshal ref="xstream-default"/> <to uri="mock:result"/> </route> <route> <from uri="direct:in-UTF-8"/> <marshal ref="xstream-utf8"/> <to uri="mock:result"/> </route> </camelContext>

#BMBKABK@FBP 5P VTF 94USFBN JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-UPQOB>J XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-xstream</artifactId> <version>x.x.x</version> </dependency>

306

% " 5" '0 3 . " 5 " 1 1 & /% * 9

"25
5IF $47 %BUB 'PSNBU VTFT "QBDIF $PNNPOT $47 UP IBOEMF $47 QBZMPBET ($PNNB 4FQBSBUFE 7BMVFT) TVDI BT UIPTF FYQPSUFE/JNQPSUFE CZ &YDFM. .MQFLKP .MQFLK DPOGJH TUSBUFHZ 3VMB $47$POGJH $474USBUFHZ #BP@OFMQFLK $BO CF VTFE UP TFU B DVTUPN CSVConfig PCKFDU. $BO CF VTFE UP TFU B DVTUPN CSVStrategy; UIF EFGBVMU JT CSVStrategy.DEFAULT_STRATEGY. 8IFUIFS PS OPU DPMVNOT BSF BVUP-HFOFSBUFE JO UIF SFTVMUJOH $47. 5IF EFGBVMU WBMVF JT true; TVCTFRVFOU NFTTBHFT VTF UIF QSFWJPVTMZ DSFBUFE DPMVNOT XJUI OFX GJFMET CFJOH BEEFE BU UIF FOE PG UIF MJOF. ">JBI 2.4: 5IF DPMVNO EFMJNJUFS UP VTF; UIF EFGBVMU WBMVF JT ",". ">JBI 2.10: 8IFUIFS PS OPU UP TLJQ UIF GJSTU MJOF PG $47 JOQVU XIFO VONBSTIBMMJOH (F.H. JG UIF DPOUFOU IBT IFBEFST PO UIF GJSTU MJOF); UIF EFGBVMU WBMVF JT false.

BVUPHFO$PMVNOT

CPPMFBO

EFMJNJUFS

4USJOH

TLJQ'JSTU-JOF

CPPMFBO

,>OPE>IIFKD > ,>M QL "25 5IF DPNQPOFOU BMMPXT ZPV UP NBSTIBM B +BWB .BQ (PS BOZ PUIFS NFTTBHF UZQF UIBU DBO CF DPOWFSUFE JO B .BQ) JOUP B $47 QBZMPBE. "O FYBNQMF: JG ZPV TFOE B NFTTBHF XJUI UIJT NBQ...
Map<String, Object> body = new HashMap<String, Object>(); body.put("foo", "abc"); body.put("bar", 123);

... UISPVHI UIJT SPVUF ...


from("direct:start"). marshal().csv(). to("mock:result");

... ZPV XJMM FOE VQ XJUI B 4USJOH DPOUBJOJOH UIJT $47 NFTTBHF abc,123

%"5 " '0 3 . "5 "11&/ %*9

307

4FOEJOH UIF .BQ CFMPX UISPVHI UIJT SPVUF XJMM SFTVMU JO B $47 NFTTBHF UIBU MPPLT MJLF foo,bar 4KJ>OPE>IIFKD > "25 JBPP>DB FKQL > )>S> +FPQ 6ONBSTIBMMJOH XJMM USBOTGPSN B $47 NFTTTBHF JOUP B +BWB -JTU XJUI $47 GJMF MJOFT (DPOUBJOJOH BOPUIFS -JTU XJUI BMM UIF GJFME WBMVFT). "O FYBNQMF: XF IBWF B $47 GJMF XJUI OBNFT PG QFSTPOT, UIFJS *2 BOE UIFJS DVSSFOU BDUJWJUZ.
Jack Dalton, 115, mad at Averell Joe Dalton, 105, calming Joe William Dalton, 105, keeping Joe from killing Averell Averell Dalton, 80, playing with Rantanplan Lucky Luke, 120, capturing the Daltons

8F DBO OPX VTF UIF $47 DPNQPOFOU UP VONBSTIBM UIJT GJMF:


from("file:src/test/resources/?fileName=daltons.csv&noop=true"). unmarshal().csv(). to("mock:daltons");

5IF SFTVMUJOH NFTTBHF XJMM DPOUBJO B List<List<String>> MJLF...


List<List<String>> data = (List<List<String>>) exchange.getIn().getBody(); for (List<String> line : data) { LOG.debug(String.format("%s has an IQ of %s and is currently %s", line.get(0), line.get(1), line.get(2))); }

,>OPE>IIFKD > +FPQ<,>M> QL "25 S>FI>?IB >P LC ">JBI 2.1 *G ZPV IBWF NVMUJQMF SPXT PG EBUB ZPV XBOU UP CF NBSTIBMMFE JOUP $47 GPSNBU ZPV DBO OPX TUPSF UIF NFTTBHF QBZMPBE BT B List<Map<String, Object>> PCKFDU XIFSF UIF MJTU DPOUBJOT B .BQ GPS FBDI SPX. %FIB /LIIBO LC "25, QEBK RKJ>OPE>IFKD (JWFO B CFBO XIJDI DBO IBOEMF UIF JODPNJOH EBUB...
Listing 1. MyCsvHandler.java
// Some comments here public void doHandleCsvData(List<List<String>> csvData) {

308

% " 5" '0 3 . " 5 " 1 1 & /% * 9

// do magic here }

... ZPVS SPVUF UIFO MPPLT BT GPMMPXT


<route> <!-- poll every 10 seconds --> <from uri="file:///some/path/to/pickup/ csvfiles?delete=true&amp;consumer.delay=10000" /> <unmarshal><csv /></unmarshal> <to uri="bean:myCsvHandler?method=doHandleCsvData" /> </route>

,>OPE>IFKD TFQE > MFMB >P ABIFJFQBO 6TJOH UIF 4QSJOH/9.- %4-:
<route> <from uri="direct:start" /> <marshal> <csv delimiter="|" /> </marshal> <to uri="bean:myCsvHandler?method=doHandleCsv" /> </route>

0S UIF +BWB %4-:


CsvDataFormat csv = new CsvDataFormat(); CSVConfig config = new CSVConfig(); config.setDelimiter('|'); csv.setConfig(config); from("direct:start") .marshal(csv) .convertBodyTo(String.class) .to("bean:myCsvHandler?method=doHandleCsv");

CsvDataFormat csv = new CsvDataFormat(); csv.setDelimiter("|"); from("direct:start") .marshal(csv) .convertBodyTo(String.class) .to("bean:myCsvHandler?method=doHandleCsv");

%"5 " '0 3 . "5 "11&/ %*9

309

4PFKD >RQLDBK"LIRJKP, @LKCFD1BC >KA PQO>QBDV1BC >QQOF?RQBP FKPFAB 7,+ #2+ S>FI>?IB >P LC ">JBI 2.9.2 / 2.10 :PV DBO DVTUPNJ[F UIF $47 %BUB 'PSNBU UP NBLF VTF PG ZPVS PXO CSVConfig BOE/PS CSVStrategy. "MTP OPUF UIBU UIF EFGBVMU WBMVF PG UIF autogenColumns PQUJPO JT USVF. 5IF GPMMPXJOH FYBNQMF TIPVME JMMVTUSBUF UIJT DVTUPNJ[BUJPO.
<route> <from uri="direct:start" /> <marshal> <!-- make use of a strategy other than the default one which is 'org.apache.commons.csv.CSVStrategy.DEFAULT_STRATEGY' --> <csv autogenColumns="false" delimiter="|" configRef="csvConfig" strategyRef="excelStrategy" /> </marshal> <convertBodyTo type="java.lang.String" /> <to uri="mock:result" /> </route> <bean id="csvConfig" class="org.apache.commons.csv.writer.CSVConfig"> <property name="fields"> <list> <bean class="org.apache.commons.csv.writer.CSVField"> <property name="name" value="orderId" /> </bean> <bean class="org.apache.commons.csv.writer.CSVField"> <property name="name" value="amount" /> </bean> </list> </property> </bean> <bean id="excelStrategy" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"> <property name="staticField" value="org.apache.commons.csv.CSVStrategy.EXCEL_STRATEGY" /> </bean>

4PFKD PHFM%FOPQ+FKB LMQFLK TEFIB RKJ>OPE>IFKD S>FI>?IB >P LC ">JBI 2.10 :PV DBO JOTUSVDU UIF $47 %BUB 'PSNBU UP TLJQ UIF GJSTU MJOF XIJDI DPOUBJOT UIF $47 IFBEFST. 6TJOH UIF 4QSJOH/9.- %4-:
<route> <from uri="direct:start" /> <unmarshal> <csv skipFirstLine="true" />

310

% " 5" '0 3 . " 5 " 1 1 & /% * 9

</unmarshal> <to uri="bean:myCsvHandler?method=doHandleCsv" /> </route>

0S UIF +BWB %4-:


CsvDataFormat csv = new CsvDataFormat(); csv.setSkipFirstLine(true); from("direct:start") .unmarshal(csv) .to("bean:myCsvHandler?method=doHandleCsv");

4KJ>OPE>IFKD TFQE > MFMB >P ABIFJFQBO 6TJOH UIF 4QSJOH/9.- %4-:
<route> <from uri="direct:start" /> <unmarshal> <csv delimiter="|" /> </unmarshal> <to uri="bean:myCsvHandler?method=doHandleCsv" /> </route>

0S UIF +BWB %4-:


CsvDataFormat csv = new CsvDataFormat(); CSVStrategy strategy = CSVStrategy.DEFAULT_STRATEGY; strategy.setDelimiter('|'); csv.setStrategy(strategy); from("direct:start") .unmarshal(csv) .to("bean:myCsvHandler?method=doHandleCsv");

CsvDataFormat csv = new CsvDataFormat(); csv.setDelimiter("|"); from("direct:start") .unmarshal(csv) .to("bean:myCsvHandler?method=doHandleCsv");

CsvDataFormat csv = new CsvDataFormat(); CSVConfig csvConfig = new CSVConfig();

%"5 " '0 3 . "5 "11&/ %*9

311

csvConfig.setDelimiter(";"); csv.setConfig(csvConfig); from("direct:start") .unmarshal(csv) .to("bean:myCsvHandler?method=doHandleCsv");

#BMBKABK@FBP 5P VTF $47 JO ZPVS $BNFM SPVUFT ZPV OFFE UP BEE B EFQFOEFODZ PO @>JBI-@PS, XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF .BWFO ZPV DBO KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU BOE HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-csv</artifactId> <version>x.x.x</version> </dependency>

5IF 4USJOH %BUB 'PSNBU JT B UFYUVBM CBTFE GPSNBU UIBU TVQQPSUT FODPEJOH. .MQFLKP .MQFLK DIBSTFU #BC>RIQ OVMM #BP@OFMQFLK 5P VTF B TQFDJGJD DIBSTFU GPS FODPEJOH. *G OPU QSPWJEFE $BNFM XJMM VTF UIF +7. EFGBVMU DIBSTFU.

,>OPE>I *O UIJT FYBNQMF XF NBSTIBM UIF GJMF DPOUFOU UP 4USJOH PCKFDU JO 65'-8 FODPEJOH.
from("file://data.csv").marshal().string("UTF-8").to("jms://myqueue");

4KJ>OPE>I *O UIJT FYBNQMF XF VONBSTIBM UIF QBZMPBE GSPN UIF +.4 RVFVF UP B 4USJOH PCKFDU VTJOH 65'-8 FODPEJOH, CFGPSF JUT QSPDFTTFE CZ UIF OFX0SEFS QSPDFTTPS.
from("jms://queue/order").unmarshal().string("UTF-8").processRef("newOrder");

312

% " 5" '0 3 . " 5 " 1 1 & /% * 9

(PPRB FK "25"LKCFD *U MPPLT MJLF UIBU


CSVConfig csvConfig = new CSVConfig(); csvConfig.setDelimiter(';');

EPFTO'U XPSL. :PV IBWF UP TFU UIF EFMJNJUFS BT B 4USJOH!

#BMBKABK@FBP 5IJT EBUB GPSNBU JT QSPWJEFE JO @>JBI-@LOB TP OP BEEJUJPOBM EFQFOEFODJFT JT OFFEFE. '+7 #>Q>%LOJ>Q 5IF )-7 DPNQPOFOU TIJQT XJUI B )-7 EBUB GPSNBU UIBU DBO CF VTFE UP GPSNBU CFUXFFO String BOE )-7 NPEFM PCKFDUT. marshal = GSPN .FTTBHF UP CZUF TUSFBN (DBO CF VTFE XIFO SFUVSOJOH BT SFTQPOTF VTJOH UIF )-7 .--1 DPEFD) unmarshal = GSPN CZUF TUSFBN UP .FTTBHF (DBO CF VTFE XIFO SFDFJWJOH TUSFBNFE EBUB GSPN UIF )-7 .--1 5P VTF UIF EBUB GPSNBU, TJNQMZ JOTUBOUJBUF BO JOTUBODF BOE JOWPLF UIF NBSTIBM PS VONBSTIBM PQFSBUJPO JO UIF SPVUF CVJMEFS:
DataFormat hl7 = new HL7DataFormat(); ... from("direct:hl7in").marshal(hl7).to("jms:queue:hl7out");

*O UIF TBNQMF BCPWF, UIF )-7 JT NBSTIBMMFE GSPN B )"1* .FTTBHF PCKFDU UP B CZUF TUSFBN BOE QVU PO B +.4 RVFVF. 5IF OFYU FYBNQMF JT UIF PQQPTJUF:
DataFormat hl7 = new HL7DataFormat(); ... from("jms:queue:hl7out").unmarshal(hl7).to("patientLookupService");

)FSF XF VONBSTIBM UIF CZUF TUSFBN JOUP B )"1* .FTTBHF PCKFDU UIBU JT QBTTFE UP PVS QBUJFOU MPPLVQ TFSWJDF. /PUJDF UIFSF JT B TIPSUIBOE TZOUBY JO $BNFM GPS XFMM-LOPXO EBUB GPSNBUT UIBU JT DPNNPOMZ VTFE. 5IFO ZPV EPO'U OFFE UP DSFBUF BO JOTUBODF PG UIF HL7DataFormat PCKFDU:

%"5 " '0 3 . "5 "11&/ %*9

313

2BDJBKQ PBM>O>QLOP "T PG ">JBI 2.11, unmarshal EPFT OPU BVUPNBUJDBMMZ GJY TFHNFOU TFQBSBUPST BOZNPSF CZ DPOWFSUJOH \n UP \r. *G ZPV OFFE UIJT DPOWFSTJPO, org.apache.camel.component.hl7.HL7#convertLFToCR QSPWJEFT B IBOEZ Expression GPS UIJT QVSQPTF.

from("direct:hl7in").marshal().hl7().to("jms:queue:hl7out"); from("jms:queue:hl7out").unmarshal().hl7().to("patientLookupService");

$#( # 3 %.1, 3
8F FODPVSBHF FOE VTFST UP MPPL BU UIF 4NPPLT XIJDI TVQQPSUT &%* BOE $BNFM OBUJWFMZ.

%+ 3/ "* # 3 %.1, 3
5IF 'MBUQBDL DPNQPOFOU TIJQT XJUI UIF 'MBUQBDL EBUB GPSNBU UIBU DBO CF VTFE UP GPSNBU CFUXFFO GJYFE XJEUI PS EFMJNJUFE UFYU NFTTBHFT UP B List PG SPXT BT Map. NBSTIBM = GSPN List<Map<String, Object>> UP OutputStream (DBO CF DPOWFSUFE UP String) VONBSTIBM = GSPN java.io.InputStream (TVDI BT B File PS String) UP B java.util.List BT BO org.apache.camel.component.flatpack.DataSetList JOTUBODF. 5IF SFTVMU PG UIF PQFSBUJPO XJMM DPOUBJO BMM UIF EBUB. *G ZPV OFFE UP QSPDFTT FBDI SPX POF CZ POF ZPV DBO TQMJU UIF FYDIBOHF, VTJOH 4QMJUUFS. -LQF@B: 5IF 'MBUQBDL MJCSBSZ EPFT DVSSFOUMZ OPU TVQQPSU IFBEFS BOE USBJMFST GPS UIF NBSTIBM PQFSBUJPO. .MQFLKP 5IF EBUB GPSNBU IBT UIF GPMMPXJOH PQUJPOT: .MQFLK definition fixed #BC>RIQ null false #BP@OFMQFLK 5IF GMBUQBDL Q[NBQ DPOGJHVSBUJPO GJMF. $BO CF PNJUUFE JO TJNQMFS TJUVBUJPOT, CVU JUT QSFGFSSFE UP VTF UIF Q[NBQ. %FMJNJUFE PS GJYFE.

314

% " 5" '0 3 . " 5 " 1 1 & /% * 9

2BOF>IFW>?IB JBPP>DBP "T PG )"1* 2.0 (VTFE CZ ">JBI 2.11), UIF )-7W2 NPEFM DMBTTFT BSF GVMMZ TFSJBMJ[BCMF. 4P ZPV DBO QVU )-7W2 NFTTBHFT EJSFDUMZ JOUP B +.4 RVFVF (J.F. XJUIPVU DBMMJOH marshal() BOE SFBE UIFN BHBJO EJSFDUMZ GSPN UIF RVFVF (J.F. XJUIPVU DBMMJOH unmarshal().

ignoreFirstRecord textQualifier delimiter parserFactory allowShortLines

true " , null false

8IFUIFS UIF GJSTU MJOF JT JHOPSFE GPS EFMJNJUFE GJMFT (GPS UIF DPMVNO IFBEFST). *G UIF UFYU JT RVBMJGJFE XJUI B DIBS TVDI BT ". 5IF EFMJNJUFS DIBS (DPVME CF ; , PS TJNJMBS) 6TFT UIF EFGBVMU 'MBUQBDL QBSTFS GBDUPSZ. ">JBI 2.9.7 >KA 2.10.5 LKT>OAP: "MMPXT GPS MJOFT UP CF TIPSUFS UIBO FYQFDUFE BOE JHOPSFT UIF FYUSB DIBSBDUFST. ">JBI 2.9.7 >KA 2.10.5 LKT>OAP: "MMPXT GPS MJOFT UP CF MPOHFS UIBO FYQFDUFE BOE JHOPSFT UIF FYUSB DIBSBDUFST.

ignoreExtraColumns

false

4P>DB 5P VTF UIF EBUB GPSNBU, TJNQMZ JOTUBOUJBUF BO JOTUBODF BOE JOWPLF UIF NBSTIBM PS VONBSTIBM PQFSBUJPO JO UIF SPVUF CVJMEFS:
FlatpackDataFormat fp = new FlatpackDataFormat(); fp.setDefinition(new ClassPathResource("INVENTORY-Delimited.pzmap.xml")); ... from("file:order/in").unmarshal(df).to("seda:queue:neworder");

5IF TBNQMF BCPWF XJMM SFBE GJMFT GSPN UIF order/in GPMEFS BOE VONBSTIBM UIF JOQVU VTJOH UIF 'MBUQBDL DPOGJHVSBUJPO GJMF INVENTORY-Delimited.pzmap.xml UIBU DPOGJHVSFT UIF TUSVDUVSF PG UIF GJMFT. 5IF SFTVMU JT B DataSetList PCKFDU XF TUPSF PO UIF 4&%" RVFVF.
FlatpackDataFormat df = new FlatpackDataFormat(); df.setDefinition(new ClassPathResource("PEOPLE-FixedLength.pzmap.xml")); df.setFixed(true); df.setIgnoreFirstRecord(false); from("seda:people").marshal(df).convertBodyTo(String.class).to("jms:queue:people");

%"5 " '0 3 . "5 "11&/ %*9

315

*O UIF DPEF BCPWF XF NBSTIBM UIF EBUB GSPN B 0CKFDU SFQSFTFOUBUJPO BT B List PG SPXT BT Maps. 5IF SPXT BT Map DPOUBJOT UIF DPMVNO OBNF BT UIF LFZ, BOE UIF UIF DPSSFTQPOEJOH WBMVF. 5IJT TUSVDUVSF DBO CF DSFBUFE JO +BWB DPEF GSPN F.H. B QSPDFTTPS. 8F NBSTIBM UIF EBUB BDDPSEJOH UP UIF 'MBUQBDL GPSNBU BOE DPOWFSU UIF SFTVMU BT B String PCKFDU BOE TUPSF JU PO B +.4 RVFVF. #BMBKABK@FBP 5P VTF 'MBUQBDL JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-CI>QM>@H XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-flatpack</artifactId> <version>x.x.x</version> </dependency>

)2.+40/ JT B %BUB 'PSNBU UP NBSTIBM BOE VONBSTIBM +BWB PCKFDUT UP BOE GSPN +40/. 'PS +40/ UP PCKFDU NBSTIBMMJOH, $BNFM QSPWJEFT JOUFHSBUJPO XJUI UISFF QPQVMBS +40/ MJCSBSJFT: 5IF 94USFBN MJCSBSZ BOE +FUUTJPO 5IF +BDLTPO MJCSBSZ ">JBI 2.10: 5IF (4PO MJCSBSZ #Z EFGBVMU $BNFM VTFT UIF 94USFBN MJCSBSZ. 4PFKD )2.- A>Q> CLOJ>Q TFQE QEB 72QOB>J IF?O>OV
// lets turn Object messages into json then send to MQSeries from("activemq:My.Queue"). marshal().json(). to("mqseries:Another.Queue");

4PFKD )2.- A>Q> CLOJ>Q TFQE QEB )>@HPLK IF?O>OV


// lets turn Object messages into json then send to MQSeries from("activemq:My.Queue").

316

% " 5" '0 3 . " 5 " 1 1 & /% * 9

#FOB@Q, ?F-AFOB@QFLK>I )2.- <=> 7,+ @LKSBOPFLKP "T PG $BNFM 2.10, $BNFM TVQQPSUT EJSFDU, CJ-EJSFDUJPOBM +40/ <=> 9.DPOWFSTJPOT WJB UIF DBNFM-YNMKTPO EBUB GPSNBU, XIJDI JT EPDVNFOUFE TFQBSBUFMZ.

marshal().json(JsonLibrary.Jackson). to("mqseries:Another.Queue");

4PFKD )2.- A>Q> CLOJ>Q TFQE QEB &2.- IF?O>OV


// lets turn Object messages into json then send to MQSeries from("activemq:My.Queue"). marshal().json(JsonLibrary.Gson). to("mqseries:Another.Queue");

4PFKD )2.- FK 2MOFKD #2+


8IFO VTJOH %BUB 'PSNBU JO 4QSJOH %4- ZPV OFFE UP EFDMBSF UIF EBUB GPSNBUT GJSTU. 5IJT JT EPOF JO UIF #>Q>%LOJ>QP 9.- UBH.
<dataFormats> <!-- here we define a Json data format with the id jack and that it should use the TestPojo as the class type when doing unmarshal. The unmarshalTypeName is optional, if not provided Camel will use a Map as the type --> <json id="jack" library="Jackson" unmarshalTypeName="org.apache.camel.component.jackson.TestPojo"/> </dataFormats>

"OE UIFO ZPV DBO SFGFS UP UIJT JE JO UIF SPVUF:


<route> <from uri="direct:back"/> <unmarshal ref="jack"/> <to uri="mock:reverse"/> </route>

$U@IRAFKD /.). CFBIAP COLJ J>OPE>IIFKD P LC ">JBI 2.10 8IFO NBSTIBMMJOH B 10+0 UP +40/ ZPV NJHIU XBOU UP FYDMVEF DFSUBJO GJFMET GSPN UIF +40/

%"5 " '0 3 . "5 "11&/ %*9

317

PVUQVU. 8JUI +BDLTPO ZPV DBO VTF +40/ WJFXT UP BDDPNQMJTI UIJT. 'JSTU DSFBUF POF PS NPSF NBSLFS DMBTTFT.
public class Views { static class Weight { } static class Age { } }

6TF UIF NBSLFS DMBTTFT XJUI UIF @JsonView BOOPUBUJPO UP JODMVEF/FYDMVEF DFSUBJO GJFMET. 5IF BOOPUBUJPO BMTP XPSLT PO HFUUFST.
@JsonView(Views.Age.class) private int age = 30; private int height = 190; @JsonView(Views.Weight.class) private int weight = 70;

'JOBMMZ VTF UIF $BNFM JacksonDataFormat UP NBSTIBMM UIF BCPWF 10+0 UP +40/.
JacksonDataFormat ageViewFormat = new JacksonDataFormat(TestPojoView.class, Views.Age.class); from("direct:inPojoAgeView").marshal(ageViewFormat);

/PUF UIBU UIF XFJHIU GJFME JT NJTTJOH JO UIF SFTVMUJOH +40/:


{"age":30, "height":190}

5IF (40/ MJCSBSZ TVQQPSUT B TJNJMBS GFBUVSF UISPVHI UIF OPUJPO PG &YDMVTJPO4USBUFHJFT:
/** * Strategy to exclude {@link ExcludeAge} annotated fields */ protected static class AgeExclusionStrategy implements ExclusionStrategy { @Override public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(ExcludeAge.class) != null; } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } }

318

% " 5" '0 3 . " 5 " 1 1 & /% * 9

5IF GsonDataFormat BDDFQUT BO ExclusionStrategy JO JUT DPOTUSVDUPS:


GsonDataFormat ageExclusionFormat = new GsonDataFormat(TestPojoExclusion.class, new AgeExclusionStrategy()); from("direct:inPojoExcludeAge").marshal(ageExclusionFormat);

5IF MJOF BCPWF XJMM FYDMVEF GJFMET BOOPUBUFE XJUI @ExcludeAge XIFO NBSTIBMMJOH UP +40/. "LKCFDROFKD CFBIA K>JFKD MLIF@V S>FI>?IB >P LC ">JBI 2.11 5IF (40/ MJCSBSZ TVQQPSUT TQFDJGZJOH QPMJDJFT BOE TUSBUFHJFT GPS NBQQJOH GSPN KTPO UP 10+0 GJFMET. " DPNNPO OBNJOH DPOWFOUJPO JT UP NBQ KTPO GJFMET VTJOH MPXFS DBTF XJUI VOEFSTDPSFT. 8F NBZ IBWF UIJT +40/ TUSJOH
{ "id" : 123, "first_name" : "Donald" "last_name" : "Duck" }

8IJDI XF XBOU UP NBQ UP B 10+0 UIBU IBT HFUUFS/TFUUFST BT


public class PersonPojo { private int id; private String firstName; private String lastName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; }

%"5 " '0 3 . "5 "11&/ %*9

319

public void setLastName(String lastName) { this.lastName = lastName; } }

5IFO XF DBO DPOGJHVSF UIF org.apache.camel.component.gson.GsonDataFormat JO B 4QSJOH 9.- GJMFT BT TIPXO CFMPX. /PUJDF XF VTF fieldNamingPolicy QSPQFSUZ UP TFU UIF GJFME NBQQJOH. 5IJT QSPQFSUZ JT BO FOVN GSPN (4PO com.google.gson.FieldNamingPolicy XIJDI IBT B OVNCFS PG QSF EFGJOFE NBQQJOHT. *G ZPV OFFE GVMM DPOUSPM ZPV DBO VTF UIF QSPQFSUZ FieldNamingStrategy BOE JNQMFNFOU B DVTUPN com.google.gson.FieldNamingStrategy XIFSF ZPV DBO DPOUSPM UIF NBQQJOH.
<!-- define the gson data format, where we configure the data format using the properties --> <bean id="gson" class="org.apache.camel.component.gson.GsonDataFormat"> <!-- we want to unmarshal to person pojo --> <property name="unmarshalType" value="org.apache.camel.component.gson.PersonPojo"/> <!-- we want to map fields to use lower case and underscores --> <property name="fieldNamingPolicy" value="LOWER_CASE_WITH_UNDERSCORES"/> </bean>

"OE VTF JU JO $BNFM SPVUFT CZ SFGFSSJOH UP JUT CFBO JE BT TIPXO:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:inPojo"/> <marshal ref="gson"/> </route> <route> <from uri="direct:backPojo"/> <unmarshal ref="gson"/> </route> </camelContext>

#BMBKABK@FBP CLO 72QOB>J 5P VTF +40/ JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-UPQOB>J XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).

320

% " 5" '0 3 . " 5 " 1 1 & /% * 9

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-xstream</artifactId> <version>2.9.2</version> </dependency>

#BMBKABK@FBP CLO )>@HPLK 5P VTF +40/ JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-G>@HPLK XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jackson</artifactId> <version>2.9.2</version> </dependency>

#BMBKABK@FBP CLO &2.5P VTF +40/ JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-DPLK XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-gson</artifactId> <version>2.10.0</version> </dependency>

5IF ;JQ %BUB 'PSNBU JT B NFTTBHF DPNQSFTTJPO BOE EF-DPNQSFTTJPO GPSNBU. .FTTBHFT NBSTIBMMFE VTJOH ;JQ DPNQSFTTJPO DBO CF VONBSTIBMMFE VTJOH ;JQ EFDPNQSFTTJPO KVTU QSJPS UP CFJOH DPOTVNFE BU UIF FOEQPJOU. 5IF DPNQSFTTJPO DBQBCJMJUZ JT RVJUF VTFGVM XIFO ZPV EFBM XJUI MBSHF 9.- BOE 5FYU CBTFE QBZMPBET. *U GBDJMJUBUFT NPSF PQUJNBM VTF PG OFUXPSL CBOEXJEUI XIJMF JODVSSJOH B TNBMM DPTU JO PSEFS UP DPNQSFTT BOE EFDPNQSFTT QBZMPBET BU UIF FOEQPJOU. .MQFLKP .MQFLK #BC>RIQ #BP@OFMQFLK

%"5 " '0 3 . "5 "11&/ %*9

321

?LRQ RPFKD TFQE %FIBP 5IF ;JQ EBUB GPSNBU, EPFT OPU (ZFU) IBWF TQFDJBM TVQQPSU GPS GJMFT. 8IJDI NFBOT UIBU XIFO VTJOH CJH GJMFT, UIF FOUJSF GJMF DPOUFOU JT MPBEFE JOUP NFNPSZ. 5IJT JT TVCKFDU UP DIBOHF JO UIF GVUVSF, UP BMMPX B TUSFBNJOH CBTFE TPMVUJPO UP IBWF B MPX NFNPSZ GPPUQSJOU.

DPNQSFTTJPO-FWFM

OVMM

5P TQFDJGZ B TQFDJGJD DPNQSFTTJPO -FWFM VTF java.util.zip.Deflater TFUUJOHT. 5IF QPTTJCMF TFUUJOHT BSFc ccccccccc - Deflater.BEST_SPEED ccccccccc - Deflater.BEST_COMPRESSION ccccccccc - Deflater.DEFAULT_COMPRESSION *G DPNQSFTTJPO-FWFM JT OPU FYQMJDJUMZ TQFDJGJFE UIF DPNQSFTTJPO-FWFM FNQMPZFE JT Deflater.DEFAULT_COMPRESSION

,>OPE>I *O UIJT FYBNQMF XF NBSTIBM B SFHVMBS UFYU/9.- QBZMPBE UP B DPNQSFTTFE QBZMPBE FNQMPZJOH [JQ DPNQSFTTJPO Deflater.BEST_COMPRESSION BOE TFOE JU BO "DUJWF.2 RVFVF DBMMFE .:@26&6&.
from("direct:start").marshal().zip(Deflater.BEST_COMPRESSION).to("activemq:queue:MY_QUEUE");

"MUFSOBUJWFMZ JG ZPV XPVME MJLF UP VTF UIF EFGBVMU TFUUJOH ZPV DPVME TFOE JU BT
from("direct:start").marshal().zip().to("activemq:queue:MY_QUEUE");

4KJ>OPE>I *O UIJT FYBNQMF XF VONBSTIBMcB [JQQFEcQBZMPBE GSPN BO "DUJWF.2 RVFVF DBMMFE .:@26&6&cUP JUT PSJHJOBM GPSNBU,cBOE GPSXBSE JU GPScQSPDFTTJOHcUP UIF 6O;JQQFE.FTTBHF1SPDFTTPS. /PUF UIBU UIF DPNQSFTTJPO -FWFM FNQMPZFE EVSJOH UIF NBSTIBMMJOH TIPVME CF JEFOUJDBM UP UIF POF FNQMPZFE EVSJOH VONBSTIBMMJOH UP BWPJE FSSPST.
from("activemq:queue:MY_QUEUE").unmarshal().zip().process(new UnZippedMessageProcessor());

322

% " 5" '0 3 . " 5 " 1 1 & /% * 9

#BMBKABK@FBP 5IJT EBUB GPSNBU JT QSPWJEFE JO @>JBI-@LOB TP OP BEEJUJPOBM EFQFOEFODJFT JT OFFEFE.

3(#8, 1*4/
5JEZ.BSLVQ JT B %BUB 'PSNBU UIBU VTFT UIF 5BH4PVQ UP UJEZ VQ )5.-. *U DBO CF VTFE UP QBSTF VHMZ )5.- BOE SFUVSO JU BT QSFUUZ XFMMGPSNFE )5.-. 5JEZ.BSLVQ POMZ TVQQPSUT UIF RKJ>OPE>I PQFSBUJPO BT XF SFBMMZ EPO'U XBOU UP UVSO XFMM GPSNFE )5.- JOUP VHMZ )5.)>S> #2+ $U>JMIB "O FYBNQMF XIFSF UIF DPOTVNFS QSPWJEFT TPNF )5.from("file://site/inbox").unmarshal().tidyMarkup().to("file://site/blogs");

2MOFKD 7,+ $U>JMIB 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP VTF 5JEZ.BSLVQ UP VONBSTIBM VTJOH 4QSJOH
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file://site/inbox"/> <unmarshal> <tidyMarkup/> </unmarshal> <to uri="file://site/blogs"/> </route> </camelContext>

#BMBKABK@FBP 5P VTF 5JEZ.BSLVQ JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIQ>DPLRM XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-tagsoup</artifactId> <version>x.x.x</version> </dependency>

%"5 " '0 3 . "5 "11&/ %*9

323

">JBI B>QP LRO LTK ALD CLLA PL>M 8F IBE TPNF JTTVFT JO PVS QEG .BOVBM XIFSF XF IBE TPNF TUSBOHF TZNCPMT. 4P +POBUIBO VTFE UIJT EBUB GPSNBU UP UJEZ VQ UIF XJLJ IUNM QBHFT UIBU BSF VTFE BT CBTF GPS SFOEFSJOH UIF QEG NBOVBMT. "OE UIFO UIF NZTUFSJPVT TZNCPMT WBOJTIFE.

!(-#8
5IF HPBM PG UIJT DPNQPOFOU JT UP BMMPX UIF QBSTJOH/CJOEJOH PG OPO-TUSVDUVSFE EBUB (PS UP CF NPSF QSFDJTF OPO-9.- EBUB) UP/GSPN +BWB #FBOT UIBU IBWF CJOEJOH NBQQJOHT EFGJOFE XJUI BOOPUBUJPOT. 6TJOH #JOEZ, ZPV DBO CJOE EBUB GSPN TPVSDFT TVDI BT : $47 SFDPSET, 'JYFE-MFOHUI SFDPSET, '*9 NFTTBHFT, PS BMNPTU BOZ PUIFS OPO-TUSVDUVSFE EBUB UP POF PS NBOZ 1MBJO 0ME +BWB 0CKFDU (10+0). #JOEZ DPOWFSUT UIF EBUB BDDPSEJOH UP UIF UZQF PG UIF KBWB QSPQFSUZ. 10+0T DBO CF MJOLFE UPHFUIFS XJUI POF-UP-NBOZ SFMBUJPOTIJQT BWBJMBCMF JO TPNF DBTFT. .PSFPWFS, GPS EBUB UZQF MJLF %BUF, %PVCMF, 'MPBU, *OUFHFS, 4IPSU, -POH BOE #JH%FDJNBM, ZPV DBO QSPWJEF UIF QBUUFSO UP BQQMZ EVSJOH UIF GPSNBUUJOH PG UIF QSPQFSUZ. 'PS UIF #JH%FDJNBM OVNCFST, ZPV DBO BMTP EFGJOF UIF QSFDJTJPO BOE UIF EFDJNBM PS HSPVQJOH TFQBSBUPST. 3VMB %BUF %FDJNBM* %LOJ>Q 3VMB %BUF'PSNBU %FDJNBMGPSNBU />QQBOK BU>JMIB "EE-..-ZZZZ" "##.###.###" +FKH IUUQ://KBWB.TVO.DPN/K2TF/1.5.0/EPDT/BQJ/KBWB/ UFYU/4JNQMF%BUF'PSNBU.IUNM IUUQ://KBWB.TVO.DPN/K2TF/1.5.0/EPDT/BQJ/KBWB/ UFYU/%FDJNBM'PSNBU.IUNM

%FDJNBM* = %PVCMF, *OUFHFS, 'MPBU, 4IPSU, -POH 5P XPSL XJUI DBNFM-CJOEZ, ZPV NVTU GJSTU EFGJOF ZPVS NPEFM JO B QBDLBHF (F.H. DPN.BDNF.NPEFM) BOE GPS FBDI NPEFM DMBTT (F.H. 0SEFS, $MJFOU, *OTUSVNFOU, ...) BEE UIF SFRVJSFE BOOPUBUJPOT (EFTDSJCFE IFSFBGUFS) UP UIF $MBTT PS GJFME.

--.3 3(.-2
5IF BOOPUBUJPOT DSFBUFE BMMPX UP NBQ EJGGFSFOU DPODFQU PG ZPVS NPEFM UP UIF 10+0 MJLF : 5ZQF PG SFDPSE (DTW, LFZ WBMVF QBJS (F.H. '*9 NFTTBHF), GJYFE MFOHUI ...), -JOL (UP MJOL PCKFDU JO BOPUIFS PCKFDU), %BUB'JFME BOE UIFJS QSPQFSUJFT (JOU, UZQF, ...), ,FZ7BMVF1BJS'JFME (GPS LFZ = WBMVF GPSNBU MJLF XF IBWF JO '*9 GJOBODJBM NFTTBHFT),

324

% " 5" '0 3 . " 5 " 1 1 & /% * 9

%LOJ>Q PRMMLOQBA 5IJT GJSTU SFMFBTF POMZ TVQQPSU DPNNB TFQBSBUFE WBMVFT GJFMET BOE LFZ WBMVF QBJS GJFMET (F.H. : '*9 NFTTBHFT). 4FDUJPO (UP JEFOUJGZ IFBEFS, CPEZ BOE GPPUFS TFDUJPO), 0OF5P.BOZ 5IJT TFDUJPO XJMM EFTDSJCF UIFN : 1. "PS1B@LOA 5IF $TW3FDPSE BOOPUBUJPO JT VTFE UP JEFOUJGJFE UIF SPPU DMBTT PG UIF NPEFM. *U SFQSFTFOUT B SFDPSE = B MJOF PG B $47 GJMF BOE DBO CF MJOLFE UP TFWFSBM DIJMESFO NPEFM DMBTTFT. KKLQ>QFLK K>JB "PS1B@LOA />O>JBQBO K>JB 1B@LOA QVMB DTW QVMB +BSBI $MBTT (KCL NBOEBUPSZ - DBO CF ',' PS ';' PS 'BOZUIJOH'. 5IJT WBMVF JT JOUFSQSFUFE BT B SFHVMBS FYQSFTTJPO. *G ZPV XBOU UP VTF B TJHO XIJDI IBT B TQFDJBM NFBOJOH JO SFHVMBS FYQSFTTJPOT, F.H. UIF ']' TJHO, UIBO ZPV IBWF UP NBTL JU, MJLF ' ]' PQUJPOBM - EFGBVMU WBMVF = GBMTF - BMMPX UP TLJQ UIF GJSTU MJOF PG UIF $47 GJMF PQUJPOBM - QPTTJCMF WBMVFT = 8*/%084,6/*9,."$, PS DVTUPN; EFGBVMU WBMVF = 8*/%084 - BMMPX UP EFGJOF UIF DBSSJBHF SFUVSO DIBSBDUFS UP VTF. *G ZPV TQFDJGZ B WBMVF PUIFS UIBO UIF UISFF MJTUFE CFGPSF, UIF WBMVF ZPV FOUFS (DVTUPN) XJMM CF VTFE BT UIF $3-' DIBSBDUFS(T) PQUJPOBM - EFGBVMU WBMVF = GBMTF - VTFT UP HFOFSBUF UIF IFBEFS DPMVNOT PG UIF $47 HFOFSBUFT PQUJPOBM - EFGBVMU WBMVF = GBMTF - BMMPX UP DIBOHF UIF PSEFS PG UIF GJFMET XIFO $47 JT HFOFSBUFE ">JBI 2.8.3/2.9: PQUJPO - BMMPX UP TQFDJGZ B RVPUF DIBSBDUFS PG UIF GJFMET XIFO $47 JT HFOFSBUFE

TFQBSBUPS

TUSJOH

TLJQ'JSTU-JOF

CPPMFBO

DSMG

TUSJOH

HFOFSBUF)FBEFS$PMVNOT JT0SEFSFE RVPUF

CPPMFBO CPPMFBO 4USJOH

%"5 " '0 3 . "5 "11&/ %*9

325

5IJT BOOPUBUJPO JT BTTPDJBUFE UP UIF SPPU DMBTT PG UIF NPEFM BOE NVTU CF EFDMBSFE POF UJNF.

@>PB 1 : PBM>O>QLO = ',' 5IF TFQBSBUPS VTFE UP TFHSFHBUF UIF GJFMET JO UIF $47 SFDPSE JT ',' : 10, +, 1BVMJOF, ., 9%12345678, 'PSUJT %ZOBNJD 15/15, 2500, 64%,08-01-2009
@CsvRecord( separator = "," ) public Class Order { ... }

@>PB 2 : PBM>O>QLO = ';' $PNQBSF UP UIF QSFWJPVT DBTF, UIF TFQBSBUPS IFSF JT ';' JOTUFBE PG ',' : 10; +; 1BVMJOF; .; 9%12345678; 'PSUJT %ZOBNJD 15/15; 2500; 64%; 08-01-2009
@CsvRecord( separator = ";" ) public Class Order { ... }

@>PB 3 : PBM>O>QLO = 'X' $PNQBSF UP UIF QSFWJPVT DBTF, UIF TFQBSBUPS IFSF JT ']' JOTUFBE PG ';' : 10] +] 1BVMJOF] .] 9%12345678] 'PSUJT %ZOBNJD 15/15] 2500] 64%] 08-01-2009
@CsvRecord( separator = "\\|" ) public Class Order { ... }

@>PB 4 : PBM>O>QLO = ';",;"' MMIFBP CLO ">JBI 2.8.2 LO LIABO 8IFO UIF GJFME UP CF QBSTFE PG UIF $47 SFDPSE DPOUBJOT ',' PS ';' XIJDI JT BMTP VTFE BT TFQBSBUPS, XF XIPVME GJOE BOPUIFS TUSBUFHZ UP UFMM DBNFM CJOEZ IPX UP IBOEMF UIJT DBTF. 5P EFGJOF UIF GJFME DPOUBJOJOH UIF EBUB XJUI B DPNNB, ZPV XJMM VTF TJNQMF PS EPVCMF RVPUFT BT EFMJNJUFS (F.H : '10', '4USFFU 10, /:', '64"' PS "10", "4USFFU 10, /:", "64""). 3FNBSL : *O UIJT DBTF, UIF GJSTU BOE MBTU DIBSBDUFS PG UIF MJOF XIJDI BSF B TJNQMF PS EPVCMF RVPUFT XJMM SFNPWFE CZ CJOEZ "10","+","1BVMJOF"," .","9%12345678","'PSUJT %ZOBNJD 15,15" 2500","64%","08-01-2009"
@CsvRecord( separator = "\",\"" ) public Class Order {

326

% " 5" '0 3 . " 5 " 1 1 & /% * 9

... }

'SPN ">JBI 2.8.3/2.9 LO KBSBO CJOEZ XJMM BVUPNBUJD EFUFDU JG UIF SFDPSE JT FODMPTFE XJUI FJUIFS TJOHMF PS EPVCMF RVPUFT BOE BVUPNBUJD SFNPWF UIPTF RVPUFT XIFO VONBSTIBMMJOH GSPN $47 UP 0CKFDU. 5IFSFGPSF EP KLQ JODMVEF UIF RVPUFT JO UIF TFQBSBUPS, CVU TJNQMF EP BT CFMPX: "10","+","1BVMJOF"," .","9%12345678","'PSUJT %ZOBNJD 15,15" 2500","64%","08-01-2009"
@CsvRecord( separator = "," ) public Class Order { ... }

/PUJDF UIBU JG ZPV XBOU UP NBSTIBM GSPN 0CKFDU UP $47 BOE VTF RVPUFT, UIFO ZPV OFFE UP TQFDJGZ XIJDI RVPUF DIBSBDUFS UP VTF, VTJOH UIF quote BUUSJCVUF PO UIF !$TW3FDPSE BT TIPXO CFMPX:
@CsvRecord( separator = ",", quote = "\"" ) public Class Order { ... }

@>PB 5 : PBM>O>QLO & PHFMCFOPQIFKB 5IF GFBUVSF JT JOUFSFTUJOH XIFO UIF DMJFOU XBOUT UP IBWF JO UIF GJSTU MJOF PG UIF GJMF, UIF OBNF PG UIF EBUB GJFMET : PSEFS JE, DMJFOU JE, GJSTU OBNF, MBTU OBNF, JTJO DPEF, JOTUSVNFOU OBNF, RVBOUJUZ, DVSSFODZ, EBUF 5P JOGPSN CJOEZ UIBU UIJT GJSTU MJOF NVTU CF TLJQQFE EVSJOH UIF QBSTJOH QSPDFTT, UIFO XF VTF UIF BUUSJCVUF :
@CsvRecord(separator = ",", skipFirstLine = true) public Class Order { ... }

@>PB 6 : DBKBO>QB'B>ABO"LIRJKP 5P BEE BU UIF GJSTU MJOF PG UIF $47 HFOFSBUFE, UIF BUUSJCVUF HFOFSBUF)FBEFS$PMVNOT NVTU CF TFU UP USVF JO UIF BOOPUBUJPO MJLF UIJT :
@CsvRecord( generateHeaderColumns = true ) public Class Order { ... }

"T B SFTVMU, #JOEZ EVSJOH UIF VONBSTIBMJOH QSPDFTT XJMM HFOFSBUF $47 MJLF UIJT :

%"5 " '0 3 . "5 "11&/ %*9

327

PSEFS JE, DMJFOU JE, GJSTU OBNF, MBTU OBNF, JTJO DPEF, JOTUSVNFOU OBNF, RVBOUJUZ, DVSSFODZ, EBUF 10, +, 1BVMJOF, ., 9%12345678, 'PSUJT %ZOBNJD 15/15, 2500, 64%,08-01-2009 @>PB 7 : @>OOF>DB OBQROK *G UIF QMBUGPSN XIFSF DBNFM-CJOEZ XJMM SVO JT OPU 8JOEPXT CVU .BDJOUPTI PS 6OJY, UIBO ZPV DBO DIBOHF UIF DSMG QSPQFSUZ MJLF UIJT. 5ISFF WBMVFT BSF BWBJMBCMF : 8*/%084, 6/*9 PS ."$
@CsvRecord(separator = ",", crlf="MAC") public Class Order { ... }

"EEJUJPOBMMZ, JG GPS TPNF SFBTPO ZPV OFFE UP BEE B EJGGFSFOU MJOF FOEJOH DIBSBDUFS, ZPV DBO PQU UP TQFDJGZ JU VTJOH UIF DSMG QBSBNFUFS. *O UIF GPMMPXJOH FYBNQMF, XF DBO FOE UIF MJOF XJUI B DPNNB GPMMPXFE CZ UIF OFXMJOF DIBSBDUFS:
@CsvRecord(separator = ",", crlf=",\n") public Class Order { ... }

@>PB 8 : FP.OABOBA 4PNFUJNFT, UIF PSEFS UP GPMMPX EVSJOH UIF DSFBUJPO PG UIF $47 SFDPSE GSPN UIF NPEFM JT EJGGFSFOU GSPN UIF PSEFS VTFE EVSJOH UIF QBSTJOH. 5IFO, JO UIJT DBTF, XF DBO VTF UIF BUUSJCVUF JT0SEFSFE = USVF UP JOEJDBUF UIJT JO DPNCJOBUJPO XJUI BUUSJCVUF 'QPTJUJPO' PG UIF %BUB'JFME BOOPUBUJPO.
@CsvRecord(isOrdered = true) public Class Order { @DataField(pos = 1, position = 11) private int orderNr; @DataField(pos = 2, position = 10) private String clientNr; ... }

3FNBSL : QPT JT VTFE UP QBSTF UIF GJMF, TUSFBN XIJMF QPTJUJPOT JT VTFE UP HFOFSBUF UIF $47 2. +FKH 5IF MJOL BOOPUBUJPO XJMM BMMPX UP MJOL PCKFDUT UPHFUIFS. KKLQ>QFLK K>JB +FKH 1B@LOA QVMB BMM +BSBI $MBTT & 1SPQFSUZ

328

% " 5" '0 3 . " 5 " 1 1 & /% * 9

/>O>JBQBO K>JB MJOL5ZQF c

QVMB -JOL5ZQF c

(KCL PQUJPOBM - CZ EFGBVMU UIF WBMVF JT -JOL5ZQF.POF5P0OF - TP ZPV BSF OPU PCMJHFE UP NFOUJPO JU 0OMZ POF-UP-POF SFMBUJPO JT BMMPXFE.

F.H : *G UIF NPEFM $MBTT $MJFOU JT MJOLFE UP UIF 0SEFS DMBTT, UIFO VTF BOOPUBUJPO -JOL JO UIF 0SEFS DMBTT MJLF UIJT :
Listing 1. Property Link
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1) private int orderNr; @Link private Client client; ...

"/% GPS UIF DMBTT $MJFOU :


Listing 1. Class Link
@Link public class Client { ... }

3. #>Q>%FBIA 5IF %BUB'JFME BOOPUBUJPO EFGJOFT UIF QSPQFSUZ PG UIF GJFME. &BDI EBUBGJFME JT JEFOUJGJFE CZ JUT QPTJUJPO JO UIF SFDPSE, B UZQF (TUSJOH, JOU, EBUF, ...) BOE PQUJPOBMMZ PG B QBUUFSO KKLQ>QFLK K>JB #>Q>%FBIA />O>JBQBO K>JB QPT QBUUFSO MFOHUI 1B@LOA QVMB BMM QVMB JOU TUSJOH JOU +BSBI 1SPQFSUZ (KCL NBOEBUPSZ - EJHJU OVNCFS TUBSUJOH GSPN 1 UP ... PQUJPOBM - EFGBVMU WBMVF = "" - XJMM CF VTFE UP GPSNBU %FDJNBM, %BUF, ... PQUJPOBM - SFQSFTFOUT UIF MFOHUI PG UIF GJFME GPS GJYFE MFOHUI GPSNBU

%"5 " '0 3 . "5 "11&/ %*9

329

QSFDJTJPO

JOU

PQUJPOBM - SFQSFTFOUT UIF QSFDJTJPO UP CF VTFE XIFO UIF %FDJNBM OVNCFS XJMM CF GPSNBUUFE/QBSTFE PQUJPOBM - EFGBVMU WBMVF = "" - JT VTFE CZ UIF +BWB 'PSNBUFS (4JNQMF%BUF'PSNBU CZ FYBNQMF) UP GPSNBU/ WBMJEBUF EBUB PQUJPOBM - NVTU CF VTFE XIFO UIF QPTJUJPO PG UIF GJFME JO UIF $47 HFOFSBUFE NVTU CF EJGGFSFOU DPNQBSF UP QPT PQUJPOBM - EFGBVMU WBMVF = "GBMTF" PQUJPOBM - EFGBVMU WBMVF = "GBMTF" PQUJPOBM - EFGBVMU WBMVF = "" - EFGJOFT UIF GJFME'T EFGBVMU WBMVF XIFO UIF SFTQFDUJWF $47 GJFME JT FNQUZ/OPU BWBJMBCMF ">JBI 2.11: PQUJPOBM - EFGBVMU WBMVF = "GBMTF" *OEJDBUFT JG UIFSF JT B EFDJNBM QPJOU JNQMJFE BU B TQFDJGJFE MPDBUJPO ">JBI 2.11: PQUJPOBM - DBO CF VTFE UP JEFOUJGZcB EBUB GJFME JO B GJYFE-MFOHUI SFDPSE UIBU EFGJOFT UIF GJYFE MFOHUI GPS UIJT GJFME ">JBI 2.11: PQUJPOBM - DBO CF VTFE UP EFNBSDBUF UIF FOE PG B WBSJBCMF-MFOHUI GJFME XJUIJO B GJYFE-MFOHUI SFDPSE

QBUUFSO

TUSJOH

QPTJUJPO SFRVJSFE USJN EFGBVMU7BMVF

JOU CPPMFBO CPPMFBO TUSJOH

JNQMJFE%FDJNBM4FQBSBUPS

CPPMFBO

MFOHUI1PT

JOU

EFMJNJUFS

TUSJOH

@>PB 1 : MLP 5IJT QBSBNFUFS/BUUSJCVUF SFQSFTFOUT UIF QPTJUJPO PG UIF GJFME JO UIF DTW SFDPSE
Listing 1. Position
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1) private int orderNr; @DataField(pos = 5) private String isinCode; ... }

"T ZPV DBO TFF JO UIJT FYBNQMF UIF QPTJUJPO TUBSUT BU '1' CVU DPOUJOVFT BU '5' JO UIF DMBTT 0SEFS. 5IF OVNCFST GSPN '2' UP '4' BSF EFGJOFE JO UIF DMBTT $MJFOU (TFF IFSF BGUFS).
Listing 1. Position continues in another model class

330

% " 5" '0 3 . " 5 " 1 1 & /% * 9

public class Client { @DataField(pos = 2) private String clientNr; @DataField(pos = 3) private String firstName; @DataField(pos = 4) private String lastName; ... }

@>PB 2 : M>QQBOK 5IF QBUUFSO BMMPXT UP FOSJDI PS WBMJEBUFT UIF GPSNBU PG ZPVS EBUB
Listing 1. Pattern
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1) private int orderNr; @DataField(pos = 5) private String isinCode; @DataField(name = "Name", pos = 6) private String instrumentName; @DataField(pos = 7, precision = 2) private BigDecimal amount; @DataField(pos = 8) private String currency; @DataField(pos = 9, pattern = "dd-MM-yyyy") -- pattern used during parsing or when the date is created private Date orderDate; ... }

@>PB 3 : MOB@FPFLK 5IF QSFDJTJPO JT IFMQGVM XIFO ZPV XBOU UP EFGJOF UIF EFDJNBM QBSU PG ZPVS OVNCFS
Listing 1. Precision
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1) private int orderNr;

%"5 " '0 3 . "5 "11&/ %*9

331

@Link private Client client; @DataField(pos = 5) private String isinCode; @DataField(name = "Name", pos = 6) private String instrumentName; @DataField(pos = 7, precision = 2) -- precision private BigDecimal amount; @DataField(pos = 8) private String currency; @DataField(pos = 9, pattern = "dd-MM-yyyy") private Date orderDate; ... }

@>PB 4 : /LPFQFLK FP AFCCBOBKQ FK LRQMRQ 5IF QPTJUJPO BUUSJCVUF XJMM JOGPSN CJOEZ IPX UP QMBDF UIF GJFME JO UIF $47 SFDPSE HFOFSBUFE. #Z EFGBVMU, UIF QPTJUJPO VTFE DPSSFTQPOET UP UIF QPTJUJPO EFGJOFE XJUI UIF BUUSJCVUF 'QPT'. *G UIF QPTJUJPO JT EJGGFSFOU (UIBU NFBOT UIBU XF IBWF BO BTZNFUSJD QSPDFTTVT DPNQBSJOH NBSTIBMJOH GSPN VONBSTIBMJOH) UIBO XF DBO VTF 'QPTJUJPO' UP JOEJDBUF UIJT. )FSF JT BO FYBNQMF
Listing 1. Position is different in output
@CsvRecord(separator = ",") public class Order { @CsvRecord(separator = ",", isOrdered = true) public class Order { // Positions of the fields start from 1 and not from 0 @DataField(pos = 1, position = 11) private int orderNr; @DataField(pos = 2, position = 10) private String clientNr; @DataField(pos = 3, position = 9) private String firstName; @DataField(pos = 4, position = 8) private String lastName; @DataField(pos = 5, position = 7) private String instrumentCode;

332

% " 5" '0 3 . " 5 " 1 1 & /% * 9

@DataField(pos = 6, position = 6) private String instrumentNumber; ... }

@>PB 5 : OBNRFOBA *G B GJFME JT NBOEBUPSZ, TJNQMZ VTF UIF BUUSJCVUF 'SFRVJSFE' TFUUFE UP USVF
Listing 1. Required
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1) private int orderNr; @DataField(pos = 2, required = true) private String clientNr; @DataField(pos = 3, required = true) private String firstName; @DataField(pos = 4, required = true) private String lastName; ... }

*G UIJT GJFME JT OPU QSFTFOU JO UIF SFDPSE, UIBO BO FSSPS XJMM CF SBJTFE CZ UIF QBSTFS XJUI UIF GPMMPXJOH JOGPSNBUJPO : 4PNF GJFMET BSF NJTTJOH (PQUJPOBM PS NBOEBUPSZ), MJOF : @>PB 6 : QOFJ *G B GJFME IBT MFBEJOH BOE/PS USBJMJOH TQBDFT XIJDI TIPVME CF SFNPWFE CFGPSF UIFZ BSF QSPDFTTFE, TJNQMZ VTF UIF BUUSJCVUF 'USJN' TFUUFE UP USVF
Listing 1. Trim
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1, trim = true) private int orderNr; @DataField(pos = 2, trim = true) private Integer clientNr; @DataField(pos = 3, required = true) private String firstName; @DataField(pos = 4) private String lastName;

%"5 " '0 3 . "5 "11&/ %*9

333

5IJT BUUSJCVUF PG UIF BOOPUBUJPO !%BUB'JFME NVTU CF VTFE JO DPNCJOBUJPO XJUI BUUSJCVUF JT0SEFSFE = USVF PG UIF BOOPUBUJPO !$TW3FDPSE

... }

@>PB 7 : ABC>RIQ5>IRB *G B GJFME JT OPU EFGJOFE UIFO VTFT UIF WBMVF JOEJDBUFE CZ UIF EFGBVMU7BMVF BUUSJCVUF
Listing 1. Default value
@CsvRecord(separator = ",") public class Order { @DataField(pos = 1) private int orderNr; @DataField(pos = 2) private Integer clientNr; @DataField(pos = 3, required = true) private String firstName; @DataField(pos = 4, defaultValue = "Barin") private String lastName; ... }

4. %FUBA+BKDQE1B@LOA 5IF 'JYFE-FOHUI3FDPSE BOOPUBUJPO JT VTFE UP JEFOUJGJFE UIF SPPU DMBTT PG UIF NPEFM. *U SFQSFTFOUT B SFDPSE = B MJOF PG B GJMF/NFTTBHF DPOUBJOJOH EBUB GJYFE MFOHUI GPSNBUUFE BOE DBO CF MJOLFE UP TFWFSBM DIJMESFO NPEFM DMBTTFT. 5IJT GPSNBU JT B CJU QBSUJDVMBS CFBVTF EBUB PG B GJFME DBO CF BMJHOFE UP UIF SJHIU PS UP UIF MFGU. 8IFO UIF TJ[F PG UIF EBUB EPFT OPU GJMM DPNQMFUFMZ UIF MFOHUI PG UIF GJFME, XF DBO UIFO BEE 'QBEE' DIBSBDUFST. KKLQ>QFLK K>JB %FUBA+BKDQE1B@LOA />O>JBQBO K>JB QVMB 1B@LOA QVMB GJYFE (KCL +BSBI $MBTT

334

% " 5" '0 3 . " 5 " 1 1 & /% * 9

5IJT BUUSJCVUF JT POMZ BQQMJDBCMF UP PQUJPOBM GJFMET.

DSMG

TUSJOH

PQUJPOBM - QPTTJCMF WBMVFT = 8*/%084,6/*9,."$, PS DVTUPN; EFGBVMU WBMVF = 8*/%084 - BMMPX UP EFGJOF UIF DBSSJBHF SFUVSO DIBSBDUFS UP VTF. *G ZPV TQFDJGZ B WBMVF PUIFS UIBO UIF UISFF MJTUFE CFGPSF, UIF WBMVF ZPV FOUFS (DVTUPN) XJMM CF VTFE BT UIF $3-' DIBSBDUFS(T) NBOEBUPSZ - EFGBVMU WBMVF = ' ' NBOEBUPSZ = TJ[F PG UIF GJYFE MFOHUI SFDPSE ">JBI 2.11 - PQUJPOBM - *OEJDBUFT UIBU UIF SFDPSE(T) PG UIJT UZQF NBZ CF QSFDFEFE CZ B TJOHMF IFBEFS SFDPSE BU UIF CFHJOOJOH PG UIF GJMF / TUSFBN ">JBI 2.11 - PQUJPOBM - *OEJDBUFT UIBU UIF SFDPSE(T) PG UIJT UZQF NBZ CF GPMMPXFE CZ B TJOHMF GPPUFS SFDPSE BU UIF FOE PG UIF GJMF / TUSFBN ">JBI 2.11 - PQUJPOBM - $POGJHVSFT UIF EBUB GPSNBU UP TLJQ NBSTIBMMJOH / VONBSTIBMMJOH PG UIF IFBEFS SFDPSE. $POGJHVSF UIJT QBSBNFUFS PO UIF QSJNBSZ SFDPSE (F.H., OPU UIF IFBEFS PS GPPUFS). ">JBI 2.11 - PQUJPOBM - $POGJHVSFT UIF EBUB GPSNBU UP TLJQ NBSTIBMMJOH / VONBSTIBMMJOH PG UIF GPPUFS SFDPSE $POGJHVSF UIJT QBSBNFUFS PO UIF QSJNBSZ SFDPSE (F.H., OPU UIF IFBEFS PS GPPUFS).. ">JBI 2.11 - PQUJPOBM - *EFOUJGJFT UIJT 'JYFE-FOHUI3FDPSE BT B IFBEFS SFDPSE ">JBI 2.11 - PQUJPOBM - *EFOUJGJFT UIJT 'JYFE-FOHUI3FDPSET BT B GPPUFS SFDPSE 5IJT BOOPUBUJPO JT BTTPDJBUFE UP UIF SPPU DMBTT PG UIF NPEFM BOE NVTU CF EFDMBSFE POF UJNF.

QBEEJOH$IBS MFOHUI IBT)FBEFS

DIBS JOU CPPMFBO

IBT'PPUFS

CPPMFBO

TLJQ)FBEFS

CPPMFBO

TLJQ'PPUFS

CPPMFBO

JT)FBEFS JT'PPUFS c

CPPMFBO CPPMFBO c

@>PB 1 : 2FJMIB CFUBA IBKDQE OB@LOA 5IJT TJNQMF FYBNQMF TIPXT IPX UP EFTJHO UIF NPEFM UP QBSTF/GPSNBU B GJYFE NFTTBHF 10"91BVMJOF.*4*/9%12345678#6:4IBSF2500.4564%01-08-2009
Listing 1. Fixed-simple
@FixedLengthRecord(length=54, paddingChar=' ') public static class Order {

%"5 " '0 3 . "5 "11&/ %*9

335

5IF IBT)FBEFS/IBT'PPUFS QBSBNFUFST BSF NVUVBMMZ FYDMVTJWF XJUI JT)FBEFS/ JT'PPUFS. " SFDPSE NBZ OPU CF CPUI B IFBEFS/GPPUFS BOE B QSJNBSZ GJYFE-MFOHUI SFDPSE.

@DataField(pos = 1, length=2) private int orderNr; @DataField(pos = 3, length=2) private String clientNr; @DataField(pos = 5, length=7) private String firstName; @DataField(pos = 12, length=1, align="L") private String lastName; @DataField(pos = 13, length=4) private String instrumentCode; @DataField(pos = 17, length=10) private String instrumentNumber; @DataField(pos = 27, length=3) private String orderType; @DataField(pos = 30, length=5) private String instrumentType; @DataField(pos = 35, precision = 2, length=7) private BigDecimal amount; @DataField(pos = 42, length=3) private String currency; @DataField(pos = 45, length=10, pattern = "dd-MM-yyyy") private Date orderDate; ...

@>PB 2 : %FUBA IBKDQE OB@LOA TFQE >IFDKJBKQ >KA M>AAFKD 5IJT NPSF FMBCPSBUFE FYBNQMF TIPX IPX UP EFGJOF UIF BMJHONFOU GPS B GJFME BOE IPX UP BTTJHO B QBEEJOH DIBSBDUFS XIJDI JT ' ' IFSF'' 10"9 1BVMJOF. *4*/9%12345678#6:4IBSF2500.4564%01-08-2009
Listing 1. Fixed-padding-align
@FixedLengthRecord(length=60, paddingChar=' ') public static class Order {

336

% " 5" '0 3 . " 5 " 1 1 & /% * 9

@DataField(pos = 1, length=2) private int orderNr; @DataField(pos = 3, length=2) private String clientNr; @DataField(pos = 5, length=9) private String firstName; @DataField(pos = 14, length=5, align="L") the block private String lastName; @DataField(pos = 19, length=4) private String instrumentCode; @DataField(pos = 23, length=10) private String instrumentNumber; @DataField(pos = 33, length=3) private String orderType; @DataField(pos = 36, length=5) private String instrumentType; @DataField(pos = 41, precision = 2, length=7) private BigDecimal amount; @DataField(pos = 48, length=3) private String currency; @DataField(pos = 51, length=10, pattern = "dd-MM-yyyy") private Date orderDate; ... // align text to the LEFT zone of

@>PB 3 : %FBIA M>AAFKD 4PNFUJNFT, UIF EFGBVMU QBEEJOH EFGJOFE GPS SFDPSE DBOOOPU CF BQQMJFE UP UIF GJFME BT XF IBWF B OVNCFS GPSNBU XIFSF XF XPVME MJLF UP QBEE XJUI '0' JOTUFBE PG ' '. *O UIJT DBTF, ZPV DBO VTF JO UIF NPEFM UIF BUUSJCVUF QBEEJOH'JFME UP TFU UIJT WBMVF. 10"9 1BVMJOF. *4*/9%12345678#6:4IBSF000002500.4564%01-08-2009
Listing 1. Fixed-padding-field
@FixedLengthRecord(length = 65, paddingChar = ' ') public static class Order { @DataField(pos = 1, length = 2) private int orderNr; @DataField(pos = 3, length = 2) private String clientNr;

%"5 " '0 3 . "5 "11&/ %*9

337

@DataField(pos = 5, length = 9) private String firstName; @DataField(pos = 14, length = 5, align = "L") private String lastName; @DataField(pos = 19, length = 4) private String instrumentCode; @DataField(pos = 23, length = 10) private String instrumentNumber; @DataField(pos = 33, length = 3) private String orderType; @DataField(pos = 36, length = 5) private String instrumentType; @DataField(pos = 41, precision = 2, length = 12, paddingChar = '0') private BigDecimal amount; @DataField(pos = 53, length = 3) private String currency; @DataField(pos = 56, length = 10, pattern = "dd-MM-yyyy") private Date orderDate; ...

@>PB 4: %FUBA IBKDQE OB@LOA TFQE ABIFJFQBO 'JYFE-MFOHUI SFDPSET TPNFUJNFT IBWF EFMJNJUFE DPOUFOU XJUIJO UIF SFDPSE. 5IF GJSTU/BNF BOE MBTU/BNF GJFMET BSF EFMJNJUFE XJUI UIF '?' DIBSBDUFS JO UIF GPMMPXJOH FYBNQMF: 10"91BVMJOF?.?*4*/9%12345678#6:4IBSF000002500.4564%01-08-2009
Listing 1. Fixed-delimited
@FixedLengthRecord() public static class Order { @DataField(pos = 1, length = 2) private int orderNr; @DataField(pos = 2, length = 2) private String clientNr; @DataField(pos = 3, delimiter = "^") private String firstName; @DataField(pos = 4, delimiter = "^") private String lastName; @DataField(pos = 5, length = 4) private String instrumentCode;

338

% " 5" '0 3 . " 5 " 1 1 & /% * 9

@DataField(pos = 6, length = 10) private String instrumentNumber; @DataField(pos = 7, length = 3) private String orderType; @DataField(pos = 8, length = 5) private String instrumentType; @DataField(pos = 9, precision = 2, length = 12, paddingChar = '0') private BigDecimal amount; @DataField(pos = 10, length = 3) private String currency; @DataField(pos = 11, length = 10, pattern = "dd-MM-yyyy") private Date orderDate;

@>PB 5 : %FUBA IBKDQE OB@LOA TFQE OB@LOA-ABCFKBA CFBIA IBKDQE 0DDBTJPOBMMZ B GJYFE-MFOHUI SFDPSE NBZ DPOUBJO B GJFME UIBU EFGJOF UIF FYQFDUFE MFOHUI PG BOPUIFS GJFME XJUIJO UIF TBNF SFDPSE. *O UIF GPMMPXJOH FYBNQMF UIF MFOHUI PG UIF JOTUSVNFOU/VNCFS GJFME WBMVF JT EFGJOFE CZ UIF WBMVF PG JOTUSVNFOU/VNCFS-FO GJFME JO UIF SFDPSE. 10"91BVMJOF?.?*4*/109%12345678#6:4IBSF000002500.4564%01-08-2009
Listing 1. Fixed-delimited
@FixedLengthRecord() public static class Order { @DataField(pos = 1, length = 2) private int orderNr; @DataField(pos = 2, length = 2) private String clientNr; @DataField(pos = 3, delimiter = "^") private String firstName; @DataField(pos = 4, delimiter = "^") private String lastName; @DataField(pos = 5, length = 4) private String instrumentCode; @DataField(pos = 6, length = 2, align = "R", paddingChar = '0') private int instrumentNumberLen; @DataField(pos = 7, lengthPos=6) private String instrumentNumber;

%"5 " '0 3 . "5 "11&/ %*9

339

"T PG ">JBI 2.11 UIF 'QPT' WBMVF(T) JO B GJYFE-MFOHUI SFDPSE NBZ PQUJPOBMMZ CF EFGJOFE VTJOH PSEJOBM, TFRVFOUJBM WBMVFT JOTUFBE PG QSFDJTF DPMVNO OVNCFST.

@DataField(pos = 8, length = 3) private String orderType; @DataField(pos = 9, length = 5) private String instrumentType; @DataField(pos = 10, precision = 2, length = 12, paddingChar = '0') private BigDecimal amount; @DataField(pos = 11, length = 3) private String currency; @DataField(pos = 12, length = 10, pattern = "dd-MM-yyyy") private Date orderDate;

@>PB 6 : %FUBA IBKDQE OB@LOA TFQE EB>ABO >KA CLLQBO #JOEZ XJMM EJTDPWFS GJYFE-MFOHUI IFBEFS BOE GPPUFS SFDPSET UIBU BSF DPOGJHVSFE BT QBSU PG UIF NPEFM f QSPWJEFE UIBU UIF BOOPUBUFE DMBTTFT FYJTU FJUIFS JO UIF TBNF QBDLBHF BT UIF QSJNBSZ !'JYFE-FOHUI3FDPSE DMBTT, PS XJUIJO POF PG UIF DPOGJHVSFE TDBO QBDLBHFT. 5IF GPMMPXJOH UFYU JMMVTUSBUFT UXP GJYFE-MFOHUI SFDPSET UIBU BSF CSBDLFUFE CZ B IFBEFS SFDPSE BOE GPPUFS SFDPSE. 101-08-2009 10"9 1BVMJOF. *4*/9%12345678#6:4IBSF000002500.4564%01-08-2009 10"9 3JDI/ *4*/9%12345678#6:4IBSF000002700.4564%01-08-2009 9000000002
Listing 1. Fixed-header-and-footer-main-class
@FixedLengthRecord(hasHeader = true, hasFooter = true) public class Order { @DataField(pos = 1, length = 2) private int orderNr; @DataField(pos = 2, length = 2) private String clientNr; @DataField(pos = 3, length = 9) private String firstName; @DataField(pos = 4, length = 5, align = "L") private String lastName; @DataField(pos = 5, length = 4) private String instrumentCode;

340

% " 5" '0 3 . " 5 " 1 1 & /% * 9

@DataField(pos = 6, length = 10) private String instrumentNumber; @DataField(pos = 7, length = 3) private String orderType; @DataField(pos = 8, length = 5) private String instrumentType; @DataField(pos = 9, precision = 2, length = 12, paddingChar = '0') private BigDecimal amount; @DataField(pos = 10, length = 3) private String currency; @DataField(pos = 11, length = 10, pattern = "dd-MM-yyyy") private Date orderDate; ... }

@FixedLengthRecord(isHeader = true) public class OrderHeader { @DataField(pos = 1, length = 1) private int recordType = 1; @DataField(pos = 2, length = 10, pattern = "dd-MM-yyyy") private Date recordDate; ... }

@FixedLengthRecord(isFooter = true) public class OrderFooter { @DataField(pos = 1, length = 1) private int recordType = 9; @DataField(pos = 2, length = 9, align = "R", paddingChar = '0') private int numberOfRecordsInTheFile; ... }

5. ,BPP>DB 5IF .FTTBHF BOOPUBUJPO JT VTFE UP JEFOUJGJFE UIF DMBTT PG ZPVS NPEFM XIP XJMM DPOUBJO LFZ WBMVF QBJST GJFMET. 5IJT LJOE PG GPSNBU JT VTFE NBJOMZ JO 'JOBODJBM &YDIBOHF 1SPUPDPM .FTTBHFT ('*9). /FWFSUIFMFTT, UIJT BOOPUBUJPO DBO CF VTFE GPS BOZ PUIFS GPSNBU XIFSF EBUB BSF JEFOUJGJFE CZ

%"5 " '0 3 . "5 "11&/ %*9

341

LFZT. 5IF LFZ QBJS WBMVFT BSF TFQBSBUFE FBDI PUIFS CZ B TFQBSBUPS XIJDI DBO CF B TQFDJBM DIBSBDUFS MJLF B UBC EFMJNJUPS (VOJDPEF SFQSFTFOUBUJPO : =V0009) PS B TUBSU PG IFBEJOH (VOJDPEF SFQSFTFOUBUJPO : =V0001) KKLQ>QFLK K>JB ,BPP>DB />O>JBQBO K>JB QBJS4FQBSBUPS LFZ7BMVF1BJS4FQBSBJS 1B@LOA QVMB LFZ WBMVF QBJS QVMB TUSJOH TUSJOH (KCL NBOEBUPSZ - DBO CF '=' PS ';' PS 'BOZUIJOH' NBOEBUPSZ - DBO CF '=V0001', '=V0009', '#' PS 'BOZUIJOH' PQUJPOBM - QPTTJCMF WBMVFT = 8*/%084,6/*9,."$, PS DVTUPN; EFGBVMU WBMVF = 8*/%084 - BMMPX UP EFGJOF UIF DBSSJBHF SFUVSO DIBSBDUFS UP VTF. *G ZPV TQFDJGZ B WBMVF PUIFS UIBO UIF UISFF MJTUFE CFGPSF, UIF WBMVF ZPV FOUFS (DVTUPN) XJMM CF VTFE BT UIF $3-' DIBSBDUFS(T) PQUJPOBM - EFGJOF UIF UZQF PG NFTTBHF (F.H. '*9, &.9, ...) PQUJPOBM - WFSTJPO PG UIF NFTTBHF (F.H. 4.1) PQUJPOBM - EFGBVMU WBMVF = GBMTF - BMMPX UP DIBOHF UIF PSEFS PG UIF GJFMET XIFO '*9 NFTTBHF JT HFOFSBUFE 5IJT BOOPUBUJPO JT BTTPDJBUFE UP UIF NFTTBHF DMBTT PG UIF NPEFM BOE NVTU CF EFDMBSFE POF UJNF. +BSBI $MBTT

DSMG

TUSJOH

UZQF WFSTJPO JT0SEFSFE c

TUSJOH TUSJOH CPPMFBO c

@>PB 1 : PBM>O>QLO = 'R0001' 5IF TFQBSBUPS VTFE UP TFHSFHBUF UIF LFZ WBMVF QBJS GJFMET JO B '*9 NFTTBHF JT UIF "4$** '01' DIBSBDUFS PS JO VOJDPEF GPSNBU '=V0001'. 5IJT DIBSBDUFS NVTU CF FTDBQFE B TFDPOE UJNF UP BWPJE B KBWB SVOUJNF FSSPS. )FSF JT BO FYBNQMF : 8='*9.4.1 9=20 34=1 35=0 49=*/7.(3 56=#3,3 1=#&.$)..001 11=$).0001-01 22=4 ... BOE IPX UP VTF UIF BOOPUBUJPO
Listing 1. FIX - message
@Message(keyValuePairSeparator = "=", pairSeparator = "\u0001", type="FIX", version="4.1") public class Order { ... }

342

% " 5" '0 3 . " 5 " 1 1 & /% * 9

"%(7 FKCLOJ>QFLK" .PSF JOGPSNBUJPO BCPVU '*9 DBO CF GPVOE PO UIJT XFC TJUF : IUUQ://XXX.GJYQSPUPDPM.PSH/. 5P XPSL XJUI '*9 NFTTBHFT, UIF NPEFM NVTU DPOUBJO B )FBEFS BOE 5SBJMFS DMBTTFT MJOLFE UP UIF SPPU NFTTBHF DMBTT XIJDI DPVME CF B 0SEFS DMBTT. 5IJT JT OPU NBOEBUPSZ CVU XJMM CF WFSZ IFMQGVM XIFO ZPV XJMM VTF DBNFM-CJOEZ JO DPNCJOBUJPO XJUI DBNFM-GJY XIJDI JT B 'JY HBUFXBZ CBTFE PO RVJDL'JY QSPKFDU IUUQ://XXX.RVJDLGJYK.PSH/.

+LLH >Q QBPQ @>PBP 5IF "4$** DIBSBDUFS MJLF UBC, ... DBOOPU CF EJTQMBZFE JO 8*,* QBHF. 4P, IBWF B MPPL UP UIF UFTU DBTF PG DBNFM-CJOEZ UP TFF FYBDUMZ IPX UIF '*9 NFTTBHF MPPLT MJLF (TSD=UFTU= EBUB=GJY=GJY.UYU) BOE UIF 0SEFS, 5SBJMFS, )FBEFS DMBTTFT (TSD=UFTU=KBWB=PSH=BQBDIF= DBNFM=EBUBGPSNBU=CJOEZ=NPEFM=GJY=TJNQMF=0SEFS.KBWB) 6. *BV5>IRB/>FO%FBIA 5IF ,FZ7BMVF1BJS'JFME BOOPUBUJPO EFGJOFT UIF QSPQFSUZ PG B LFZ WBMVF QBJS GJFME. &BDI ,FZ7BMVF1BJS'JFME JT JEFOUJGJFE CZ B UBH (= LFZ) BOE JUT WBMVF BTTPDJBUFE, B UZQF (TUSJOH, JOU, EBUF, ...), PQUJPOBMZ B QBUUFSO BOE JG UIF GJFME JT SFRVJSFE KKLQ>QFLK K>JB *BV5>IRB/>FO%FBIA />O>JBQBO K>JB UBH QBUUFSO 1B@LOA QVMB ,FZ 7BMVF 1BJS - '*9 QVMB JOU TUSJOH (KCL NBOEBUPSZ - EJHJU OVNCFS JEFOUJGZJOH UIF GJFME JO UIF NFTTBHF - NVTU CF VOJRVF PQUJPOBM - EFGBVMU WBMVF = "" - XJMM CF VTFE UP GPSNBU %FDJNBM, %BUF, ... PQUJPOBM - EJHJU OVNCFS - SFQSFTFOUT UIF QSFDJTJPO UP CF VTFE XIFO UIF %FDJNBM OVNCFS XJMM CF GPSNBUUFE/ QBSTFE PQUJPOBM - NVTU CF VTFE XIFO UIF QPTJUJPO PG UIF LFZ/ UBH JO UIF '*9 NFTTBHF NVTU CF EJGGFSFOU PQUJPOBM - EFGBVMU WBMVF = "GBMTF" ">JBI 2.11: PQUJPOBM - EFGBVMU WBMVF = "GBMTF" *OEJDBUFT JG UIFSF JT B EFDJNBM QPJOU JNQMJFE BU B TQFDJGJFE MPDBUJPO +BSBI 1SPQFSUZ

QSFDJTJPO

JOU

QPTJUJPO SFRVJSFE JNQMJFE%FDJNBM4FQBSBUPS

JOU CPPMFBO CPPMFBO

%"5 " '0 3 . "5 "11&/ %*9

343

@>PB 1 : Q>D 5IJT QBSBNFUFS SFQSFTFOUT UIF LFZ PG UIF GJFME JO UIF NFTTBHF
Listing 1. FIX message - Tag
@Message(keyValuePairSeparator = "=", pairSeparator = "\u0001", type="FIX", version="4.1") public class Order { @Link Header header; @Link Trailer trailer; @KeyValuePairField(tag = 1) // Client reference private String Account; @KeyValuePairField(tag = 11) // Order reference private String ClOrdId; @KeyValuePairField(tag = 22) // Fund ID type (Sedol, ISIN, ...) private String IDSource; @KeyValuePairField(tag = 48) // Fund code private String SecurityId; @KeyValuePairField(tag = 54) // Movement type ( 1 = Buy, 2 = sell) private String Side; @KeyValuePairField(tag = 58) // Free text private String Text; ... }

@>PB 2 : #FCCBOBKQ MLPFQFLK FK LRQMRQ *G UIF UBHT/LFZT UIBU XF XJMM QVU JO UIF '*9 NFTTBHF NVTU CF TPSUFE BDDPSEJOH UP B QSFEFGJOF PSEFS, UIFO VTF UIF BUUSJCVUF 'QPTJUJPO' PG UIF BOOPUBUJPO !,FZ7BMVF1BJS'JFME
Listing 1. FIX message - Tag - sort
@Message(keyValuePairSeparator = "=", pairSeparator = "\\u0001", type = "FIX", version = "4.1", isOrdered = true) public class Order { @Link Header header; @Link Trailer trailer; @KeyValuePairField(tag = 1, position = 1) // Client reference private String account; @KeyValuePairField(tag = 11, position = 3) // Order reference private String clOrdId;

344

% " 5" '0 3 . " 5 " 1 1 & /% * 9

... }

7. 2B@QFLK *O '*9 NFTTBHF PG GJYFE MFOHUI SFDPSET, JU JT DPNNPO UP IBWF EJGGFSFOU TFDUJPOT JO UIF SFQSFTFOUBUJPO PG UIF JOGPSNBUJPO : IFBEFS, CPEZ BOE TFDUJPO. 5IF QVSQPTF PG UIF BOOPUBUJPO !4FDUJPO JT UP JOGPSN CJOEZ BCPVU XIJDI DMBTT PG UIF NPEFM SFQSFTFOUT UIF IFBEFS (= TFDUJPO 1), CPEZ (= TFDUJPO 2) BOE GPPUFS (= TFDUJPO 3) 0OMZ POF BUUSJCVUF/QBSBNFUFS FYJTUT GPS UIJT BOOPUBUJPO. KKLQ>QFLK K>JB 2B@QFLK />O>JBQBO K>JB OVNCFS 1B@LOA QVMB '*9 QVMB JOU (KCL EJHJU OVNCFS JEFOUJGZJOH UIF TFDUJPO QPTJUJPO +BSBI $MBTT

@>PB 1 : 2B@QFLK ". %FGJOJUJPO PG UIF IFBEFS TFDUJPO


Listing 1. FIX message - Section - Header
@Section(number = 1) public class Header { @KeyValuePairField(tag = 8, position = 1) // Message Header private String beginString; @KeyValuePairField(tag = 9, position = 2) // Checksum private int bodyLength; ... }

#. %FGJOJUJPO PG UIF CPEZ TFDUJPO


Listing 1. FIX message - Section - Body
@Section(number = 2) @Message(keyValuePairSeparator = "=", pairSeparator = "\\u0001", type = "FIX", version = "4.1", isOrdered = true) public class Order { @Link Header header; @Link Trailer trailer; @KeyValuePairField(tag = 1, position = 1) // Client reference private String account;

%"5 " '0 3 . "5 "11&/ %*9

345

@KeyValuePairField(tag = 11, position = 3) // Order reference private String clOrdId;

$. %FGJOJUJPO PG UIF GPPUFS TFDUJPO


Listing 1. FIX message - Section - Footer
@Section(number = 3) public class Trailer { @KeyValuePairField(tag = 10, position = 1) // CheckSum private int checkSum; public int getCheckSum() { return checkSum; }

8. .KB3L,>KV 5IF QVSQPTF PG UIF BOOPUBUJPO !0OF5P.BOZ JT UP BMMPX UP XPSL XJUI B -JTU< > GJFME EFGJOFE B 10+0 DMBTT PS GSPN B SFDPSE DPOUBJOJOH SFQFUJUJWF HSPVQT. 5IF SFMBUJPO 0OF5P.BOZ 0/-: 803,4 JO UIF GPMMPXJOH DBTFT : 3FBEJOH B '*9 NFTTBHF DPOUBJOJOH SFQFUJUJWF HSPVQT (= HSPVQ PG UBHT/LFZT) (FOFSBUJOH B $47 XJUI SFQFUJUJWF EBUB KKLQ>QFLK K>JB .KB3L,>KV />O>JBQBO K>JB NBQQFE5P 1B@LOA QVMB BMM QVMB TUSJOH (KCL PQUJPOBM - TUSJOH - DMBTT OBNF BTTPDJBUFE UP UIF UZQF PG UIF -JTU<5ZQF PG UIF $MBTT> +BSBI QSPQFSUZ

@>PB 1 : &BKBO>QFKD "25 TFQE OBMBQFQFSB A>Q> )FSF JT UIF $47 PVUQVU UIBU XF XBOU : $MBVT,*CTFO,$BNFM JO "DUJPO 1,2010,35 $MBVT,*CTFO,$BNFM JO "DUJPO 2,2012,35 $MBVT,*CTFO,$BNFM JO "DUJPO 3,2013,35 $MBVT,*CTFO,$BNFM JO "DUJPO 4,2014,35 3FNBSL : UIF SFQFUJUJWF EBUB DPODFSO UIF UJUMF PG UIF CPPL BOE JUT QVCMJDBUJPO EBUF XIJMF GJSTU, MBTU OBNF BOE BHF BSF DPNNPO BOE UIF DMBTTFT VTFE UP NPEFMJOH UIJT. 5IF "VUIPS DMBTT DPOUBJOT B -JTU PG #PPL.
Listing 1. Generate CSV with repetitive data

346

% " 5" '0 3 . " 5 " 1 1 & /% * 9

1BPQOF@QFLKP .KB3L,>KV #F DBSFGVM, UIF POF UP NBOZ PG CJOEZ EPFT OPU BMMPX UP IBOEMF SFQFUJUJPOT EFGJOFE PO TFWFSBM MFWFMT PG UIF IJFSBSDIZ

@CsvRecord(separator=",") public class Author { @DataField(pos = 1) private String firstName; @DataField(pos = 2) private String lastName; @OneToMany private List<Book> books; @DataField(pos = 5) private String Age; ...

public class Book { @DataField(pos = 3) private String title; @DataField(pos = 4) private String year;

7FSZ TJNQMF JTO'U JU !!! @>PB 2 : 1B>AFKD %(7 JBPP>DB @LKQ>FKFKD DOLRM LC Q>DP/HBVP )FSF JT UIF NFTTBHF UIBU XF XPVME MJLF UP QSPDFTT JO PVS NPEFM : "8='*9 4.19=2034=135=049=*/7.(356=#3,3" "1=#&.$)..00111=$).0001-0158=UIJT JT B DBNFM - CJOEZ UFTU" "22=448=#&000124567854=1" "22=548=#&000987654354=2" "22=648=#&000999999954=3" "10=220" UBHT 22, 48 BOE 54 BSF SFQFBUFE BOE UIF DPEF
Listing 1. Reading FIX message containing group of tags/keys
public class Order { @Link Header header;

%"5 " '0 3 . "5 "11&/ %*9

347

@Link Trailer trailer; @KeyValuePairField(tag = 1) // Client reference private String account; @KeyValuePairField(tag = 11) // Order reference private String clOrdId; @KeyValuePairField(tag = 58) // Free text private String text; @OneToMany(mappedTo = "org.apache.camel.dataformat.bindy.model.fix.complex.onetomany.Security") List<Security> securities; ... public class Security { @KeyValuePairField(tag = 22) // Fund ID type (Sedol, ISIN, ...) private String idSource; @KeyValuePairField(tag = 48) // Fund code private String securityCode; @KeyValuePairField(tag = 54) // Movement type ( 1 = Buy, 2 = sell) private String side;

4PFKD QEB )>S> #2+ 5IF OFYU TUFQ DPOTJTUT JO JOTUBOUJBUJOH UIF %BUB'PSNBU bindy DMBTT BTTPDJBUFE XJUI UIJT SFDPSE UZQF BOE QSPWJEJOH +BWB QBDLBHF OBNF(T) BT QBSBNFUFS. 'PS FYBNQMF UIF GPMMPXJOH VTFT UIF DMBTT BindyCsvDataFormat (XIP DPSSFTQPOE UP UIF DMBTT BTTPDJBUFE XJUI UIF $47 SFDPSE UZQF) XIJDI JT DPOGJHVSFE XJUI "DPN.BDNF.NPEFM" QBDLBHF OBNF UP JOJUJBMJ[F UIF NPEFM PCKFDUT DPOGJHVSFE JO UIJT QBDLBHF.
DataFormat bindy = new BindyCsvDataFormat("com.acme.model");

4KJ>OPE>IFKD
from("file://inbox") .unmarshal(bindy) .to("direct:handleOrders");

348

% " 5" '0 3 . " 5 " 1 1 & /% * 9

"MUFSOBUJWFMZ, ZPV DBO VTF B OBNFE SFGFSFODF UP B EBUB GPSNBU XIJDI DBO UIFO CF EFGJOFE JO ZPVS 3FHJTUSZ F.H. ZPVS 4QSJOH 9.- GJMF:
from("file://inbox") .unmarshal("myBindyDataFormat") .to("direct:handleOrders");

5IF $BNFM SPVUF XJMM QJDL-VQ GJMFT JO UIF JOCPY EJSFDUPSZ, VONBSTIBMM $47 SFDPSET JOUP B DPMMFDUJPO PG NPEFM PCKFDUT BOE TFOE UIF DPMMFDUJPO UP UIF SPVUF SFGFSFODFE CZ 'IBOEMF0SEFST'. 5IF DPMMFDUJPO SFUVSOFE JT B +FPQ LC ,>M PCKFDUT. &BDI .BQ XJUIJO UIF MJTU DPOUBJOT UIF NPEFM PCKFDUT UIBU XFSF NBSTIBMMFE PVU PG FBDI MJOF PG UIF $47. 5IF SFBTPO CFIJOE UIJT JT UIBU each line can correspond to more than one object. 5IJT DBO CF DPOGVTJOH XIFO ZPV TJNQMZ FYQFDU POF PCKFDU UP CF SFUVSOFE QFS MJOF. &BDI PCKFDU DBO CF SFUSJFWF VTJOH JUT DMBTT OBNF.
List<Map<String, Object>> unmarshaledModels = (List<Map<String, Object>>) exchange.getIn().getBody(); int modelCount = 0; for (Map<String, Object> model : unmarshaledModels) { for (String className : model.keySet()) { Object obj = model.get(className); LOG.info("Count : " + modelCount + ", " + obj.toString()); } modelCount++; } LOG.info("Total CSV records received by the csv bean : " + modelCount);

"TTVNJOH UIBU ZPV XBOU UP FYUSBDU B TJOHMF 0SEFS PCKFDU GSPN UIJT NBQ GPS QSPDFTTJOH JO B SPVUF, ZPV DPVME VTF B DPNCJOBUJPO PG B 4QMJUUFS BOE B 1SPDFTTPS BT QFS UIF GPMMPXJOH:
from("file://inbox") .unmarshal(bindy) .split(body()) .process(new Processor() { public void process(Exchange exchange) throws Exception { Message in = exchange.getIn(); Map<String, Object> modelMap = (Map<String, Object>) in.getBody(); in.setBody(modelMap.get(Order.class.getCanonicalName())); } }) .to("direct:handleSingleOrder") .end();

%"5 " '0 3 . "5 "11&/ %*9

349

,>OPE>IFKD
5P HFOFSBUF $47 SFDPSET GSPN B DPMMFDUJPO PG NPEFM PCKFDUT, ZPV DSFBUF UIF GPMMPXJOH SPVUF :
from("direct:handleOrders") .marshal(bindy) .to("file://outbox")

4KFQ QBPQ )FSF JT UXP FYBNQMFT TIPXJOH IPX UP NBSTIBMM PS VONBSTIBMM B $47 GJMF XJUI $BNFM
Listing 1. Marshall
package org.apache.camel.dataformat.bindy.csv; import import import import import import import import import import import import import import import import import import import import import java.math.BigDecimal; java.util.ArrayList; java.util.Calendar; java.util.GregorianCalendar; java.util.HashMap; java.util.List; java.util.Map; org.apache.camel.EndpointInject; org.apache.camel.Produce; org.apache.camel.ProducerTemplate; org.apache.camel.builder.RouteBuilder; org.apache.camel.component.mock.MockEndpoint; org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink.Client; org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink.Order; org.apache.camel.spring.javaconfig.SingleRouteCamelConfiguration; org.junit.Test; org.springframework.config.java.annotation.Bean; org.springframework.config.java.annotation.Configuration; org.springframework.config.java.test.JavaConfigContextLoader; org.springframework.test.context.ContextConfiguration; org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = "org.apache.camel.dataformat.bindy.csv.BindyComplexCsvMarshallTest$ContextConfig", loader = JavaConfigContextLoader.class) public class BindyComplexCsvMarshallTest extends AbstractJUnit4SpringContextTests { private List<Map<String, Object>> models = new ArrayList<Map<String, Object>>(); private String result = "10,A1,Julia,Roberts,BE123456789,Belgium Ventage 10/ 12,150,USD,14-01-2009"; @Produce(uri = "direct:start") private ProducerTemplate template; @EndpointInject(uri = "mock:result")

350

% " 5" '0 3 . " 5 " 1 1 & /% * 9

private MockEndpoint resultEndpoint; @Test public void testMarshallMessage() throws Exception { resultEndpoint.expectedBodiesReceived(result); template.sendBody(generateModel()); resultEndpoint.assertIsSatisfied(); } private List<Map<String, Object>> generateModel() { Map<String, Object> model = new HashMap<String, Object>(); Order order = new Order(); order.setOrderNr(10); order.setAmount(new BigDecimal("150")); order.setIsinCode("BE123456789"); order.setInstrumentName("Belgium Ventage 10/12"); order.setCurrency("USD"); Calendar calendar = new GregorianCalendar(); calendar.set(2009, 0, 14); order.setOrderDate(calendar.getTime()); Client client = new Client(); client.setClientNr("A1"); client.setFirstName("Julia"); client.setLastName("Roberts"); order.setClient(client); model.put(order.getClass().getName(), order); model.put(client.getClass().getName(), client); models.add(0, model); return models; } @Configuration public static class ContextConfig extends SingleRouteCamelConfiguration { BindyCsvDataFormat camelDataFormat = new BindyCsvDataFormat("org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink"); @Override @Bean public RouteBuilder route() { return new RouteBuilder() { @Override public void configure() { from("direct:start").marshal(camelDataFormat).to("mock:result"); } };

%"5 " '0 3 . "5 "11&/ %*9

351

} } }

Listing 1. Unmarshall
package org.apache.camel.dataformat.bindy.csv; import import import import import import import import import import org.apache.camel.EndpointInject; org.apache.camel.builder.RouteBuilder; org.apache.camel.component.mock.MockEndpoint; org.apache.camel.spring.javaconfig.SingleRouteCamelConfiguration; org.junit.Test; org.springframework.config.java.annotation.Bean; org.springframework.config.java.annotation.Configuration; org.springframework.config.java.test.JavaConfigContextLoader; org.springframework.test.context.ContextConfiguration; org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = "org.apache.camel.dataformat.bindy.csv.BindyComplexCsvUnmarshallTest$ContextConfig", loader = JavaConfigContextLoader.class) public class BindyComplexCsvUnmarshallTest extends AbstractJUnit4SpringContextTests { @EndpointInject(uri = "mock:result") private MockEndpoint resultEndpoint; @Test public void testUnMarshallMessage() throws Exception { resultEndpoint.expectedMessageCount(1); resultEndpoint.assertIsSatisfied(); } @Configuration public static class ContextConfig extends SingleRouteCamelConfiguration { BindyCsvDataFormat csvBindyDataFormat = new BindyCsvDataFormat("org.apache.camel.dataformat.bindy.model.complex.twoclassesandonelink"); @Override @Bean public RouteBuilder route() { return new RouteBuilder() { @Override public void configure() { from("file://src/test/ data?noop=true").unmarshal(csvBindyDataFormat).to("mock:result"); } }; } } }

352

% " 5" '0 3 . " 5 " 1 1 & /% * 9

*O UIJT FYBNQMF, #JOEZ$TW%BUB'PSNBU DMBTT IBT CFFO JOTUBOUJBUFE JO B USBEJUJPOBM XBZ CVU JU JT BMTP QPTTJCMF UP QSPWJEF JOGPSNBUJPO EJSFDUMZ UP UIF GVODUJPO (VO)NBSTIBM MJLF UIJT XIFSF #JOEZ5ZQF DPSSFTQPOET UP UIF #JOEZ %BUB'PSNBU DMBTT UP JOTUBOUJBUF BOE UIF QBSBNFUFS DPOUBJOT UIF MJTU PG QBDLBHF OBNFT.
public static class ContextConfig extends SingleRouteCamelConfiguration { @Override @Bean public RouteBuilder route() { return new RouteBuilder() { @Override public void configure() { from("direct:start") .marshal().bindy(BindyType.Csv, "org.apache.camel.dataformat.bindy.model.simple.oneclass") .to("mock:result"); } }; } }

4PFKD 2MOFKD 7,+ 5IJT JT SFBMMZ FBTZ UP VTF 4QSJOH BT ZPVS GBWPSJUF %4- MBOHVBHF UP EFDMBSF UIF SPVUFT UP CF VTFE GPS DBNFM-CJOEZ. 5IF GPMMPXJOH FYBNQMF TIPXT UXP SPVUFT XIFSF UIF GJSTU XJMM QJDL-VQ SFDPSET GSPN GJMFT, VONBSTIBM UIF DPOUFOU BOE CJOE JU UP UIFJS NPEFM. 5IF SFTVMU JT UIFO TFOE UP B QPKP (EPJOH OPUIJOH TQFDJBM) BOE QMBDF UIFN JOUP B RVFVF. 5IF TFDPOE SPVUF XJMM FYUSBDU UIF QPKPT GSPN UIF RVFVF BOE NBSTIBM UIF DPOUFOU UP HFOFSBUF B GJMF DPOUBJOJOH UIF DTW SFDPSE
Listing 1. spring dsl
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <bean id="bindyDataformat" class="org.apache.camel.dataformat.bindy.csv.BindyCsvDataFormat"> <constructor-arg value="org.apache.camel.bindy.model" /> </bean> <bean id="csv" class="org.apache.camel.bindy.csv.HandleOrderBean" />

%"5 " '0 3 . "5 "11&/ %*9

353

<!-- Queuing engine - ActiveMq - work locally in mode virtual memory --> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="brokerURL" value="vm://localhost:61616"/> </bean>

<camelContext xmlns="http://camel.apache.org/schema/spring"> <jmxAgent id="agent" disabled="false" /> <route> <from uri="file://src/data/csv/?noop=true" /> <unmarshal ref="bindyDataformat" /> <to uri="bean:csv" /> <to uri="activemq:queue:in" /> </route> <route> <from uri="activemq:queue:in" /> <marshal ref="bindyDataformat" /> <to uri="file://src/data/csv/out/" /> </route> </camelContext> </beans>

#BMBKABK@FBP 5P VTF #JOEZ JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-?FKAV XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-bindy</artifactId> <version>x.x.x</version> </dependency>

7,+2$"41(38 # 3

%.1, 3

5IF 9.-4FDVSJUZ %BUB 'PSNBU GBDJMJUBUFT FODSZQUJPO BOE EFDSZQUJPO PG 9.- QBZMPBET BU UIF %PDVNFOU, &MFNFOU, BOE &MFNFOU $POUFOU MFWFMT (JODMVEJOH TJNVMUBOFPVT NVMUJ-OPEF FODSZQUJPO/ EFDSZQUJPO VTJOH 91BUI). 5IF FODSZQUJPO DBQBCJMJUZ JT CBTFE PO GPSNBUT TVQQPSUFE VTJOH UIF "QBDIF 9.- 4FDVSJUZ (4BOUBVSJP) QSPKFDU. 4ZNNFUSJD FODSZQUJPO/EFDSZQUJPO JT DVSSFOUMZ TVQQPSUFE VTJOH 5SJQMF-%&4 BOE "&4 (128, 192, BOE 256) FODSZQUJPO GPSNBUT. "EEJUJPOBM GPSNBUT DBO CF FBTJMZ BEEFE MBUFS BT

354

% " 5" '0 3 . " 5 " 1 1 & /% * 9

!B @>OBCRI 1MFBTF WFSJGZ UIBU ZPVS NPEFM DMBTTFT JNQMFNFOUT TFSJBMJ[BCMF PUIFSXJTF UIF RVFVF NBOBHFS XJMM SBJTF BO FSSPS OFFEFE. 5IJT DBQBCJMJUZ BMMPXT $BNFM VTFST UP FODSZQU/EFDSZQU QBZMPBET XIJMF CFJOH EJTQBUDIFE PS SFDFJWFE BMPOH B SPVUF. S>FI>?IB >P LC ">JBI 2.9 5IF 9.-4FDVSJUZ %BUB 'PSNBU TVQQPSUT BTZNNFUSJD LFZ FODSZQUJPO. *O UIJT FODSZQUJPO NPEFM B TZNNFUSJD LFZ JT HFOFSBUFE BOE VTFE UP QFSGPSN 9.- DPOUFOU FODSZQUJPO PS EFDSZQUJPO. 5IJT "DPOUFOU FODSZQUJPO LFZ" JT UIFO JUTFMG FODSZQUFE VTJOH BO BTZNNFUSJD FODSZQUJPO BMHPSJUIN UIBU MFWFSBHFT UIF SFDJQJFOU'T QVCMJD LFZ BT UIF "LFZ FODSZQUJPO LFZ". 6TF PG BO BTZNNFUSJD LFZ FODSZQUJPO BMHPSJUIN FOTVSFT UIBU POMZ UIF IPMEFS PG UIF SFDJQJFOU'T QSJWBUF LFZ DBO BDDFTT UIF HFOFSBUFE TZNNFUSJD FODSZQUJPO LFZ. 5IVT, POMZ UIF QSJWBUF LFZ IPMEFS DBO EFDPEF UIF NFTTBHF. 5IF 9.-4FDVSJUZ %BUB 'PSNBU IBOEMFT BMM PG UIF MPHJD SFRVJSFE UP FODSZQU BOE EFDSZQU UIF NFTTBHF DPOUFOU BOE FODSZQUJPO LFZ(T) VTJOH BTZNNFUSJD LFZ FODSZQUJPO. 5IF 9.-4FDVSJUZ %BUB 'PSNBU BMTP IBT JNQSPWFE TVQQPSU GPS OBNFTQBDFT XIFO QSPDFTTJOH UIF 91BUI RVFSJFT UIBU TFMFDU DPOUFOU GPS FODSZQUJPO. " OBNFTQBDF EFGJOJUJPO NBQQJOH DBO CF JODMVEFE BT QBSU PG UIF EBUB GPSNBU DPOGJHVSBUJPO. 5IJT FOBCMFT USVF OBNFTQBDF NBUDIJOH, FWFO JG UIF QSFGJY WBMVFT JO UIF 91BUI RVFSZ BOE UIF UBSHFU YNM EPDVNFOU BSF OPU FRVJWBMFOU TUSJOHT. !>PF@ .MQFLKP .MQFLK #BC>RIQ #BP@OFMQFLK 5IF 91BUI SFGFSFODF UP UIF 9.- &MFNFOU TFMFDUFE GPS FODSZQUJPO/EFDSZQUJPO. *G OP UBH JT TQFDJGJFE, UIF FOUJSF QBZMPBE JT FODSZQUFE/ EFDSZQUFE. " CPPMFBO WBMVF UP TQFDJGZ XIFUIFS UIF 9.&MFNFOU JT UP CF FODSZQUFE PS UIF DPOUFOUT PG UIF 9.- &MFNFOU ` false = &MFNFOU -FWFM ` true = &MFNFOU $POUFOU -FWFM

secureTag

null

secureTagContents

false

%"5 " '0 3 . "5 "11&/ %*9

355

passPhrase

null

" 4USJOH VTFE BT QBTT1ISBTF UP FODSZQU/EFDSZQU DPOUFOU. 5IF QBTT1ISBTF IBT UP CF QSPWJEFE. *G OP QBTT1ISBTF JT TQFDJGJFE, B EFGBVMU QBTT1ISBTF JT VTFE. 5IF QBTT1ISBTF OFFET UP CF QVU UPHFUIFS JO DPOKVODUJPO XJUI UIF BQQSPQSJBUF FODSZQUJPO BMHPSJUIN. 'PS FYBNQMF VTJOH TRIPLEDES UIF QBTT1IBTF DBO CF B "Only another 24 Byte key" 5IF DJQIFS BMHPSJUIN UP CF VTFE GPS FODSZQUJPO/EFDSZQUJPO PG UIF 9.- NFTTBHF DPOUFOU. 5IF BWBJMBCMF DIPJDFT BSF: ` XMLCipher.TRIPLEDES ` XMLCipher.AES_128 ` XMLCipher.AES_192 ` XMLCipher.AES_256 " NBQ PG OBNFTQBDF WBMVFT JOEFYFE CZ QSFGJY. 5IF JOEFY WBMVFT NVTU NBUDI UIF QSFGJYFT VTFE JO UIF secureTag 91BUI RVFSZ.

xmlCipherAlgorithm

TRIPLEDES

namespaces

null

PVJJBQOF@ $K@OVMQFLK .MQFLKP 5IFTF PQUJPOT DBO CF BQQMJFE JO BEEJUJPO UP SFMFWBOU UIF #BTJD PQUJPOT UP VTF BTZNNFUSJD LFZ FODSZQUJPO. .MQFLK #BC>RIQ #BP@OFMQFLK 5IF LFZ BMJBT UP CF VTFE XIFO SFUSJFWJOH UIF SFDJQJFOU'T QVCMJD PS QSJWBUF LFZ GSPN B ,FZ4UPSF XIFO QFSGPSNJOH BTZNNFUSJD LFZ FODSZQUJPO PS EFDSZQUJPO. 5IF DJQIFS BMHPSJUIN UP CF VTFE GPS FODSZQUJPO/EFDSZQUJPO PG UIF BTZNNFUSJD LFZ. 5IF BWBJMBCMF DIPJDFT BSF: ` XMLCipher.RSA_v1dot5 ` XMLCipher.RSA_OAEP $POGJHVSBUJPO PQUJPOT GPS DSFBUJOH BOE MPBEJOH B ,FZ4UPSF JOTUBODF UIBU SFQSFTFOUT UIF TFOEFS'T USVTU4UPSF PS SFDJQJFOU'T LFZ4UPSF.

recipientKeyAlias

null

keyCipherAlgorithm

null

keyOrTrustStoreParameters

null

356

% " 5" '0 3 . " 5 " 1 1 & /% * 9

keyPassword

null

">JBI 2.10.2 / 2.11: 5IF QBTTXPSE UP CF VTFE GPS SFUSJFWJOH UIF QSJWBUF LFZ GSPN UIF ,FZ4UPSF. 5IJT LFZ JT VTFE GPS BTZNNFUSJD EFDSZQUJPO.

,>OPE>I *O PSEFS UP FODSZQU UIF QBZMPBE, UIF marshal QSPDFTTPS OFFET UP CF BQQMJFE PO UIF SPVUF GPMMPXFE CZ UIF secureXML() UBH. 4KJ>OPE>I *O PSEFS UP EFDSZQU UIF QBZMPBE, UIF unmarshal QSPDFTTPS OFFET UP CF BQQMJFE PO UIF SPVUF GPMMPXFE CZ UIF secureXML() UBH. $U>JMIBP (JWFO CFMPX BSF TFWFSBM FYBNQMFT PG IPX NBSTIBMMJOH DPVME CF QFSGPSNFE BU UIF %PDVNFOU, &MFNFOU, BOE $POUFOU MFWFMT.

%RII />VIL>A BK@OVMQFLK/AB@OVMQFLK


from("direct:start") .marshal().secureXML() .unmarshal().secureXML() .to("direct:end");

/>OQF>I />VIL>A "LKQBKQ .KIV BK@OVMQFLK/AB@OVMQFLK


String tagXPATH = "//cheesesites/italy/cheese"; boolean secureTagContent = true; ... from("direct:start") .marshal().secureXML(tagXPATH, secureTagContent) .unmarshal().secureXML(tagXPATH, secureTagContent) .to("direct:end");

%"5 " '0 3 . "5 "11&/ %*9

357

/>OQF>I ,RIQF -LAB />VIL>A "LKQBKQ .KIV BK@OVMQFLK/ AB@OVMQFLK


String tagXPATH = "//cheesesites/*/cheese"; boolean secureTagContent = true; ... from("direct:start") .marshal().secureXML(tagXPATH, secureTagContent) .unmarshal().secureXML(tagXPATH, secureTagContent) .to("direct:end");

/>OQF>I />VIL>A "LKQBKQ .KIV BK@OVMQFLK/AB@OVMQFLK TFQE @ELF@B LC M>PP/EO>PB(M>PPTLOA)


String tagXPATH = "//cheesesites/italy/cheese"; boolean secureTagContent = true; ... String passPhrase = "Just another 24 Byte key"; from("direct:start") .marshal().secureXML(tagXPATH, secureTagContent, passPhrase) .unmarshal().secureXML(tagXPATH, secureTagContent, passPhrase) .to("direct:end");

/>OQF>I />VIL>A "LKQBKQ .KIV BK@OVMQFLK/AB@OVMQFLK TFQE M>PP/EO>PB(M>PPTLOA) >KA IDLOFQEJ


import org.apache.xml.security.encryption.XMLCipher; .... String tagXPATH = "//cheesesites/italy/cheese"; boolean secureTagContent = true; String passPhrase = "Just another 24 Byte key"; String algorithm= XMLCipher.TRIPLEDES; from("direct:start") .marshal().secureXML(tagXPATH, secureTagContent, passPhrase, algorithm) .unmarshal().secureXML(tagXPATH, secureTagContent, passPhrase, algorithm) .to("direct:end");

358

% " 5" '0 3 . " 5 " 1 1 & /% * 9

/>OQF>I />OVIL>A "LKQBKQ TFQE ->JBPM>@B PRMMLOQ


)>S> #2+
final Map<String, String> namespaces = new HashMap<String, String>(); namespaces.put("cust", "http://cheese.xmlsecurity.camel.apache.org/"); final KeyStoreParameters tsParameters = new KeyStoreParameters(); tsParameters.setPassword("password"); tsParameters.setResource("sender.ts"); context.addRoutes(new RouteBuilder() { public void configure() { from("direct:start") .marshal().secureXML("//cust:cheesesites/italy", namespaces, true, "recipient", testCypherAlgorithm, XMLCipher.RSA_v1dot5, tsParameters) .to("mock:encrypted"); } }

2MOFKD 7,+ " OBNFTQBDF QSFGJY UIBU JT EFGJOFE BT QBSU PG UIF camelContext EFGJOJUJPO DBO CF SF-VTFE JO DPOUFYU XJUIJO UIF EBUB GPSNBU secureTag BUUSJCVUF PG UIF secureXML FMFNFOU.
<camelContext id="springXmlSecurityDataFormatTestCamelContext" xmlns="http://camel.apache.org/schema/spring" xmlns:cheese="http://cheese.xmlsecurity.camel.apache.org/"> <route> <from uri="direct://start"/> <marshal> <secureXML secureTag="//cheese:cheesesites/italy" secureTagContents="true"/> </marshal> ...

PVJJBQOF@ *BV $K@OVMQFLK


2MOFKD 7,+ 2BKABO
<!-- trust store configuration --> <camel:keyStoreParameters id="trustStoreParams" resource="./sender.ts"

%"5 " '0 3 . "5 "11&/ %*9

359

password="password"/> <camelContext id="springXmlSecurityDataFormatTestCamelContext" xmlns="http://camel.apache.org/schema/spring" xmlns:cheese="http://cheese.xmlsecurity.camel.apache.org/"> <route> <from uri="direct://start"/> <marshal> <secureXML secureTag="//cheese:cheesesites/italy" secureTagContents="true" xmlCipherAlgorithm="http://www.w3.org/2001/04/ xmlenc#aes128-cbc" keyCipherAlgorithm="http://www.w3.org/2001/04/ xmlenc#rsa-1_5" recipientKeyAlias="recipient" keyOrTrustStoreParametersId="trustStoreParams"/> </marshal> ...

2MOFKD 7,+ 1B@FMFBKQ

<!-- key store configuration --> <camel:keyStoreParameters id="keyStoreParams" resource="./recipient.ks" password="password" /> <camelContext id="springXmlSecurityDataFormatTestCamelContext" xmlns="http://camel.apache.org/schema/spring" xmlns:cheese="http://cheese.xmlsecurity.camel.apache.org/"> <route> <from uri="direct://encrypted"/> <unmarshal> <secureXML secureTag="//cheese:cheesesites/italy" secureTagContents="true" xmlCipherAlgorithm="http://www.w3.org/2001/04/ xmlenc#aes128-cbc" keyCipherAlgorithm="http://www.w3.org/2001/04/ xmlenc#rsa-1_5" recipientKeyAlias="recipient" keyOrTrustStoreParametersId="keyStoreParams" keyPassword="privateKeyPassword" /> </unmarshal> ...

#BMBKABK@FBP 5IJT EBUB GPSNBU JT QSPWJEFE XJUIJO UIF @>JBI-UJIPB@ROFQV DPNQPOFOU. 5IF (;JQ %BUB 'PSNBU JT B NFTTBHF DPNQSFTTJPO BOE EF-DPNQSFTTJPO GPSNBU. *U VTFT UIF TBNF EFGMBUF BMHPSJUIN UIBU JT VTFE JO ;JQ %BUB'PSNBU, BMUIPVHI TPNF BEEJUJPOBM IFBEFST BSF

360

% " 5" '0 3 . " 5 " 1 1 & /% * 9

QSPWJEFE. 5IJT GPSNBU JT QSPEVDFE CZ QPQVMBS gzip/gunzip UPPM. .FTTBHFT NBSTIBMMFE VTJOH (;JQ DPNQSFTTJPO DBO CF VONBSTIBMMFE VTJOH (;JQ EFDPNQSFTTJPO KVTU QSJPS UP CFJOH DPOTVNFE BU UIF FOEQPJOU. 5IF DPNQSFTTJPO DBQBCJMJUZ JT RVJUF VTFGVM XIFO ZPV EFBM XJUI MBSHF 9.- BOE 5FYU CBTFE QBZMPBET PS XIFO ZPV SFBE NFTTBHFT QSFWJPVTMZ DPNSFTTFE VTJOH gzip UPPM. .MQFLKP 5IFSF BSF OP PQUJPOT QSPWJEFE GPS UIJT EBUB GPSNBU. ,>OPE>I *O UIJT FYBNQMF XF NBSTIBM B SFHVMBS UFYU/9.- QBZMPBE UP B DPNQSFTTFE QBZMPBE FNQMPZJOH H[JQ DPNQSFTTJPO GPSNBU BOE TFOE JU BO "DUJWF.2 RVFVF DBMMFE .:@26&6&.
from("direct:start").marshal().gzip().to("activemq:queue:MY_QUEUE");

4KJ>OPE>I *O UIJT FYBNQMF XF VONBSTIBMcB H[JQQFEcQBZMPBE GSPN BO "DUJWF.2 RVFVF DBMMFE .:@26&6&cUP JUT PSJHJOBM GPSNBU,cBOE GPSXBSE JU GPScQSPDFTTJOHcUP UIF UnGZippedMessageProcessor.
from("activemq:queue:MY_QUEUE").unmarshal().gzip().process(new UnGZippedMessageProcessor());

#BMBKABK@FBP 5IJT EBUB GPSNBU JT QSPWJEFE JO @>JBI-@LOB TP OP BEEJUJPOBM EFQFOEFODJFT JT OFFEFE.

" 23.1
S>FI>?IB >P LC ">JBI 2.1 $BTUPS JT B %BUB 'PSNBU XIJDI VTFT UIF $BTUPS 9.- MJCSBSZ UP VONBSTIBM BO 9.- QBZMPBE JOUP +BWB PCKFDUT PS UP NBSTIBM +BWB PCKFDUT JOUP BO 9.- QBZMPBE. "T VTVBMMZ ZPV DBO VTF FJUIFS +BWB %4- PS 4QSJOH 9.- UP XPSL XJUI $BTUPS %BUB 'PSNBU.

%"5 " '0 3 . "5 "11&/ %*9

361

4PFKD QEB )>S> #2+


from("direct:order"). marshal().castor(). to("activemq:queue:order");

'PS FYBNQMF UIF GPMMPXJOH VTFT B OBNFE %BUB'PSNBU PG $BTUPS XIJDI VTFT EFGBVMU $BTUPS EBUB CJOEJOH GFBUVSFT.
CastorDataFormat castor = new CastorDataFormat (); from("activemq:My.Queue"). unmarshal(castor). to("mqseries:Another.Queue");

*G ZPV QSFGFS UP VTF B OBNFE SFGFSFODF UP B EBUB GPSNBU XIJDI DBO UIFO CF EFGJOFE JO ZPVS 3FHJTUSZ TVDI BT WJB ZPVS 4QSJOH 9.- GJMF. F.H.
from("activemq:My.Queue"). unmarshal("mycastorType"). to("mqseries:Another.Queue");

*G ZPV XBOU UP PWFSSJEF EFGBVMU NBQQJOH TDIFNB CZ QSPWJEJOH B NBQQJOH GJMF ZPV DBO TFU JU BT GPMMPXT.
CastorDataFormat castor = new CastorDataFormat (); castor.setMappingFile("mapping.xml");

"MTP JG ZPV XBOU UP IBWF NPSF DPOUSPM PO $BTUPS .BSTIBMMFS BOE 6ONBSTIBMMFS ZPV DBO BDDFTT UIFN BT CFMPX.
castor.getMarshaller(); castor.getUnmarshaller();

4PFKD 2MOFKD 7,+ 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP VTF $BTUPS UP VONBSTIBM VTJOH 4QSJOH DPOGJHVSJOH UIF DBTUPS EBUB UZQF
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <unmarshal> <castor validation="true" /> </unmarshal>

362

% " 5" '0 3 . " 5 " 1 1 & /% * 9

<to uri="mock:result"/> </route> </camelContext>

5IJT FYBNQMF TIPXT IPX UP DPOGJHVSF UIF EBUB UZQF KVTU PODF BOE SFVTF JU PO NVMUJQMF SPVUFT. :PV IBWF UP TFU UIF <DBTUPS> FMFNFOU EJSFDUMZ JO <DBNFM$POUFYU>.
<camelContext> <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <castor id="myCastor"/> </dataFormats> <route> <from uri="direct:start"/> <marshal ref="myCastor"/> <to uri="direct:marshalled"/> </route> <route> <from uri="direct:marshalled"/> <unmarshal ref="myCastor"/> <to uri="mock:result"/> </route> </camelContext>

.MQFLKP $BTUPS TVQQPSUT UIF GPMMPXJOH PQUJPOT .MQFLK FODPEJOH WBMJEBUJPO NBQQJOH'JMF QBDLBHFT DMBTT/BNFT 3VMB 4USJOH #PPMFBO 4USJOH 4USJOH<> 4USJOH<> #BC>RIQ 65'-8 GBMTF OVMM OVMM OVMM #BP@OFMQFLK &ODPEJOH UP VTF XIFO NBSTIBMMJOH BO 0CKFDU UP 9.8IFUIFS WBMJEBUJPO JT UVSOFE PO PS PGG. 1BUI UP B $BTUPS NBQQJOH GJMF UP MPBE GSPN UIF DMBTTQBUI. "EE BEEJUJPOBM QBDLBHFT UP $BTUPS 9NM$POUFYU "EE BEEJUJPOBM DMBTT OBNFT UP $BTUPS 9NM$POUFYU

#BMBKABK@FBP 5P VTF $BTUPS JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-@>PQLO XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).

%"5 " '0 3 . "5 "11&/ %*9

363

/OLQL?RC - /OLQL@LI !RCCBOP

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-castor</artifactId> <version>x.x.x</version> </dependency>

"1SPUPDPM #VGGFST - (PPHMF'T EBUB JOUFSDIBOHF GPSNBU" $BNFM QSPWJEFT B %BUB 'PSNBU UP TFSJBMTF CFUXFFO +BWB BOE UIF 1SPUPDPM #VGGFS QSPUPDPM. 5IF QSPKFDU'T TJUF EFUBJMT XIZ ZPV NBZ XJTI UP DIPPTF UIJT GPSNBU PWFS YNM. 1SPUPDPM #VGGFS JT MBOHVBHF-OFVUSBM BOE QMBUGPSN-OFVUSBM, TP NFTTBHFT QSPEVDFE CZ ZPVS $BNFM SPVUFT NBZ CF DPOTVNFE CZ PUIFS MBOHVBHF JNQMFNFOUBUJPOT. "1* 4JUF 1SPUPCVG *NQMFNFOUBUJPO 1SPUPCVG +BWB 5VUPSJBM

/1.3.!4% .5$15($6
5IJT RVJDL PWFSWJFX PG IPX UP VTF 1SPUPCVG. 'PS NPSF EFUBJM TFF UIF DPNQMFUF UVUPSJBM #BCFKFKD QEB MOLQL CLOJ>Q 5IF GJSTU TUFQ JT UP EFGJOF UIF GPSNBU GPS UIF CPEZ PG ZPVS FYDIBOHF. 5IJT JT EFGJOFE JO B .QSPUP GJMF BT TP:
Listing 1. addressbook.proto
package org.apache.camel.component.protobuf; option java_package = "org.apache.camel.component.protobuf"; option java_outer_classname = "AddressBookProtos"; message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2;

364

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

"WBJMBCMF GSPN $BNFM 2.2

} message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; }

&BKBO>QFKD )>S> @I>PPBP 5IF 1SPUPCVG 4%, QSPWJEFT B DPNQJMFS XIJDI XJMM HFOFSBUF UIF +BWB DMBTTFT GPS UIF GPSNBU XF EFGJOFE JO PVS .QSPUP GJMF. :PV DBO SVO UIF DPNQJMFS GPS BOZ BEEJUJPOBM TVQQPSUFE MBOHVBHFT ZPV SFRVJSF. protoc --java_out=. ./addressbook.proto 5IJT XJMM HFOFSBUF B TJOHMF +BWB DMBTT OBNFE "EESFTT#PPL1SPUPT XIJDI DPOUBJOT JOOFS DMBTTFT GPS 1FSTPO BOE "EESFTT#PPL. #VJMEFST BSF BMTP JNQMFNFOUFE GPS ZPV. 5IF HFOFSBUFE DMBTTFT JNQMFNFOU DPN.HPPHMF.QSPUPCVG..FTTBHF XIJDI JT SFRVJSFE CZ UIF TFSJBMJTBUJPO NFDIBOJTN. 'PS UIJT SFBTPO JU JNQPSUBOU UIBU POMZ UIFTF DMBTTFT BSF VTFE JO UIF CPEZ PG ZPVS FYDIBOHFT. $BNFM XJMM UISPX BO FYDFQUJPO PO SPVUF DSFBUJPO JG ZPV BUUFNQU UP UFMM UIF %BUB 'PSNBU UP VTF B DMBTT UIBU EPFT OPU JNQMFNFOU DPN.HPPHMF.QSPUPCVG..FTTBHF. 6TF UIF HFOFSBUFE CVJMEFST UP USBOTMBUF UIF EBUB GSPN BOZ PG ZPVS FYJTUJOH EPNBJO DMBTTFT.

) 5

#2+

:PV DBO VTF DSFBUF UIF 1SPUPCVG%BUB'PSNBU JOTUBODF BOE QBTT JU UP $BNFM %BUB'PSNBU NBSTIBM BOE VONBSTIB "1* MJLF UIJT.
ProtobufDataFormat format = new ProtobufDataFormat(Person.getDefaultInstance()); from("direct:in").marshal(format); from("direct:back").unmarshal(format).to("mock:reverse");

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

365

0S VTF UIF %4- QSPUPCVG() QBTTJOH UIF VONBSTIBM EFGBVMU JOTUBODF PS EFGBVMU JOTUBODF DMBTT OBNF MJLF UIJT.
// You don't need to specify the default instance for protobuf marshaling from("direct:marshal").marshal().protobuf(); from("direct:unmarshalA").unmarshal(). protobuf("org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person"). to ("mock:reverse");

from("direct:unmarshalB").unmarshal().protobuf(Person.getDefaultInstance()).to("mock:reverse");

2/1(-& #2+
5IF GPMMPXJOH FYBNQMF TIPXT IPX UP VTF $BTUPS UP VONBSTIBM VTJOH 4QSJOH DPOGJHVSJOH UIF QSPUPCVG EBUB UZQF
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <unmarshal> <protobuf instanceClass="org.apache.camel.dataformat.protobuf.generated.AddressBookProtos$Person" /> </unmarshal> <to uri="mock:result"/> </route> </camelContext>

#BMBKABK@FBP 5P VTF 1SPUPCVG JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBIMOLQL?RC XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-protobuf</artifactId> <version>2.2.0</version> </dependency>

366

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

2. / # 3 %.1, 3
S>FI>?IB >P LC ">JBI 2.3 40"1 JT B %BUB 'PSNBU XIJDI VTFT +"9#2 BOE +"9-84 BOOPUBUJPOT UP NBSTIBM BOE VONBSTIBM 40"1 QBZMPBET. *U QSPWJEFT UIF CBTJD GFBUVSFT PG "QBDIF $9' XJUIPVU OFFE GPS UIF $9' 4UBDL. $IBJBKQ->JB2QO>QBDV "O FMFNFOU OBNF TUSBUFHZ JT VTFE GPS UXP QVSQPTFT. 5IF GJSTU JT UP GJOE B YNM FMFNFOU OBNF GPS B HJWFO PCKFDU BOE TPBQ BDUJPO XIFO NBSTIBMJOH UIF PCKFDU JOUP B 40"1 NFTTBHF. 5IF TFDPOE JT UP GJOE BO &YDFQUJPO DMBTT GPS B HJWFO TPBQ GBVMU OBNF. 2QO>QBDV 2/BNF4USBUFHZ 4P>DB 6TFT B GJYFE R/BNF UIBU JT DPOGJHVSFE PO JOTUBOUJBUJPO. &YDFQUJPO MPPLVQ JT OPU TVQQPSUFE 6TFT UIF OBNF BOE OBNFTQBDF GSPN UIF !9.-5ZQF BOOPUBUJPO PG UIF HJWFO UZQF. *G OP OBNFTQBDF JT TFU UIFO QBDLBHF-JOGP JT VTFE. &YDFQUJPO MPPLVQ JT OPU TVQQPSUFE 6TFT JOGPSNBUJPO GSPN B XFCTFSWJDF JOUFSGBDF UP EFUFSNJOF UIF UZQF OBNF BOE UP GJOE UIF FYDFQUJPO DMBTT GPS B 40"1 GBVMU

5ZQF/BNF4USBUFHZ

4FSWJDF*OUFSGBDF4USBUFHZ

*G ZPV IBWF HFOFSBUFE UIF XFC TFSWJDF TUVC DPEF XJUI DYG-DPEFHFO PS B TJNJMBS UPPM UIFO ZPV QSPCBCMZ XJMM XBOU UP VTF UIF 4FSWJDF*OUFSGBDF4USBUFHZ. *O UIF DBTF ZPV IBWF OP BOOPUBUFE TFSWJDF JOUFSGBDF ZPV TIPVME VTF 2/BNF4USBUFHZ PS 5ZQF/BNF4USBUFHZ. 4PFKD QEB )>S> #2+ 5IF GPMMPXJOH FYBNQMF VTFT B OBNFE %BUB'PSNBU PG soap XIJDI JT DPOGJHVSFE XJUI UIF QBDLBHF DPN.FYBNQMF.DVTUPNFSTFSWJDF UP JOJUJBMJ[F UIF +"9#$POUFYU. 5IF TFDPOE QBSBNFUFS JT UIF &MFNFOU/BNF4USBUFHZ. 5IF SPVUF JT BCMF UP NBSTIBM OPSNBM PCKFDUT BT XFMM BT FYDFQUJPOT. (/PUF UIF CFMPX KVTU TFOET B 40"1 &OWFMPQF UP B RVFVF. " XFC TFSWJDF QSPWJEFS XPVME BDUVBMMZ OFFE UP CF MJTUFOJOH UP UIF RVFVF GPS B 40"1 DBMM UP BDUVBMMZ PDDVS, JO XIJDI DBTF JU XPVME CF B POF XBZ 40"1 SFRVFTU. *G ZPV OFFE SFRVFTU SFQMZ UIFO ZPV TIPVME MPPL BU UIF OFYU FYBNQMF.)
SoapJaxbDataFormat soap = new SoapJaxbDataFormat("com.example.customerservice", new ServiceInterfaceStrategy(CustomerService.class)); from("direct:start") .marshal(soap) .to("jms:myQueue");

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

367

2RMMLOQBA 2. / SBOPFLKP 40"1 1.1 JT TVQQPSUFE CZ EFGBVMU. 40"1 1.2 JT TVQQPSUFE GSPN $BNFM 2.11 POXBSET.

->JBPM>@B MOBCFU J>MMFKD 4FF +"9# GPS EFUBJMT IPX ZPV DBO DPOUSPM OBNFTQBDF QSFGJY NBQQJOHT XIFO NBSTIBMMJOH VTJOH 40"1 EBUB GPSNBU.

2BB >IPL "T UIF 40"1 EBUBGPSNBU JOIFSJUT GSPN UIF +"9# EBUBGPSNBU NPTU TFUUJOHT BQQMZ IFSF BT XFMM

4PFKD 2. / 1.2
S>FI>?IB >P LC ">JBI 2.11
SoapJaxbDataFormat soap = new SoapJaxbDataFormat("com.example.customerservice", new ServiceInterfaceStrategy(CustomerService.class)); soap.setVersion("1.2"); from("direct:start") .marshal(soap) .to("jms:myQueue");

8IFO VTJOH 9.- %4- UIFSF JT B WFSTJPO BUUSJCVUF ZPV DBO TFU PO UIF <TPBQ> FMFNFOU.
<!-- Defining a ServiceInterfaceStrategy for retrieving the element name when marshalling --> <bean id="myNameStrategy" class="org.apache.camel.dataformat.soap.name.ServiceInterfaceStrategy"> <constructor-arg value="com.example.customerservice.CustomerService"/> <constructor-arg value="true"/> </bean>

"OE JO UIF $BNFM SPVUF


<route> <from uri="direct:start"/> <marshal> <soap contentPath="com.example.customerservice" version="1.2"

368

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

elementNameStrategyRef="myNameStrategy"/> </marshal> <to uri="jms:myQueue"/> </route>

,RIQF-M>OQ ,BPP>DBP S>FI>?IB >P LC ">JBI 2.8.1 .VMUJ-QBSU 40"1 NFTTBHFT BSF TVQQPSUFE CZ UIF 4FSWJDF*OUFSGBDF4USBUFHZ. 5IF 4FSWJDF*OUFSGBDF4USBUFHZ NVTU CF JOJUJBMJ[FE XJUI B TFSWJDF JOUFSGBDF EFGJOJUJPO UIBU JT BOOPUBUFE JO BDDPSEBODF XJUI +"9-84 2.2 BOE NFFUT UIF SFRVJSFNFOUT PG UIF %PDVNFOU #BSF TUZMF. 5IF UBSHFU NFUIPE NVTU NFFU UIF GPMMPXJOH DSJUFSJB, BT QFS UIF +"9-84 TQFDJGJDBUJPO: 1) JU NVTU IBWF BU NPTU POF in PS in/out OPO-IFBEFS QBSBNFUFS, 2) JG JU IBT B SFUVSO UZQF PUIFS UIBO void JU NVTU IBWF OP in/out PS out OPO-IFBEFS QBSBNFUFST, 3) JG JU JU IBT B SFUVSO UZQF PG void JU NVTU IBWF BU NPTU POF in/out PS out OPO-IFBEFS QBSBNFUFS. 5IF 4FSWJDF*OUFSGBDF4USBUFHZ TIPVME CF JOJUJBMJ[FE XJUI B CPPMFBO QBSBNFUFS UIBU JOEJDBUFT XIFUIFS UIF NBQQJOH TUSBUFHZ BQQMJFT UP UIF SFRVFTU QBSBNFUFST PS SFTQPOTF QBSBNFUFST.
ServiceInterfaceStrategy strat = new ServiceInterfaceStrategy(com.example.customerservice.multipart.MultiPartCustomerService.class, true); SoapJaxbDataFormat soapDataFormat = new SoapJaxbDataFormat("com.example.customerservice.multipart", strat);

,RIQF-M>OQ 1BNRBPQ
5IF QBZMPBE QBSBNFUFST GPS B NVMUJ-QBSU SFRVFTU BSF JOJUJB[MJFE VTJOH B BeanInvocation PCKFDU UIBU SFGMFDUT UIF TJHOBUVSF PG UIF UBSHFU PQFSBUJPO. 5IF DBNFM-TPBQ %BUB'PSNBU NBQT UIF DPOUFOU JO UIF BeanInvocation UP GJFMET JO UIF 40"1 IFBEFS BOE CPEZ JO BDDPSEBODF XJUI UIF +"9-84 NBQQJOH XIFO UIF marshal() QSPDFTTPS JT JOWPLFE.
BeanInvocation beanInvocation = new BeanInvocation(); // Identify the target method beanInvocation.setMethod(MultiPartCustomerService.class.getMethod("getCustomersByName", GetCustomersByName.class, com.example.customerservice.multipart.Product.class)); // Populate the method arguments GetCustomersByName getCustomersByName = new GetCustomersByName(); getCustomersByName.setName("Dr. Multipart"); Product product = new Product(); product.setName("Multiuse Product");

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

369

product.setDescription("Useful for lots of things."); Object[] args = new Object[] {getCustomersByName, product}; // Add the arguments to the bean invocation beanInvocation.setArgs(args); // Set the bean invocation object as the message body exchange.getIn().setBody(beanInvocation);

,RIQF-M>OQ 1BPMLKPB
" NVMUJ-QBSU TPBQ SFTQPOTF NBZ JODMVEF BO FMFNFOU JO UIF TPBQ CPEZ BOE XJMM IBWF POF PS NPSF FMFNFOUT JO UIF TPBQ IFBEFS. 5IF DBNFM-TPBQ %BUB'PSNBU XJMM VONBSTIBMM UIF FMFNFOU JO UIF TPBQ CPEZ (JG JU FYJTUT) BOE QMBDF JU POUP UIF CPEZ PG UIF PVU NFTTBHF JO UIF FYDIBOHF. )FBEFS FMFNFOUT XJMM KLQ CF NBSTIBMFE JOUP UIFJS +"9# NBQQFE PCKFDU UZQFT. *OTUFBE, UIFTF FMFNFOUT BSF QMBDFE JOUP UIF DBNFM PVU NFTTBHF IFBEFS org.apache.camel.dataformat.soap.UNMARSHALLED_HEADER_LIST. 5IF FMFNFOUT XJMM BQQFBS FJUIFS BT FMFNFOU JOTUBODF WBMVFT, PS BT +"9#&MFNFOU WBMVFT, EFQFOEJOH VQPO UIF TFUUJOH GPS UIF ignoreJAXBElement QSPQFSUZ. 5IJT QSPQFSUZ JT JOIFSJUFE GSPN DBNFM-KBYC. :PV DBO BMTP IBWF UIF DBNFM-TPBQ %BUB'PSNBUF JHOPSF IFBEFS DPOUFOU BMM-UPHFUIFS CZ TFUUJOH UIF ignoreUnmarshalledHeaders WBMVF UP true.

'LIABO .?GB@Q J>MMFKD


+"9-84 TQFDJGJFT UIF VTF PG B UZQF-QBSBNFUFSJ[FE javax.xml.ws.Holder PCKFDU GPS In/ Out BOE Out QBSBNFUFST. " Holder PCKFDU NBZ CF VTFE XIFO CVJMEJOH UIF BeanInvocation, PS ZPV NBZ VTF BO JOTUBODF PG UIF QBSBNFUFSJ[FE-UZQF EJSFDUMZ. 5IF DBNFM-TPBQ %BUB'PSNBU NBSTIBMT )PMEFS WBMVFT JO BDDPSEBODF XJUI UIF +"9# NBQQJOH GPS UIF DMBTT PG UIF Holder'T WBMVF. /P NBQQJOH JT QSPWJEFE GPS Holder PCKFDUT JO BO VONBSTIBMMFE SFTQPOTF. $U>JMIBP

6B?PBOSF@B @IFBKQ
5IF GPMMPXJOH SPVUF TVQQPSUT NBSTIBMMJOH UIF SFRVFTU BOE VONBSTIBMMJOH B SFTQPOTF PS GBVMU.

370

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

String WS_URI = "cxf://http://myserver/ customerservice?serviceClass=com.example.customerservice&dataFormat=MESSAGE"; SoapJaxbDataFormat soapDF = new SoapJaxbDataFormat("com.example.customerservice", new ServiceInterfaceStrategy(CustomerService.class)); from("direct:customerServiceClient") .onException(Exception.class) .handled(true) .unmarshal(soapDF) .end() .marshal(soapDF) .to(WS_URI) .unmarshal(soapDF);

5IF CFMPX TOJQQFU DSFBUFT B QSPYZ GPS UIF TFSWJDF JOUFSGBDF BOE NBLFT B 40"1 DBMM UP UIF BCPWF SPVUF.
import org.apache.camel.Endpoint; import org.apache.camel.component.bean.ProxyHelper; ... Endpoint startEndpoint = context.getEndpoint("direct:customerServiceClient"); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // CustomerService below is the service endpoint interface, *not* the javax.xml.ws.Service subclass CustomerService proxy = ProxyHelper.createProxy(startEndpoint, classLoader, CustomerService.class); GetCustomersByNameResponse response = proxy.getCustomersByName(new GetCustomersByName());

6B?PBOSF@B 2BOSBO
6TJOH UIF GPMMPXJOH SPVUF TFUT VQ B XFCTFSWJDF TFSWFS UIBU MJTUFOT PO KNT RVFVF DVTUPNFS4FSWJDF2VFVF BOE QSPDFTTFT SFRVFTUT VTJOH UIF DMBTT $VTUPNFS4FSWJDF*NQM. 5IF DVTUPNFS4FSWJDF*NQM PG DPVSTF TIPVME JNQMFNFOU UIF JOUFSGBDF $VTUPNFS4FSWJDF. *OTUFBE PG EJSFDUMZ JOTUBOUJBUJOH UIF TFSWFS DMBTT JU DPVME CF EFGJOFE JO B TQSJOH DPOUFYU BT B SFHVMBS CFBO.
SoapJaxbDataFormat soapDF = new SoapJaxbDataFormat("com.example.customerservice", new ServiceInterfaceStrategy(CustomerService.class)); CustomerService serverBean = new CustomerServiceImpl(); from("jms://queue:customerServiceQueue") .onException(Exception.class) .handled(true) .marshal(soapDF) .end() .unmarshal(soapDF) .bean(serverBean) .marshal(soapDF);

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

371

#BMBKABK@FBP 5P VTF UIF 40"1 EBUBGPSNBU JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP ZPVS QPN.
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-soap</artifactId> <version>2.3.0</version> </dependency>

"18/3.
S>FI>?IB >P LC ">JBI 2.3 /&/ S>FI>?IB >P LC ">JBI 2.9 5IF $SZQUP %BUB 'PSNBU JOUFHSBUFT UIF +BWB $SZQUPHSBQIJD &YUFOTJPO JOUP $BNFM, BMMPXJOH TJNQMF BOE GMFYJCMF FODSZQUJPO BOE EFDSZQUJPO PG NFTTBHFT VTJOH $BNFM'T GBNJMJBS NBSTIBMM BOE VONBSTIBM GPSNBUUJOH NFDIBOJTN. *U BTTVNFT NBSTIBMMJOH UP NFBO FODSZQUJPO UP DZQIFSUFYU BOE VONBSTIBMMJOH UP NFBO EFDSZQUJPO CBDL UP UIF PSJHJOBM QMBJOUFYU. .MQFLKP
->JB
algorithm algorithmParamterSpec bufferSize cryptoProvider initializationVector inline macAlgorithm shouldAppendHMAC

3VMB
String AlgorithmParameterSpec Integer String byte[] boolean String boolean

#BC>RIQ
DES/CBC/ PKCS5Padding null 2048 null null false null null

#BP@OFMQFLK
5IF +$& BMHPPSJUIN OBNF JOEJDBUJOH UIF DSZQUPHSBQIJD BMHPSJUIN UIBU XJMM CF VTFE. " +$& "MHPSJUIN1BSBNFUFS4QFD VTFE UP JOJUJBMJ[F UIF $JQIFS. UIF TJ[F PG UIF CVGGFS VTFE JO UIF TJHOBUVSF QSPDFTT. 5IF OBNF PG UIF +$& 4FDVSJUZ 1SPWJEFS UIBU TIPVME CF VTFE. " CZUF BSSBZ DPOUBJOJOH UIF *OJUJBMJ[BUJPO 7FDUPS UIBU XJMM CF VTFE UP JOJUJBMJ[F UIF $JQIFS. 'MBH JOEJDBUJOH UIBU UIF DPOGJHVSFE *7 TIPVME CF JOMJOFE JOUP UIF FODSZQUFE EBUB TUSFBN. 5IF +$& BMHPSJUIN OBNF JOEJDBUJOH UIF .FTTBHF "VUIFOUJDBUJPO BMHPSJUIN. 'MBH JOEJDBUJOH UIBU B .FTTBHF "VUIFOUJDBUJPO $PEF TIPVME CF DBMDVMBUFE BOE BQQFOEFE UP UIF FODSZQUFE EBUB.

!>PF@ 4P>DB "U JUT NPTU CBTJD BMM UIBU JT SFRVJSFE UP FODSZQU/EFDSZQU BO FYDIBOHF JT B TIBSFE TFDSFU LFZ. *G POF PS NPSF JOTUBODFT PG UIF $SZQUP EBUB GPSNBU BSF DPOGJHVSFE XJUI UIJT LFZ UIF GPSNBU DBO CF VTFE UP FODSZQU UIF QBZMPBE JO POF SPVUF (PS QBSU PG POF) BOE EFDSZQUFE JO BOPUIFS. 'PS FYBNQMF, VTJOH UIF +BWB %4- BT GPMMPXT:
KeyGenerator generator = KeyGenerator.getInstance("DES");

372

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES", generator.generateKey()); from("direct:basic-encryption") .marshal(cryptoFormat) .to("mock:encrypted") .unmarshal(cryptoFormat) .to("mock:unencrypted");

*O 4QSJOH UIF EBUBGPSNBU JT DPOGJHVSFE GJSTU BOE UIFO VTFE JO SPVUFT


<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <crypto id="basic" algorithm="DES" keyRef="desKey" /> </dataFormats> ... <route> <from uri="direct:basic-encryption" /> <marshal ref="basic" /> <to uri="mock:encrypted" /> <unmarshal ref="basic" /> <to uri="mock:unencrypted" /> </route> </camelContext>

2MB@FCVFKD QEB $K@OVMQFLK

IDLOFQEJ

$IBOHJOH UIF BMHPSJUIN JT B NBUUFS PG TVQQMZJOH UIF +$& BMHPSJUIN OBNF. *G ZPV DIBOHF UIF BMHPSJUIN ZPV XJMM OFFE UP VTF B DPNQBUJCMF LFZ.
KeyGenerator generator = KeyGenerator.getInstance("DES"); CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES", generator.generateKey()); cryptoFormat.setShouldAppendHMAC(true); cryptoFormat.setMacAlgorithm("HmacMD5"); from("direct:hmac-algorithm") .marshal(cryptoFormat) .to("mock:encrypted") .unmarshal(cryptoFormat) .to("mock:unencrypted");

2MB@FCVFKD >K (KFQF>IFW>QFLK 5B@QLO 4PNF DSZQUP BMHPSIJUINT, QBSUJDVMBSMZ CMPDL BMHPSJUINT, SFRVJSF DPOGJHVSBUJPO XJUI BO JOJUJBM CMPDL PG EBUB LOPXO BT BO *OJUJBMJ[BUJPO 7FDUPS. *O UIF +$& UIJT JT QBTTFE BT BO "MHPSJUIN1BSBNFUFS4QFD XIFO UIF $JQIFS JT JOJUJBMJ[FE. 5P VTF TVDI B WFDUPS XJUI UIF $SZQUP%BUB'PSNBU ZPV DBO DPOGJHVSF JU XJUI B CZUF<> DPOUJBOJOH UIF SFRVJSFE EBUB F.H.

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

373

KeyGenerator generator = KeyGenerator.getInstance("DES"); byte[] initializationVector = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES/CBC/PKCS5Padding", generator.generateKey()); cryptoFormat.setInitializationVector(initializationVector); from("direct:init-vector") .marshal(cryptoFormat) .to("mock:encrypted") .unmarshal(cryptoFormat) .to("mock:unencrypted");

PS XJUI TQSJOH, TVQQMJOH B SFGFSFODF UP B CZUF<>


<crypto id="initvector" algorithm="DES/CBC/PKCS5Padding" keyRef="desKey" initVectorRef="initializationVector" />

5IF TBNF WFDUPS JT SFRVJSFE JO CPUI UIF FODSZQUJPO BOE EFDSZQUJPO QIBTFT. "T JU JT OPU OFDFTTBSZ UP LFFQ UIF *7 B TFDSFU, UIF %BUB'PSNBU BMMPXT GPS JU UP CF JOMJOFE JOUP UIF FODSZQUFE EBUB BOE TVCTFRVFOUMZ SFBE PVU JO UIF EFDSZQUJPO QIBTF UP JOJUJBMJ[F UIF $JQIFS. 5P JOMJOF UIF *7 TFU UIF /PJOMJOF GMBH.
KeyGenerator generator = KeyGenerator.getInstance("DES"); byte[] initializationVector = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; SecretKey key = generator.generateKey(); CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES/CBC/PKCS5Padding", key); cryptoFormat.setInitializationVector(initializationVector); cryptoFormat.setShouldInlineInitializationVector(true); CryptoDataFormat decryptFormat = new CryptoDataFormat("DES/CBC/PKCS5Padding", key); decryptFormat.setShouldInlineInitializationVector(true); from("direct:inline") .marshal(cryptoFormat) .to("mock:encrypted") .unmarshal(decryptFormat) .to("mock:unencrypted");

PS XJUI TQSJOH.
<crypto id="inline" algorithm="DES/CBC/PKCS5Padding" keyRef="desKey" initVectorRef="initializationVector" inline="true" /> <crypto id="inline-decrypt" algorithm="DES/CBC/PKCS5Padding" keyRef="desKey" inline="true" />

374

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

'PS NPSF JOGPSNBUJPO PG UIF VTF PG *OJUJBMJ[BUJPO 7FDUPST, DPOTVMU ` IUUQ://FO.XJLJQFEJB.PSH/XJLJ/*OJUJBMJ[BUJPO@WFDUPS ` IUUQ://XXX.IFSPOHZBOH.DPN/$SZQUPHSBQIZ/ ` IUUQ://FO.XJLJQFEJB.PSH/XJLJ/#MPDL@DJQIFS@NPEFT@PG@PQFSBUJPO '>PEBA ,BPP>DB RQEBKQF@>QFLK "LABP (', ")

5P BWPJE BUUBDLT BHBJOTU UIF FODSZQUFE EBUB XIJMF JU JT JO USBOTJU UIF $SZQUP%BUB'PSNBU DBO BMTP DBMDVMBUF B .FTTBHF "VUIFOUJDBUJPO $PEF GPSUIF FODSZQUFE FYDIBOHF DPOUFOUT CBTFE PO B DPOGJHVSBCMF ."$ BMHPSJUIN. 5IF DBMDVMBUFE )."$ JT BQQFOEFE UP UIF TUSFBN BGUFS FODSZQUJPO. *U JT TFQBSBUFE GSPN UIF TUSFBN JO UIF EFDSZQUJPO QIBTF. 5IF ."$ JT SFDBMDVMBUFE BOE WFSJGJFE BHBJOTU UIF USBOTNJUUFE WFSTJPO UP JOTVSF OPUIJOH XBT UBNQFSFE XJUI JO USBOTJU.'PS NPSF JOGPSNBUJPO PO .FTTBHF "VUIFOUJDBUJPO $PEFT TFF IUUQ://FO.XJLJQFEJB.PSH/XJLJ/)."$
KeyGenerator generator = KeyGenerator.getInstance("DES"); CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES", generator.generateKey()); cryptoFormat.setShouldAppendHMAC(true); from("direct:hmac") .marshal(cryptoFormat) .to("mock:encrypted") .unmarshal(cryptoFormat) .to("mock:unencrypted");

PS XJUI TQSJOH.
<crypto id="hmac" algorithm="DES" keyRef="desKey" shouldAppendHMAC="true" />

#Z EFGBVMU UIF )."$ JT DBMDVMBUFE VTJOH UIF )NBD4)"1 NBD BMHPSJUIN UIPVHI UIJT DBO CF FBTJMZ DIBOHFE CZ TVQQMZJOH B EJGGFSFOU BMHPSJUIN OBNF. 4FF <IFSF> GPS IPX UP DIFDL XIBU BMHPSJUINT BSF BWBJMBCMF UISPVHI UIF DPOGJHVSFE TFDVSJUZ QSPWJEFST
KeyGenerator generator = KeyGenerator.getInstance("DES"); CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES", generator.generateKey()); cryptoFormat.setShouldAppendHMAC(true); cryptoFormat.setMacAlgorithm("HmacMD5"); from("direct:hmac-algorithm") .marshal(cryptoFormat) .to("mock:encrypted") .unmarshal(cryptoFormat) .to("mock:unencrypted");

PS XJUI TQSJOH.

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

375

<crypto id="hmac-algorithm" algorithm="DES" keyRef="desKey" macAlgorithm="HmacMD5" shouldAppendHMAC="true" />

2RMMIVFKD *BVP #VK>JF@>IIV 8IFO VTJOH B 3FDJQJFOU MJTU PS TJNJMBS &*1 UIF SFDJQJFOU PG BO FYDIBOHF DBO WBSZ EZOBNJDBMMZ. 6TJOH UIF TBNF LFZ BDSPTT BMM SFDJQJFOUT NBZ OFJUIFS CF GFBTJCMF PS EFTJSBCMF. *U XPVME CF VTFGVM UP CF BCMF UP TQFDJGZ LFZT EZOBNJDBMMZ PO B QFS FYDIBOHF CBTJT. 5IF FYDIBOHF DPVME UIFO CF EZOBNJDBMMZ FOSJDIFE XJUI UIF LFZ PG JUT UBSHFU SFDJQJFOU CFGPSF CFJOH QSPDFTTFE CZ UIF EBUB GPSNBU. 5P GBDJMJUBUF UIJT UIF %BUB'PSNBU BMMPX GPS LFZT UP CF TVQQMJFE EZOBNJDBMMZ WJB UIF NFTTBHF IFBEFST CFMPX ` CryptoDataFormat.KEY "CamelCryptoKey"
CryptoDataFormat cryptoFormat = new CryptoDataFormat("DES", null); /** * Note: the header containing the key should be cleared after * marshalling to stop it from leaking by accident and * potentially being compromised. The processor version below is * arguably better as the key is left in the header when you use * the DSL leaks the fact that camel encryption was used. */ from("direct:key-in-header-encrypt") .marshal(cryptoFormat) .removeHeader(CryptoDataFormat.KEY) .to("mock:encrypted"); from("direct:key-in-header-decrypt").unmarshal(cryptoFormat).process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getIn().getHeaders().remove(CryptoDataFormat.KEY); exchange.getOut().copyFrom(exchange.getIn()); } }).to("mock:unencrypted");

PS XJUI TQSJOH.
<crypto id="nokey" algorithm="DES" />

/&/#>Q>%LOJ>Q .MQFLKP
->JB
keyUserid password keyFileName signatureKeyUserid

3VMB
String String String String

#BC>RIQ
null null null null

#BP@OFMQFLK
5IF VTFSJE PG UIF LFZ JO UIF 1(1 LFZSJOH. 1BTTXPSE VTFE XIFO PQFOJOH UIF QSJWBUF LFZ (OPU VTFE GPS FODSZQUJPO). 'JMFOBNF PG UIF LFZSJOH; NVTU CF BDDFTTJCMF BT B DMBTTQBUI SFTPVSDF (CVU ZPV DBO TQFDJGZ B MPDBUJPO JO UIF GJMF TZTUFN CZ VTJOH UIF "GJMF:" QSFGJY). 2FK@B ">JBI 2.11.0 0QUJPOBM VTFSJE PG UIF LFZ JO UIF 1(1 LFZSJOH UP VTF GPS TJHOJOH (EVSJOH FODSZQUJPO) PS TJHOBUVSF WFSJGJDBUJPO (EVSJOH EFDSZQUJPO) .

376

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

signaturePassword

String

null

2FK@B ">JBI 2.11.0 0QUJPOBM QBTTXPSE VTFE XIFO PQFOJOH UIF QSJWBUF LFZ VTFE GPS TJHOJOH (EVSJOH FODSZQUJPO). 2FK@B ">JBI 2.11.0 0QUJPOBM GJMFOBNF PG UIF LFZSJOH UP VTF GPS TJHOJOH (EVSJOH FODSZQUJPO) PS GPS TJHOBUVSF WFSJGJDBUJPO (EVSJOH EFDSZQUJPO); NVTU CF BDDFTTJCMF BT B DMBTTQBUI SFTPVSDF (CVU ZPV DBO TQFDJGZ B MPDBUJPO JO UIF GJMF TZTUFN CZ VTJOH UIF "GJMF:" QSFGJY). 5IJT PQUJPO XJMM DBVTF 1(1 UP CBTF64 FODPEF UIF FODSZQUFE UFYU, NBLJOH JU BWBJMBCMF GPS DPQZ/QBTUF, FUD. "EET BO JOUFHSJUZ DIFDL/TJHO JOUP UIF FODSZQUJPO GJMF.

signatureKeyFileName armored integrity

String boolean boolean

null false true

/&/#>Q>%LOJ>Q ,BPP>DB 'B>ABOP :PV DBO PWFSSJEF UIF 1(1%BUB'PSNBU PQUJPOT CZ BQQMZJOH CFMPX IFBEFST JOUP NFTTBHF EZOBNJDBMMZ. ->JB 3VMB #BP@OFMQFLK 2FK@B ">JBI 2.11.0 'JMFOBNF PG UIF LFZSJOH; XJMM PWFSSJEF FYJTUJOH TFUUJOH EJSFDUMZ PO UIF 1(1%BUB'PSNBU. 2FK@B ">JBI 2.11.0 5IF VTFSJE PG UIF LFZ JO UIF 1(1 LFZSJOH; XJMM PWFSSJEF FYJTUJOH TFUUJOH EJSFDUMZ PO UIF 1(1%BUB'PSNBU. 2FK@B ">JBI 2.11.0 1BTTXPSE VTFE XIFO PQFOJOH UIF QSJWBUF LFZ; XJMM PWFSSJEF FYJTUJOH TFUUJOH EJSFDUMZ PO UIF 1(1%BUB'PSNBU. 2FK@B ">JBI 2.11.0 'JMFOBNF PG UIF TJHOBUVSF LFZSJOH; XJMM PWFSSJEF FYJTUJOH TFUUJOH EJSFDUMZ PO UIF 1(1%BUB'PSNBU.

CamelPGPDataFormatKeyFileName

String

CamelPGPDataFormatKeyUserid

String

CamelPGPDataFormatKeyPassword

String

CamelPGPDataFormatSignatureKeyFileName

String

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

377

CamelPGPDataFormatSignatureKeyUserid

String

2FK@B ">JBI 2.11.0 5IF VTFSJE PG UIF TJHOBUVSF LFZ JO UIF 1(1 LFZSJOH; XJMM PWFSSJEF FYJTUJOH TFUUJOH EJSFDUMZ PO UIF 1(1%BUB'PSNBU. 2FK@B ">JBI 2.11.0 1BTTXPSE VTFE XIFO PQFOJOH UIF TJHOBUVSF QSJWBUF LFZ; XJMM PWFSSJEF FYJTUJOH TFUUJOH EJSFDUMZ PO UIF 1(1%BUB'PSNBU.

CamelPGPDataFormatSignatureKeyPassword

String

$K@OVMQFKD TFQE /&/#>Q>%LOJ>Q 5IF GPMMPXJOH TBNQMF VTFT UIF QPQVMBS 1(1 GPSNBU GPS FODSZQUJOH/EFDSZQUJOH GJMFT VTJOH UIF #PVODZ $BTUMF +BWB MJCSBSJFT:
// Public Key FileName String keyFileName = getKeyFileName(); // Private Key FileName String keyFileNameSec = getKeyFileNameSec(); // Keyring Userid Used to Encrypt String keyUserid = getKeyUserId(); // Private key password String keyPassword = getKeyPassword(); from("direct:inline") .marshal().pgp(keyFileName, keyUserid) .to("mock:encrypted") .unmarshal().pgp(keyFileNameSec, keyUserid, keyPassword) .to("mock:unencrypted");

5IF GPMMPXJOH TBNQMF QFSGPSNT TJHOJOH + FODSZQUJPO, BOE UIFO TJHOBUVSF WFSJGJDBUJPO + EFDSZQUJPO. *U VTFT UIF TBNF LFZSJOH GPS CPUI TJHOJOH BOE FODSZQUJPO, CVU ZPV DBO PCWJPVTMZ VTF EJGGFSFOU LFZT:
PGPDataFormat pgpSignAndEncrypt = new PGPDataFormat(); pgpSignAndEncrypt.setKeyFileName(keyFileName); pgpSignAndEncrypt.setKeyUserid(keyUserid); pgpSignAndEncrypt.setSignatureKeyFileName(keyFileNameSec); pgpSignAndEncrypt.setSignatureKeyUserid(keyUserid);

378

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

pgpSignAndEncrypt.setSignaturePassword(keyPassword); PGPDataFormat pgpVerifyAndDecrypt = new PGPDataFormat(); pgpVerifyAndDecrypt.setKeyFileName(keyFileNameSec); pgpVerifyAndDecrypt.setKeyUserid(keyUserid); pgpVerifyAndDecrypt.setPassword(keyPassword); pgpVerifyAndDecrypt.setSignatureKeyFileName(keyFileName); pgpVerifyAndDecrypt.setSignatureKeyUserid(keyUserid); from("direct:inline-sign") .marshal(pgpSignAndEncrypt) .to("mock:encrypted") .unmarshal(pgpVerifyAndDecrypt) .to("mock:unencrypted");

0S VTJOH 4QSJOH:
<dataFormats> <!-- will load the file from classpath by default, but you can prefix with file: to load from file system --> <pgp id="encrypt" keyFileName="org/apache/camel/component/crypto/pubring.gpg" keyUserid="sdude@nowhere.net"/> <pgp id="decrypt" keyFileName="org/apache/camel/component/crypto/secring.gpg" keyUserid="sdude@nowhere.net" password="sdude"/> </dataFormats> <route> <from uri="direct:inline"/> <marshal ref="encrypt"/> <to uri="mock:encrypted"/> <unmarshal ref="decrypt"/> <to uri="mock:unencrypted"/> </route>

3L TLOH TFQE QEB MOBSFLRP BU>JMIB VLR KBBA QEB CLIILTFKD


` " QVCMJD LFZSJOH GJMF XIJDI DPOUBJOT UIF QVCMJD LFZT VTFE UP FODSZQU UIF EBUB ` " QSJWBUF LFZSJOH GJMF XIJDI DPOUBJOT UIF LFZT VTFE UP EFDSZQU UIF EBUB ` 5IF LFZSJOH QBTTXPSE

,>K>DFKD VLRO HBVOFKD


5P NBOBHF UIF LFZSJOH, * VTF UIF DPNNBOE MJOF UPPMT, * GJOE UIJT UP CF UIF TJNQMFTU BQQSPBDI JO NBOBHJOH UIF LFZT. 5IFSF BSF BMTP +BWB MJCSBSJFT BWBJMBCMF GSPN IUUQ://XXX.CPVODZDBTUMF.PSH/ KBWB.IUNM JG ZPV XPVME QSFGFS UP EP JU UIBU XBZ. 1. *OTUBMM UIF DPNNBOE MJOF VUJMJUJFT PO MJOVY

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

379

apt-get install gnupg

2. $SFBUF ZPVS LFZSJOH, FOUFSJOH B TFDVSF QBTTXPSE


gpg --gen-key

3. *G ZPV OFFE UP JNQPSU TPNFPOF FMTFT QVCMJD LFZ TP UIBU ZPV DBO FODSZQU B GJMF GPS UIFN.
gpg --import <filename.key

4. 5IF GPMMPXJOH GJMFT TIPVME OPX FYJTU BOE DBO CF VTFE UP SVO UIF FYBNQMF
ls -l ~/.gnupg/pubring.gpg ~/.gnupg/secring.gpg

#BMBKABK@FBP 5P VTF UIF $SZQUP EBUBGPSNBU JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP ZPVS QPN.
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-crypto</artifactId> <version>2.9.0</version> </dependency>

2BB

IPL ` %BUB 'PSNBU ` $SZQUP (%JHJUBM 4JHOBUVSFT) ` IUUQ://XXX.CPVODZDBTUMF.PSH/KBWB.IUNM

282+.& # 3 %.1, 3
S>FI>?IB >P LC ">JBI 2.6 5IF PVPILD EBUBGPSNBU JT VTFE GPS XPSLJOH XJUI 3'$3164 NFTTBHFT. 5IJT DPNQPOFOU TVQQPSUT UIF GPMMPXJOH: 6%1 DPOTVNQUJPO PG TZTMPH NFTTBHFT "HOPTUJD EBUB GPSNBU VTJOH FJUIFS QMBJO 4USJOH PCKFDUT PS 4ZTMPH.FTTBHF NPEFM PCKFDUT. 5ZQF $POWFSUFS GSPN/UP 4ZTMPH.FTTBHF BOE 4USJOH *OUFHSBUJPO XJUI UIF DBNFM-NJOB DPNQPOFOU.

380

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

*OUFHSBUJPO XJUI UIF DBNFM-OFUUZ DPNQPOFOU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-syslog</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

1%"3164 2VPILD MOLQL@LI 4ZTMPH VTFT UIF VTFS EBUBHSBN QSPUPDPM (6%1) <1> BT JUT VOEFSMZJOH USBOTQPSU MBZFS NFDIBOJTN. 5IF 6%1 QPSU UIBU IBT CFFO BTTJHOFE UP TZTMPH JT 514. 5P FYQPTF B 4ZTMPH MJTUFOFS TFSWJDF XF SFVTF UIF FYJTUJOH DBNFM-NJOB DPNQPOFOU PS DBNFMOFUUZ XIFSF XF KVTU VTF UIF Rfc3164SyslogDataFormat UP NBSTIBM BOE VONBSTIBM NFTTBHFT

$UMLPFKD > 2VPILD IFPQBKBO


*O PVS 4QSJOH 9.- GJMF, XF DPOGJHVSF BO FOEQPJOU UP MJTUFO GPS VEQ NFTTBHFT PO QPSU 10514, OPUF UIBU JO OFUUZ XF EJTBCMF UIF EFGBVMU$PEFD, UIJT XJMM BMMPX B GBMMCBDL UP B /FUUZ5ZQF$POWFSUFS BOE EFMJWFST UIF NFTTBHF BT BO *OQVU4USFBN:
<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <syslog id="mySyslog"/> </dataFormats> <route> <from uri="netty:udp://localhost:10514?sync=false&amp;allowDefaultCodec=false"/> <unmarshal ref="mySyslog"/> <to uri="mock:stop1"/> </route> </camelContext>

5IF TBNF SPVUF VTJOH DBNFM-NJOB


<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <syslog id="mySyslog"/> </dataFormats>

13 0 5 0 # 6' - 13 0 5 0 $0 - # 6''&3 4

381

<route> <from uri="mina:udp://localhost:10514"/> <unmarshal ref="mySyslog"/> <to uri="mock:stop1"/> </route> </camelContext>

2BKAFKD PVPILD JBPP>DBP QL > OBJLQB ABPQFK>QFLK


<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring"> <dataFormats> <syslog id="mySyslog"/> </dataFormats> <route> <from uri="direct:syslogMessages"/> <marshal ref="mySyslog"/> <to uri="mina:udp://remotehost:10514"/> </route> </camelContext>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

382

13 0 5 0 #6 ' - 13 05 0$0- # 6 ' ' & 3 4

"' YYYY

/3$1

10

/>QQBOK

MMBKAFU

5IFSF OPX GPMMPXT B CSFBLEPXO PG UIF WBSJPVT &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT UIBU $BNFM TVQQPSUT

,$22 &(-& 2823$,2


,BPP>DB "E>KKBI $BNFM TVQQPSUT UIF .FTTBHF $IBOOFM GSPN UIF &*1 QBUUFSOT. 5IF .FTTBHF $IBOOFM JT BO JOUFSOBM JNQMFNFOUBUJPO EFUBJM PG UIF &OEQPJOU JOUFSGBDF BOE BMM JOUFSBDUJPOT XJUI UIF .FTTBHF $IBOOFM BSF WJB UIF &OEQPJOU JOUFSGBDFT.

'PS NPSF EFUBJMT TFF ` .FTTBHF ` .FTTBHF &OEQPJOU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DB $BNFM TVQQPSUT UIF .FTTBHF GSPN UIF &*1 QBUUFSOT VTJOH UIF .FTTBHF JOUFSGBDF.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

383

5P TVQQPSU WBSJPVT NFTTBHF FYDIBOHF QBUUFSOT MJLF POF XBZ &WFOU .FTTBHF BOE 3FRVFTU 3FQMZ NFTTBHFT $BNFM VTFT BO &YDIBOHF JOUFSGBDF XIJDI IBT B M>QQBOK QSPQFSUZ XIJDI DBO CF TFU UP (K.KIV GPS BO &WFOU .FTTBHF XIJDI IBT B TJOHMF JOCPVOE .FTTBHF, PS (K.RQ GPS B 3FRVFTU 3FQMZ XIFSF UIFSF JT BO JOCPVOE BOE PVUCPVOE NFTTBHF. )FSF JT B CBTJD FYBNQMF PG TFOEJOH B .FTTBHF UP B SPVUF JO (K.KIV BOE (K.RQ NPEFT 1BNRBPQLO "LAB
//InOnly getContext().createProducerTemplate().sendBody("direct:startInOnly", "Hello World"); //InOut String result = (String) getContext().createProducerTemplate().requestBody("direct:startInOut", "Hello World");

1LRQB 4PFKD QEB %IRBKQ !RFIABOP


from("direct:startInOnly").inOnly("bean:process"); from("direct:startInOut").inOut("bean:process");

1LRQB 4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:startInOnly"/> <inOnly uri="bean:process"/> </route> <route> <from uri="direct:startInOut"/> <inOut uri="bean:process"/> </route>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

384

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

/FMBP >KA %FIQBOP $BNFM TVQQPSUT UIF 1JQFT BOE 'JMUFST GSPN UIF &*1 QBUUFSOT JO WBSJPVT XBZT.

8JUI $BNFM ZPV DBO TQMJU ZPVS QSPDFTTJOH BDSPTT NVMUJQMF JOEFQFOEFOU &OEQPJOU JOTUBODFT XIJDI DBO UIFO CF DIBJOFE UPHFUIFS.

4PFKD 1LRQFKD +LDF@


:PV DBO DSFBUF QJQFMJOFT PG MPHJD VTJOH NVMUJQMF &OEQPJOU PS .FTTBHF 5SBOTMBUPS JOTUBODFT BT GPMMPXT
from("direct:a").pipeline("direct:x", "direct:y", "direct:z", "mock:result");

5IPVHI QJQFMJOF JT UIF EFGBVMU NPEF PG PQFSBUJPO XIFO ZPV TQFDJGZ NVMUJQMF PVUQVUT JO $BNFM. 5IF PQQPTJUF UP QJQFMJOF JT NVMUJDBTU; XIJDI GJSFT UIF TBNF NFTTBHF JOUP FBDI PG JUT PVUQVUT. (4FF UIF FYBNQMF CFMPX). *O 4QSJOH 9.- ZPV DBO VTF UIF <QJQFMJOF/> FMFNFOU
<route> <from uri="activemq:SomeQueue"/> <pipeline> <bean ref="foo"/> <bean ref="bar"/> <to uri="activemq:OutputQueue"/> </pipeline> </route>

*O UIF BCPWF UIF QJQFMJOF FMFNFOU JT BDUVBMMZ VOOFDFTTBSZ, ZPV DPVME VTF UIJT...
<route> <from uri="activemq:SomeQueue"/> <bean ref="foo"/> <bean ref="bar"/> <to uri="activemq:OutputQueue"/> </route>

*UT KVTU B CJU NPSF FYQMJDJU. )PXFWFS JG ZPV XJTI UP VTF <NVMUJDBTU/> UP BWPJE B QJQFMJOF - UP TFOE UIF TBNF NFTTBHF JOUP NVMUJQMF QJQFMJOFT - UIFO UIF <QJQFMJOF/> FMFNFOU DPNFT JOUP JUT PXO.
<route> <from uri="activemq:SomeQueue"/>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

385

<multicast> <pipeline> <bean ref="something"/> <to uri="log:Something"/> </pipeline> <pipeline> <bean ref="foo"/> <bean ref="bar"/> <to uri="activemq:OutputQueue"/> </pipeline> </multicast> </route>

*O UIF BCPWF FYBNQMF XF BSF SPVUJOH GSPN B TJOHMF &OEQPJOU UP B MJTU PG EJGGFSFOU FOEQPJOUT TQFDJGJFE VTJOH 63*T. *G ZPV GJOE UIF BCPWF B CJU DPOGVTJOH, USZ SFBEJOH BCPVU UIF "SDIJUFDUVSF PS USZ UIF &YBNQMFT

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DB 1LRQBO 5IF .FTTBHF 3PVUFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP DPOTVNF GSPN BO JOQVU EFTUJOBUJPO, FWBMVBUF TPNF QSFEJDBUF UIFO DIPPTF UIF SJHIU PVUQVU EFTUJOBUJPO.

5IF GPMMPXJOH FYBNQMF TIPXT IPX UP SPVUF B SFRVFTU GSPN BO JOQVU NRBRB:> FOEQPJOU UP FJUIFS NRBRB:?, NRBRB:@ PS NRBRB:A EFQFOEJOH PO UIF FWBMVBUJPO PG WBSJPVT 1SFEJDBUF FYQSFTTJPOT 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .choice() .when(header("foo").isEqualTo("bar"))

386

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

.to("direct:b") .when(header("foo").isEqualTo("cheese")) .to("direct:c") .otherwise() .to("direct:d"); } };

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/> <choice> <when> <xpath>$foo = 'bar'</xpath> <to uri="direct:b"/> </when> <when> <xpath>$foo = 'cheese'</xpath> <to uri="direct:c"/> </when> <otherwise> <to uri="direct:d"/> </otherwise> </choice> </route> </camelContext>

"ELF@B TFQELRQ LQEBOTFPB


*G ZPV VTF B choice XJUIPVU BEEJOH BO otherwise, BOZ VONBUDIFE FYDIBOHFT XJMM CF ESPQQFE CZ EFGBVMU.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DB 3O>KPI>QLO $BNFM TVQQPSUT UIF .FTTBHF 5SBOTMBUPS GSPN UIF &*1 QBUUFSOT CZ VTJOH BO BSCJUSBSZ 1SPDFTTPS JO UIF SPVUJOH MPHJD, CZ VTJOH B CFBO UP QFSGPSN UIF USBOTGPSNBUJPO, PS CZ VTJOH USBOTGPSN() JO

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

387

UIF %4-. :PV DBO BMTP VTF B %BUB 'PSNBU UP NBSTIBM BOE VONBSTIBM NFTTBHFT JO EJGGFSFOU FODPEJOHT.

4PFKD QEB %IRBKQ !RFIABOP :PV DBO USBOTGPSN B NFTTBHF VTJOH $BNFM'T #FBO *OUFHSBUJPO UP DBMM BOZ NFUIPE PO B CFBO JO ZPVS 3FHJTUSZ TVDI BT ZPVS 4QSJOH 9.- DPOGJHVSBUJPO GJMF BT GPMMPXT
from("activemq:SomeQueue"). beanRef("myTransformerBean", "myMethodName"). to("mqseries:AnotherQueue");

8IFSF UIF "NZ5SBOTGPSNFS#FBO" XPVME CF EFGJOFE JO B 4QSJOH 9.- GJMF PS EFGJOFE JO +/%* FUD. :PV DBO PNJU UIF NFUIPE OBNF QBSBNFUFS GSPN CFBO3FG() BOE UIF #FBO *OUFHSBUJPO XJMM USZ UP EFEVDF UIF NFUIPE UP JOWPLF GSPN UIF NFTTBHF FYDIBOHF. PS ZPV DBO BEE ZPVS PXO FYQMJDJU 1SPDFTTPS UP EP UIF USBOTGPSNBUJPO
from("direct:start").process(new Processor() { public void process(Exchange exchange) { Message in = exchange.getIn(); in.setBody(in.getBody(String.class) + " World!"); } }).to("mock:result");

PS ZPV DBO VTF UIF %4- UP FYQMJDJUMZ DPOGJHVSF UIF USBOTGPSNBUJPO


from("direct:start").transform(body().append(" World!")).to("mock:result");

4PB 2MOFKD 7,+ :PV DBO BMTP VTF 4QSJOH 9.- &YUFOTJPOT UP EP B USBOTGPSNBUJPO. #BTJDBMMZ BOZ &YQSFTTJPO MBOHVBHF DBO CF TVCTUJUVUFE JOTJEF UIF USBOTGPSN FMFNFOU BT TIPXO CFMPX
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <transform> <simple>${in.body} extra data!</simple> </transform> <to uri="mock:end"/> </route> </camelContext>

0S ZPV DBO VTF UIF #FBO *OUFHSBUJPO UP JOWPLF B CFBO


388 $) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<route> <from uri="activemq:Input"/> <bean ref="myBeanName" method="doTransform"/> <to uri="activemq:Output"/> </route>

:PV DBO BMTP VTF 5FNQMBUJOH UP DPOTVNF B NFTTBHF GSPN POF EFTUJOBUJPO, USBOTGPSN JU XJUI TPNFUIJOH MJLF 7FMPDJUZ PS 92VFSZ BOE UIFO TFOE JU PO UP BOPUIFS EFTUJOBUJPO. 'PS FYBNQMF VTJOH *O0OMZ (POF XBZ NFTTBHJOH)
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm"). to("activemq:Another.Queue");

*G ZPV XBOU UP VTF *O0VU (SFRVFTU-SFQMZ) TFNBOUJDT UP QSPDFTT SFRVFTUT PO UIF ,V.0RBRB RVFVF PO "DUJWF.2 XJUI B UFNQMBUF HFOFSBUFE SFTQPOTF, UIFO TFOEJOH SFTQPOTFT CBDL UP UIF +.43FQMZ5P %FTUJOBUJPO ZPV DPVME VTF UIJT.
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm");

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. $POUFOU &OSJDIFS 6TJOH HFU*O PS HFU0VU NFUIPET PO &YDIBOHF ,BPP>DB $KAMLFKQ $BNFM TVQQPSUT UIF .FTTBHF &OEQPJOU GSPN UIF &*1 QBUUFSOT VTJOH UIF &OEQPJOU JOUFSGBDF.

8IFO VTJOH UIF %4- UP DSFBUF 3PVUFT ZPV UZQJDBMMZ SFGFS UP .FTTBHF &OEQPJOUT CZ UIFJS 63*T SBUIFS UIBO EJSFDUMZ VTJOH UIF &OEQPJOU JOUFSGBDF. *UT UIFO B SFTQPOTJCJMJUZ PG UIF $BNFM$POUFYU UP DSFBUF BOE BDUJWBUF UIF OFDFTTBSZ &OEQPJOU JOTUBODFT VTJOH UIF BWBJMBCMF $PNQPOFOU JNQMFNFOUBUJPOT. 'PS NPSF EFUBJMT TFF

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

389

` .FTTBHF

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

,$22 &(-& "' --$+2


/LFKQ QL /LFKQ "E>KKBI $BNFM TVQQPSUT UIF 1PJOU UP 1PJOU $IBOOFM GSPN UIF &*1 QBUUFSOT VTJOH UIF GPMMPXJOH DPNQPOFOUT ` 4&%" GPS JO-7. TFEB CBTFE NFTTBHJOH ` +.4 GPS XPSLJOH XJUI +.4 2VFVFT GPS IJHI QFSGPSNBODF, DMVTUFSJOH BOE MPBE CBMBODJOH ` +1" GPS VTJOH B EBUBCBTF BT B TJNQMF NFTTBHF RVFVF ` 9.11 GPS QPJOU-UP-QPJOU DPNNVOJDBUJPO PWFS 9.11 (+BCCFS) ` BOE PUIFST

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. /R?IFPE 2R?P@OF?B "E>KKBI $BNFM TVQQPSUT UIF 1VCMJTI 4VCTDSJCF $IBOOFM GSPN UIF &*1 QBUUFSOT VTJOH GPS FYBNQMF UIF GPMMPXJOH DPNQPOFOUT: ` +.4 GPS XPSLJOH XJUI +.4 5PQJDT GPS IJHI QFSGPSNBODF, DMVTUFSJOH BOE MPBE CBMBODJOH ` 9.11 XIFO VTJOH SPPNT GPS HSPVQ DPNNVOJDBUJPO ` 4&%" GPS XPSLJOH XJUI 4&%" JO UIF TBNF $BNFM$POUFYU XIJDI DBO XPSL JO QVC-TVC, CVU BMMPXJOH NVMUJQMF DPOTVNFST. ` 7. BT 4&%" CVU GPS JOUSB-+7..

390

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4PFKD 1LRQFKD +LDF@


"OPUIFS PQUJPO JT UP FYQMJDJUMZ MJTU UIF QVCMJTI-TVCTDSJCF SFMBUJPOTIJQ JO ZPVS SPVUJOH MPHJD; UIJT LFFQT UIF QSPEVDFS BOE DPOTVNFS EFDPVQMFE CVU MFUT ZPV DPOUSPM UIF GJOF HSBJOFE SPVUJOH DPOGJHVSBUJPO VTJOH UIF %4- PS 9NM $POGJHVSBUJPO. 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .multicast().to("direct:b", "direct:c", "direct:d"); } };

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/> <multicast> <to uri="direct:b"/> <to uri="direct:c"/> <to uri="direct:d"/> </multicast> </route> </camelContext>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

391

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

#$ # +$33$1 "' --$+


$BNFM TVQQPSUT UIF %FBE -FUUFS $IBOOFM GSPN UIF &*1 QBUUFSOT VTJOH UIF %FBE-FUUFS$IBOOFM QSPDFTTPS XIJDI JT BO &SSPS )BOEMFS.

1BABIFSBOV *U JT DPNNPO GPS B UFNQPSBSZ PVUBHF PS EBUBCBTF EFBEMPDL UP DBVTF B NFTTBHF UP GBJM UP QSPDFTT; CVU UIF DIBODFT BSF JG JUT USJFE B GFX NPSF UJNFT XJUI TPNF UJNF EFMBZ UIFO JU XJMM DPNQMFUF GJOF. 4P XF UZQJDBMMZ XJTI UP VTF TPNF LJOE PG SFEFMJWFSZ QPMJDZ UP EFDJEF IPX NBOZ UJNFT UP USZ SFEFMJWFS B NFTTBHF BOE IPX MPOH UP XBJU CFGPSF SFEFMJWFSZ BUUFNQUT. 5IF 3FEFMJWFSZ1PMJDZ EFGJOFT IPX UIF NFTTBHF JT UP CF SFEFMJWFSFE. :PV DBO DVTUPNJ[F UIJOHT MJLF ` IPX NBOZ UJNFT B NFTTBHF JT BUUFNQUFE UP CF SFEFMJWFSFE CFGPSF JU JT DPOTJEFSFE B GBJMVSF BOE TFOU UP UIF EFBE MFUUFS DIBOOFM ` UIF JOJUJBM SFEFMJWFSZ UJNFPVU ` XIFUIFS PS OPU FYQPOFOUJBM CBDLPGG JT VTFE (J.F. UIF UJNF CFUXFFO SFUSJFT JODSFBTFT VTJOH B CBDLPGG NVMUJQMJFS) ` XIFUIFS UP VTF DPMMJTJPO BWPJEBODF UP BEE TPNF SBOEPNOFTT UP UIF UJNJOHT ` EFMBZ QBUUFSO (TFF CFMPX GPS EFUBJMT) ` ">JBI 2.11: XIFUIFS UP BMMPX SFEFMJWFSZ EVSJOH TUPQQJOH/TIVUEPXO 0ODF BMM BUUFNQUT BU SFEFMJWFSJOH UIF NFTTBHF GBJMT UIFO UIF NFTTBHF JT GPSXBSEFE UP UIF EFBE MFUUFS RVFVF. ?LRQ JLSFKD $U@E>KDB QL AB>A IBQQBO NRBRB >KA RPFKD E>KAIBA '>KAIBA PO %FBE -FUUFS $IBOOFM

392

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

#FCCBOBK@B ?BQTBBK #B>A +BQQBO "E>KKBI >KA #BC>RIQ $OOLO '>KAIBO 5IF NBKPS EJGGFSFODF JT UIBU %FBE -FUUFS $IBOOFM IBT B EFBE MFUUFS RVFVF UIBU XIFOFWFS BO &YDIBOHF DPVME OPU CF QSPDFTTFE JT NPWFE UP. *U XJMM >IT>VP NPWF GBJMFE FYDIBOHFT UP UIJT RVFVF.
6OMJLF UIF %FGBVMU &SSPS )BOEMFS UIBU EPFT KLQ IBWF B EFBE MFUUFS RVFVF. 4P XIFOFWFS BO &YDIBOHF DPVME OPU CF QSPDFTTFE UIF FSSPS JT QSPQBHBUFE CBDL UP UIF DMJFOU. -LQF@B: :PV DBO BEKVTU UIJT CFIBWJPS PG XIFUIFS UIF DMJFOU TIPVME CF OPUJGJFE PS OPU XJUI UIF E>KAIBA PQUJPO.

8IFO BMM BUUFNQUT PG SFEFMJWFSZ IBWF GBJMFE UIF &YDIBOHF JT NPWFE UP UIF EFBE MFUUFS RVFVF (UIF EFBE MFUUFS FOEQPJOU). 5IF FYDIBOHF JT UIFO DPNQMFUF BOE GSPN UIF DMJFOU QPJOU PG WJFX JU XBT QSPDFTTFE. "T TVDI UIF %FBE -FUUFS $IBOOFM IBWF IBOEMFE UIF &YDIBOHF. 'PS JOTUBODF DPOGJHVSJOH UIF EFBE MFUUFS DIBOOFM BT: 4PFKD QEB %IRBKQ !RFIABOP
errorHandler(deadLetterChannel("jms:queue:dead") .maximumRedeliveries(3).redeliveryDelay(5000));

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route errorHandlerRef="myDeadLetterErrorHandler"> ... </route> <bean id="myDeadLetterErrorHandler" class="org.apache.camel.builder.DeadLetterChannelBuilder"> <property name="deadLetterUri" value="jms:queue:dead"/> <property name="redeliveryPolicy" ref="myRedeliveryPolicyConfig"/> </bean> <bean id="myRedeliveryPolicyConfig" class="org.apache.camel.processor.RedeliveryPolicy"> <property name="maximumRedeliveries" value="3"/> <property name="redeliveryDelay" value="5000"/> </bean>

5IF %FBE -FUUFS $IBOOFM BCPWF XJMM DMFBS UIF DBVTFE FYDFQUJPO (setException(null)), CZ NPWJOH UIF DBVTFE FYDFQUJPO UP B QSPQFSUZ PO UIF &YDIBOHF, XJUI UIF LFZ Exchange.EXCEPTION_CAUGHT. 5IFO UIF &YDIBOHF JT NPWFE UP UIF "jms:queue:dead" EFTUJOBUJPO BOE UIF DMJFOU XJMM OPU OPUJDF UIF GBJMVSF.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

393

?LRQ JLSFKD $U@E>KDB QL AB>A IBQQBO NRBRB >KA RPFKD QEB LOFDFK>I JBPP>DB 5IF PQUJPO RPB.OFDFK>I,BPP>DB JT VTFE GPS SPVUJOH UIF PSJHJOBM JOQVU NFTTBHF JOTUFBE PG UIF DVSSFOU NFTTBHF UIBU QPUFOUJBMMZ JT NPEJGJFE EVSJOH SPVUJOH. 'PS JOTUBODF JG ZPV IBWF UIJT SPVUF:
from("jms:queue:order:input") .to("bean:validateOrder") .to("bean:transformOrder") .to("bean:handleOrder");

5IF SPVUF MJTUFO GPS +.4 NFTTBHFT BOE WBMJEBUFT, USBOTGPSNT BOE IBOEMF JU. %VSJOH UIJT UIF &YDIBOHF QBZMPBE JT USBOTGPSNFE/NPEJGJFE. 4P JO DBTF TPNFUIJOH HPFT XSPOH BOE XF XBOU UP NPWF UIF NFTTBHF UP BOPUIFS +.4 EFTUJOBUJPO, UIFO XF DBO DPOGJHVSF PVS %FBE -FUUFS $IBOOFM XJUI UIF RPB.OFDFK>I,BPP>DB PQUJPO. #VU XIFO XF NPWF UIF &YDIBOHF UP UIJT EFTUJOBUJPO XF EP OPU LOPX JO XIJDI TUBUF UIF NFTTBHF JT JO. %JE UIF FSSPS IBQQFO JO CFGPSF UIF USBOTGPSN0SEFS PS BGUFS 4P UP CF TVSF XF XBOU UP NPWF UIF PSJHJOBM JOQVU NFTTBHF XF SFDFJWFE GSPN jms:queue:order:input. 4P XF DBO EP UIJT CZ FOBCMJOH UIF RPB.OFDFK>I,BPP>DB PQUJPO BT TIPXO CFMPX:
// will use original body errorHandler(deadLetterChannel("jms:queue:dead") .useOriginalMessage().mamimumRedeliveries(5).redeliverDelay(5000);

5IFO UIF NFTTBHFT SPVUFE UP UIF jms:queue:dead JT UIF PSJHJOBM JOQVU. *G XF XBOU UP NBOVBMMZ SFUSZ XF DBO NPWF UIF +.4 NFTTBHF GSPN UIF GBJMFE UP UIF JOQVU RVFVF, XJUI OP QSPCMFN BT UIF NFTTBHF JT UIF TBNF BT UIF PSJHJOBM XF SFDFJWFE. .K1BABIFSBOV 8IFO %FBE -FUUFS $IBOOFM JT EPJOH SFEFMJWFS JUT QPTTJCMF UP DPOGJHVSF B 1SPDFTTPS UIBU JT FYFDVUFE KVTU ?BCLOB FWFSZ SFEFMJWFSZ BUUFNQU. 5IJT DBO CF VTFE GPS UIF TJUVBUJPOT XIFSF ZPV OFFE UP BMUFS UIF NFTTBHF CFGPSF JUT SFEFMJWFSFE. 4FF CFMPX GPS TBNQMF. 1BABIFSBOV ABC>RIQ S>IRBP 3FEFMJWFSZ JT EJTBCMFE CZ EFGBVMU. 5IF EFGBVMU SFEFMJWFS QPMJDZ XJMM VTF UIF GPMMPXJOH WBMVFT: ` NBYJNVN3FEFMJWFSJFT=0 ` SFEFMJWFS%FMBZ=1000- (1 TFDPOE) ` NBYJNVN3FEFMJWFSZ%FMBZ = 60 * 1000- (60 TFDPOET) ` "OE UIF FYQPOFOUJBM CBDLPGG BOE DPMMJTJPO BWPJEBODF JT UVSOFE PGG. ` 5IF SFUSJFT&YIBVTUFE-PH-FWFM BSF TFU UP -PHHJOH-FWFM.&3303 ` 5IF SFUSZ"UUFNQUFE-PH-FWFM BSF TFU UP -PHHJOH-FWFM.%&#6(

394

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

LK$U@BMQFLK >KA LK1BABIFSBO 8F BMTP TVQQPSU GPS QFS LK$U@BMQFLK UP TFU B LK1BABIFSBO. 5IBU NFBOT ZPV DBO EP TQFDJBM PO SFEFMJWFSZ GPS EJGGFSFOU FYDFQUJPOT, BT PQQPTFE UP PO3FEFMJWFSZ TFU PO %FBE -FUUFS $IBOOFM DBO CF WJFXFE BT B HMPCBM TDPQF. ` 4UBDL USBDFT JT MPHHFE GPS FYIBVTUFE NFTTBHFT GSPN $BNFM 2.2 POXBSET. ` )BOEMFE FYDFQUJPOT JT OPU MPHHFE GSPN $BNFM 2.3 POXBSET 5IF NBYJNVN SFEFMJWFS EFMBZ FOTVSFT UIBU B EFMBZ JT OFWFS MPOHFS UIBO UIF WBMVF, EFGBVMU 1 NJOVUF. 5IJT DBO IBQQFO JG ZPV UVSO PO UIF FYQPOFOUJBM CBDLPGG. 5IF NBYJNVN SFEFMJWFSJFT JT UIF OVNCFS PG OB EFMJWFSZ BUUFNQUT. #Z EFGBVMU $BNFM XJMM USZ UP QSPDFTT UIF FYDIBOHF 1 + 5 UJNFT. 1 UJNF GPS UIF OPSNBM BUUFNQU BOE UIFO 5 BUUFNQUT BT SFEFMJWFSJFT. 4FUUJOH UIF NBYJNVN3FEFMJWFSJFT UP B OFHBUJWF WBMVF TVDI BT -1 XJMM UIFO BMXBZT SFEFMJWFSZ (VOMJNJUFE). 4FUUJOH UIF NBYJNVN3FEFMJWFSJFT UP 0 XJMM EJTBCMF BOZ SF EFMJWFSZ BUUFNQU. $BNFM XJMM MPH EFMJWFSZ GBJMVSFT BU UIF %&#6( MPHHJOH MFWFM CZ EFGBVMU. :PV DBO DIBOHF UIJT CZ TQFDJGZJOH SFUSJFT&YIBVTUFE-PH-FWFM BOE/PS SFUSZ"UUFNQUFE-PH-FWFM. 4FF &YDFQUJPO#VJMEFS8JUI3FUSZ-PHHJOH-FWFM4FU5FTU GPS BO FYBNQMF. :PV DBO UVSO MPHHJOH PG TUBDL USBDFT PO/PGG. *G UVSOFE PGG $BNFM XJMM TUJMM MPH UIF SFEFMJWFSZ BUUFNQU. *UT KVTU NVDI MFTT WFSCPTF.

1BABIFSBO #BI>V />QQBOK


%FMBZ QBUUFSO JT VTFE BT B TJOHMF PQUJPO UP TFU B SBOHF QBUUFSO GPS EFMBZT. *G VTFE UIFO UIF GPMMPXJOH PQUJPOT EPFT OPU BQQMZ: (EFMBZ, CBDL0GG.VMUJQMJFS, VTF&YQPOFOUJBM#BDL0GG, VTF$PMMJTJPO"WPJEBODF, NBYJNVN3FEFMJWFSZ%FMBZ). 5IF JEFB JT UP TFU HSPVQT PG SBOHFT VTJOH UIF GPMMPXJOH TZOUBY: limit:delay;limit 2:delay 2;limit 3:delay 3;...;limit N:delay N &BDI HSPVQ IBT UXP WBMVFT TFQBSBUFE XJUI DPMPO MJNJU = VQQFS MJNJU EFMBZ = EFMBZ JO NJMMJT "OE UIF HSPVQT JT BHBJO TFQBSBUFE XJUI TFNJ DPMPO. 5IF SVMF PG UIVNC JT UIBU UIF OFYU HSPVQT TIPVME IBWF B IJHIFS MJNJU UIBO UIF QSFWJPVT HSPVQ. -FUT DMBSJGZ UIJT XJUI BO FYBNQMF: delayPattern=5:1000;10:5000;20:20000 5IBU HJWFT VT 3 HSPVQT: 5:1000 10:5000

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

395

20:20000 3FTVMUJOH JO UIFTF EFMBZT GPS SFEFMJWFSZ BUUFNQU: 3FEFMJWFSZ BUUFNQU OVNCFS 1..4 = 0 NJMMJT (BT UIF GJSTU HSPVQ TUBSU XJUI 5) 3FEFMJWFSZ BUUFNQU OVNCFS 5..9 = 1000 NJMMJT (UIF GJSTU HSPVQ) 3FEFMJWFSZ BUUFNQU OVNCFS 10..19 = 5000 NJMMJT (UIF TFDPOE HSPVQ) 3FEFMJWFSZ BUUFNQU OVNCFS 20.. = 20000 NJMMJT (UIF MBTU HSPVQ) /PUF: 5IF GJSTU SFEFMJWFSZ BUUFNQU JT 1, TP UIF GJSTU HSPVQ TIPVME TUBSU XJUI 1 PS IJHIFS. :PV DBO TUBSU B HSPVQ XJUI MJNJU 1 UP FH IBWF B TUBSUJOH EFMBZ: delayPattern=1:1000;5:5000 3FEFMJWFSZ BUUFNQU OVNCFS 1..4 = 1000 NJMMJT (UIF GJSTU HSPVQ) 3FEFMJWFSZ BUUFNQU OVNCFS 5.. = 5000 NJMMJT (UIF MBTU HSPVQ) 5IFSF JT OP SFRVJSFNFOU UIBU UIF OFYU EFMBZ TIPVME CF IJHIFS UIBO UIF QSFWJPVT. :PV DBO VTF BOZ EFMBZ WBMVF ZPV MJLF. 'PS FYBNQMF XJUI delayPattern=1:5000;3:1000 XF TUBSU XJUI 5 TFD EFMBZ BOE UIFO MBUFS SFEVDF UIBU UP 1 TFDPOE. 1BABIFSBOV EB>ABO 8IFO B NFTTBHF JT SFEFMJWFSFE UIF %FBE-FUUFS$IBOOFM XJMM BQQFOE B DVTUPNJ[BCMF IFBEFS UP UIF NFTTBHF UP JOEJDBUF IPX NBOZ UJNFT JUT CFFO SFEFMJWFSFE. #FGPSF $BNFM 2.6: 5IF IFBEFS JT ">JBI1BABIFSBOV"LRKQBO, XIJDI JT BMTP EFGJOFE PO UIF Exchange.REDELIVERY_COUNTER. 4UBSUJOH XJUI 2.6: 5IF IFBEFS ">JBI1BABIFSBOV,>U"LRKQBO, XIJDI JT BMTP EFGJOFE PO UIF Exchange.REDELIVERY_MAX_COUNTER, DPOUBJOT UIF NBYJNVN SFEFMJWFSZ TFUUJOH. 5IJT IFBEFS JT BCTFOU JG ZPV VTF retryWhile PS IBWF VOMJNJUFE NBYJNVN SFEFMJWFSZ DPOGJHVSFE. "OE B CPPMFBO GMBH XIFUIFS JU JT CFJOH SFEFMJWFSFE PS OPU (GJSTU BUUFNQU) 5IF IFBEFS ">JBI1BABIFSBOBA DPOUBJOT B CPPMFBO JG UIF NFTTBHF JT SFEFMJWFSFE PS OPU, XIJDI JT BMTP EFGJOFE PO UIF Exchange.REDELIVERED. %ZOBNJDBMMZ DBMDVMBUFE EFMBZ GSPN UIF FYDIBOHF *O $BNFM 2.9 BOE 2.8.2: 5IF IFBEFS JT ">JBI1BABIFSBOV#BI>V, XIJDI JT BMTP EFGJOFE PO UIF Exchange.REDELIVERY_DELAY. *T UIJT IFBEFS JT BCTFOU, OPSNBM SFEFMJWFSZ SVMFT BQQMZ.

6EF@E BKAMLFKQ C>FIBA


S>FI>?IB >P LC ">JBI 2.1 8IFO $BNFM SPVUFT NFTTBHFT JU XJMM EFDPSBUF UIF &YDIBOHF XJUI B QSPQFSUZ UIBU DPOUBJOT UIF I>PQ FOEQPJOU $BNFM TFOE UIF &YDIBOHF UP:
String lastEndpointUri = exchange.getProperty(Exchange.TO_ENDPOINT, String.class);

5IF Exchange.TO_ENDPOINT IBWF UIF DPOTUBOU WBMVF CamelToEndpoint.

396

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

5IJT JOGPSNBUJPO JT VQEBUFE XIFO $BNFM TFOET B NFTTBHF UP BOZ FOEQPJOU. 4P JG JU FYJTUT JUT UIF I>PQ FOEQPJOU XIJDI $BNFM TFOE UIF &YDIBOHF UP. 8IFO GPS FYBNQMF QSPDFTTJOH UIF &YDIBOHF BU B HJWFO &OEQPJOU BOE UIF NFTTBHF JT UP CF NPWFE JOUP UIF EFBE MFUUFS RVFVF, UIFO $BNFM BMTP EFDPSBUFT UIF &YDIBOHF XJUI BOPUIFS QSPQFSUZ UIBU DPOUBJOT UIBU I>PQ FOEQPJOU:
String failedEndpointUri = exchange.getProperty(Exchange.FAILURE_ENDPOINT, String.class);

5IF Exchange.FAILURE_ENDPOINT IBWF UIF DPOTUBOU WBMVF CamelFailureEndpoint. 5IJT BMMPXT GPS FYBNQMF ZPV UP GFUDI UIJT JOGPSNBUJPO JO ZPVS EFBE MFUUFS RVFVF BOE VTF UIBU GPS FSSPS SFQPSUJOH. 5IJT JT VTFBCMF JG UIF $BNFM SPVUF JT B CJU EZOBNJD TVDI BT UIF EZOBNJD 3FDJQJFOU -JTU TP ZPV LOPX XIJDI FOEQPJOUT GBJMFE. -LQF@B: 5IFTF JOGPSNBUJPO JT LFQU PO UIF &YDIBOHF FWFO JG UIF NFTTBHF XBT TVDDFTTGVMMZ QSPDFTTFE CZ B HJWFO FOEQPJOU, BOE UIFO MBUFS GBJMT GPS FYBNQMF JO B MPDBM #FBO QSPDFTTJOH JOTUFBE. 4P CFXBSF UIBU UIJT JT B IJOU UIBU IFMQT QJOQPJOU FSSPST.
from("activemq:queue:foo") .to("http://someserver/somepath") .beanRef("foo");

/PX TVQQPTF UIF SPVUF BCPWF BOE B GBJMVSF IBQQFOT JO UIF foo CFBO. 5IFO UIF Exchange.TO_ENDPOINT BOE Exchange.FAILURE_ENDPOINT XJMM TUJMM DPOUBJO UIF WBMVF PG http://someserver/somepath. 6EF@E OLRQB C>FIBA S>FI>?IB >P LC ">JBI 2.10.4/2.11 8IFO $BNFM FSSPS IBOEMFS IBOEMFT BO FSSPS TVDI BT %FBE -FUUFS $IBOOFM PS VTJOH &YDFQUJPO $MBVTF XJUI IBOEMFE=USVF, UIFO $BNFM XJMM EFDPSBUF UIF &YDIBOHF XJUI UIF SPVUF JE XIFSF UIF FSSPS PDDVSSFE.
String failedRouteId = exchange.getProperty(Exchange.FAILURE_ROUTE_ID, String.class);

5IF Exchange.FAILURE_ROUTE_ID IBWF UIF DPOTUBOU WBMVF CamelFailureRouteId. 5IJT BMMPXT GPS FYBNQMF ZPV UP GFUDI UIJT JOGPSNBUJPO JO ZPVS EFBE MFUUFS RVFVF BOE VTF UIBU GPS FSSPS SFQPSUJOH. "LKQOLI FC OBABIFSBOV FP >IILTBA AROFKD PQLMMFKD/PERQALTK S>FI>?IB >P LC ">JBI 2.11
$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9 397

1SJPS UP $BNFM 2.10, $BNFM XJMM QFSGPSN SFEFMJWFSZ XIJMF TUPQQJOH B SPVUF, PS TIVUUJOH EPXO $BNFM. 5IJT IBT JNQSPWFE B CJU JO $BNFM 2.10 POXBSET, BT $BNFM XJMM OPU QFSGPSN SFEFMJWFSZ BUUFNQUT XIFO TIVUUJOH EPXO BHHSFTTJWFMZ (FH EVSJOH (SBDFGVM 4IVUEPXO BOE UJNFPVU IJU). 'SPN $BNFM 2.11 POXBSET UIFSF JT B OFX PQUJPO allowRedeliveryWhileStopping XIJDI ZPV DBO VTF UP DPOUSPM JG SFEFMJWFSZ JT BMMPXFE PS OPU; OPUJDF UIBU BOZ JO QSPHSFTT SFEFMJWFSZ XJMM TUJMM CF FYFDVUFE. 5IJT PQUJPO DBO POMZ EJTBMMPX BOZ SFEFMJWFSZ UP CF FYFDVUFE >CQBO UIF TUPQQJOH PG B SPVUF/TIVUEPXO PG $BNFM IBT CFFO USJHHFSFE. *G B SFEFMJWFSZ JT EJTTBMMPXFE UIFO B RejectedExcutionException JT TFU PO UIF &YDIBOHF BOE UIF QSPDFTTJOH PG UIF &YDIBOHF TUPQT. 5IJT NFBOT BOZ DPOTVNFS XJMM TFF UIF &YDIBOHF BT GBJMFE EVF UIF RejectedExecutionException. 5IF EFGBVMU WBMVF JT true UP CF CBDLXBSET DPNQBUJCMF BT CFGPSF. 'PS FYBNQMF UIF GPMMPXJOH TBNQMF TIPXT IPX UP EP UIJT XJUI +BWB %4- BOE 9.- %4// this error handler will try up till 20 redelivery attempts with 1 second between. // however if we are stopping then do not allow any redeliver attempts. errorHandler(defaultErrorHandler() .allowRedeliveryWhileStopping(false) .maximumRedeliveries(20).redeliveryDelay(1000).retryAttemptedLogLevel(LoggingLevel.INFO)); from("seda:foo").routeId("foo") .to("mock:foo") .throwException(new IllegalArgumentException("Forced"));

"OE UIF TBNQMF TBNQMF XJUI 9.- %4<!-- notice we use the errorHandlerRef attribute to refer to the error handler to use as default --> <camelContext errorHandlerRef="myErrorHandler" xmlns="http://camel.apache.org/ schema/spring"> <!-- configure error handler, to redeliver up till 10 times, with 1 sec delay and if we are stopping then do not allow redeliveries, to stop faster --> <errorHandler id="myErrorHandler" type="DefaultErrorHandler"> <redeliveryPolicy maximumRedeliveries="20" redeliveryDelay="1000" allowRedeliveryWhileStopping="false" retryAttemptedLogLevel="INFO"/> </errorHandler> <route id="foo"> <from uri="seda:foo"/> <to uri="mock:foo"/> <throwException ref="forced"/> </route> </camelContext>

398

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2>JMIBP 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DPOGJHVSF UIF %FBE -FUUFS $IBOOFM DPOGJHVSBUJPO VTJOH UIF %4RouteBuilder builder = new RouteBuilder() { public void configure() { // using dead letter channel with a seda queue for errors errorHandler(deadLetterChannel("seda:errors")); // here is our route from("seda:a").to("seda:b"); } };

:PV DBO BMTP DPOGJHVSF UIF 3FEFMJWFSZ1PMJDZ BT UIJT FYBNQMF TIPXT


RouteBuilder builder = new RouteBuilder() { public void configure() { // configures dead letter channel to use seda queue for errors and use at most 2 redelveries // and exponential backoff errorHandler(deadLetterChannel("seda:errors").maximumRedeliveries(2).useExponentialBackOff()); // here is our route from("seda:a").to("seda:b"); } };

'LT @>K ( JLAFCV QEB $U@E>KDB ?BCLOB OBABIFSBOV? 8F TVQQPSU EJSFDUMZ JO %FBE -FUUFS $IBOOFM UP TFU B 1SPDFTTPS UIBU JT FYFDVUFE ?BCLOB FBDI SFEFMJWFSZ BUUFNQU. 8IFO %FBE -FUUFS $IBOOFM JT EPJOH SFEFMJWFS JUT QPTTJCMF UP DPOGJHVSF B 1SPDFTTPS UIBU JT FYFDVUFE KVTU ?BCLOB FWFSZ SFEFMJWFSZ BUUFNQU. 5IJT DBO CF VTFE GPS UIF TJUVBUJPOT XIFSF ZPV OFFE UP BMUFS UIF NFTTBHF CFGPSF JUT SFEFMJWFSFE. )FSF XF DPOGJHVSF UIF %FBE -FUUFS $IBOOFM UP VTF PVS QSPDFTTPS MyRedeliveryProcessor UP CF FYFDVUFE CFGPSF FBDI SFEFMJWFSZ.
// we configure our Dead Letter Channel to invoke // MyRedeliveryProcessor before a redelivery is // attempted. This allows us to alter the message before errorHandler(deadLetterChannel("mock:error").maximumRedeliveries(5) .onRedelivery(new MyRedeliverProcessor()) // setting delay to zero is just to make unit testing faster .redeliveryDelay(0L));

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

399

"OE UIJT JT UIF QSPDFTTPS MyRedeliveryProcessor XIFSF XF BMUFS UIF NFTTBHF.


// This is our processor that is executed before every redelivery attempt // here we can do what we want in the java code, such as altering the message public class MyRedeliverProcessor implements Processor { public void process(Exchange exchange) throws Exception { // the message is being redelivered so we can alter it // we just append the redelivery counter to the body // you can of course do all kind of stuff instead String body = exchange.getIn().getBody(String.class); int count = exchange.getIn().getHeader(Exchange.REDELIVERY_COUNTER, Integer.class); exchange.getIn().setBody(body + count); // the maximum redelivery was set to 5 int max = exchange.getIn().getHeader(Exchange.REDELIVERY_MAX_COUNTER, Integer.class); assertEquals(5, max); } }

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. &SSPS )BOEMFS &YDFQUJPO $MBVTF &R>O>KQBBA #BIFSBOV $BNFM TVQQPSUT UIF (VBSBOUFFE %FMJWFSZ GSPN UIF &*1 QBUUFSOT VTJOH BNPOH PUIFST UIF GPMMPXJOH DPNQPOFOUT: ` 'JMF GPS VTJOH GJMF TZTUFNT BT B QFSTJTUFOU TUPSF PG NFTTBHFT ` +.4 XIFO VTJOH QFSTJTUFOU EFMJWFSZ (UIF EFGBVMU) GPS XPSLJOH XJUI +.4 2VFVFT BOE 5PQJDT GPS IJHI QFSGPSNBODF, DMVTUFSJOH BOE MPBE CBMBODJOH ` +1" GPS VTJOH B EBUBCBTF BT B QFSTJTUFODF MBZFS, PS VTF BOZ PG UIF NBOZ PUIFS EBUBCBTF DPNQPOFOU TVDI BT 42-, +%#$, J#"5*4/.Z#BUJT, )JCFSOBUF ` )BXU%# GPS B MJHIUXFJHIU LFZ-WBMVF QFSTJTUFOU TUPSF

400

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DB !RP $BNFM TVQQPSUT UIF .FTTBHF #VT GSPN UIF &*1 QBUUFSOT. :PV DPVME WJFX $BNFM BT B .FTTBHF #VT JUTFMG BT JU BMMPXT QSPEVDFST BOE DPOTVNFST UP CF EFDPVQMFE.

'PMLT PGUFO BTTVNF UIBU B .FTTBHF #VT JT B +.4 UIPVHI TP ZPV NBZ XJTI UP SFGFS UP UIF +.4 DPNQPOFOU GPS USBEJUJPOBM .0. TVQQPSU. "MTP XPSUIZ PG OPUF JT UIF 9.11 DPNQPOFOU GPS TVQQPSUJOH NFTTBHJOH PWFS 9.11 (+BCCFS) 0G DPVSTF UIFSF BSF BMTP &4# QSPEVDUT TVDI BT "QBDIF 4FSWJDF.JY XIJDI TFSWF BT GVMM GMFEHFE NFTTBHF CVTTFT. :PV DBO JOUFSBDU XJUI "QBDIF 4FSWJDF.JY GSPN $BNFM JO NBOZ XBZT, CVU JO QBSUJDVMBS ZPV DBO VTF UIF /.3 PS +#* DPNQPOFOU UP BDDFTT UIF 4FSWJDF.JY NFTTBHF CVT EJSFDUMZ.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

401

,BPP>DB "LKPQOR@QFLK

$5$-3 ,$22 &$


$BNFM TVQQPSUT UIF &WFOU .FTTBHF GSPN UIF &*1 QBUUFSOT CZ TVQQPSUJOH UIF &YDIBOHF 1BUUFSO PO B .FTTBHF XIJDI DBO CF TFU UP (K.KIV UP JOEJDBUF B POFXBZ FWFOU NFTTBHF. $BNFM $PNQPOFOUT UIFO JNQMFNFOU UIJT QBUUFSO VTJOH UIF VOEFSMZJOH USBOTQPSU PS QSPUPDPMT.

5IF EFGBVMU CFIBWJPVS PG NBOZ $PNQPOFOUT JT *O0OMZ TVDI BT GPS +.4, 'JMF PS 4&%" $UMIF@FQIV PMB@FCVFKD (K.KIV *G ZPV BSF VTJOH B DPNQPOFOU XIJDI EFGBVMUT UP *O0VU ZPV DBO PWFSSJEF UIF &YDIBOHF 1BUUFSO GPS BO FOEQPJOU VTJOH UIF QBUUFSO QSPQFSUZ.
foo:bar?exchangePattern=InOnly

'SPN 2.0 POXBSET PO $BNFM ZPV DBO TQFDJGZ UIF &YDIBOHF 1BUUFSO VTJOH UIF ETM. 4PFKD QEB %IRBKQ !RFIABOP
from("mq:someQueue"). inOnly(). bean(Foo.class);

PS ZPV DBO JOWPLF BO FOEQPJOU XJUI BO FYQMJDJU QBUUFSO


from("mq:someQueue"). inOnly("mq:anotherQueue");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP

402

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

1BI>QBA 4FF UIF SFMBUFE 3FRVFTU 3FQMZ NFTTBHF.

<route> <from uri="mq:someQueue"/> <inOnly uri="bean:foo"/> </route>

<route> <from uri="mq:someQueue"/> <inOnly uri="mq:anotherQueue"/> </route>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

1$04$23 1$/+8
$BNFM TVQQPSUT UIF 3FRVFTU 3FQMZ GSPN UIF &*1 QBUUFSOT CZ TVQQPSUJOH UIF &YDIBOHF 1BUUFSO PO B .FTTBHF XIJDI DBO CF TFU UP (K.RQ UP JOEJDBUF B SFRVFTU/SFQMZ. $BNFM $PNQPOFOUT UIFO JNQMFNFOU UIJT QBUUFSO VTJOH UIF VOEFSMZJOH USBOTQPSU PS QSPUPDPMT.

'PS FYBNQMF XIFO VTJOH +.4 XJUI *O0VU UIF DPNQPOFOU XJMM CZ EFGBVMU QFSGPSN UIFTF BDUJPOT ` DSFBUF CZ EFGBVMU B UFNQPSBSZ JOCPVOE RVFVF ` TFU UIF +.43FQMZ5P EFTUJOBUJPO PO UIF SFRVFTU NFTTBHF ` TFU UIF +.4$PSSFMBUJPO*% PO UIF SFRVFTU NFTTBHF ` TFOE UIF SFRVFTU NFTTBHF ` DPOTVNF UIF SFTQPOTF BOE BTTPDJBUF UIF JOCPVOE NFTTBHF UP UIF SFRVFTU VTJOH UIF +.4$PSSFMBUJPO*% (BT ZPV NBZ CF QFSGPSNJOH NBOZ DPODVSSFOU SFRVFTU/SFTQPOTFT).

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

403

1BI>QBA 4FF UIF SFMBUFE &WFOU .FTTBHF NFTTBHF $UMIF@FQIV PMB@FCVFKD (K.RQ 8IFO DPOTVNJOH NFTTBHFT GSPN +.4 B 3FRVFTU-3FQMZ JT JOEJDBUFE CZ UIF QSFTFODF PG UIF ),21BMIV3L IFBEFS. :PV DBO FYQMJDJUMZ GPSDF BO FOEQPJOU UP CF JO 3FRVFTU 3FQMZ NPEF CZ TFUUJOH UIF FYDIBOHF QBUUFSO PO UIF 63*. F.H.
jms:MyQueue?exchangePattern=InOut

:PV DBO TQFDJGZ UIF FYDIBOHF QBUUFSO JO %4- SVMF PS 4QSJOH DPOGJHVSBUJPO.
// Send to an endpoint using InOut from("direct:testInOut").inOut("mock:result"); // Send to an endpoint using InOut from("direct:testInOnly").inOnly("mock:result"); // Set the exchange pattern to InOut, then send it from direct:inOnly to mock:result endpoint from("direct:testSetToInOnlyThenTo") .setExchangePattern(ExchangePattern.InOnly) .to("mock:result"); from("direct:testSetToInOutThenTo") .setExchangePattern(ExchangePattern.InOut) .to("mock:result"); // Or we can pass the pattern as a parameter to the to() method from("direct:testToWithInOnlyParam").to(ExchangePattern.InOnly, "mock:result"); from("direct:testToWithInOutParam").to(ExchangePattern.InOut, "mock:result"); from("direct:testToWithRobustInOnlyParam").to(ExchangePattern.RobustInOnly, "mock:result"); // Set the exchange pattern to InOut, then send it on from("direct:testSetExchangePatternInOnly") .setExchangePattern(ExchangePattern.InOnly).to("mock:result");

<camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- Send the exchange as InOnly --> <route> <from uri="direct:testInOut"/> <inOut uri="mock:result"/> </route> <!-- Send the exchange as InOnly -->

404

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<route> <from uri="direct:testInOnly"/> <inOnly uri="mock:result"/> </route>

<!-- lets set the exchange pattern then send it on --> <route> <from uri="direct:testSetToInOnlyThenTo"/> <setExchangePattern pattern="InOnly"/> <to uri="mock:result"/> </route> <route> <from uri="direct:testSetToInOutThenTo"/> <setExchangePattern pattern="InOut"/> <to uri="mock:result"/> </route> <route> <from uri="direct:testSetExchangePatternInOnly"/> <setExchangePattern pattern="InOnly"/> <to uri="mock:result"/> </route>

<!-- Lets pass the pattern as an argument in the to element --> <route> <from uri="direct:testToWithInOnlyParam"/> <to uri="mock:result" pattern="InOnly"/> </route> <route> <from uri="direct:testToWithInOutParam"/> <to uri="mock:result" pattern="InOut"/> </route> <route> <from uri="direct:testToWithRobustInOnlyParam"/> <to uri="mock:result" pattern="RobustInOnly"/> </route> </camelContext>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. "LOOBI>QFLK (ABKQFCFBO $BNFM TVQQPSUT UIF $PSSFMBUJPO *EFOUJGJFS GSPN UIF &*1 QBUUFSOT CZ HFUUJOH PS TFUUJOH B IFBEFS PO B .FTTBHF.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

405

8IFO XPSLJOH XJUI UIF "DUJWF.2 PS +.4 DPNQPOFOUT UIF DPSSFMBUJPO JEFOUJGJFS IFBEFS JT DBMMFE ),2"LOOBI>QFLK(#. :PV DBO BEE ZPVS PXO DPSSFMBUJPO JEFOUJGJFS UP BOZ NFTTBHF FYDIBOHF UP IFMQ DPSSFMBUF NFTTBHFT UPHFUIFS UP B TJOHMF DPOWFSTBUJPO (PS CVTJOFTT QSPDFTT).

5IF VTF PG B $PSSFMBUJPO *EFOUJGJFS JT LFZ UP XPSLJOH XJUI UIF $BNFM #VTJOFTT "DUJWJUZ .POJUPSJOH 'SBNFXPSL BOE DBO BMTP CF IJHIMZ VTFGVM XIFO UFTUJOH XJUI TJNVMBUJPO PS DBOOFE EBUB TVDI BT XJUI UIF .PDL UFTUJOH GSBNFXPSL 4PNF &*1 QBUUFSOT XJMM TQJO PGG B TVC NFTTBHF, BOE JO UIPTF DBTFT, $BNFM XJMM BEE B DPSSFMBUJPO JE PO UIF &YDIBOHF BT B QSPQFSUZ XJUI UIFZ LFZ Exchange.CORRELATION_ID, XIJDI MJOLT CBDL UP UIF TPVSDF &YDIBOHF. 'PS FYBNQMF UIF 4QMJUUFS, .VMUJDBTU, 3FDJQJFOU -JTU, BOE 8JSF 5BQ &*1 EPFT UIJT.

2BB

IPL
` #".

1$341-

##1$22

$BNFM TVQQPSUT UIF 3FUVSO "EESFTT GSPN UIF &*1 QBUUFSOT CZ VTJOH UIF JMSReplyTo IFBEFS.

'PS FYBNQMF XIFO VTJOH +.4 XJUI *O0VU UIF DPNQPOFOU XJMM CZ EFGBVMU SFUVSO UP UIF BEESFTT HJWFO JO JMSReplyTo. 1BNRBPQLO "LAB

406

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

getMockEndpoint("mock:bar").expectedBodiesReceived("Bye World"); template.sendBodyAndHeader("direct:start", "World", "JMSReplyTo", "queue:bar");

1LRQB 4PFKD QEB %IRBKQ !RFIABOP


from("direct:start").to("activemq:queue:foo?preserveMessageQos=true"); from("activemq:queue:foo").transform(body().prepend("Bye ")); from("activemq:queue:bar?disableReplyTo=true").to("mock:bar");

1LRQB 4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:start"/> <to uri="activemq:queue:foo?preserveMessageQos=true"/> </route> <route> <from uri="activemq:queue:foo"/> <transform> <simple>Bye ${in.body}</simple> </transform> </route> <route> <from uri="activemq:queue:bar?disableReplyTo=true"/> <to uri="mock:bar"/> </route>

'PS B DPNQMFUF FYBNQMF PG UIJT QBUUFSO, TFF UIJT KVOJU UFTU DBTF

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

,$22 &$ 1.43(-&


"LKQBKQ !>PBA 1LRQBO 5IF $POUFOU #BTFE 3PVUFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SPVUF NFTTBHFT UP UIF DPSSFDU EFTUJOBUJPO CBTFE PO UIF DPOUFOUT PG UIF NFTTBHF FYDIBOHFT.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

407

5IF GPMMPXJOH FYBNQMF TIPXT IPX UP SPVUF B SFRVFTU GSPN BO JOQVU PBA>:> FOEQPJOU UP FJUIFS PBA>:?, PBA>:@ PS PBA>:A EFQFOEJOH PO UIF FWBMVBUJPO PG WBSJPVT 1SFEJDBUF FYQSFTTJPOT 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .choice() .when(header("foo").isEqualTo("bar")) .to("direct:b") .when(header("foo").isEqualTo("cheese")) .to("direct:c") .otherwise() .to("direct:d"); } };

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/> <choice> <when> <xpath>$foo = 'bar'</xpath> <to uri="direct:b"/> </when> <when> <xpath>$foo = 'cheese'</xpath> <to uri="direct:c"/> </when> <otherwise> <to uri="direct:d"/> </otherwise> </choice> </route> </camelContext>

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF KVOJU UFTU DBTF

408

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DB %FIQBO 5IF .FTTBHF 'JMUFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP GJMUFS NFTTBHFT

5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DSFBUF B .FTTBHF 'JMUFS SPVUF DPOTVNJOH NFTTBHFT GSPN BO FOEQPJOU DBMMFE NRBRB:>, XIJDI JG UIF 1SFEJDBUF JT USVF XJMM CF EJTQBUDIFE UP NRBRB:? 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .filter(header("foo").isEqualTo("bar")) .to("direct:b"); } };

:PV DBO, PG DPVSTF, VTF NBOZ EJGGFSFOU 1SFEJDBUF MBOHVBHFT TVDI BT 91BUI, 92VFSZ, 42- PS WBSJPVT 4DSJQUJOH -BOHVBHFT. )FSF JT BO 91BUI FYBNQMF
from("direct:start"). filter().xpath("/person[@name='James']"). to("mock:result");

)FSF JT BOPUIFS FYBNQMF PG VTJOH B CFBO UP EFGJOF UIF GJMUFS CFIBWJPS


from("direct:start") .filter().method(MyBean.class, "isGoldCustomer").to("mock:result").end() .to("mock:end"); public static class MyBean { public boolean isGoldCustomer(@Header("level") String level) { return level.equals("gold"); } }

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

409

<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/> <filter> <xpath>$foo = 'bar'</xpath> <to uri="direct:b"/> </filter> </route> </camelContext>

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF KVOJU UFTU DBTF

4PFKD PQLM
S>FI>?IB >P LC ">JBI 2.0 4UPQ JT B CJU EJGGFSFOU UIBO B NFTTBHF GJMUFS BT JU XJMM GJMUFS PVU BMM NFTTBHFT BOE FOE UIF SPVUF FOUJSFMZ (GJMUFS POMZ BQQMJFT UP JUT DIJME QSPDFTTPS). 4UPQ JT DPOWFOJFOU UP VTF JO B $POUFOU #BTFE 3PVUFS XIFO ZPV GPS FYBNQMF OFFE UP TUPQ GVSUIFS QSPDFTTJOH JO POF PG UIF QSFEJDBUFT. *O UIF FYBNQMF CFMPX XF EP OPU XBOU UP SPVUF NFTTBHFT BOZ GVSUIFS UIBU IBT UIF XPSE Bye JO UIF NFTTBHF CPEZ. /PUJDF IPX XF QSFWFOU UIJT JO UIF XIFO QSFEJDBUF CZ VTJOH UIF .stop().
from("direct:start") .choice() .when(body().contains("Hello")).to("mock:hello") .when(body().contains("Bye")).to("mock:bye").stop() .otherwise().to("mock:other") .end() .to("mock:result");

*KLTFKD FC $U@E>KDB T>P CFIQBOBA LO KLQ


S>FI>?IB >P LC ">JBI 2.5 5IF .FTTBHF 'JMUFS &*1 XJMM BEE B QSPQFSUZ PO UIF &YDIBOHF UIBU TUBUFT JG JU XBT GJMUFSFE PS OPU. 5IF QSPQFSUZ IBT UIF LFZ Exchange.FILTER_MATCHED, XIJDI IBT UIF 4USJOH WBMVF PG CamelFilterMatched. *UT WBMVF JT B CPPMFBO JOEJDBUJOH true PS false. *G UIF WBMVF JT true UIFO UIF &YDIBOHF XBT SPVUFE JO UIF GJMUFS CMPDL. 5IJT QSPQFSUZ XJMM CF WJTJCMF XJUIJO UIF .FTTBHF 'JMUFS CMPDL XIP'T 1SFEJDBUF NBUDIFT (WBMVF TFU UP true), BOE UP UIF TUFQT JNNFEJBUFMZ GPMMPXJOH UIF .FTTBHF 'JMUFS XJUI UIF WBMVF TFU CBTFE PO UIF SFTVMUT PG UIF MBTU .FTTBHF 'JMUFS 1SFEJDBUF FWBMVBUFE.

410

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

CFIQBOBA BKAMLFKQ OBNRFOBA FKPFAB </CFIQBO> Q>D NBLF TVSF ZPV QVU UIF FOEQPJOU ZPV XBOU UP GJMUFS (<UP VSJ="TFEB:C"/>, FUD.) CFGPSF UIF DMPTJOH </GJMUFS> UBH PS UIF GJMUFS XJMM OPU CF BQQMJFE (JO 2.8+, PNJUUJOH UIJT XJMM SFTVMU JO BO FSSPS)

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

#8- ,(" 1.43$1


5IF %ZOBNJD 3PVUFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SPVUF NFTTBHFT XIJMF BWPJEJOH UIF EFQFOEFODZ PG UIF SPVUFS PO BMM QPTTJCMF EFTUJOBUJPOT XIJMF NBJOUBJOJOH JUT FGGJDJFODZ.

*O ">JBI 2.5 XF JOUSPEVDFE B dynamicRouter JO UIF %4- XIJDI JT MJLF B EZOBNJD 3PVUJOH 4MJQ XIJDI FWBMVBUFT UIF TMJQ on-the-fly. .MQFLKP
->JB
uriDelimiter ignoreInvalidEndpoints

#BC>RIQ 5>IRB
, false

#BP@OFMQFLK
%FMJNJUFS VTFE JG UIF &YQSFTTJPO SFUVSOFE NVMUJQMF FOEQPJOUT. *G BO FOEQPJOU VSJ DPVME OPU CF SFTPMWFE, TIPVME JU CF JHOPSFE. 0UIFSXJTF $BNFM XJMM UISPXO BO FYDFQUJPO TUBUJOH UIF FOEQPJOU VSJ JT OPU WBMJE.

#VK>JF@ 1LRQBO FK ">JBI 2.5 LKT>OAP 'SPN $BNFM 2.5 UIF %ZOBNJD 3PVUFS XJMM TFU B QSPQFSUZ (&YDIBOHF.4-*1@&/%10*/5) PO UIF &YDIBOHF XIJDI DPOUBJOT UIF DVSSFOU FOEQPJOU BT JU BEWBODFE UIPVHI UIF TMJQ. 5IJT BMMPXT ZPV UP LOPX IPX GBS XF IBWF QSPDFTTFE JO UIF TMJQ. (*U'T B TMJQ CFDBVTF UIF %ZOBNJD 3PVUFS JNQMFNFOUBUJPO JT CBTFE PO UPQ PG 3PVUJOH 4MJQ).
$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9 411

!BT>OB :PV NVTU FOTVSF UIF FYQSFTTJPO VTFE GPS UIF dynamicRouter TVDI BT B CFBO, XJMM SFUVSO null UP JOEJDBUF UIF FOE. 0UIFSXJTF UIF dynamicRouter XJMM LFFQ SFQFBUJOH FOEMFTTMZ.

)>S> #2+
*O +BWB %4- ZPV DBO VTF UIF dynamicRouter BT TIPXO CFMPX:
from("direct:start") // use a bean as the dynamic router .dynamicRouter(method(DynamicRouterTest.class, "slip"));

8IJDI XJMM MFWFSBHF B #FBO UP DPNQVUF UIF TMJQ on-the-fly, XIJDI DPVME CF JNQMFNFOUFE BT GPMMPXT:
/** * Use this method to compute dynamic where we should route next. * * @param body the message body * @return endpoints to go, or <tt>null</tt> to indicate the end */ public String slip(String body) { bodies.add(body); invoked++; if (invoked == 1) { return "mock:a"; } else if (invoked == 2) { return "mock:b,mock:c"; } else if (invoked == 3) { return "direct:foo"; } else if (invoked == 4) { return "mock:result"; } // no more so return null return null; }

.JOE UIBU UIJT FYBNQMF JT POMZ GPS TIPX BOE UFMM. 5IF DVSSFOU JNQMFNFOUBUJPO JT OPU UISFBE TBGF. :PV XPVME IBWF UP TUPSF UIF TUBUF PO UIF &YDIBOHF, UP FOTVSF UISFBE TBGFUZ, BT TIPXO CFMPX:
/** * Use this method to compute dynamic where we should route next. *

412

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

* @param body the message body * @param properties the exchange properties where we can store state between invocations * @return endpoints to go, or <tt>null</tt> to indicate the end */ public String slip(String body, @Properties Map<String, Object> properties) { bodies.add(body); // get the state from the exchange properties and keep track how many times // we have been invoked int invoked = 0; Object current = properties.get("invoked"); if (current != null) { invoked = Integer.valueOf(current.toString()); } invoked++; // and store the state back on the properties properties.put("invoked", invoked); if (invoked == 1) { return "mock:a"; } else if (invoked == 2) { return "mock:b,mock:c"; } else if (invoked == 3) { return "direct:foo"; } else if (invoked == 4) { return "mock:result"; } // no more so return null return null; }

:PV DPVME BMTP TUPSF TUBUF BT NFTTBHF IFBEFST, CVU UIFZ BSF OPU HVBSBOUFFE UP CF QSFTFSWFE EVSJOH SPVUJOH, XIFSF BT QSPQFSUJFT PO UIF &YDIBOHF BSF. "MUIPVHI UIFSF XBT B CVH JO UIF NFUIPE DBMM FYQSFTTJPO, TFF UIF XBSOJOH CFMPX.

2MOFKD 7,+
5IF TBNF FYBNQMF JO 4QSJOH 9.- XPVME CF:
<bean id="mySlip" class="org.apache.camel.processor.DynamicRouterTest"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <dynamicRouter> <!-- use a method call on a bean as dynamic router --> <method ref="mySlip" method="slip"/> </dynamicRouter>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

413

4PFKD ?B>KP QL PQLOB PQ>QB .JOE UIBU JO $BNFM 2.9.2 PS PMEFS, XIFO VTJOH B #FBO UIF TUBUF JT OPU QSPQBHBUFE, TP ZPV XJMM IBWF UP VTF B 1SPDFTTPS JOTUFBE. 5IJT JT GJYFE JO $BNFM 2.9.3 POXBSET.

</route> <route> <from uri="direct:foo"/> <transform><constant>Bye World</constant></transform> <to uri="mock:foo"/> </route> </camelContext>

@#VK>JF@1LRQBO >KKLQ>QFLK
:PV DBO BMTP VTF UIF @DynamicRouter BOOPUBUJPO, GPS FYBNQMF UIF $BNFM 2.4 FYBNQMF CFMPX DPVME CF XSJUUFO BT GPMMPXT. 5IF route NFUIPE XPVME UIFO CF JOWPLFE SFQFBUFEMZ BT UIF NFTTBHF JT QSPDFTTFE EZOBNJDBMMZ. 5IF JEFB JT UP SFUVSO UIF OFYU FOEQPJOU VSJ XIFSF UP HP. 3FUVSO null UP JOEJDBUF UIF FOE. :PV DBO SFUVSO NVMUJQMF FOEQPJOUT JG ZPV MJLF, KVTU BT UIF 3PVUJOH 4MJQ, XIFSF FBDI FOEQPJOU JT TFQBSBUFE CZ B EFMJNJUFS.
public class MyDynamicRouter { @Consume(uri = "activemq:foo") @DynamicRouter public String route(@XPath("/customer/id") String customerId, @Header("Location") String location, Document body) { // query a database to find the best match of the endpoint based on the input parameteres // return the next endpoint uri, where to go. Return null to indicate the end. } }

#VK>JF@ 1LRQBO FK ">JBI 2.4 LO LIABO 5IF TJNQMFTU XBZ UP JNQMFNFOU UIJT JT UP VTF UIF 3FDJQJFOU-JTU "OOPUBUJPO PO B #FBO NFUIPE UP EFUFSNJOF XIFSF UP SPVUF UIF NFTTBHF.
public class MyDynamicRouter { @Consume(uri = "activemq:foo")

414

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

@RecipientList public List<String> route(@XPath("/customer/id") String customerId, @Header("Location") String location, Document body) { // query a database to find the best match of the endpoint based on the input parameteres ... } }

*O UIF BCPWF XF DBO VTF UIF 1BSBNFUFS #JOEJOH "OOPUBUJPOT UP CJOE EJGGFSFOU QBSUT PG UIF .FTTBHF UP NFUIPE QBSBNFUFST PS VTF BO &YQSFTTJPO TVDI BT VTJOH 91BUI PS 92VFSZ. 5IF NFUIPE DBO CF JOWPLFE JO B OVNCFS PG XBZT BT EFTDSJCFE JO UIF #FBO *OUFHSBUJPO TVDI BT ` 10+0 1SPEVDJOH ` 4QSJOH 3FNPUJOH ` #FBO DPNQPOFOU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 1B@FMFBKQ +FPQ 5IF 3FDJQJFOU -JTU GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SPVUF NFTTBHFT UP B OVNCFS PG EZOBNJDBMMZ TQFDJGJFE SFDJQJFOUT.

5IF SFDJQJFOUT XJMM SFDFJWF B DPQZ PG UIF P>JB &YDIBOHF, BOE $BNFM XJMM FYFDVUF UIFN TFRVFOUJBMMZ. .MQFLKP
->JB
delimiter

#BC>RIQ 5>IRB
,

#BP@OFMQFLK
%FMJNJUFS VTFE JG UIF &YQSFTTJPO SFUVSOFE NVMUJQMF FOEQPJOUT.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

415

strategyRef

"O "HHSFHBUJPO4USBUFHZ UIBU XJMM BTTFNCMF UIF SFQMJFT GSPN SFDJQJFOUT JOUP B TJOHMF PVUHPJOH NFTTBHF GSPN UIF 3FDJQJFOU -JTU. #Z EFGBVMU $BNFM XJMM VTF UIF MBTU SFQMZ BT UIF PVUHPJOH NFTTBHF. ">JBI 2.2: *G FOBCMFE, NFTTBHFT BSF TFOU UP UIF SFDJQJFOUT DPODVSSFOUMZ. /PUF UIBU UIF DBMMJOH UISFBE XJMM TUJMM XBJU VOUJM BMM NFTTBHFT IBWF CFFO GVMMZ QSPDFTTFE CFGPSF JU DPOUJOVFT; JU'T UIF TFOEJOH BOE QSPDFTTJOH PG SFQMJFT GSPN SFDJQJFOUT XIJDI IBQQFOT JO QBSBMMFM. ">JBI 2.2: " DVTUPN 5ISFBE 1PPM UP VTF GPS QBSBMMFM QSPDFTTJOH. /PUF UIBU FOBCMJOH UIJT PQUJPO JNQMJFT QBSBMMFM QSPDFTTJOH, TP ZPV OFFE OPU FOBCMF UIBU PQUJPO BT XFMM. ">JBI 2.2: 8IFUIFS UP JNNFEJBUFMZ TUPQ QSPDFTTJOH XIFO BO FYDFQUJPO PDDVST. *G EJTBCMFE, $BNFM XJMM TFOE UIF NFTTBHF UP BMM SFDJQJFOUT SFHBSEMFTT PG BOZ JOEJWJEVBM GBJMVSFT. :PV DBO QSPDFTT FYDFQUJPOT JO BO "HHSFHBUJPO4USBUFHZ JNQMFNFOUBUJPO, XIJDI TVQQPSUT GVMM DPOUSPM PG FSSPS IBOEMJOH. ">JBI 2.3: 8IFUIFS UP JHOPSF BO FOEQPJOU 63* UIBU DPVME OPU CF SFTPMWFE. *G EJTBCMFE, $BNFM XJMM UISPX BO FYDFQUJPO JEFOUJGZJOH UIF JOWBMJE FOEQPJOU 63*. ">JBI 2.5: *G FOBCMFE, $BNFM XJMM QSPDFTT SFQMJFT PVU-PG-PSEFS - UIBU JT, JO UIF PSEFS SFDFJWFE JO SFQMZ GSPN FBDI SFDJQJFOU. *G EJTBCMFE, $BNFM XJMM QSPDFTT SFQMJFT JO UIF TBNF PSEFS BT TQFDJGJFE CZ UIF &YQSFTTJPO. ">JBI 2.5: 4QFDJGJFT B QSPDFTTJOH UJNFPVU NJMMJTFDPOET. *G UIF 3FDJQJFOU -JTU IBTO'U CFFO BCMF UP TFOE BOE QSPDFTT BMM SFQMJFT XJUIJO UIJT UJNFGSBNF, UIFO UIF UJNFPVU USJHHFST BOE UIF 3FDJQJFOU -JTU CSFBLT PVU, XJUI NFTTBHF GMPX DPOUJOVJOH UP UIF OFYU FMFNFOU. /PUF UIBU JG ZPV QSPWJEF B 5JNFPVU"XBSF"HHSFHBUJPO4USBUFHZ, JUT timeout NFUIPE JT JOWPLFE CFGPSF CSFBLJOH PVU. !BT>OB: *G UIF UJNFPVU JT SFBDIFE XJUI SVOOJOH UBTLT TUJMM SFNBJOJOH, DFSUBJO UBTLT GPS XIJDI JU JT EJGGJDVMU GPS $BNFM UP TIVU EPXO JO B HSBDFGVM NBOOFS NBZ DPOUJOVF UP SVO. 4P VTF UIJT PQUJPO XJUI B CJU PG DBSF. 8F NBZ CF BCMF UP JNQSPWF UIJT GVODUJPOBMJUZ JO GVUVSF $BNFM SFMFBTFT. ">JBI 2.8: " DVTUPN 1SPDFTTPS UP QSFQBSF UIF DPQZ PG UIF &YDIBOHF FBDI SFDJQJFOU XJMM SFDFJWF. 5IJT BMMPXT ZPV UP QFSGPSN BSCJUSBSZ USBOTGPSNBUJPOT, TVDI BT EFFQ-DMPOJOH UIF NFTTBHF QBZMPBE (PS BOZ PUIFS DVTUPN MPHJD). ">JBI 2.8: 8IFUIFS UIF VOJU PG XPSL TIPVME CF TIBSFE. 4FF UIF TBNF PQUJPO PO 4QMJUUFS GPS NPSF EFUBJMT.

parallelProcessing

false

executorServiceRef

stopOnException

false

ignoreInvalidEndpoints streaming

false false

timeout

onPrepareRef shareUnitOfWork

c false

2Q>QF@ 1B@FMFBKQ +FPQ


5IF GPMMPXJOH FYBNQMF TIPXT IPX UP SPVUF B SFRVFTU GSPN BO JOQVU NRBRB:> FOEQPJOU UP B TUBUJD MJTU PG EFTUJOBUJPOT 4PFKD KKLQ>QFLKP :PV DBO VTF UIF 3FDJQJFOU-JTU "OOPUBUJPO PO B 10+0 UP DSFBUF B %ZOBNJD 3FDJQJFOU -JTU. 'PS NPSF EFUBJMT TFF UIF #FBO *OUFHSBUJPO. 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .multicast().to("direct:b", "direct:c", "direct:d"); } };

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/> <multicast> <to uri="direct:b"/> <to uri="direct:c"/> <to uri="direct:d"/> </multicast>

416

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

</route> </camelContext>

#VK>JF@ 1B@FMFBKQ +FPQ


6TVBMMZ POF PG UIF NBJO SFBTPOT GPS VTJOH UIF 3FDJQJFOU -JTU QBUUFSO JT UIBU UIF MJTU PG SFDJQJFOUT JT EZOBNJD BOE DBMDVMBUFE BU SVOUJNF. 5IF GPMMPXJOH FYBNQMF EFNPOTUSBUFT IPX UP DSFBUF B EZOBNJD SFDJQJFOU MJTU VTJOH BO &YQSFTTJPO (XIJDI JO UIJT DBTF JU FYUSBDUT B OBNFE IFBEFS WBMVF EZOBNJDBMMZ) UP DBMDVMBUF UIF MJTU PG FOEQPJOUT XIJDI BSF FJUIFS PG UZQF &OEQPJOU PS BSF DPOWFSUFE UP B 4USJOH BOE UIFO SFTPMWFE VTJOH UIF FOEQPJOU 63*T. 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .recipientList(header("foo")); } };

5IF BCPWF BTTVNFT UIBU UIF IFBEFS DPOUBJOT B MJTU PG FOEQPJOU 63*T. 5IF GPMMPXJOH UBLFT B TJOHMF TUSJOH IFBEFS BOE UPLFOJ[FT JU
from("direct:a").recipientList( header("recipientListHeader").tokenize(","));

(QBO>Q>?IB S>IRB 5IF EZOBNJD MJTU PG SFDJQJFOUT UIBU BSF EFGJOFE JO UIF IFBEFS NVTU CF JUFSBUBCMF TVDI BT: java.util.Collection java.util.Iterator BSSBZT org.w3c.dom.NodeList B TJOHMF 4USJOH XJUI WBMVFT TFQBSBUFE XJUI DPNNB BOZ PUIFS UZQF XJMM CF SFHBSEFE BT B TJOHMF WBMVF 4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP
<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

417

<recipientList> <xpath>$foo</xpath> </recipientList> </route> </camelContext>

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU POF PG UIF KVOJU UFTU DBTF 4PFKD ABIFJFQBO FK 2MOFKD 7,+ *O 4QSJOH %4- ZPV DBO TFU UIF delimiter BUUSJCVUF GPS TFUUJOH B EFMJNJUFS UP CF VTFE JG UIF IFBEFS WBMVF JT B TJOHMF 4USJOH XJUI NVMUJQMF TFQBSBUFE FOEQPJOUT. #Z EFGBVMU $BNFM VTFT DPNNB BT EFMJNJUFS, CVU UIJT PQUJPO MFUT ZPV TQFDJGZ B DVTUPNFS EFMJNJUFS UP VTF JOTUFBE.
<route> <from uri="direct:a" /> <!-- use comma as a delimiter for String based values --> <recipientList delimiter=","> <header>myHeader</header> </recipientList> </route>

4P JG JV'B>ABO DPOUBJOT B 4USJOH XJUI UIF WBMVF "activemq:queue:foo, activemq:topic:hello , log:bar" UIFO $BNFM XJMM TQMJU UIF 4USJOH VTJOH UIF EFMJNJUFS HJWFO JO UIF 9.- UIBU XBT DPNNB, SFTVMUJOH JOUP 3 FOEQPJOUT UP TFOE UP. :PV DBO VTF TQBDFT CFUXFFO UIF FOEQPJOUT BT $BNFM XJMM USJN UIF WBMVF XIFO JU MPPLVQ UIF FOEQPJOU UP TFOE UP. /PUF: *O +BWB %4- ZPV VTF UIF tokenizer UP BSDIJWF UIF TBNF. 5IF SPVUF BCPWF JO +BWB %4-:
from("direct:a").recipientList(header("myHeader").tokenize(","));

*O ">JBI 2.1 JUT B CJU FBTJFS BT ZPV DBO QBTT JO UIF EFMJNJUFS BT 2OE QBSBNFUFS:
from("direct:a").recipientList(header("myHeader"), "#");

2BKAFKD QL JRIQFMIB OB@FMFBKQP FK M>O>IIBI S>FI>?IB >P LC ">JBI 2.2 5IF 3FDJQJFOU -JTU OPX TVQQPSUT parallelProcessing UIBU GPS FYBNQMF 4QMJUUFS BMTP TVQQPSUT. :PV DBO VTF JU UP VTF B UISFBE QPPM UP IBWF DPODVSSFOU UBTLT TFOEJOH UIF &YDIBOHF UP NVMUJQMF SFDJQJFOUT DPODVSSFOUMZ.

418

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

from("direct:a").recipientList(header("myHeader")).parallelProcessing();

"OE JO 4QSJOH 9.- JUT BO BUUSJCVUF PO UIF SFDJQJFOU MJTU UBH.


<route> <from uri="direct:a"/> <recipientList parallelProcessing="true"> <header>myHeader</header> </recipientList> </route>

2QLM @LKQFKRFKD FK @>PB LKB OB@FMFBKQ C>FIBA S>FI>?IB >P LC ">JBI 2.2 5IF 3FDJQJFOU -JTU OPX TVQQPSUT stopOnException UIBU GPS FYBNQMF 4QMJUUFS BMTP TVQQPSUT. :PV DBO VTF JU UP TUPQ TFOEJOH UP BOZ GVSUIFS SFDJQJFOUT JO DBTF BOZ SFDJQJFOU GBJMFE.
from("direct:a").recipientList(header("myHeader")).stopOnException();

"OE JO 4QSJOH 9.- JUT BO BUUSJCVUF PO UIF SFDJQJFOU MJTU UBH.


<route> <from uri="direct:a"/> <recipientList stopOnException="true"> <header>myHeader</header> </recipientList> </route>

-LQB: :PV DBO DPNCJOF parallelProcessing BOE stopOnException BOE IBWF UIFN CPUI true. (DKLOB FKS>IFA BKAMLFKQP S>FI>?IB >P LC ">JBI 2.3 5IF 3FDJQJFOU -JTU OPX TVQQPSUT ignoreInvalidEndpoints XIJDI UIF 3PVUJOH 4MJQ BMTP TVQQPSUT. :PV DBO VTF JU UP TLJQ FOEQPJOUT XIJDI JT JOWBMJE.
from("direct:a").recipientList(header("myHeader")).ignoreInvalidEndpoints();

"OE JO 4QSJOH 9.- JUT BO BUUSJCVUF PO UIF SFDJQJFOU MJTU UBH.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

419

<route> <from uri="direct:a"/> <recipientList ignoreInvalidEndpoints="true"> <header>myHeader</header> </recipientList> </route>

5IFO MFUT TBZ UIF myHeader DPOUBJOT UIF GPMMPXJOH UXP FOEQPJOUT direct:foo,xxx:bar. 5IF GJSTU FOEQPJOU JT WBMJE BOE XPSLT. )PXFWFS UIF 2OE JT JOWBMJE BOE XJMM KVTU CF JHOPSFE. $BNFM MPHT BU */'0 MFWFM BCPVU, TP ZPV DBO TFF XIZ UIF FOEQPJOU XBT JOWBMJE. 4PFKD @RPQLJ AggregationStrategy S>FI>?IB >P LC ">JBI 2.2 :PV DBO OPX VTF ZPV PXO AggregationStrategy XJUI UIF 3FDJQJFOU -JTU. )PXFWFS JUT OPU UIBU PGUFO ZPV OFFE UIBU. 8IBU JUT HPPE GPS JT UIBU JO DBTF ZPV BSF VTJOH 3FRVFTU 3FQMZ NFTTBHJOH UIFO UIF SFQMJFT GSPN UIF SFDJQJFOU DBO CF BHHSFHBUFE. #Z EFGBVMU $BNFM VTFT UseLatestAggregationStrategy XIJDI KVTU LFFQT UIBU MBTU SFDFJWFE SFQMZ. 8IBU JG ZPV NVTU SFNFNCFS BMM UIF CPEJFT UIBU BMM UIF SFDJQJFOUT TFOE CBDL, UIFO ZPV DBO VTF ZPVS PXO DVTUPN BHHSFHBUPS UIBU LFFQT UIPTF. *UT UIF TBNF QSJODJQMF BT XJUI UIF "HHSFHBUPS &*1 TP DIFDL JU PVU GPS EFUBJMT.
from("direct:a") .recipientList(header("myHeader")).aggregationStrategy(new MyOwnAggregationStrategy()) .to("direct:b");

"OE JO 4QSJOH 9.- JUT BO BUUSJCVUF PO UIF SFDJQJFOU MJTU UBH.


<route> <from uri="direct:a"/> <recipientList strategyRef="myStrategy"> <header>myHeader</header> </recipientList> <to uri="direct:b"/> </route> <bean id="myStrategy" class="com.mycompany.MyOwnAggregationStrategy"/>

4PFKD @RPQLJ QEOB>A MLLI S>FI>?IB >P LC ">JBI 2.2 " UISFBE QPPM JT POMZ VTFE GPS parallelProcessing. :PV TVQQMZ ZPVS PXO DVTUPN UISFBE QPPM WJB UIF ExecutorServiceStrategy (TFF $BNFM'T 5ISFBEJOH .PEFM), UIF TBNF

420

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

XBZ ZPV XPVME EP JU GPS UIF aggregationStrategy. #Z EFGBVMU $BNFM VTFT B UISFBE QPPM XJUI 10 UISFBET (TVCKFDU UP DIBOHF JO B GVUVSF WFSTJPO). 4PFKD JBQELA @>II >P OB@FMFBKQ IFPQ :PV DBO VTF B #FBO UP QSPWJEF UIF SFDJQJFOUT, GPS FYBNQMF:
from("activemq:queue:test").recipientList().method(MessageRouter.class, "routeTo");

"OE UIFO MessageRouter:


public class MessageRouter { public String routeTo() { String queueName = "activemq:queue:test2"; return queueName; } }

8IFO ZPV VTF B #FBO UIFO EP KLQ BMTP VTF UIF @RecipientList BOOPUBUJPO BT UIJT XJMM JO GBDU BEE ZFU BOPUIFS SFDJQJFOU MJTU, TP ZPV FOE VQ IBWJOH UXP. %P KLQ EP MJLF UIJT.
public class MessageRouter { @RecipientList public String routeTo() { String queueName = "activemq:queue:test2"; return queueName; } }

8FMM ZPV TIPVME POMZ EP MJLF UIBU BCPWF (VTJOH @RecipientList) JG ZPV SPVUF KVTU SPVUF UP B #FBO XIJDI ZPV UIFO XBOU UP BDU BT B SFDJQJFOU MJTU. 4P UIF PSJHJOBM SPVUF DBO CF DIBOHFE UP:
from("activemq:queue:test").bean(MessageRouter.class, "routeTo");

8IJDI UIFO XPVME JOWPLF UIF SPVUF5P NFUIPE BOE EFUFDU JUT BOOPUBUFE XJUI @RecipientList BOE UIFO BDU BDDPSEJOHMZ BT JG JU XBT B SFDJQJFOU MJTU &*1. 4PFKD QFJBLRQ S>FI>?IB >P LC ">JBI 2.5 *G ZPV VTF parallelProcessing UIFO ZPV DBO DPOGJHVSF B UPUBM timeout WBMVF JO NJMMJT. $BNFM XJMM UIFO QSPDFTT UIF NFTTBHFT JO QBSBMMFM VOUJM UIF UJNFPVU JT IJU. 5IJT BMMPXT ZPV UP

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

421

DPOUJOVF QSPDFTTJOH JG POF NFTTBHF JT TMPX. 'PS FYBNQMF ZPV DBO TFU B UJNFPVU WBMVF PG 20 TFD. 'PS FYBNQMF JO UIF VOJU UFTU CFMPX ZPV DBO TFF XF NVMUJDBTU UIF NFTTBHF UP 3 EFTUJOBUJPOT. 8F IBWF B UJNFPVU PG 2 TFDPOET, XIJDI NFBOT POMZ UIF MBTU UXP NFTTBHFT DBO CF DPNQMFUFE XJUIJO UIF UJNFGSBNF. 5IJT NFBOT XF XJMM POMZ BHHSFHBUF UIF MBTU UXP XIJDI ZJFMET B SFTVMU BHHSFHBUJPO XIJDI PVUQVUT "BC".
from("direct:start") .multicast(new AggregationStrategy() { public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { if (oldExchange == null) { return newExchange; } String body = oldExchange.getIn().getBody(String.class); oldExchange.getIn().setBody(body + newExchange.getIn().getBody(String.class)); return oldExchange; } }) .parallelProcessing().timeout(250).to("direct:a", "direct:b", "direct:c") // use end to indicate end of multicast route .end() .to("mock:result"); from("direct:a").delay(1000).to("mock:A").setBody(constant("A")); from("direct:b").to("mock:B").setBody(constant("B")); from("direct:c").to("mock:C").setBody(constant("C"));

#Z EFGBVMU JG B UJNFPVU PDDVST UIF AggregationStrategy JT OPU JOWPLFE. )PXFWFS ZPV DBO JNQMFNFOU B TQFDJBMJ[FE WFSTJPO
public interface TimeoutAwareAggregationStrategy extends AggregationStrategy { /** * A timeout occurred * * @param oldExchange the oldest exchange (is <tt>null</tt> on first aggregation as we only have the new exchange) * @param index the index * @param total the total * @param timeout the timeout value in millis */ void timeout(Exchange oldExchange, int index, int total, long timeout);

5IJT BMMPXT ZPV UP EFBM XJUI UIF UJNFPVU JO UIF AggregationStrategy JG ZPV SFBMMZ OFFE UP.

422

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

3>PHP J>V HBBM ORKKFKD *G UIF UJNFPVU JT SFBDIFE XJUI SVOOJOH UBTLT TUJMM SFNBJOJOH, DFSUBJO UBTLT GPS XIJDI JU JT EJGGJDVMU GPS $BNFM UP TIVU EPXO JO B HSBDFGVM NBOOFS NBZ DPOUJOVF UP SVO. 4P VTF UIJT PQUJPO XJUI B CJU PG DBSF. 8F NBZ CF BCMF UP JNQSPWF UIJT GVODUJPOBMJUZ JO GVUVSF $BNFM SFMFBTFT.

3FJBLRQ FK LQEBO $(/P 5IJT timeout GFBUVSF JT BMTP TVQQPSUFE CZ 4QMJUUFS BOE CPUI multicast BOE recipientList.

3FJBLRQ FP QLQ>I 5IF UJNFPVU JT UPUBM, XIJDI NFBOT UIBU BGUFS 9 UJNF, $BNFM XJMM BHHSFHBUF UIF NFTTBHFT XIJDI IBT DPNQMFUFE XJUIJO UIF UJNFGSBNF. 5IF SFNBJOEFST XJMM CF DBODFMMFE. $BNFM XJMM BMTP POMZ JOWPLF UIF timeout NFUIPE JO UIF TimeoutAwareAggregationStrategy PODF, GPS UIF GJSTU JOEFY XIJDI DBVTFE UIF UJNFPVU. 4PFKD LK/OBM>OB QL BUB@RQB @RPQLJ ILDF@ TEBK MOBM>OFKD JBPP>DBP S>FI>?IB >P LC ">JBI 2.8 4FF EFUBJMT BU .VMUJDBTU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2MIFQQBO 5IF 4QMJUUFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV TQMJU B NFTTBHF JOUP B OVNCFS PG QJFDFT BOE QSPDFTT UIFN JOEJWJEVBMMZ

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

423

:PV OFFE UP TQFDJGZ B 4QMJUUFS BT split(). *O FBSMJFS WFSTJPOT PG $BNFM, ZPV OFFE UP VTF splitter(). .MQFLKP
->JB
strategyRef parallelProcessing executorServiceRef

#BC>RIQ 5>IRB
c false c

#BP@OFMQFLK
3FGFST UP BO "HHSFHBUJPO4USBUFHZ UP CF VTFE UP BTTFNCMF UIF SFQMJFT GSPN UIF TVC-NFTTBHFT, JOUP B TJOHMF PVUHPJOH NFTTBHF GSPN UIF 4QMJUUFS. 4FF UIF EFGBVMUT EFTDSJCFE CFMPX JO What the Splitter returns. *G FOBCMFT UIFO QSPDFTTJOH UIF TVC-NFTTBHFT PDDVST DPODVSSFOUMZ. /PUF UIF DBMMFS UISFBE XJMM TUJMM XBJU VOUJM BMM TVC-NFTTBHFT IBT CFFO GVMMZ QSPDFTTFE, CFGPSF JU DPOUJOVFT. 3FGFST UP B DVTUPN 5ISFBE 1PPM UP CF VTFE GPS QBSBMMFM QSPDFTTJOH. /PUJDF JG ZPV TFU UIJT PQUJPO, UIFO QBSBMMFM QSPDFTTJOH JT BVUPNBUJD JNQMJFE, BOE ZPV EP OPU IBWF UP FOBCMF UIBU PQUJPO BT XFMM. ">JBI 2.2: 8IFUIFS PS OPU UP TUPQ DPOUJOVF QSPDFTTJOH JNNFEJBUFMZ XIFO BO FYDFQUJPO PDDVSSFE. *G EJTBCMF, UIFO $BNFM DPOUJOVF TQMJUUJOH BOE QSPDFTT UIF TVC-NFTTBHFT SFHBSEMFTT JG POF PG UIFN GBJMFE. :PV DBO EFBM XJUI FYDFQUJPOT JO UIF "HHSFHBUJPO4USBUFHZ DMBTT XIFSF ZPV IBWF GVMM DPOUSPM IPX UP IBOEMF UIBU. *G FOBCMFE UIFO $BNFM XJMM TQMJU JO B TUSFBNJOH GBTIJPO, XIJDI NFBOT JU XJMM TQMJU UIF JOQVU NFTTBHF JO DIVOLT. 5IJT SFEVDFT UIF NFNPSZ PWFSIFBE. 'PS FYBNQMF JG ZPV TQMJU CJH NFTTBHFT JUT SFDPNNFOEFE UP FOBCMF TUSFBNJOH. *G TUSFBNJOH JT FOBCMFE UIFO UIF TVC-NFTTBHF SFQMJFT XJMM CF BHHSFHBUFE PVU-PG-PSEFS, FH JO UIF PSEFS UIFZ DPNF CBDL. *G EJTBCMFE, $BNFM XJMM QSPDFTT TVC-NFTTBHF SFQMJFT JO UIF TBNF PSEFS BT UIFZ XIFSF TQMJUUFE. ">JBI 2.5: 4FUT B UPUBM UJNFPVU TQFDJGJFE JO NJMMJT. *G UIF 3FDJQJFOU -JTU IBTO'U CFFO BCMF UP TQMJU BOE QSPDFTT BMM SFQMJFT XJUIJO UIF HJWFO UJNFGSBNF, UIFO UIF UJNFPVU USJHHFST BOE UIF 4QMJUUFS CSFBLT PVU BOE DPOUJOVFT. /PUJDF JG ZPV QSPWJEF B 5JNFPVU"XBSF"HHSFHBUJPO4USBUFHZ UIFO UIF timeout NFUIPE JT JOWPLFE CFGPSF CSFBLJOH PVU. *G UIF UJNFPVU JT SFBDIFE XJUI SVOOJOH UBTLT TUJMM SFNBJOJOH, DFSUBJO UBTLT GPS XIJDI JU JT EJGGJDVMU GPS $BNFM UP TIVU EPXO JO B HSBDFGVM NBOOFS NBZ DPOUJOVF UP SVO. 4P VTF UIJT PQUJPO XJUI B CJU PG DBSF. 8F NBZ CF BCMF UP JNQSPWF UIJT GVODUJPOBMJUZ JO GVUVSF $BNFM SFMFBTFT. ">JBI 2.8: 3FGFST UP B DVTUPN 1SPDFTTPS UP QSFQBSF UIF TVC-NFTTBHF PG UIF &YDIBOHF, CFGPSF JUT QSPDFTTFE. 5IJT BMMPXT ZPV UP EP BOZ DVTUPN MPHJD, TVDI BT EFFQ-DMPOJOH UIF NFTTBHF QBZMPBE JG UIBU'T OFFEFE FUD. ">JBI 2.8: 8IFUIFS UIF VOJU PG XPSL TIPVME CF TIBSFE. 4FF GVSUIFS CFMPX GPS NPSF EFUBJMT.

stopOnException

false

streaming

false

timeout

onPrepareRef shareUnitOfWork

c false

$U@E>KDB MOLMBOQFBP 5IF GPMMPXJOH QSPQFSUJFT BSF TFU PO FBDI &YDIBOHF UIBU BSF TQMJU: MOLMBOQV CamelSplitIndex QVMB JOU ABP@OFMQFLK " TQMJU DPVOUFS UIBU JODSFBTFT GPS FBDI &YDIBOHF CFJOH TQMJU. 5IF DPVOUFS TUBSUT GSPN 0. 5IF UPUBM OVNCFS PG &YDIBOHFT UIBU XBT TQMJUUFE. 5IJT IFBEFS JT OPU BQQMJFE GPS TUSFBN CBTFE TQMJUUJOH. 'SPN ">JBI 2.9 POXBSET UIJT IFBEFS JT BMTP TFU JO TUSFBN CBTFE TQMJUUJOH, CVU POMZ PO UIF DPNQMFUFE &YDIBOHF. ">JBI 2.4: 8IFUIFS PS OPU UIJT &YDIBOHF JT UIF MBTU.

CamelSplitSize

JOU

CamelSplitComplete

CPPMFBO

424

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

$U>JMIBP 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP UBLF B SFRVFTU GSPN UIF NRBRB:> FOEQPJOU UIF TQMJU JU JOUP QJFDFT VTJOH BO &YQSFTTJPO, UIFO GPSXBSE FBDI QJFDF UP NRBRB:? 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .split(body(String.class).tokenize("\n")) .to("direct:b"); } };

5IF TQMJUUFS DBO VTF BOZ &YQSFTTJPO MBOHVBHF TP ZPV DPVME VTF BOZ PG UIF -BOHVBHFT 4VQQPSUFE TVDI BT 91BUI, 92VFSZ, 42- PS POF PG UIF 4DSJQUJOH -BOHVBHFT UP QFSGPSN UIF TQMJU. F.H.
from("activemq:my.queue").split(xpath("//foo/ bar")).convertBodyTo(String.class).to("file://some/directory")

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:a"/> <split> <xpath>/invoice/lineItems</xpath> <to uri="direct:b"/> </split> </route> </camelContext>

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU POF PG UIF KVOJU UFTU DBTF 4PFKD 3LHBKFWBO COLJ 2MOFKD 7,+ $UQBKPFLKP* :PV DBO VTF UIF UPLFOJ[FS FYQSFTTJPO JO UIF 4QSJOH %4- UP TQMJU CPEJFT PS IFBEFST VTJOH B UPLFO. 5IJT JT B DPNNPO VTF-DBTF, TP XF QSPWJEFE B TQFDJBM QLHBKFWBO UBH GPS UIJT. *O UIF TBNQMF CFMPX XF TQMJU UIF CPEZ VTJOH B ! BT TFQBSBUPS. :PV DBO PG DPVSTF VTF DPNNB PS TQBDF PS FWFO B SFHFY QBUUFSO, BMTP TFU SFHFY=USVF.
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

425

<split> <tokenize token="@"/> <to uri="mock:result"/> </split> </route> </camelContext>

4QMJUUJOH UIF CPEZ JO 4QSJOH 9.- JT B CJU IBSEFS BT ZPV OFFE UP VTF UIF 4JNQMF MBOHVBHF UP EJDUBUF UIJT
<split> <simple>${body}</simple> <to uri="mock:result"/> </split>

6E>Q QEB 2MIFQQBO OBQROKP ">JBI 2.2 LO LIABO: 5IF 4QMJUUFS XJMM CZ EFGBVMU SFUVSO UIF I>PQ TQMJUUFE NFTTBHF. ">JBI 2.3 >KA KBTBO 5IF 4QMJUUFS XJMM CZ EFGBVMU SFUVSO UIF PSJHJOBM JOQVU NFTTBHF. %LO >II SBOPFLKP :PV DBO PWFSSJEF UIJT CZ TVQQMJOH ZPVS PXO TUSBUFHZ BT BO AggregationStrategy. 5IFSF JT B TBNQMF PO UIJT QBHF (4QMJU BHHSFHBUF SFRVFTU/SFQMZ TBNQMF). /PUJDF JUT UIF TBNF TUSBUFHZ BT UIF "HHSFHBUPS TVQQPSUT. 5IJT 4QMJUUFS DBO CF WJFXFE BT IBWJOH B CVJME JO MJHIU XFJHIU "HHSFHBUPS. />O>IIBI BUB@RQFLK LC AFPQFK@Q 'M>OQP' *G ZPV XBOU UP FYFDVUF BMM QBSUT JO QBSBMMFM ZPV DBO VTF TQFDJBM OPUBUJPO PG split() XJUI UXP BSHVNFOUT, XIFSF UIF TFDPOE POF JT B ?LLIB>K GMBH JG QSPDFTTJOH TIPVME CF QBSBMMFM. F.H.
XPathBuilder xPathBuilder = new XPathBuilder("//foo/bar"); from("activemq:my.queue").split(xPathBuilder, true).to("activemq:my.parts");

5IF CPPMFBO PQUJPO IBT CFFO SFGBDUPSFE JOUP B CVJMEFS NFUIPE parallelProcessing TP JUT FBTJFS UP VOEFSTUBOE XIBU UIF SPVUF EPFT XIFO XF VTF B NFUIPE JOTUFBE PG USVF]GBMTF.
XPathBuilder xPathBuilder = new XPathBuilder("//foo/bar"); from("activemq:my.queue").split(xPathBuilder).parallelProcessing().to("activemq:my.parts");

2QOB>J ?>PBA

426

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2MIFQQFKD ?FD 7,+ M>VIL>AP 5IF 91BUI FOHJOF JO +BWB BOE TBYPO XJMM MPBE UIF FOUJSF 9.- DPOUFOU JOUP NFNPSZ. "OE UIVT UIFZ BSF OPU XFMM TVJUFE GPS WFSZ CJH 9.- QBZMPBET. *OTUFBE ZPV DBO VTF B DVTUPN &YQSFTTJPO XIJDI XJMM JUFSBUF UIF 9.- QBZMPBE JO B TUSFBNFE GBTIJPO. 'SPN $BNFM 2.9 POXBSET ZPV DBO VTF UIF 5PLFOJ[FS MBOHVBHF XIJDI TVQQPSUT UIJT XIFO ZPV TVQQMZ UIF TUBSU BOE FOE UPLFOT. :PV DBO TQMJU TUSFBNT CZ FOBCMJOH UIF TUSFBNJOH NPEF VTJOH UIF streaming CVJMEFS NFUIPE.

from("direct:streaming").split(body().tokenize(",")).streaming().to("activemq:my.parts");

:PV DBO BMTP TVQQMZ ZPVS DVTUPN TQMJUUFS UP VTF XJUI TUSFBNJOH MJLF UIJT:
import static org.apache.camel.builder.ExpressionBuilder.beanExpression; from("direct:streaming") .split(beanExpression(new MyCustomIteratorFactory(), "iterator")) .streaming().to("activemq:my.parts")

2QOB>JFKD ?FD 7,+ M>VIL>AP RPFKD 3LHBKFWBO I>KDR>DB


S>FI>?IB >P LC ">JBI 2.9 *G ZPV IBWF B CJH 9.- QBZMPBE, GSPN B GJMF TPVSDF, BOE XBOU UP TQMJU JU JO TUSFBNJOH NPEF, UIFO ZPV DBO VTF UIF 5PLFOJ[FS MBOHVBHF XJUI TUBSU/FOE UPLFOT UP EP UIJT XJUI MPX NFNPSZ GPPUQSJOU. 'PS FYBNQMF ZPV NBZ IBWF B 9.- QBZMPBE TUSVDUVSFE BT GPMMPXT
<orders> <order> <!-- order stuff here --> </order> <order> <!-- order stuff here --> </order> ... <order> <!-- order stuff here --> </order> </orders>

/PX UP TQMJU UIJT CJH GJMF VTJOH 91BUI XPVME DBVTF UIF FOUJSF DPOUFOU UP CF MPBEFE JOUP NFNPSZ. 4P JOTUFBE XF DBO VTF UIF 5PLFOJ[FS MBOHVBHF UP EP UIJT BT GPMMPXT:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

427

2Q 7 @LJMLKBKQ 5IF $BNFM 4U"9 DPNQPOFOU DBO BMTP CF VTFE UP TQMJU CJH 9.- GJMFT JO B TUSFBNJOH NPEF. 4FF NPSF EFUBJMT BU 4U"9.

from("file:inbox") .split().tokenizeXML("order").streaming() .to("activemq:queue:order");

*O 9.- %4- UIF SPVUF XPVME CF BT GPMMPXT:


<route> <from uri="file:inbox"/> <split streaming="true"> <tokenize token="order" xml="true"/> <to uri="activemq:queue:order"/> </split> </route>

/PUJDF UIF tokenizeXML NFUIPE XIJDI XJMM TQMJU UIF GJMF VTJOH UIF UBH OBNF PG UIF DIJME OPEF, XIJDI NFBO JU XJMM HSBC UIF DPOUFOU CFUXFFO UIF <order> BOE </order> UBHT (JODM. UIF UPLFOT). 4P GPS FYBNQMF B TQMJUUFE NFTTBHF XPVME CF BT GPMMPXT:
<order> <!-- order stuff here --> </order>

*G ZPV XBOU UP JOIFSJU OBNFTQBDFT GSPN B SPPU/QBSFOU UBH, UIFO ZPV DBO EP UIJT BT XFMM CZ QSPWJEJOH UIF OBNF PG UIF SPPU/QBSFOU UBH:
<route> <from uri="file:inbox"/> <split streaming="true"> <tokenize token="order" inheritNamespaceTagName="orders" xml="true"/> <to uri="activemq:queue:order"/> </split> </route>

"OE JO +BWB %4- JUT BT GPMMPXT:


from("file:inbox") .split().tokenizeXML("order", "orders").streaming() .to("activemq:queue:order");

428

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2MIFQQFKD CFIBP ?V DOLRMFKD - IFKBP QLDBQEBO


S>FI>?IB >P LC ">JBI 2.10 5IF 5PLFOJ[FS MBOHVBHF IBT B OFX PQUJPO group UIBU BMMPXT ZPV UP HSPVQ / QBSUT UPHFUIFS, GPS FYBNQMF UP TQMJU CJH GJMFT JOUP DIVOLT PG 1000 MJOFT.
from("file:inbox") .split().tokenize("\n", 1000).streaming() .to("activemq:queue:order");

"OE JO 9.- %4<route> <from uri="file:inbox"/> <split streaming="true"> <tokenize token="\n" group="1000"/> <to uri="activemq:queue:order"/> </split> </route>

5IF group PQUJPO JT B OVNCFS UIBU NVTU CF B QPTJUJWF OVNCFS UIBU EJDUBUFT IPX NBOZ HSPVQT UP DPNCJOF UPHFUIFS. &BDI QBSU XJMM CF DPNCJOFE VTJOH UIF UPLFO. 4P JO UIF FYBNQMF BCPWF UIF NFTTBHF CFJOH TFOU UP UIF BDUJWFNR PSEFS RVFVF, XJMM DPOUBJO 1000 MJOFT, BOE FBDI MJOF TFQBSBUFE CZ UIF UPLFO (XIJDI JT B OFX MJOF UPLFO). 5IF PVUQVU XIFO VTJOH UIF group PQUJPO JT BMXBZT B java.lang.String UZQF.

2MB@FCVFKD > @RPQLJ >DDOBD>QFLK PQO>QBDV


5IJT JT TQFDJGJFE TJNJMBS UP UIF "HHSFHBUPS.

2MB@FCVFKD > @RPQLJ 3EOB>A/LLI$UB@RQLO


:PV DBO DVTUPNJ[F UIF VOEFSMZJOH 5ISFBE1PPM&YFDVUPS VTFE JO UIF QBSBMMFM TQMJUUFS. *O UIF +BWB %4- USZ TPNFUIJOH MJLF UIJT:
XPathBuilder xPathBuilder = new XPathBuilder("//foo/bar"); ExecutorService pool = ... from("activemq:my.queue") .split(xPathBuilder).parallelProcessing().executorService(pool) .to("activemq:my.parts");

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

429

4PFKD > /LGL QL AL QEB PMIFQQFKD


"T UIF 4QMJUUFS DBO VTF BOZ &YQSFTTJPO UP EP UIF BDUVBM TQMJUUJOH XF MFWFSBHF UIJT GBDU BOE VTF B JBQELA FYQSFTTJPO UP JOWPLF B #FBO UP HFU UIF TQMJUUFE QBSUT. 5IF #FBO TIPVME SFUVSO B WBMVF UIBU JT JUFSBCMF TVDI BT: java.util.Collection, java.util.Iterator PS BO BSSBZ. 4P UIF SFUVSOFE WBMVF, XJMM UIFO CF VTFE CZ $BNFM BU SVOUJNF, UP TQMJU UIF NFTTBHF. *O UIF SPVUF XF EFGJOF UIF &YQSFTTJPO BT B NFUIPE DBMM UP JOWPLF PVS #FBO UIBU XF IBWF SFHJTUFSFE XJUI UIF JE NZ4QMJUUFS#FBO JO UIF 3FHJTUSZ.
from("direct:body") // here we use a POJO bean mySplitterBean to do the split of the payload .split().method("mySplitterBean", "splitBody") .to("mock:result"); from("direct:message") // here we use a POJO bean mySplitterBean to do the split of the message // with a certain header value .split().method("mySplitterBean", "splitMessage") .to("mock:result");

"OE UIF MPHJD GPS PVS #FBO JT BT TJNQMF BT. /PUJDF XF VTF $BNFM #FBO #JOEJOH UP QBTT JO UIF NFTTBHF CPEZ BT B 4USJOH PCKFDU.
public class MySplitterBean { /** * The split body method returns something that is iteratable such as a java.util.List. * * @param body the payload of the incoming message * @return a list containing each part splitted */ public List<String> splitBody(String body) { // since this is based on an unit test you can of cause // use different logic for splitting as Camel have out // of the box support for splitting a String based on comma // but this is for show and tell, since this is java code // you have the full power how you like to split your messages List<String> answer = new ArrayList<String>(); String[] parts = body.split(","); for (String part : parts) { answer.add(part); } return answer; } /** * The split message method returns something that is iteratable such as a java.util.List. * * @param header the header of the incoming message with the name user

430

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2QOB>JFKD JLAB >KA RPFKD MLGL 8IFO ZPV IBWF FOBCMFE UIF TUSFBNJOH NPEF, UIFO ZPV TIPVME SFUVSO B Iterator UP FOTVSF TUSFBNJTI GBTIJPO. 'PS FYBNQMF JG UIF NFTTBHF JT B CJH GJMF, UIFO CZ VTJOH BO JUFSBUPS, UIBU SFUVSOT B QJFDF PG UIF GJMF JO DIVOLT, JO UIF next NFUIPE PG UIF Iterator FOTVSFT MPX NFNPSZ GPPUQSJOU. 5IJT BWPJET UIF OFFE GPS SFBEJOH UIF FOUJSF DPOUFOU JOUP NFNPSZ. 'PS BO FYBNQMF TFF UIF TPVSDF DPEF GPS UIF 5PLFOJ[F1BJS JNQMFNFOUBUJPO.

* @param body the payload of the incoming message * @return a list containing each part splitted */ public List<Message> splitMessage(@Header(value = "user") String header, @Body String body) { // we can leverage the Parameter Binding Annotations // http://camel.apache.org/parameter-binding-annotations.html // to access the message header and body at same time, // then create the message that we want, splitter will // take care rest of them. // *NOTE* this feature requires Camel version >= 1.6.1 List<Message> answer = new ArrayList<Message>(); String[] parts = header.split(","); for (String part : parts) { DefaultMessage message = new DefaultMessage(); message.setHeader("user", part); message.setBody(body); answer.add(message); } return answer; } }

2MIFQ >DDOBD>QB OBNRBPQ/OBMIV P>JMIB


5IJT TBNQMF TIPXT IPX ZPV DBO TQMJU BO &YDIBOHF, QSPDFTT FBDI TQMJUUFE NFTTBHF, BHHSFHBUF BOE SFUVSO B DPNCJOFE SFTQPOTF UP UIF PSJHJOBM DBMMFS VTJOH SFRVFTU/SFQMZ. 5IF SPVUF CFMPX JMMVTUSBUFT UIJT BOE IPX UIF TQMJU TVQQPSUT B >DDOBD>QFLK2QO>QBDV UP IPME UIF JO QSPHSFTT QSPDFTTFE NFTTBHFT:
// this routes starts from the direct:start endpoint // the body is then splitted based on @ separator // the splitter in Camel supports InOut as well and for that we need // to be able to aggregate what response we need to send back, so we provide our // own strategy with the class MyOrderStrategy. from("direct:start")

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

431

.split(body().tokenize("@"), new MyOrderStrategy()) // each splitted message is then send to this bean where we can process it .to("bean:MyOrderService?method=handleOrder") // this is important to end the splitter route as we do not want to do more routing // on each splitted message .end() // after we have splitted and handled each message we want to send a single combined // response back to the original caller, so we let this bean build it for us // this bean will receive the result of the aggregate strategy: MyOrderStrategy .to("bean:MyOrderService?method=buildCombinedResponse")

"OE UIF 0SEFS4FSWJDF CFBO JT BT GPMMPXT:


public static class MyOrderService { private static int counter; /** * We just handle the order by returning a id line for the order */ public String handleOrder(String line) { LOG.debug("HandleOrder: " + line); return "(id=" + ++counter + ",item=" + line + ")"; } /** * We use the same bean for building the combined response to send * back to the original caller */ public String buildCombinedResponse(String line) { LOG.debug("BuildCombinedResponse: " + line); return "Response[" + line + "]"; } }

"OE PVS DVTUPN >DDOBD>QFLK2QO>QBDV UIBU JT SFTQPOTJCMF GPS IPMEJOH UIF JO QSPHSFTT BHHSFHBUFE NFTTBHF UIBU BGUFS UIF TQMJUUFS JT FOEFE XJMM CF TFOU UP UIF ?RFIA"LJ?FKBA1BPMLKPB NFUIPE GPS GJOBM QSPDFTTJOH CFGPSF UIF DPNCJOFE SFTQPOTF DBO CF SFUVSOFE UP UIF XBJUJOH DBMMFS.
/** * This is our own order aggregation strategy where we can control * how each splitted message should be combined. As we do not want to * loos any message we copy from the new to the old to preserve the * order lines as long we process them */ public static class MyOrderStrategy implements AggregationStrategy {

432

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { // put order together in old exchange by adding the order from new exchange if (oldExchange == null) { // the first time we aggregate we only have the new exchange, // so we just return it return newExchange; } String orders = oldExchange.getIn().getBody(String.class); String newLine = newExchange.getIn().getBody(String.class); LOG.debug("Aggregate old orders: " + orders); LOG.debug("Aggregate new order: " + newLine); // put orders together separating by semi colon orders = orders + ";" + newLine; // put combined order back on old to preserve it oldExchange.getIn().setBody(orders); // return old as this is the one that has all the orders gathered until now return oldExchange; } }

4P MFUT SVO UIF TBNQMF BOE TFF IPX JU XPSLT. 8F TFOE BO &YDIBOHF UP UIF AFOB@Q:PQ>OQ FOEQPJOU DPOUBJOJOH B */ CPEZ XJUI UIF 4USJOH WBMVF: A@B@C. 5IF GMPX JT:
HandleOrder: A HandleOrder: B Aggregate old orders: (id=1,item=A) Aggregate new order: (id=2,item=B) HandleOrder: C Aggregate old orders: (id=1,item=A);(id=2,item=B) Aggregate new order: (id=3,item=C) BuildCombinedResponse: (id=1,item=A);(id=2,item=B);(id=3,item=C) Response to caller: Response[(id=1,item=A);(id=2,item=B);(id=3,item=C)]

2QLM MOL@BPPFKD FK @>PB LC BU@BMQFLK S>FI>?IB >P LC ">JBI 2.1 5IF 4QMJUUFS XJMM CZ EFGBVMU DPOUJOVF UP QSPDFTT UIF FOUJSF &YDIBOHF FWFO JO DBTF PG POF PG UIF TQMJUUFE NFTTBHF XJMM UISPXO BO FYDFQUJPO EVSJOH SPVUJOH. 'PS FYBNQMF JG ZPV IBWF BO &YDIBOHF XJUI 1000 SPXT UIBU ZPV TQMJU BOE SPVUF FBDI TVC NFTTBHF. %VSJOH QSPDFTTJOH PG UIFTF TVC NFTTBHFT BO FYDFQUJPO JT UISPXO BU UIF 17UI. 8IBU $BNFM EPFT CZ EFGBVMU JT UP QSPDFTT UIF SFNBJOEFS 983 NFTTBHFT. :PV IBWF UIF DIBODF UP SFNFEZ PS IBOEMF UIJT JO UIF AggregationStrategy.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

433

#VU TPNFUJNFT ZPV KVTU XBOU $BNFM UP TUPQ BOE MFU UIF FYDFQUJPO CF QSPQBHBUFE CBDL, BOE MFU UIF $BNFM FSSPS IBOEMFS IBOEMF JU. :PV DBO EP UIJT JO $BNFM 2.1 CZ TQFDJGZJOH UIBU JU TIPVME TUPQ JO DBTF PG BO FYDFQUJPO PDDVSSFE. 5IJT JT EPOF CZ UIF stopOnException PQUJPO BT TIPXO CFMPX:
from("direct:start") .split(body().tokenize(",")).stopOnException() .process(new MyProcessor()) .to("mock:split");

"OE VTJOH 9.- %4- ZPV TQFDJGZ JU BT GPMMPXT:


<route> <from uri="direct:start"/> <split stopOnException="true"> <tokenize token=","/> <process ref="myProcessor"/> <to uri="mock:split"/> </split> </route>

4PFKD LK/OBM>OB QL BUB@RQB @RPQLJ ILDF@ TEBK MOBM>OFKD JBPP>DBP S>FI>?IB >P LC ">JBI 2.8 4FF EFUBJMT BU .VMUJDBTU 2E>OFKD RKFQ LC TLOH S>FI>?IB >P LC ">JBI 2.8 5IF 4QMJUUFS XJMM CZ EFGBVMU OPU TIBSF VOJU PG XPSL CFUXFFO UIF QBSFOU FYDIBOHF BOE FBDI TQMJUUFE FYDIBOHF. 5IJT NFBOT FBDI TVC FYDIBOHF IBT JUT PXO JOEJWJEVBM VOJU PG XPSL. 'PS FYBNQMF ZPV NBZ IBWF BO VTF DBTF, XIFSF ZPV XBOU UP TQMJU B CJH NFTTBHF. "OE ZPV XBOU UP SFHBSE UIBU QSPDFTT BT BO BUPNJD JTPMBUFE PQFSBUJPO UIBU FJUIFS JT B TVDDFTT PS GBJMVSF. *O DBTF PG B GBJMVSF ZPV XBOU UIBU CJH NFTTBHF UP CF NPWFE JOUP B EFBE MFUUFS RVFVF. 5P TVQQPSU UIJT VTF DBTF, ZPV XPVME IBWF UP TIBSF UIF VOJU PG XPSL PO UIF 4QMJUUFS. )FSF JT BO FYBNQMF JO +BWB %4errorHandler(deadLetterChannel("mock:dead").useOriginalMessage() .maximumRedeliveries(3).redeliveryDelay(0)); from("direct:start") .to("mock:a") // share unit of work in the splitter, which tells Camel to propagate failures from // processing the splitted messages back to the result of the splitter, which allows

434

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

// it to act as a combined unit of work .split(body().tokenize(",")).shareUnitOfWork() .to("mock:b") .to("direct:line") .end() .to("mock:result"); from("direct:line") .to("log:line") .process(new MyProcessor()) .to("mock:line");

/PX JO UIJT FYBNQMF XIBU XPVME IBQQFO JT UIBU JO DBTF UIFSF JT B QSPCMFN QSPDFTTJOH FBDI TVC NFTTBHF, UIF FSSPS IBOEMFS XJMM LJDL JO (ZFT FSSPS IBOEMJOH TUJMM BQQMJFT GPS UIF TVC NFTTBHFT). !RQ XIBU EPFTO'U IBQQFO JT UIBU JG B TVC NFTTBHF GBJMT BMM SFEFMJWFSZ BUUFNQUT (JUT FYIBVTUFE), UIFO JUT KLQ NPWFE JOUP UIBU EFBE MFUUFS RVFVF. 5IF SFBTPO JT UIBU XF IBWF TIBSFE UIF VOJU PG XPSL, TP UIF TVC NFTTBHF XJMM SFQPSU UIF FSSPS PO UIF TIBSFE VOJU PG XPSL. 8IFO UIF 4QMJUUFS JT EPOF, JU DIFDLT UIF TUBUF PG UIF TIBSFE VOJU PG XPSL BOE DIFDLT JG BOZ FSSPST PDDVSSFE. "OE JG BO FSSPS PDDVSSFE JU XJMM TFU UIF FYDFQUJPO PO UIF &YDIBOHF BOE NBSL JU GPS SPMMCBDL. 5IF FSSPS IBOEMFS XJMM ZFU BHBJO LJDL JO, BT UIF &YDIBOHF IBT CFFO NBSLFE BT SPMMCBDL BOE JU IBE BO FYDFQUJPO BT XFMM. /P SFEFMJWFSZ BUUFNQUT JT QFSGPSNFE (BT JU XBT NBSLFE GPS SPMMCBDL) BOE UIF &YDIBOHF XJMM CF NPWFE JOUP UIF EFBE MFUUFS RVFVF. 6TJOH UIJT GSPN 9.- %4- JT KVTU BT FBTZ BT ZPV KVTU IBWF UP TFU UIF TIBSF6OJU0G8PSL BUUSJCVUF UP USVF:
<camelContext errorHandlerRef="dlc" xmlns="http://camel.apache.org/schema/spring"> <!-- define error handler as DLC, with use original message enabled --> <errorHandler id="dlc" type="DeadLetterChannel" deadLetterUri="mock:dead" useOriginalMessage="true"> <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="0"/> </errorHandler> <route> <from uri="direct:start"/> <to uri="mock:a"/> <!-- share unit of work in the splitter, which tells Camel to propagate failures from processing the splitted messages back to the result of the splitter, which allows it to act as a combined unit of work --> <split shareUnitOfWork="true"> <tokenize token=","/> <to uri="mock:b"/> <to uri="direct:line"/> </split> <to uri="mock:result"/> </route>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

435

<!-- route for processing each splitted line --> <route> <from uri="direct:line"/> <to uri="log:line"/> <process ref="myProcessor"/> <to uri="mock:line"/> </route> </camelContext>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. DDOBD>QLO 3EFP >MMIFBP CLO ">JBI SBOPFLK 2.3 LO KBTBO. (C VLR RPB >K LIABO SBOPFLK QEBK RPB QEFP DDOBD>QLO IFKH FKPQB>A. 5IF "HHSFHBUPS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP DPNCJOF B OVNCFS PG NFTTBHFT UPHFUIFS JOUP B TJOHMF NFTTBHF.

" DPSSFMBUJPO &YQSFTTJPO JT VTFE UP EFUFSNJOF UIF NFTTBHFT XIJDI TIPVME CF BHHSFHBUFE UPHFUIFS. *G ZPV XBOU UP BHHSFHBUF BMM NFTTBHFT JOUP B TJOHMF NFTTBHF, KVTU VTF B DPOTUBOU FYQSFTTJPO. "O "HHSFHBUJPO4USBUFHZ JT VTFE UP DPNCJOF BMM UIF NFTTBHF FYDIBOHFT GPS B TJOHMF DPSSFMBUJPO LFZ JOUP B TJOHMF NFTTBHF FYDIBOHF. DDOBD>QLO LMQFLKP 5IF BHHSFHBUPS TVQQPSUT UIF GPMMPXJOH PQUJPOT:
.MQFLK
DPSSFMBUJPO&YQSFTTJPO

#BC>RIQ
c

#BP@OFMQFLK
.BOEBUPSZ &YQSFTTJPO XIJDI FWBMVBUFT UIF DPSSFMBUJPO LFZ UP VTF GPS BHHSFHBUJPO. 5IF &YDIBOHF XIJDI IBT UIF TBNF DPSSFMBUJPO LFZ JT BHHSFHBUFE UPHFUIFS. *G UIF DPSSFMBUJPO LFZ DPVME OPU CF FWBMVBUFE BO &YDFQUJPO JT UISPXO. :PV DBO EJTBCMF UIJT CZ VTJOH UIF ignoreBadCorrelationKeys PQUJPO. .BOEBUPSZ AggregationStrategy XIJDI JT VTFE UP merge UIF JODPNJOH &YDIBOHF XJUI UIF FYJTUJOH BMSFBEZ NFSHFE FYDIBOHFT. "U GJSTU DBMM UIF oldExchange QBSBNFUFS JT null. 0O TVCTFRVFOU JOWPDBUJPOT UIF oldExchange DPOUBJOT UIF NFSHFE FYDIBOHFT BOE newExchange JT PG DPVSTF UIF OFX JODPNJOH &YDIBOHF. 'SPN ">JBI 2.9.2 POXBSET UIF TUSBUFHZ DBO BMTP CF B TimeoutAwareAggregationStrategy JNQMFNFOUBUJPO, TVQQPSUJOH UIF UJNFPVU DBMMCBDL, TFF GVSUIFS CFMPX GPS NPSF EFUBJMT. " SFGFSFODF UP MPPLVQ UIF AggregationStrategy JO UIF 3FHJTUSZ.

BHHSFHBUJPO4USBUFHZ

TUSBUFHZ3FG

436

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

(JMIBJBKQ>QFLK LC PE>OBA RKFQ LC TLOH 4P JO SFBMJUZ UIF VOJU PG XPSL JT OPU TIBSFE BT B TJOHMF PCKFDU JOTUBODF. *OTUFBE SubUnitOfWork JT BUUBDIFE UP UIFJS QBSFOU, BOE JTTVFT DBMMCBDL UP UIF QBSFOU BCPVU UIFJS TUBUVT (DPNNJU PS SPMMCBDL). 5IJT NBZ CF SFGBDUPSFE JO $BNFM 3.0 XIFSF MBSHFS "1* DIBOHFT DBO CF EPOF.
/VNCFS PG NFTTBHFT BHHSFHBUFE CFGPSF UIF BHHSFHBUJPO JT DPNQMFUF. 5IJT PQUJPO DBO CF TFU BT FJUIFS B GJYFE WBMVF PS VTJOH BO &YQSFTTJPO XIJDI BMMPXT ZPV UP FWBMVBUF B TJ[F EZOBNJDBMMZ - XJMM VTF Integer BT SFTVMU. *G CPUI BSF TFU $BNFM XJMM GBMMCBDL UP VTF UIF GJYFE WBMVF JG UIF &YQSFTTJPO SFTVMU XBT null PS 0. 5JNF JO NJMMJT UIBU BO BHHSFHBUFE FYDIBOHF TIPVME CF JOBDUJWF CFGPSF JUT DPNQMFUF. 5IJT PQUJPO DBO CF TFU BT FJUIFS B GJYFE WBMVF PS VTJOH BO &YQSFTTJPO XIJDI BMMPXT ZPV UP FWBMVBUF B UJNFPVU EZOBNJDBMMZ - XJMM VTF Long BT SFTVMU. *G CPUI BSF TFU $BNFM XJMM GBMMCBDL UP VTF UIF GJYFE WBMVF JG UIF &YQSFTTJPO SFTVMU XBT null PS 0. :PV DBOOPU VTF UIJT PQUJPO UPHFUIFS XJUI DPNQMFUJPO*OUFSWBM, POMZ POF PG UIF UXP DBO CF VTFE. " SFQFBUJOH QFSJPE JO NJMMJT CZ XIJDI UIF BHHSFHBUPS XJMM DPNQMFUF BMM DVSSFOU BHHSFHBUFE FYDIBOHFT. $BNFM IBT B CBDLHSPVOE UBTL XIJDI JT USJHHFSFE FWFSZ QFSJPE. :PV DBOOPU VTF UIJT PQUJPO UPHFUIFS XJUI DPNQMFUJPO5JNFPVU, POMZ POF PG UIFN DBO CF VTFE. " 1SFEJDBUF UP JOEJDBUF XIFO BO BHHSFHBUFE FYDIBOHF JT DPNQMFUF. 5IJT PQUJPO JT JG UIF FYDIBOHFT BSF DPNJOH GSPN B #BUDI $POTVNFS. 5IFO XIFO FOBCMFE UIF "HHSFHBUPS2 XJMM VTF UIF CBUDI TJ[F EFUFSNJOFE CZ UIF #BUDI $POTVNFS JO UIF NFTTBHF IFBEFS CamelBatchSize. 4FF NPSF EFUBJMT BU #BUDI $POTVNFS. 5IJT DBO CF VTFE UP BHHSFHBUF BMM GJMFT DPOTVNFE GSPN B 'JMF FOEQPJOU JO UIBU HJWFO QPMM. ">JBI 2.9 *OEJDBUFT UP DPNQMFUF BMM DVSSFOU BHHSFHBUFE FYDIBOHFT XIFO UIF DPOUFYU JT TUPQQFE 8IFUIFS PS OPU UP FBHFS DIFDL GPS DPNQMFUJPO XIFO B OFX JODPNJOH &YDIBOHF IBT CFFO SFDFJWFE. 5IJT PQUJPO JOGMVFODFT UIF CFIBWJPS PG UIF completionPredicate PQUJPO BT UIF &YDIBOHF CFJOH QBTTFE JO DIBOHFT BDDPSEJOHMZ. 8IFO false UIF &YDIBOHF QBTTFE JO UIF 1SFEJDBUF JT UIF aggregated &YDIBOHF XIJDI NFBOT BOZ JOGPSNBUJPO ZPV NBZ TUPSF PO UIF BHHSFHBUFE &YDIBOHF GSPN UIF AggregationStrategy JT BWBJMBCMF GPS UIF 1SFEJDBUF. 8IFO true UIF &YDIBOHF QBTTFE JO UIF 1SFEJDBUF JT UIF incoming &YDIBOHF, XIJDI NFBOT ZPV DBO BDDFTT EBUB GSPN UIF JODPNJOH &YDIBOHF. *G FOBCMFE UIFO $BNFM XJMM HSPVQ BMM BHHSFHBUFE &YDIBOHFT JOUP B TJOHMF DPNCJOFE org.apache.camel.impl.GroupedExchange IPMEFS DMBTT UIBU IPMET BMM UIF BHHSFHBUFE &YDIBOHFT. "OE BT B SFTVMU POMZ POF &YDIBOHF JT CFJOH TFOU PVU GSPN UIF BHHSFHBUPS. $BO CF VTFE UP DPNCJOF NBOZ JODPNJOH &YDIBOHFT JOUP B TJOHMF PVUQVU &YDIBOHF XJUIPVU DPEJOH B DVTUPN AggregationStrategy ZPVSTFMG. (JMLOQ>KQ: 5IJT PQUJPO EPFT KLQ TVQQPSU QFSTJTUBOU SFQPTJUPSZ XJUI UIF BHHSFHBUPS. 8IFUIFS PS OPU UP JHOPSF DPSSFMBUJPO LFZT XIJDI DPVME OPU CF FWBMVBUFE UP B WBMVF. #Z EFGBVMU $BNFM XJMM UISPX BO &YDFQUJPO, CVU ZPV DBO FOBCMF UIJT PQUJPO BOE JHOPSF UIF TJUVBUJPO JOTUFBE. 8IFUIFS PS OPU UPP late &YDIBOHFT TIPVME CF BDDFQUFE PS OPU. :PV DBO FOBCMF UIJT UP JOEJDBUF UIBU JG B DPSSFMBUJPO LFZ IBT BMSFBEZ CFFO DPNQMFUFE, UIFO BOZ OFX FYDIBOHFT XJUI UIF TBNF DPSSFMBUJPO LFZ CF EFOJFE. $BNFM XJMM UIFO UISPX B closedCorrelationKeyException FYDFQUJPO. 8IFO VTJOH UIJT PQUJPO ZPV QBTT JO B integer XIJDI JT B OVNCFS GPS B -36$BDIF XIJDI LFFQT UIBU MBTU 9 OVNCFS PG DMPTFE DPSSFMBUJPO LFZT. :PV DBO QBTT JO 0 PS B OFHBUJWF WBMVF UP JOEJDBUF B VOCPVOEFE DBDIF. #Z QBTTJOH JO B OVNCFS ZPV BSF FOTVSFE UIBU DBDIF XPO'U HSPX UPP CJH JG ZPV VTF B MPH PG EJGGFSFOU DPSSFMBUJPO LFZT. ">JBI 2.5: 8IFUIFS PS OPU FYDIBOHFT XIJDI DPNQMFUF EVF UP B UJNFPVU TIPVME CF EJTDBSEFE. *G FOBCMFE UIFO XIFO B UJNFPVU PDDVST UIF BHHSFHBUFE NFTTBHF XJMM KLQ CF TFOU PVU CVU ESPQQFE (EJTDBSEFE). "MMPXT ZPV UP QMVHJO ZPV PXO JNQMFNFOUBUJPO PG org.apache.camel.spi.AggregationRepository XIJDI LFFQT USBDL PG UIF DVSSFOU JOGMJHIU BHHSFHBUFE FYDIBOHFT. $BNFM VTFT CZ EFGBVMU B NFNPSZ CBTFE JNQMFNFOUBUJPO. 3FGFSFODF UP MPPLVQ B aggregationRepository JO UIF 3FHJTUSZ. 8IFO BHHSFHBUFE BSF DPNQMFUFE UIFZ BSF CFJOH TFOE PVU PG UIF BHHSFHBUPS. 5IJT PQUJPO JOEJDBUFT XIFUIFS PS OPU $BNFM TIPVME VTF B UISFBE QPPM XJUI NVMUJQMF UISFBET GPS DPODVSSFODZ. *G OP DVTUPN UISFBE QPPM IBT CFFO TQFDJGJFE UIFO $BNFM DSFBUFT B EFGBVMU QPPM XJUI 10 DPODVSSFOU UISFBET. *G VTJOH parallelProcessing ZPV DBO TQFDJGZ B DVTUPN UISFBE QPPM UP CF VTFE. *O GBDU BMTP JG ZPV BSF OPU VTJOH parallelProcessing UIJT DVTUPN UISFBE QPPM JT VTFE UP TFOE PVU BHHSFHBUFE FYDIBOHFT BT XFMM. 3FGFSFODF UP MPPLVQ B executorService JO UIF 3FHJTUSZ ">JBI 2.9: *G VTJOH FJUIFS PG UIF completionTimeout, completionTimeoutExpression, PS completionInterval PQUJPOT B CBDLHSPVOE UISFBE JT DSFBUFE UP DIFDL GPS UIF DPNQMFUJPO GPS FWFSZ BHHSFHBUPS. 4FU UIJT PQUJPO UP QSPWJEF B DVTUPN UISFBE QPPM UP CF VTFE SBUIFS UIBO DSFBUJOH B OFX UISFBE GPS FWFSZ BHHSFHBUPS. ">JBI 2.9: 3FGFSFODF UP MPPLVQ B timeoutCheckerExecutorService JO UIF 3FHJTUSZ ">JBI 2.11: 5VSOT PO VTJOH PQUJNJTUJD MPDLJOH, XIJDI SFRVJSFT UIF aggregationRepository CFJOH VTFE, JT TVQQPSUJOH UIJT CZ JNQMFNFOUJOH UIF org.apache.camel.spi.OptimisticLockingAggregationRepository JOUFSGBDF. 4FF GVSUIFS CFMPX GPS NPSF EFUBJMT.

DPNQMFUJPO4J[F

DPNQMFUJPO5JNFPVU

DPNQMFUJPO*OUFSWBM DPNQMFUJPO1SFEJDBUF DPNQMFUJPO'SPN#BUDI$POTVNFS GPSDF$PNQMFUJPO0O4UPQ

c c false false

FBHFS$IFDL$PNQMFUJPO

false

HSPVQ&YDIBOHFT

false

JHOPSF*OWBMJE$PSSFMBUJPO,FZT

false

DMPTF$PSSFMBUJPO,FZ0O$PNQMFUJPO

EJTDBSE0O$PNQMFUJPO5JNFPVU BHHSFHBUJPO3FQPTJUPSZ BHHSFHBUJPO3FQPTJUPSZ3FG QBSBMMFM1SPDFTTJOH

false c c false

FYFDVUPS4FSWJDF FYFDVUPS4FSWJDF3FG UJNFPVU$IFDLFS&YFDVUPS4FSWJDF UJNFPVU$IFDLFS&YFDVUPS4FSWJDF3FG

c c c c

PQUJNJTUJD-PDLJOH

false

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

437

$U@E>KDB /OLMBOQFBP 5IF GPMMPXJOH QSPQFSUJFT BSF TFU PO FBDI BHHSFHBUFE &YDIBOHF:
EB>ABO
CamelAggregatedSize CamelAggregatedCompletedBy

QVMB
JOU 4USJOH

ABP@OFMQFLK
5IF UPUBM OVNCFS PG &YDIBOHFT BHHSFHBUFE JOUP UIJT DPNCJOFE &YDIBOHF. *OEJDBUPS IPX UIF BHHSFHBUJPO XBT DPNQMFUFE BT B WBMVF PG FJUIFS: predicate, size, consumer, timeout PS interval.

?LRQ

DDOBD>QFLK2QO>QBDV

5IF AggregationStrategy JT VTFE GPS BHHSFHBUJOH UIF PME (MPPLVQ CZ JUT DPSSFMBUJPO JE) BOE UIF OFX FYDIBOHFT UPHFUIFS JOUP B TJOHMF FYDIBOHF. 1PTTJCMF JNQMFNFOUBUJPOT JODMVEF QFSGPSNJOH TPNF LJOE PG DPNCJOJOH PS EFMUB QSPDFTTJOH, TVDI BT BEEJOH MJOF JUFNT UPHFUIFS JOUP BO JOWPJDF PS KVTU VTJOH UIF OFXFTU FYDIBOHF BOE SFNPWJOH PME FYDIBOHFT TVDI BT GPS TUBUF USBDLJOH PS NBSLFU EBUB QSJDFT; XIFSF PME WBMVFT BSF PG MJUUMF VTF. /PUJDF UIF BHHSFHBUJPO TUSBUFHZ JT B NBOEBUPSZ PQUJPO BOE NVTU CF QSPWJEFE UP UIF BHHSFHBUPS. )FSF BSF B GFX FYBNQMF "HHSFHBUJPO4USBUFHZ JNQMFNFOUBUJPOT UIBU TIPVME IFMQ ZPV DSFBUF ZPVS PXO DVTUPN TUSBUFHZ.
//simply combines Exchange String body values using '+' as a delimiter class StringAggregationStrategy implements AggregationStrategy { public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { if (oldExchange == null) { return newExchange; } String oldBody = oldExchange.getIn().getBody(String.class); String newBody = newExchange.getIn().getBody(String.class); oldExchange.getIn().setBody(oldBody + "+" + newBody); return oldExchange; } } //simply combines Exchange body values into an ArrayList<Object> class ArrayListAggregationStrategy implements AggregationStrategy { public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { Object newBody = newExchange.getIn().getBody(); ArrayList<Object> list = null; if (oldExchange == null) { list = new ArrayList<Object>(); list.add(newBody); newExchange.getIn().setBody(list); return newExchange; } else { list = oldExchange.getIn().getBody(ArrayList.class); list.add(newBody); return oldExchange;

438

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

} } }

?LRQ @LJMIBQFLK 8IFO BHHSFHBUJPO &YDIBOHFT BU TPNF QPJOU ZPV OFFE UP JOEJDBUF UIBU UIF BHHSFHBUFE FYDIBOHFT JT DPNQMFUF, TP UIFZ DBO CF TFOE PVU PG UIF BHHSFHBUPS. $BNFM BMMPXT ZPV UP JOEJDBUF DPNQMFUJPO JO WBSJPVT XBZT BT GPMMPXT: DPNQMFUJPO5JNFPVU - *T BO JOBDUJWJUZ UJNFPVU JO XIJDI JT USJHHFSFE JG OP OFX FYDIBOHFT IBWF CFFO BHHSFHBUFE GPS UIBU QBSUJDVMBS DPSSFMBUJPO LFZ XJUIJO UIF QFSJPE. DPNQMFUJPO*OUFSWBM - 0ODF FWFSZ 9 QFSJPE BMM UIF DVSSFOU BHHSFHBUFE FYDIBOHFT BSF DPNQMFUFE. DPNQMFUJPO4J[F - *T B OVNCFS JOEJDBUJOH UIBU BGUFS 9 BHHSFHBUFE FYDIBOHFT JU'T DPNQMFUF. DPNQMFUJPO1SFEJDBUF - 3VOT B 1SFEJDBUF XIFO B OFX FYDIBOHF JT BHHSFHBUFE UP EFUFSNJOF JG XF BSF DPNQMFUF PS OPU DPNQMFUJPO'SPN#BUDI$POTVNFS - 4QFDJBM PQUJPO GPS #BUDI $POTVNFS XIJDI BMMPXT ZPV UP DPNQMFUF XIFO BMM UIF NFTTBHFT GSPN UIF CBUDI IBT CFFO BHHSFHBUFE. GPSDF$PNQMFUJPO0O4UPQ - ">JBI 2.9 *OEJDBUFT UP DPNQMFUF BMM DVSSFOU BHHSFHBUFE FYDIBOHFT XIFO UIF DPOUFYU JT TUPQQFE /PUJDF UIBU BMM UIF DPNQMFUJPO XBZT BSF QFS DPSSFMBUJPO LFZ. "OE ZPV DBO DPNCJOF UIFN JO BOZ XBZ ZPV MJLF. *U'T CBTJDBMMZ UIF GJSTU XIJDI USJHHFST UIBU XJOT. 4P ZPV DBO VTF B DPNQMFUJPO TJ[F UPHFUIFS XJUI B DPNQMFUJPO UJNFPVU. 0OMZ DPNQMFUJPO5JNFPVU BOE DPNQMFUJPO*OUFSWBM DBOOPU CF VTFE BU UIF TBNF UJNF. /PUJDF UIF DPNQMFUJPO JT B NBOEBUPSZ PQUJPO BOE NVTU CF QSPWJEFE UP UIF BHHSFHBUPS. *G OPU QSPWJEFE $BNFM XJMM UISPXO BO &YDFQUJPO PO TUBSUVQ. /BOPFPQBKQ DDOBD>QFLK1BMLPFQLOV

5IF BHHSFHBUPS QSPWJEFT B QMVHHBCMF SFQPTJUPSZ XIJDI ZPV DBO JNQMFNFOU ZPVS PXO org.apache.camel.spi.AggregationRepository. *G ZPV OFFE QFSTJTUFOU SFQPTJUPSZ UIFO ZPV DBO VTF FJUIFS $BNFM )BXU%# PS 42- $PNQPOFOU DPNQPOFOUT. $U>JMIBP 4FF TPNF FYBNQMFT GSPN UIF PME "HHSFHBUPS XIJDI JT TPNFXIBU TJNJMBS UP UIJT OFX BHHSFHBUPS.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

439

">II?>@HP 4FF UIF TimeoutAwareAggregationStrategy BOE CompletionAwareAggregationStrategy FYUFOTJPOT UP AggregationStrategy UIBU IBT DBMMCBDLT XIFO UIF BHHSFHBUFE &YDIBOHF XBT DPNQMFUFE BOE JG B UJNFPVU PDDVSSFE.

2BQQFKD LMQFLKP FK 2MOFKD 7,+ .BOZ PG UIF PQUJPOT BSF DPOGJHVSBCMF BT BUUSJCVUFT PO UIF <aggregate> UBH XIFO VTJOH 4QSJOH 9.-.

4PFKD @LJMIBQFLK3FJBLRQ
*O UIJT FYBNQMF XF XBOU UP BHHSFHBUF BMM JODPNJOH NFTTBHFT BOE BGUFS 3 TFDPOET PG JOBDUJWJUZ XF XBOU UIF BHHSFHBUJPO UP DPNQMFUF. 5IJT JT EPOF VTJOH UIF completionTimeout PQUJPO BT TIPXO:
from("direct:start") // aggregate all exchanges correlated by the id header. // Aggregate them using the BodyInAggregatingStrategy strategy which // and after 3 seconds of inactivity them timeout and complete the aggregation // and send it to mock:aggregated .aggregate(header("id"), new BodyInAggregatingStrategy()).completionTimeout(3000) .to("mock:aggregated");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <aggregate strategyRef="aggregatorStrategy" completionTimeout="3000"> <correlationExpression> <simple>header.id</simple> </correlationExpression> <to uri="mock:aggregated"/> </aggregate> </route> </camelContext> <bean id="aggregatorStrategy" class="org.apache.camel.processor.BodyInAggregatingStrategy"/>

440

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4PFKD 3FJBLRQ T>OB DDOBD>QFLK2QO>QBDV


S>FI>?IB >P LC ">JBI 2.9.2 *G ZPVS BHHSFHBUJPO TUSBUFHZ JNQMFNFOUT TimeoutAwareAggregationStrategy, UIFO $BNFM XJMM JOWPLF UIF timeout NFUIPE XIFO UIF UJNFPVU PDDVST. /PUJDF UIBU UIF WBMVFT GPS JOEFY BOE UPUBM QBSBNFUFST XJMM CF -1, BOE UIF UJNFPVU QBSBNFUFS XJMM CF QSPWJEFE POMZ JG DPOGJHVSFE BT B GJYFE WBMVF. :PV NVTU KLQ UISPX BOZ FYDFQUJPOT GSPN UIF timeout NFUIPE.

4PFKD "LJMIBQFLK T>OB DDOBD>QFLK2QO>QBDV


S>FI>?IB >P LC ">JBI 2.9.3 *G ZPVS BHHSFHBUJPO TUSBUFHZ JNQMFNFOUT CompletionAwareAggregationStrategy, UIFO $BNFM XJMM JOWPLF UIF onComplete NFUIPE XIFO UIF BHHSFHBUFE &YDIBOHF JT DPNQMFUFE. 5IJT BMMPXT ZPV UP EP BOZ MBTU NJOVUF DVTUPN MPHJD TVDI BT UP DMFBOVQ TPNF SFTPVSDFT, PS BEEJUJPOBM XPSL PO UIF FYDIBOHF BT JU'T OPX DPNQMFUFE. :PV NVTU KLQ UISPX BOZ FYDFQUJPOT GSPN UIF onCompletion NFUIPE.

4PFKD @LJMIBQFLK2FWB
*O UIJT FYBNQMF XF XBOU UP BHHSFHBUF BMM JODPNJOH NFTTBHFT BOE XIFO XF IBWF 3 NFTTBHFT BHHSFHBUFE (JO UIF TBNF DPSSFMBUJPO HSPVQ) XF XBOU UIF BHHSFHBUJPO UP DPNQMFUF. 5IJT JT EPOF VTJOH UIF completionSize PQUJPO BT TIPXO:
from("direct:start") // aggregate all exchanges correlated by the id header. // Aggregate them using the BodyInAggregatingStrategy strategy which // and after 3 messages has been aggregated then complete the aggregation // and send it to mock:aggregated .aggregate(header("id"), new BodyInAggregatingStrategy()).completionSize(3) .to("mock:aggregated");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <aggregate strategyRef="aggregatorStrategy" completionSize="3"> <correlationExpression> <simple>header.id</simple> </correlationExpression> <to uri="mock:aggregated"/> </aggregate> </route> </camelContext>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

441

<bean id="aggregatorStrategy" class="org.apache.camel.processor.BodyInAggregatingStrategy"/>

4PFKD @LJMIBQFLK/OBAF@>QB
*O UIJT FYBNQMF XF XBOU UP BHHSFHBUF BMM JODPNJOH NFTTBHFT BOE VTF B 1SFEJDBUF UP EFUFSNJOF XIFO XF BSF DPNQMFUF. 5IF 1SFEJDBUF DBO CF FWBMVBUFE VTJOH FJUIFS UIF BHHSFHBUFE FYDIBOHF (EFGBVMU) PS UIF JODPNJOH FYDIBOHF. 8F XJMM TP CPUI TJUVBUJPOT BT FYBNQMFT. 8F TUBSU XJUI UIF EFGBVMU TJUVBUJPO BT TIPXO:
from("direct:start") // aggregate all exchanges correlated by the id header. // Aggregate them using the BodyInAggregatingStrategy strategy which // and when the aggregated body contains A+B+C then complete the aggregation // and send it to mock:aggregated .aggregate(header("id"), new BodyInAggregatingStrategy()).completionPredicate(body().contains("A+B+C")) .to("mock:aggregated");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <aggregate strategyRef="aggregatorStrategy"> <correlationExpression> <simple>header.id</simple> </correlationExpression> <completionPredicate> <simple>${body} contains 'A+B+C'</simple> </completionPredicate> <to uri="mock:aggregated"/> </aggregate> </route> </camelContext> <bean id="aggregatorStrategy" class="org.apache.camel.processor.BodyInAggregatingStrategy"/>

"OE UIF PUIFS TJUVBUJPO XIFSF XF VTF UIF eagerCheckCompletion PQUJPO UP UFMM $BNFM UP VTF UIF JODPNJOH &YDIBOHF. /PUJDF IPX XF DBO KVTU UFTU JO UIF DPNQMFUJPO QSFEJDBUF UIBU UIF JODPNJOH NFTTBHF JT UIF END NFTTBHF:
from("direct:start") // aggregate all exchanges correlated by the id header. // Aggregate them using the BodyInAggregatingStrategy strategy

442

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

// do eager checking which means the completion predicate will use the incoming exchange // which allows us to trigger completion when a certain exchange arrived which is the // END message .aggregate(header("id"), new BodyInAggregatingStrategy()) .eagerCheckCompletion().completionPredicate(body().isEqualTo("END")) .to("mock:aggregated");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <aggregate strategyRef="aggregatorStrategy" eagerCheckCompletion="true"> <correlationExpression> <simple>header.id</simple> </correlationExpression> <completionPredicate> <simple>${body} == 'END'</simple> </completionPredicate> <to uri="mock:aggregated"/> </aggregate> </route> </camelContext> <bean id="aggregatorStrategy" class="org.apache.camel.processor.BodyInAggregatingStrategy"/>

4PFKD AVK>JF@ @LJMIBQFLK3FJBLRQ


*O UIJT FYBNQMF XF XBOU UP BHHSFHBUF BMM JODPNJOH NFTTBHFT BOE BGUFS B QFSJPE PG JOBDUJWJUZ XF XBOU UIF BHHSFHBUJPO UP DPNQMFUF. 5IF QFSJPE TIPVME CF DPNQVUFE BU SVOUJNF CBTFE PO UIF timeout IFBEFS JO UIF JODPNJOH NFTTBHFT. 5IJT JT EPOF VTJOH UIF completionTimeout PQUJPO BT TIPXO:
from("direct:start") // aggregate all exchanges correlated by the id header. // Aggregate them using the BodyInAggregatingStrategy strategy which // and the timeout header contains the timeout in millis of inactivity them timeout and complete the aggregation // and send it to mock:aggregated .aggregate(header("id"), new BodyInAggregatingStrategy()).completionTimeout(header("timeout")) .to("mock:aggregated");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

443

<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <aggregate strategyRef="aggregatorStrategy"> <correlationExpression> <simple>header.id</simple> </correlationExpression> <completionTimeout> <header>timeout</header> </completionTimeout> <to uri="mock:aggregated"/> </aggregate> </route> </camelContext> <bean id="aggregatorStrategy" class="org.apache.camel.processor.BodyInAggregatingStrategy"/>

-LQB: :PV DBO BMTP BEE B GJYFE UJNFPVU WBMVF BOE $BNFM XJMM GBMMCBDL UP VTF UIJT WBMVF JG UIF EZOBNJD WBMVF XBT null PS 0.

4PFKD AVK>JF@ @LJMIBQFLK2FWB


*O UIJT FYBNQMF XF XBOU UP BHHSFHBUF BMM JODPNJOH NFTTBHFT CBTFE PO B EZOBNJD TJ[F QFS DPSSFMBUJPO LFZ. 5IF TJ[F JT DPNQVUFE BU SVOUJNF CBTFE PO UIF mySize IFBEFS JO UIF JODPNJOH NFTTBHFT. 5IJT JT EPOF VTJOH UIF completionSize PQUJPO BT TIPXO:
from("direct:start") // aggregate all exchanges correlated by the id header. // Aggregate them using the BodyInAggregatingStrategy strategy which // and the header mySize determines the number of aggregated messages should trigger the completion // and send it to mock:aggregated .aggregate(header("id"), new BodyInAggregatingStrategy()).completionSize(header("mySize")) .to("mock:aggregated");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <aggregate strategyRef="aggregatorStrategy"> <correlationExpression> <simple>header.id</simple> </correlationExpression> <completionSize> <header>mySize</header>

444

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

</completionSize> <to uri="mock:aggregated"/> </aggregate> </route> </camelContext> <bean id="aggregatorStrategy" class="org.apache.camel.processor.BodyInAggregatingStrategy"/>

-LQB: :PV DBO BMTP BEE B GJYFE TJ[F WBMVF BOE $BNFM XJMM GBMMCBDL UP VTF UIJT WBMVF JG UIF EZOBNJD WBMVF XBT null PS 0.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

,>KR>IIV %LO@B QEB "LJMIBQFLK LC (JJBAF>QBIV

II

DDOBD>QBA $U@E>KDBP

S>FI>?IB >P LC ">JBI 2.9 :PV DBO NBOVBMMZ USJHHFS DPNQMFUJPO PG BMM DVSSFOU BHHSFHBUFE FYDIBOHFT CZ TFOEJOH B NFTTBHF DPOUBJOJOH UIF IFBEFS &YDIBOHF."((3&("5*0/@$0.1-&5&@"--@(30614 TFU UP USVF. 5IF NFTTBHF JT DPOTJEFSFE B TJHOBM NFTTBHF POMZ, UIF NFTTBHF IFBEFST/DPOUFOUT XJMM OPU CF QSPDFTTFE PUIFSXJTF. S>FI>?IB >P LC ">JBI 2.11 :PV DBO BMUFSOBUJWFMZ TFU UIF IFBEFS &YDIBOHF."((3&("5*0/@$0.1-&5&@"--@(30614@*/$-64*7& UP USVF UP USJHHFS DPNQMFUJPO PG BMM HSPVQT BGUFS QSPDFTTJOH UIF DVSSFOU NFTTBHF.

4PFKD > +FPQ<5> FK

DDOBD>QFLK2QO>QBDV

S>FI>?IB >P LC ">JBI 2.11 *G ZPV XBOU UP BHHSFHBUF TPNF WBMVF GSPN UIF NFTTBHFT <7> JOUP B -JTU<7> UIFO XF IBWF BEEFE B org.apache.camel.processor.aggregate.AbstractListAggregationStrategy BCTUSBDU DMBTT JO ">JBI 2.11 UIBU NBLFT UIJT FBTJFS. 5IF DPNQMFUFE &YDIBOHF UIBU JT TFOU PVU PG UIF BHHSFHBUPS XJMM DPOUBJO UIF -JTU<7> JO UIF NFTTBHF CPEZ. 'PS FYBNQMF UP BHHSFHBUF B -JTU<*OUFHFS> ZPV DBO FYUFOE UIJT DMBTT BT TIPXO CFMPX, BOE JNQMFNFOU UIF getValue NFUIPE:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

445

/** * Our strategy just group a list of integers. */ public final class MyListOfNumbersStrategy extends AbstractListAggregationStrategy<Integer> { @Override public Integer getValue(Exchange exchange) { // the message body contains a number, so just return that as-is return exchange.getIn().getBody(Integer.class); } }

2BB >IPL 5IF -PBO #SPLFS &YBNQMF XIJDI VTFT BO BHHSFHBUPS #MPH QPTU CZ 5PSTUFO .JFMLF BCPVU VTJOH UIF BHHSFHBUPS DPSSFDUMZ. 5IF PME "HHSFHBUPS )BXU%# PS 42- $PNQPOFOU GPS QFSTJTUFODF TVQQPSU "HHSFHBUF &YBNQMF GPS BO FYBNQMF BQQMJDBUJPO

1BPBNRBK@BO 5IF 3FTFRVFODFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SFPSHBOJTF NFTTBHFT CBTFE PO TPNF DPNQBSBUPS. #Z EFGBVMU JO $BNFM XF VTF BO &YQSFTTJPO UP DSFBUF UIF DPNQBSBUPS; TP UIBU ZPV DBO DPNQBSF CZ B NFTTBHF IFBEFS PS UIF CPEZ PS B QJFDF PG B NFTTBHF FUD.

$BNFM TVQQPSUT UXP SFTFRVFODJOH BMHPSJUINT: ` !>Q@E OBPBNRBK@FKD DPMMFDUT NFTTBHFT JOUP B CBUDI, TPSUT UIF NFTTBHFT BOE TFOET UIFN UP UIFJS PVUQVU. ` 2QOB>J OBPBNRBK@FKD SF-PSEFST (DPOUJOVPVT) NFTTBHF TUSFBNT CBTFE PO UIF EFUFDUJPO PG HBQT CFUXFFO NFTTBHFT. #Z EFGBVMU UIF 3FTFRVFODFS EPFT OPU TVQQPSU EVQMJDBUF NFTTBHFT BOE XJMM POMZ LFFQ UIF MBTU NFTTBHF, JO DBTF B NFTTBHF BSSJWFT XJUI UIF TBNF NFTTBHF FYQSFTTJPO. )PXFWFS JO UIF CBUDI NPEF ZPV DBO FOBCMF JU UP BMMPX EVQMJDBUFT. !>Q@E 1BPBNRBK@FKD 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP VTF UIF CBUDI-QSPDFTTJOH SFTFRVFODFS TP UIBU NFTTBHFT BSF TPSUFE JO PSEFS PG UIF ?LAV() FYQSFTTJPO. 5IBU JT NFTTBHFT BSF DPMMFDUFE JOUP B CBUDI

446

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

"E>KDB FK ">JBI 2.7 5IF <batch-config> BOE <stream-config> UBHT JO 9.- %4- JO UIF 3FTFRVFODFS &*1 NVTU OPX CF DPOGJHVSFE JO UIF UPQ, BOE OPU JO UIF CPUUPN. 4P JG ZPV VTF UIPTF, UIFO NPWF UIFN VQ KVTU CFMPX UIF <resequence> &*1 TUBSUT JO UIF 9.-. *G ZPV BSF VTJOH $BNFM PMEFS UIBO 2.7, UIFO UIPTF DPOGJHT TIPVME CF BU UIF CPUUPN. (FJUIFS CZ B NBYJNVN OVNCFS PG NFTTBHFT QFS CBUDI PS VTJOH B UJNFPVU) UIFO UIFZ BSF TPSUFE JO PSEFS BOE UIFO TFOU PVU UP UIFJS PVUQVU. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:start") .resequence().body() .to("mock:result");

5IJT JT FRVWBMFOU UP
from("direct:start") .resequence(body()).batch() .to("mock:result");

5IF CBUDI-QSPDFTTJOH SFTFRVFODFS DBO CF GVSUIFS DPOGJHVSFE WJB UIF size() BOE timeout() NFUIPET.
from("direct:start") .resequence(body()).batch().size(300).timeout(4000L) .to("mock:result")

5IJT TFUT UIF CBUDI TJ[F UP 300 BOE UIF CBUDI UJNFPVU UP 4000 NT (CZ EFGBVMU, UIF CBUDI TJ[F JT 100 BOE UIF UJNFPVU JT 1000 NT). "MUFSOBUJWFMZ, ZPV DBO QSPWJEF B DPOGJHVSBUJPO PCKFDU.
from("direct:start") .resequence(body()).batch(new BatchResequencerConfig(300, 4000L)) .to("mock:result")

4P UIF BCPWF FYBNQMF XJMM SFPSEFS NFTTBHFT GSPN FOEQPJOU AFOB@Q:> JO PSEFS PG UIFJS CPEJFT, UP UIF FOEQPJOU JL@H:OBPRIQ. 5ZQJDBMMZ ZPV'E VTF B IFBEFS SBUIFS UIBO UIF CPEZ UP PSEFS UIJOHT; PS NBZCF B QBSU PG UIF CPEZ. 4P ZPV DPVME SFQMBDF UIJT FYQSFTTJPO XJUI
resequencer(header("mySeqNo"))

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

447

GPS FYBNQMF UP SFPSEFS NFTTBHFT VTJOH B DVTUPN TFRVFODF OVNCFS JO UIF IFBEFS mySeqNo. :PV DBO PG DPVSTF VTF NBOZ EJGGFSFOU &YQSFTTJPO MBOHVBHFT TVDI BT 91BUI, 92VFSZ, 42- PS WBSJPVT 4DSJQUJOH -BOHVBHFT. 4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start" /> <resequence> <simple>body</simple> <to uri="mock:result" /> <!-batch-config can be ommitted for default (batch) resequencer settings --> <batch-config batchSize="300" batchTimeout="4000" /> </resequence> </route> </camelContext>

IILT #RMIF@>QBP
S>FI>?IB >P LC ">JBI 2.4 *O UIF batch NPEF, ZPV DBO OPX BMMPX EVQMJDBUFT. *O +BWB %4- UIFSF JT B allowDuplicates() NFUIPE BOE JO 4QSJOH 9.- UIFSF JT BO allowDuplicates=true BUUSJCVUF PO UIF <batch-config/> ZPV DBO VTF UP FOBCMF JU.

1BSBOPB
S>FI>?IB >P LC ">JBI 2.4 *O UIF batch NPEF, ZPV DBO OPX SFWFSTF UIF FYQSFTTJPO PSEFSJOH. #Z EFGBVMU UIF PSEFS JT CBTFE PO 0..9,"..;, XIJDI XPVME MFU NFTTBHFT XJUI MPX OVNCFST CF PSEFSFE GJSTU, BOE UIVT BMTP BMTP PVUHPJOH GJSTU. *O TPNF DBTFT ZPV XBOU UP SFWFSTF PSEFS, XIJDI JT OPX QPTTJCMF. *O +BWB %4- UIFSF JT B reverse() NFUIPE BOE JO 4QSJOH 9.- UIFSF JT BO reverse=true BUUSJCVUF PO UIF <batch-config/> ZPV DBO VTF UP FOBCMF JU.

1BPBNRBK@B ),2 JBPP>DBP ?>PBA LK ),2/OFLOFQV


S>FI>?IB >P LC ">JBI 2.4 *U'T OPX NVDI FBTJFS UP VTF UIF 3FTFRVFODFS UP SFTFRVFODF NFTTBHFT GSPN +.4 RVFVFT CBTFE PO JMSPriority. 'PS UIBU UP XPSL ZPV OFFE UP VTF UIF UXP OFX PQUJPOT allowDuplicates BOE reverse.

448

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

from("jms:queue:foo") // sort by JMSPriority by allowing duplicates (message can have same JMSPriority) // and use reverse ordering so 9 is first output (most important), and 0 is last // use batch mode and fire every 3th second .resequence(header("JMSPriority")).batch().timeout(3000).allowDuplicates().reverse() .to("mock:result");

/PUJDF UIJT JT LKIV QPTTJCMF JO UIF batch NPEF PG UIF 3FTFRVFODFS.

(DKLOB FKS>IFA BU@E>KDBP


S>FI>?IB >P LC ">JBI 2.9 5IF 3FTFRVFODFS &*1 XJMM GSPN $BNFM 2.9 POXBSET UISPX B CamelExchangeException JG UIF JODPNJOH &YDIBOHF JT OPU WBMJE GPS UIF SFTFRVFODFS - JF. UIF FYQSFTTJPO DBOOPU CF FWBMVBUFE, TVDI BT B NJTTJOH IFBEFS. :PV DBO VTF UIF PQUJPO ignoreInvalidExchanges UP JHOPSF UIFTF FYDFQUJPOT XIJDI NFBOT UIF 3FTFRVFODFS XJMM UIFO TLJQ UIF JOWBMJE &YDIBOHF.
from("direct:start") .resequence(header("seqno")).batch().timeout(1000) // ignore invalid exchanges (they are discarded) .ignoreInvalidExchanges() .to("mock:result");

5IJT PQUJPO JT BWBJMBCMF GPS CPUI CBUDI BOE TUSFBN SFTFRVFODFS.

1BGB@Q .IA $U@E>KDBP


S>FI>?IB >P LC ">JBI 2.11 5IJT PQUJPO DBO CF VTFE UP QSFWFOU PVU PG PSEFS NFTTBHFT GSPN CFJOH TFOU SFHBSEMFTT PG UIF FWFOU UIBU EFMJWFSFE NFTTBHFT EPXOTUSFBN (DBQBDJUZ, UJNFPVU, FUD). *G FOBCMFE VTJOH rejectOld(), UIF 3FTFRVFODFS XJMM UISPX B MessageRejectedException XIFO BO JODPNJOH &YDIBOHF JT "PMEFS" (CBTFE PO UIF $PNQBSBUPS) UIBO UIF MBTU EFMJWFSFE NFTTBHF. 5IJT QSPWJEFT BO FYUSB MFWFM PG DPOUSPM XJUI SFHBSET UP EFMBZFE NFTTBHF PSEFSJOH.
from("direct:start") .onException(MessageRejectedException.class).handled(true).to("mock:error").end() .resequence(header("seqno")).stream().timeout(1000).rejectOld() .to("mock:result");

5IJT PQUJPO JT BWBJMBCMF GPS UIF TUSFBN SFTFRVFODFS POMZ.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

449

2QOB>J 1BPBNRBK@FKD 5IF OFYU FYBNQMF TIPXT IPX UP VTF UIF TUSFBN-QSPDFTTJOH SFTFRVFODFS. .FTTBHFT BSF SFPSEFSFE CBTFE PO UIFJS TFRVFODF OVNCFST HJWFO CZ B seqnum IFBEFS VTJOH HBQ EFUFDUJPO BOE UJNFPVUT PO UIF MFWFM PG JOEJWJEVBM NFTTBHFT. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:start").resequence(header("seqnum")).stream().to("mock:result");

5IF TUSFBN-QSPDFTTJOH SFTFRVFODFS DBO CF GVSUIFS DPOGJHVSFE WJB UIF capacity() BOE timeout() NFUIPET.
from("direct:start") .resequence(header("seqnum")).stream().capacity(5000).timeout(4000L) .to("mock:result")

5IJT TFUT UIF SFTFRVFODFS'T DBQBDJUZ UP 5000 BOE UIF UJNFPVU UP 4000 NT (CZ EFGBVMU, UIF DBQBDJUZ JT 1000 BOE UIF UJNFPVU JT 1000 NT). "MUFSOBUJWFMZ, ZPV DBO QSPWJEF B DPOGJHVSBUJPO PCKFDU.
from("direct:start") .resequence(header("seqnum")).stream(new StreamResequencerConfig(5000, 4000L)) .to("mock:result")

5IF TUSFBN-QSPDFTTJOH SFTFRVFODFS BMHPSJUIN JT CBTFE PO UIF EFUFDUJPO PG HBQT JO B NFTTBHF TUSFBN SBUIFS UIBO PO B GJYFE CBUDI TJ[F. (BQ EFUFDUJPO JO DPNCJOBUJPO XJUI UJNFPVUT SFNPWFT UIF DPOTUSBJOU PG IBWJOH UP LOPX UIF OVNCFS PG NFTTBHFT PG B TFRVFODF (J.F. UIF CBUDI TJ[F) JO BEWBODF. .FTTBHFT NVTU DPOUBJO B VOJRVF TFRVFODF OVNCFS GPS XIJDI B QSFEFDFTTPS BOE B TVDDFTTPS JT LOPXO. 'PS FYBNQMF B NFTTBHF XJUI UIF TFRVFODF OVNCFS 3 IBT B QSFEFDFTTPS NFTTBHF XJUI UIF TFRVFODF OVNCFS 2 BOE B TVDDFTTPS NFTTBHF XJUI UIF TFRVFODF OVNCFS 4. 5IF NFTTBHF TFRVFODF 2,3,5 IBT B HBQ CFDBVTF UIF TVDFTTPS PG 3 JT NJTTJOH. 5IF SFTFRVFODFS UIFSFGPSF IBT UP SFUBJO NFTTBHF 5 VOUJM NFTTBHF 4 BSSJWFT (PS B UJNFPVU PDDVST). *G UIF NBYJNVN UJNF EJGGFSFODF CFUXFFO NFTTBHFT (XJUI TVDDFTTPS/QSFEFDFTTPS SFMBUJPOTIJQ XJUI SFTQFDU UP UIF TFRVFODF OVNCFS) JO B NFTTBHF TUSFBN JT LOPXO, UIFO UIF SFTFRVFODFS'T UJNFPVU QBSBNFUFS TIPVME CF TFU UP UIJT WBMVF. *O UIJT DBTF JU JT HVBSBOUFFE UIBU BMM NFTTBHFT PG B TUSFBN BSF EFMJWFSFE JO DPSSFDU PSEFS UP UIF OFYU QSPDFTTPS. 5IF MPXFS UIF UJNFPVU WBMVF JT DPNQBSFE UP UIF PVU-PG-TFRVFODF UJNF EJGGFSFODF UIF IJHIFS JT UIF QSPCBCJMJUZ GPS PVU-PGTFRVFODF NFTTBHFT EFMJWFSFE CZ UIJT SFTFRVFODFS. -BSHF UJNFPVU WBMVFT TIPVME CF TVQQPSUFE CZ TVGGJDJFOUMZ IJHI DBQBDJUZ WBMVFT. 5IF DBQBDJUZ QBSBNFUFS JT VTFE UP QSFWFOU UIF SFTFRVFODFS GSPN SVOOJOH PVU PG NFNPSZ. #Z EFGBVMU, UIF TUSFBN SFTFRVFODFS FYQFDUT long TFRVFODF OVNCFST CVU PUIFS TFRVFODF OVNCFST UZQFT DBO CF TVQQPSUFE BT XFMM CZ QSPWJEJOH B DVTUPN FYQSFTTJPO.

450

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

public class MyFileNameExpression implements Expression { public String getFileName(Exchange exchange) { return exchange.getIn().getBody(String.class); } public Object evaluate(Exchange exchange) { // parser the file name with YYYYMMDD-DNNN pattern String fileName = getFileName(exchange); String[] files = fileName.split("-D"); Long answer = Long.parseLong(files[0]) * 1000 + Long.parseLong(files[1]); return answer; }

public <T> T evaluate(Exchange exchange, Class<T> type) { Object result = evaluate(exchange); return exchange.getContext().getTypeConverter().convertTo(type, result); } }

from("direct:start").resequence(new MyFileNameExpression()).stream().timeout(100).to("mock:result");

PS DVTUPN DPNQBSBUPS WJB UIF comparator() NFUIPE


ExpressionResultComparator<Exchange> comparator = new MyComparator(); from("direct:start") .resequence(header("seqnum")).stream().comparator(comparator) .to("mock:result");

PS WJB B StreamResequencerConfig PCKFDU.


ExpressionResultComparator<Exchange> comparator = new MyComparator(); StreamResequencerConfig config = new StreamResequencerConfig(100, 1000L, comparator); from("direct:start") .resequence(header("seqnum")).stream(config) .to("mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <resequence> <simple>in.header.seqnum</simple>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

451

<to uri="mock:result" /> <stream-config capacity="5000" timeout="4000"/> </resequence> </route> </camelContext>

%ROQEBO $U>JMIBP 'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF CBUDI-QSPDFTTJOH SFTFRVFODFS KVOJU UFTU DBTF BOE UIF TUSFBN-QSPDFTTJOH SFTFRVFODFS KVOJU UFTU DBTF

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. "LJMLPBA ,BPP>DB /OL@BPPLO 5IF $PNQPTFE .FTTBHF 1SPDFTTPS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP QSPDFTT B DPNQPTJUF NFTTBHF CZ TQMJUUJOH JU VQ, SPVUJOH UIF TVC-NFTTBHFT UP BQQSPQSJBUF EFTUJOBUJPOT BOE UIF SFBHHSFHBUJOH UIF SFTQPOTFT CBDL JOUP B TJOHMF NFTTBHF.

*O $BNFM XF QSPWJEF UXP TPMVUJPOT VTJOH CPUI B 4QMJUUFS BOE "HHSFHBUPS &*1T VTJOH POMZ B 4QMJUUFS 5IF EJGGFSFODF JT XIFO VTJOH POMZ B 4QMJUUFS JU BHHSFHBUFT CBDL BMM UIF TQMJUUFE NFTTBHFT JOUP UIF TBNF BHHSFHBUJPO HSPVQ, FH MJLF B GPSL/KPJO QBUUFSO. 8IFSFBT VTJOH UIF "HHSFHBUPS BMMPXT ZPV HSPVQ JOUP NVMUJQMF HSPVQT, B QBUUFSO XIJDI QSPWJEFT NPSF PQUJPOT.

452

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

6TJOH UIF TQMJUUFS BMPOF JT PGUFO FBTJFS BOE QPTTJCMZ B CFUUFS TPMVUJPO. 4P UBLF B MPPL BU UIJT GJSTU, CFGPSF JOWPMWJOH UIF BHHSFHBUPS. $U>JMIB RPFKD ?LQE 2MIFQQBO >KA DDOBD>QLO

*O UIJT FYBNQMF XF XBOU UP DIFDL UIBU B NVMUJQBSU PSEFS DBO CF GJMMFE. &BDI QBSU PG UIF PSEFS SFRVJSFT B DIFDL BU B EJGGFSFOU JOWFOUPSZ.
// split up the order so individual OrderItems can be validated by the appropriate bean from("direct:start") .split().body() .choice() .when().method("orderItemHelper", "isWidget") .to("bean:widgetInventory") .otherwise() .to("bean:gadgetInventory") .end() .to("seda:aggregate"); // collect and re-assemble the validated OrderItems into an order again from("seda:aggregate") .aggregate(new MyOrderAggregationStrategy()).header("orderId").completionTimeout(1000L) .to("mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:start"/> <split> <simple>body</simple> <choice> <when> <method bean="orderItemHelper" method="isWidget"/> <to uri="bean:widgetInventory"/> </when> <otherwise> <to uri="bean:gadgetInventory"/> </otherwise> </choice> <to uri="seda:aggregate"/> </split> </route> <route> <from uri="seda:aggregate"/> <aggregate strategyRef="myOrderAggregatorStrategy" completionTimeout="1000"> <correlationExpression> <simple>header.orderId</simple>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

453

</correlationExpression> <to uri="mock:result"/> </aggregate> </route>

5P EP UIJT XF TQMJU VQ UIF PSEFS VTJOH B 4QMJUUFS. 5IF 4QMJUUFS UIFO TFOET JOEJWJEVBM OrderItems UP B $POUFOU #BTFE 3PVUFS XIJDI DIFDLT UIF JUFN UZQF. 8JEHFU JUFNT HFU TFOU GPS DIFDLJOH JO UIF widgetInventory CFBO BOE HBEHFUT HFU TFOU UP UIF gadgetInventory CFBO. 0ODF UIFTF OrderItems IBWF CFFO WBMJEBUFE CZ UIF BQQSPQSJBUF CFBO, UIFZ BSF TFOU PO UP UIF "HHSFHBUPS XIJDI DPMMFDUT BOE SF-BTTFNCMFT UIF WBMJEBUFE OrderItems JOUP BO PSEFS BHBJO. 8IFO BO PSEFS JT TFOU JU DPOUBJOT B IFBEFS XJUI UIF PSEFS JE. 8F VTF UIJT GBDU XIFO XF BHHSFHBUF, BT XF DPOGJHVSF UIJT .header("orderId") PO UIF aggregate %4- UP JOTUSVDU $BNFM UP VTF UIF IFBEFS XJUI UIF LFZ orderId BT DPSSFMBUJPO FYQSFTTJPO. 'PS GVMM EFUBJMT, DIFDL UIF FYBNQMF TPVSDF IFSF: DBNFM-DPSF/TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/QSPDFTTPS/$PNQPTFE.FTTBHF1SPDFTTPS5FTU.KBWB $U>JMIB RPFKD LKIV 2MIFQQBO *O UIJT FYBNQMF XF XBOU UP TQMJU BO JODPNJOH PSEFS VTJOH UIF 4QMJUUFS FJQ, USBOTGPSN FBDI PSEFS MJOF, BOE UIFO DPNCJOF UIF PSEFS MJOFT JOUP B OFX PSEFS NFTTBHF.
// this routes starts from the direct:start endpoint // the body is then splitted based on @ separator // the splitter in Camel supports InOut as well and for that we need // to be able to aggregate what response we need to send back, so we provide our // own strategy with the class MyOrderStrategy. from("direct:start") .split(body().tokenize("@"), new MyOrderStrategy()) // each splitted message is then send to this bean where we can process it .to("bean:MyOrderService?method=handleOrder") // this is important to end the splitter route as we do not want to do more routing // on each splitted message .end() // after we have splitted and handled each message we want to send a single combined // response back to the original caller, so we let this bean build it for us // this bean will receive the result of the aggregate strategy: MyOrderStrategy .to("bean:MyOrderService?method=buildCombinedResponse")

5IF CFBO XJUI UIF NFUIPET UP USBOTGPSN UIF PSEFS MJOF BOE QSPDFTT UIF PSEFS BT XFMM:
public static class MyOrderService { private static int counter;

454

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4PFKD 7,+ *G ZPV VTF 9.-, UIFO UIF <TQMJU> UBH PGGFST UIF TUSBUFHZ3FG BUUSJCVUF UP SFGFS UP ZPVS DVTUPN AggregationStrategy

/** * We just handle the order by returning a id line for the order */ public String handleOrder(String line) { LOG.debug("HandleOrder: " + line); return "(id=" + ++counter + ",item=" + line + ")"; } /** * We use the same bean for building the combined response to send * back to the original caller */ public String buildCombinedResponse(String line) { LOG.debug("BuildCombinedResponse: " + line); return "Response[" + line + "]"; } }

"OE UIF AggregationStrategy XF VTF XJUI UIF 4QMJUUFS FJQ UP DPNCJOF UIF PSEFST CBDL BHBJO (FH GPSL/KPJO):
/** * This is our own order aggregation strategy where we can control * how each splitted message should be combined. As we do not want to * loos any message we copy from the new to the old to preserve the * order lines as long we process them */ public static class MyOrderStrategy implements AggregationStrategy { public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { // put order together in old exchange by adding the order from new exchange if (oldExchange == null) { // the first time we aggregate we only have the new exchange, // so we just return it return newExchange; } String orders = oldExchange.getIn().getBody(String.class); String newLine = newExchange.getIn().getBody(String.class); LOG.debug("Aggregate old orders: " + orders); LOG.debug("Aggregate new order: " + newLine);

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

455

// put orders together separating by semi colon orders = orders + ";" + newLine; // put combined order back on old to preserve it oldExchange.getIn().setBody(orders); // return old as this is the one that has all the orders gathered until now return oldExchange; } }

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2@>QQBO-&>QEBO 5IF 4DBUUFS-(BUIFS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SPVUF NFTTBHFT UP B OVNCFS PG EZOBNJDBMMZ TQFDJGJFE SFDJQJFOUT BOE SF-BHHSFHBUF UIF SFTQPOTFT CBDL JOUP B TJOHMF NFTTBHF.

#VK>JF@ 2@>QQBO-&>QEBO $U>JMIB


*O UIJT FYBNQMF XF XBOU UP HFU UIF CFTU RVPUF GPS CFFS GSPN TFWFSBM EJGGFSFOU WFOEPST. 8F VTF B EZOBNJD 3FDJQJFOU -JTU UP HFU UIF SFRVFTU GPS B RVPUF UP BMM WFOEPST BOE BO "HHSFHBUPS UP QJDL UIF CFTU RVPUF PVU PG BMM UIF SFTQPOTFT. 5IF SPVUFT GPS UIJT BSF EFGJOFE BT:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <recipientList> <header>listOfVendors</header> </recipientList>

456

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

</route> <route> <from uri="seda:quoteAggregator"/> <aggregate strategyRef="aggregatorStrategy" completionTimeout="1000"> <correlationExpression> <header>quoteRequestId</header> </correlationExpression> <to uri="mock:result"/> </aggregate> </route> </camelContext>

4P JO UIF GJSTU SPVUF ZPV TFF UIBU UIF 3FDJQJFOU -JTU JT MPPLJOH BU UIF listOfVendors IFBEFS GPS UIF MJTU PG SFDJQJFOUT. 4P, XF OFFE UP TFOE B NFTTBHF MJLF
Map<String, Object> headers = new HashMap<String, Object>(); headers.put("listOfVendors", "bean:vendor1, bean:vendor2, bean:vendor3"); headers.put("quoteRequestId", "quoteRequest-1"); template.sendBodyAndHeaders("direct:start", "<quote_request item=\"beer\"/>", headers);

5IJT NFTTBHF XJMM CF EJTUSJCVUFE UP UIF GPMMPXJOH &OEQPJOUT: bean:vendor1, bean:vendor2, BOE bean:vendor3. 5IFTF BSF BMM CFBOT XIJDI MPPL MJLF
public class MyVendor { private int beerPrice; @Produce(uri = "seda:quoteAggregator") private ProducerTemplate quoteAggregator; public MyVendor(int beerPrice) { this.beerPrice = beerPrice; } public void getQuote(@XPath("/quote_request/@item") String item, Exchange exchange) throws Exception { if ("beer".equals(item)) { exchange.getIn().setBody(beerPrice); quoteAggregator.send(exchange); } else { throw new Exception("No quote available for " + item); } } }

BOE BSF MPBEFE VQ JO 4QSJOH MJLF


<bean id="aggregatorStrategy" class="org.apache.camel.spring.processor.scattergather.LowestQuoteAggregationStrategy"/>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

457

<bean id="vendor1" class="org.apache.camel.spring.processor.scattergather.MyVendor"> <constructor-arg> <value>1</value> </constructor-arg> </bean> <bean id="vendor2" class="org.apache.camel.spring.processor.scattergather.MyVendor"> <constructor-arg> <value>2</value> </constructor-arg> </bean> <bean id="vendor3" class="org.apache.camel.spring.processor.scattergather.MyVendor"> <constructor-arg> <value>3</value> </constructor-arg> </bean>

&BDI CFBO JT MPBEFE XJUI B EJGGFSFOU QSJDF GPS CFFS. 8IFO UIF NFTTBHF JT TFOU UP FBDI CFBO FOEQPJOU, JU XJMM BSSJWF BU UIF MyVendor.getQuote NFUIPE. 5IJT NFUIPE EPFT B TJNQMF DIFDL XIFUIFS UIJT RVPUF SFRVFTU JT GPS CFFS BOE UIFO TFUT UIF QSJDF PG CFFS PO UIF FYDIBOHF GPS SFUSJFWBM BU B MBUFS TUFQ. 5IF NFTTBHF JT GPSXBSEFE PO UP UIF OFYU TUFQ VTJOH 10+0 1SPEVDJOH (TFF UIF !1SPEVDF BOOPUBUJPO). "U UIF OFYU TUFQ XF XBOU UP UBLF UIF CFFS RVPUFT GSPN BMM WFOEPST BOE GJOE PVU XIJDI POF XBT UIF CFTU (J.F. UIF MPXFTU!). 5P EP UIJT XF VTF BO "HHSFHBUPS XJUI B DVTUPN BHHSFHBUJPO TUSBUFHZ. 5IF "HHSFHBUPS OFFET UP CF BCMF UP DPNQBSF POMZ UIF NFTTBHFT GSPN UIJT QBSUJDVMBS RVPUF; UIJT JT FBTJMZ EPOF CZ TQFDJGZJOH B DPSSFMBUJPO&YQSFTTJPO FRVBM UP UIF WBMVF PG UIF RVPUF3FRVFTU*E IFBEFS. "T TIPXO BCPWF JO UIF NFTTBHF TFOEJOH TOJQQFU, XF TFU UIJT IFBEFS UP quoteRequest-1. 5IJT DPSSFMBUJPO WBMVF TIPVME CF VOJRVF PS ZPV NBZ JODMVEF SFTQPOTFT UIBU BSF OPU QBSU PG UIJT RVPUF. 5P QJDL UIF MPXFTU RVPUF PVU PG UIF TFU, XF VTF B DVTUPN BHHSFHBUJPO TUSBUFHZ MJLF
public class LowestQuoteAggregationStrategy implements AggregationStrategy { public Exchange aggregate(Exchange oldExchange, Exchange newExchange) { // the first time we only have the new exchange if (oldExchange == null) { return newExchange; } if (oldExchange.getIn().getBody(int.class) < newExchange.getIn().getBody(int.class)) { return oldExchange; } else { return newExchange; } } }

'JOBMMZ, XF FYQFDU UP HFU UIF MPXFTU RVPUF PG $1 PVU PG $1, $2, BOE $3.

458

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

result.expectedBodiesReceived(1); // expect the lowest quote

:PV DBO GJOE UIF GVMM FYBNQMF TPVSDF IFSF: DBNFM-TQSJOH/TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/TQSJOH/QSPDFTTPS/TDBUUFSHBUIFS/ DBNFM-TQSJOH/TSD/UFTU/SFTPVSDFT/PSH/BQBDIF/DBNFM/TQSJOH/QSPDFTTPS/TDBUUFSHBUIFS/TDBUUFSHBUIFS.YNM

2Q>QF@ 2@>QQBO-&>QEBO $U>JMIB


:PV DBO MPDL EPXO XIJDI SFDJQJFOUT BSF VTFE JO UIF 4DBUUFS-(BUIFS CZ VTJOH B TUBUJD 3FDJQJFOU -JTU. *U MPPLT TPNFUIJOH MJLF UIJT
from("direct:start").multicast().to("seda:vendor1", "seda:vendor2", "seda:vendor3"); from("seda:vendor1").to("bean:vendor1").to("seda:quoteAggregator"); from("seda:vendor2").to("bean:vendor2").to("seda:quoteAggregator"); from("seda:vendor3").to("bean:vendor3").to("seda:quoteAggregator"); from("seda:quoteAggregator") .aggregate(header("quoteRequestId"), new LowestQuoteAggregationStrategy()).to("mock:result")

" GVMM FYBNQMF PG UIF TUBUJD 4DBUUFS-(BUIFS DPOGJHVSBUJPO DBO CF GPVOE JO UIF -PBO #SPLFS &YBNQMF.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 1LRQFKD 2IFM 5IF 3PVUJOH 4MJQ GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SPVUF B NFTTBHF DPOTFDVUJWFMZ UISPVHI B TFSJFT PG QSPDFTTJOH TUFQT XIFSF UIF TFRVFODF PG TUFQT JT OPU LOPXO BU EFTJHO UJNF BOE DBO WBSZ GPS FBDI NFTTBHF.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

459

.MQFLKP
->JB
uriDelimiter ignoreInvalidEndpoints

#BC>RIQ 5>IRB
, false

#BP@OFMQFLK
%FMJNJUFS VTFE JG UIF &YQSFTTJPO SFUVSOFE NVMUJQMF FOEQPJOUT. *G BO FOEQPJOU VSJ DPVME OPU CF SFTPMWFE, TIPVME JU CF JHOPSFE. 0UIFSXJTF $BNFM XJMM UISPX BO FYDFQUJPO TUBUJOH UIF FOEQPJOU VSJ JT OPU WBMJE.

$U>JMIB
5IF GPMMPXJOH SPVUF XJMM UBLF BOZ NFTTBHFT TFOU UP UIF "QBDIF "DUJWF.2 RVFVF 2LJB0RBRB BOE QBTT UIFN JOUP UIF 3PVUJOH 4MJQ QBUUFSO.
from("activemq:SomeQueue").routingSlip("aRoutingSlipHeader");

.FTTBHFT XJMM CF DIFDLFE GPS UIF FYJTUBODF PG UIF "B3PVUJOH4MJQ)FBEFS" IFBEFS. 5IF WBMVF PG UIJT IFBEFS TIPVME CF B DPNNB-EFMJNJUFE MJTU PG FOEQPJOU 63*T ZPV XJTI UIF NFTTBHF UP CF SPVUFE UP. 5IF .FTTBHF XJMM CF SPVUFE JO B QJQFMJOF GBTIJPO (J.F. POF BGUFS UIF PUIFS). 'SPN $BNFM 2.5 UIF 3PVUJOH 4MJQ XJMM TFU B QSPQFSUZ (Exchange.SLIP_ENDPOINT) PO UIF &YDIBOHF XIJDI DPOUBJOT UIF DVSSFOU FOEQPJOU BT JU BEWBODFE UIPVHI UIF TMJQ. 5IJT BMMPXT ZPV UP know IPX GBS XF IBWF QSPDFTTFE JO UIF TMJQ. 5IF 3PVUJOH 4MJQ XJMM DPNQVUF UIF TMJQ ?BCLOBE>KA XIJDI NFBOT, UIF TMJQ JT POMZ DPNQVUFE PODF. *G ZPV OFFE UP DPNQVUF UIF TMJQ on-the-fly UIFO VTF UIF %ZOBNJD 3PVUFS QBUUFSO JOTUFBE.

"LKCFDRO>QFLK LMQFLKP
)FSF XF TFU UIF IFBEFS OBNF BOE UIF 63* EFMJNJUFS UP TPNFUIJOH EJGGFSFOU. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:c").routingSlip(header("aRoutingSlipHeader"), "#");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP

460

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<camelContext id="buildRoutingSlip" xmlns="http://activemq.apache.org/camel/schema/ spring"> <route> <from uri="direct:c"/> <routingSlip uriDelimiter="#"> <header>aRoutingSlipHeader</header> </routingSlip> </route> </camelContext>

(DKLOB FKS>IFA BKAMLFKQP S>FI>?IB >P LC ">JBI 2.3 5IF 3PVUJOH 4MJQ OPX TVQQPSUT ignoreInvalidEndpoints XIJDI UIF 3FDJQJFOU -JTU BMTP TVQQPSUT. :PV DBO VTF JU UP TLJQ FOEQPJOUT XIJDI BSF JOWBMJE.
from("direct:a").routingSlip("myHeader").ignoreInvalidEndpoints();

"OE JO 4QSJOH 9.- JUT BO BUUSJCVUF PO UIF SFDJQJFOU MJTU UBH.


<route> <from uri="direct:a"/> <routingSlip ignoreInvalidEndpoints="true"/> <header>myHeader</header> </routingSlip> </route>

5IFO MFUT TBZ UIF myHeader DPOUBJOT UIF GPMMPXJOH UXP FOEQPJOUT direct:foo,xxx:bar. 5IF GJSTU FOEQPJOU JT WBMJE BOE XPSLT. )PXFWFS UIF 2OE JT JOWBMJE BOE XJMM KVTU CF JHOPSFE. $BNFM MPHT BU */'0 MFWFM, TP ZPV DBO TFF XIZ UIF FOEQPJOU XBT JOWBMJE. $UMOBPPFLK PRMMLOQFKD S>FI>?IB >P LC ">JBI 2.4 5IF 3PVUJOH 4MJQ OPX TVQQPSUT UP UBLF UIF FYQSFTTJPO QBSBNFUFS BT UIF 3FDJQJFOU -JTU EPFT. :PV DBO UFMM $BNFM UIF FYQSFTTJPO UIBU ZPV XBOU UP VTF UP HFU UIF SPVUJOH TMJQ.
from("direct:a").routingSlip(header("myHeader")).ignoreInvalidEndpoints();

"OE JO 4QSJOH 9.- JUT BO BUUSJCVUF PO UIF SFDJQJFOU MJTU UBH.


<route> <from uri="direct:a"/> <!--NOTE from Camel 2.4.0, you need to specify the expression element inside of

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

461

the routingSlip element --> <routingSlip ignoreInvalidEndpoints="true"> <header>myHeader</header> </routingSlip> </route>

%ROQEBO $U>JMIBP
'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF SPVUJOH TMJQ UFTU DBTFT.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 3EOLQQIBO 5IF 5ISPUUMFS 1BUUFSO BMMPXT ZPV UP FOTVSF UIBU B TQFDJGJD FOEQPJOU EPFT OPU HFU PWFSMPBEFE, PS UIBU XF EPO'U FYDFFE BO BHSFFE 4-" XJUI TPNF FYUFSOBM TFSWJDF. .MQFLKP
->JB
maximumRequestsPerPeriod timePeriodMillis asyncDelayed executorServiceRef callerRunsWhenRejected

#BC>RIQ 5>IRB
c 1000 false c true

#BP@OFMQFLK
.BYJNVN OVNCFS PG SFRVFTUT QFS QFSJPE UP UISPUUMF. 5IJT PQUJPO NVTU CF QSPWJEFE BT B QPTJUJWF OVNCFS. /PUJDF, JO UIF 9.- %4-, GSPN ">JBI 2.8 POXBSET UIJT PQUJPO JT DPOGJHVSFE VTJOH BO &YQSFTTJPO JOTUFBE PG BO BUUSJCVUF. 5IF UJNF QFSJPE JO NJMMJTFDPOET, JO XIJDI UIF UISPUUMFS XJMM BMMPX BU NPTU maximumRequestsPerPeriod OVNCFS PG NFTTBHFT. ">JBI 2.4: *G FOBCMFE UIFO BOZ NFTTBHFT XIJDI JT EFMBZFE IBQQFOT BTZODISPOPVTMZ VTJOH B TDIFEVMFE UISFBE QPPM. ">JBI 2.4: 3FGFST UP B DVTUPN 5ISFBE 1PPM UP CF VTFE JG asyncDelay IBT CFFO FOBCMFE. ">JBI 2.4: *T VTFE JG asyncDelayed XBT FOBCMFE. 5IJT DPOUSPMT JG UIF DBMMFS UISFBE TIPVME FYFDVUF UIF UBTL JG UIF UISFBE QPPM SFKFDUFE UIF UBTL.

$U>JMIBP 4PFKD QEB %IRBKQ !RFIABOP


from("seda:a").throttle(3).timePeriodMillis(10000).to("log:result", "mock:result");

4P UIF BCPWF FYBNQMF XJMM UISPUUMF NFTTBHFT BMM NFTTBHFT SFDFJWFE PO PBA>:> CFGPSF CFJOH TFOU UP JL@H:OBPRIQ FOTVSJOH UIBU B NBYJNVN PG 3 NFTTBHFT BSF TFOU JO BOZ 10 TFDPOE XJOEPX.

462

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

/PUF UIBU TJODF timePeriodMillis EFGBVMUT UP 1000 NJMMJTFDPOET, KVTU TFUUJOH UIF maximumRequestsPerPeriod IBT UIF FGGFDU PG TFUUJOH UIF NBYJNVN OVNCFS PG SFRVFTUT QFS TFDPOE. 4P UP UISPUUMF SFRVFTUT BU 100 SFRVFTUT QFS TFDPOE CFUXFFO UXP FOEQPJOUT, JU XPVME MPPL NPSF MJLF UIJT...
from("seda:a").throttle(100).to("seda:b");

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF KVOJU UFTU DBTF 4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP

">JBI 2.7.U LO LIABO


<route> <from uri="seda:a" /> <throttle maximumRequestsPerPeriod="3" timePeriodMillis="10000"> <to uri="mock:result" /> </throttle> </route>

">JBI 2.8 LKT>OAP


*O $BNFM 2.8 POXBSET ZPV NVTU TFU UIF NBYJNVN QFSJPE BT BO &YQSFTTJPO BT TIPXO CFMPX XIFSF XF VTF B $POTUBOU FYQSFTTJPO:
<route> <from uri="seda:a"/> <!-- throttle 3 messages per 10 sec --> <throttle timePeriodMillis="10000"> <constant>3</constant> <to uri="mock:result"/> </throttle> </route>

#VK>JF@>IIV @E>KDFKD J>UFJRJ OBNRBPQP MBO MBOFLA S>FI>?IB >P LC ">JBI 2.8 4JODF XF VTF BO &YQSFTTJPO ZPV DBO BEKVTU UIJT WBMVF BU SVOUJNF, GPS FYBNQMF ZPV DBO QSPWJEF B IFBEFS XJUI UIF WBMVF. "U SVOUJNF $BNFM FWBMVBUFT UIF FYQSFTTJPO BOE DPOWFSUT UIF SFTVMU UP B java.lang.Long UZQF. *O UIF FYBNQMF CFMPX XF VTF B IFBEFS GSPN UIF NFTTBHF UP EFUFSNJOF UIF NBYJNVN SFRVFTUT QFS QFSJPE. *G UIF IFBEFS JT BCTFOU, UIFO UIF 5ISPUUMFS VTFT UIF PME WBMVF. 4P UIBU BMMPXT ZPV UP POMZ QSPWJEF B IFBEFS JG UIF WBMVF JT UP CF DIBOHFE:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

463

<route> <from uri="direct:expressionHeader"/> <throttle timePeriodMillis="500"> <!-- use a header to determine how many messages to throttle per 0.5 sec --> <header>throttleValue</header> <to uri="mock:result"/> </throttle> </route>

PVK@EOLKLRP ABI>VFKD S>FI>?IB >P LC ">JBI 2.4 :PV DBO MFU UIF 5ISPUUMFS VTF OPO CMPDLJOH BTZODISPOPVT EFMBZJOH, XIJDI NFBOT $BNFM XJMM VTF B TDIFEVMFS UP TDIFEVMF B UBTL UP CF FYFDVUFE JO UIF GVUVSF. 5IF UBTL XJMM UIFO DPOUJOVF SPVUJOH. 5IJT BMMPXT UIF DBMMFS UISFBE UP OPU CMPDL BOE CF BCMF UP TFSWJDF PUIFS NFTTBHFT, FUD.
from("seda:a").throttle(100).asyncDelayed().to("seda:b");

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

2 ,/+(-& 3'1.33+$1
S>FI>?IB >P LC ">JBI 2.1 " TBNQMJOH UISPUUMFS BMMPXT ZPV UP FYUSBDU B TBNQMF PG UIF FYDIBOHFT GSPN UIF USBGGJD UISPVHI B SPVUF. *U JT DPOGJHVSFE XJUI B TBNQMJOH QFSJPE EVSJOH XIJDI POMZ B TJOHMF FYDIBOHF JT BMMPXFE UP QBTT UISPVHI. "MM PUIFS FYDIBOHFT XJMM CF TUPQQFE. 8JMM CZ EFGBVMU VTF B TBNQMF QFSJPE PG 1 TFDPOET. .MQFLKP
->JB
messageFrequency samplePeriod units

#BC>RIQ 5>IRB
c 1 SECOND

#BP@OFMQFLK
4BNQMFT UIF NFTTBHF FWFSZ /'UI NFTTBHF. :PV DBO POMZ VTF FJUIFS GSFRVFODZ PS QFSJPE. 4BNQMFT UIF NFTTBHF FWFSZ /'UI QFSJPE. :PV DBO POMZ VTF FJUIFS GSFRVFODZ PS QFSJPE. 5JNF VOJU BT BO FOVN PG java.util.concurrent.TimeUnit GSPN UIF +%,.

464

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2>JMIBP :PV VTF UIJT &*1 XJUI UIF sample %4- BT TIPX JO UIFTF TBNQMFT. 4PFKD QEB %IRBKQ !RFIABOP 5IFTF TBNQMFT BMTP TIPX IPX ZPV DBO VTF UIF EJGGFSFOU TZOUBY UP DPOGJHVSF UIF TBNQMJOH QFSJPE:
from("direct:sample") .sample() .to("mock:result"); from("direct:sample-configured") .sample(1, TimeUnit.SECONDS) .to("mock:result"); from("direct:sample-configured-via-dsl") .sample().samplePeriod(1).timeUnits(TimeUnit.SECONDS) .to("mock:result"); from("direct:sample-messageFrequency") .sample(10) .to("mock:result"); from("direct:sample-messageFrequency-via-dsl") .sample().sampleMessageFrequency(5) .to("mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP "OE UIF TBNF FYBNQMF JO 4QSJOH 9.- JT:
<route> <from uri="direct:sample"/> <sample samplePeriod="1" units="seconds"> <to uri="mock:result"/> </sample> </route> <route> <from uri="direct:sample-messageFrequency"/> <sample messageFrequency="10"> <to uri="mock:result"/> </sample> </route> <route> <from uri="direct:sample-messageFrequency-via-dsl"/> <sample messageFrequency="5"> <to uri="mock:result"/> </sample> </route>

"OE TJODF JU VTFT B EFGBVMU PG 1 TFDPOE ZPV DBO PNJU UIJT DPOGJHVSBUJPO JO DBTF ZPV BMTP XBOU UP VTF 1 TFDPOE

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

465

<route> <from uri="direct:sample"/> <!-- will by default use 1 second period --> <sample> <to uri="mock:result"/> </sample> </route>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2BB IPL 5ISPUUMFS "HHSFHBUPS #BI>VBO 5IF %FMBZFS 1BUUFSO BMMPXT ZPV UP EFMBZ UIF EFMJWFSZ PG NFTTBHFT UP TPNF EFTUJOBUJPO. .MQFLKP
->JB
asyncDelayed executorServiceRef callerRunsWhenRejected

#BC>RIQ 5>IRB
false c true

#BP@OFMQFLK
">JBI 2.4: *G FOBCMFE UIFO EFMBZFE NFTTBHFT IBQQFOT BTZODISPOPVTMZ VTJOH B TDIFEVMFE UISFBE QPPM. ">JBI 2.4: 3FGFST UP B DVTUPN 5ISFBE 1PPM UP CF VTFE JG asyncDelay IBT CFFO FOBCMFE. ">JBI 2.4: *T VTFE JG asyncDelayed XBT FOBCMFE. 5IJT DPOUSPMT JG UIF DBMMFS UISFBE TIPVME FYFDVUF UIF UBTL JG UIF UISFBE QPPM SFKFDUFE UIF UBTL.

4PFKD QEB %IRBKQ !RFIABOP


from("seda:b").delay(1000).to("mock:result");

4P UIF BCPWF FYBNQMF XJMM EFMBZ BMM NFTTBHFT SFDFJWFE PO PBA>:? 1 TFDPOE CFGPSF TFOEJOH UIFN UP JL@H:OBPRIQ. :PV DBO PG DPVSTF VTF NBOZ EJGGFSFOU &YQSFTTJPO MBOHVBHFT TVDI BT 91BUI, 92VFSZ, 42- PS WBSJPVT 4DSJQUJOH -BOHVBHFT. :PV DBO KVTU EFMBZ UIJOHT B GJYFE BNPVOU PG UJNF GSPN UIF QPJOU BU XIJDI UIF EFMBZFS SFDFJWFT UIF NFTTBHF. 'PS FYBNQMF UP EFMBZ UIJOHT 2 TFDPOET
delayer(2000)

466

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

5IF FYQSFTTJPO JT B WBMVF JO NJMMJT UP XBJU GSPN UIF DVSSFOU UJNF, TP UIF FYQSFTTJPO TIPVME KVTU CF 3000. )PXFWFS ZPV DBO VTF B MPOH WBMVF GPS B GJYFE WBMVF UP JOEJDBUF UIF EFMBZ JO NJMMJT. 4FF UIF 4QSJOH %4- TBNQMFT GPS %FMBZFS.

4PFKD #BI>VBO FK )>S> #2+ 4FF UIJT UJDLFU: IUUQT://JTTVFT.BQBDIF.PSH/KJSB/CSPXTF/$".&--2654 5IF BCPWF BTTVNF UIBU UIF EFMJWFSZ PSEFS JT NBJOUBJOFE BOE UIBU UIF NFTTBHFT BSF EFMJWFSFE JO EFMBZ PSEFS. *G ZPV XBOU UP SFPSEFS UIF NFTTBHFT CBTFE PO EFMJWFSZ UJNF, ZPV DBO VTF UIF 3FTFRVFODFS XJUI UIJT QBUUFSO. 'PS FYBNQMF

from("activemq:someQueue").resequencer(header("MyDeliveryTime")).delay("MyRedeliveryTime").to("activem

2MOFKD #2+
5IF TBNQMF CFMPX EFNPOTUSBUFT UIF EFMBZ JO 4QSJOH %4-:
<bean id="myDelayBean" class="org.apache.camel.processor.MyDelayCalcBean"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="seda:a"/> <delay> <header>MyDelay</header> </delay> <to uri="mock:result"/> </route> <route> <from uri="seda:b"/> <delay> <constant>1000</constant> </delay> <to uri="mock:result"/> </route> <route> <from uri="seda:c"/> <delay> <method ref="myDelayBean" method="delayMe"/> </delay> <to uri="mock:result"/>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

467

</route> </camelContext>

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF KVOJU UFTU DBTF PVK@EOLKLRP ABI>VFKD S>FI>?IB >P LC ">JBI 2.4 :PV DBO MFU UIF %FMBZFS VTF OPO CMPDLJOH BTZODISPOPVT EFMBZJOH, XIJDI NFBOT $BNFM XJMM VTF B TDIFEVMFS UP TDIFEVMF B UBTL UP CF FYFDVUFE JO UIF GVUVSF. 5IF UBTL XJMM UIFO DPOUJOVF SPVUJOH. 5IJT BMMPXT UIF DBMMFS UISFBE UP OPU CMPDL BOE CF BCMF UP TFSWJDF PUIFS NFTTBHFT FUD.

%OLJ )>S> #2+


:PV VTF UIF asyncDelayed() UP FOBCMF UIF BTZOD CFIBWJPS.
from("activemq:queue:foo").delay(1000).asyncDelayed().to("activemq:aDelayedQueue");

%OLJ 2MOFKD 7,+


:PV VTF UIF asyncDelayed="true" BUUSJCVUF UP FOBCMF UIF BTZOD CFIBWJPS.
<route> <from uri="activemq:queue:foo"/> <delay asyncDelayed="true"> <constant>1000</constant> </delay> <to uri="activemq:aDealyedQueue"/> </route>

"OB>QFKD > @RPQLJ ABI>V :PV DBO VTF BO FYQSFTTJPO UP EFUFSNJOF XIFO UP TFOE B NFTTBHF VTJOH TPNFUIJOH MJLF UIJT
from("activemq:foo"). delay().method("someBean", "computeDelay"). to("activemq:bar");

UIFO UIF CFBO XPVME MPPL MJLF UIJT...

468

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

public class SomeBean { public long computeDelay() { long delay = 0; // use java code to compute a delay value in millis return delay; } }

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2BB IPL ` %FMBZ *OUFSDFQUPS +L>A !>I>K@BO 5IF -PBE #BMBODFS 1BUUFSO BMMPXT ZPV UP EFMFHBUF UP POF PG B OVNCFS PG FOEQPJOUT VTJOH B WBSJFUZ PG EJGGFSFOU MPBE CBMBODJOH QPMJDJFT. !RFIQ-FK IL>A ?>I>K@FKD MLIF@FBP $BNFM QSPWJEFT UIF GPMMPXJOH QPMJDJFT PVU-PG-UIF-CPY: /LIF@V 3PVOE 3PCJO 3BOEPN 4UJDLZ 5PQJD 'BJMPWFS 8FJHIUFE 3PVOE3PCJO #BP@OFMQFLK 5IF FYDIBOHFT BSF TFMFDUFE GSPN JO B SPVOE SPCJO GBTIJPO. 5IJT JT B XFMM LOPXO BOE DMBTTJD QPMJDZ, XIJDI TQSFBET UIF MPBE FWFOMZ. " SBOEPN FOEQPJOU JT TFMFDUFE GPS FBDI FYDIBOHF. 4UJDLZ MPBE CBMBODJOH VTJOH BO &YQSFTTJPO UP DBMDVMBUF B DPSSFMBUJPO LFZ UP QFSGPSN UIF TUJDLZ MPBE CBMBODJOH; SBUIFS MJLF KTFTTJPOJE JO UIF XFC PS +.49(SPVQ*% JO +.4. 5PQJD XIJDI TFOET UP BMM EFTUJOBUJPOT (SBUIFS MJLF +.4 5PQJDT) *O DBTF PG GBJMVSFT UIF FYDIBOHF XJMM CF USJFE PO UIF OFYU FOEQPJOU. ">JBI 2.5: 5IF XFJHIUFE MPBE CBMBODJOH QPMJDZ BMMPXT ZPV UP TQFDJGZ B QSPDFTTJOH MPBE EJTUSJCVUJPO SBUJP GPS FBDI TFSWFS XJUI SFTQFDU UP UIF PUIFST. *O BEEJUJPO UP UIF XFJHIU, FOEQPJOU TFMFDUJPO JT UIFO GVSUIFS SFGJOFE VTJOH OLRKAOL?FK EJTUSJCVUJPO CBTFE PO XFJHIU.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

469

8FJHIUFE 3BOEPN

">JBI 2.5: 5IF XFJHIUFE MPBE CBMBODJOH QPMJDZ BMMPXT ZPV UP TQFDJGZ B QSPDFTTJOH MPBE EJTUSJCVUJPO SBUJP GPS FBDI TFSWFS XJUI SFTQFDU UP PUIFST.*O BEEJUJPO UP UIF XFJHIU, FOEQPJOU TFMFDUJPO JT UIFO GVSUIFS SFGJOFE VTJOH O>KALJ EJTUSJCVUJPO CBTFE PO XFJHIU. ">JBI 2.8: 'SPN $BNFM 2.8 POXBSET UIF QSFGFSSFE XBZ PG VTJOH B DVTUPN -PBE #BMBODFS JT UP VTF UIJT QPMJDZ, JOTUFBE PG VTJOH UIF !EFQSFDBUFE ref BUUSJCVUF.

$VTUPN

1LRKA 1L?FK 5IF SPVOE SPCJO MPBE CBMBODFS JT OPU NFBOU UP XPSL XJUI GBJMPWFS, GPS UIBU ZPV TIPVME VTF UIF EFEJDBUFE C>FILSBO MPBE CBMBODFS. 5IF SPVOE SPCJO MPBE CBMBODFS XJMM POMZ DIBOHF UP OFYU FOEQPJOU QFS NFTTBHF. 5IF SPVOE SPCJO MPBE CBMBODFS JT TUBUFGVM BT JU LFFQT TUBUF PG XIJDI FOEQPJOU UP VTF OFYU UJNF. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:start").loadBalance(). roundRobin().to("mock:x", "mock:y", "mock:z");

4PFKD QEB 2MOFKD @LKCFDRO>QFLK


<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <loadBalance> <roundRobin/> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route> </camelContext>

5IF BCPWF FYBNQMF MPBET CBMBODF SFRVFTUT GSPN AFOB@Q:PQ>OQ UP POF PG UIF BWBJMBCMF JL@H BKAMLFKQ JOTUBODFT, JO UIJT DBTF VTJOH B SPVOE SPCJO QPMJDZ. 'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO MPPL BU UIJT KVOJU UFTU DBTF %>FILSBO 5IF failover MPBE CBMBODFS JT DBQBCMF PG USZJOH UIF OFYU QSPDFTTPS JO DBTF BO &YDIBOHF GBJMFE XJUI BO exception EVSJOH QSPDFTTJOH. :PV DBO DPOTUSBJO UIF failover UP BDUJWBUF POMZ XIFO POF FYDFQUJPO PG B MJTU ZPV TQFDJGZ PDDVST. *G ZPV EP OPU TQFDJGZ B MJTU BOZ FYDFQUJPO XJMM DBVTF GBJM PWFS UP PDDVS. 5IJT CBMBODFS VTFT

470

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

+L>A ?>I>K@FKD '33/ BKAMLFKQP *G ZPV BSF QSPYZJOH BOE MPBE CBMBODJOH )551, UIFO TFF UIJT QBHF GPS NPSF EFUBJMT. UIF TBNF TUSBUFHZ GPS NBUDIJOH FYDFQUJPOT BT UIF &YDFQUJPO $MBVTF EPFT GPS UIF LK$U@BMQFLK. 'BJMPWFS PGGFST UIF GPMMPXJOH PQUJPOT: .MQFLK 3VMB #BC>RIQ #BP@OFMQFLK ">JBI 2.3: 8IFUIFS PS OPU UIF &SSPS )BOEMFS DPOGJHVSFE PO UIF SPVUF TIPVME CF VTFE. %JTBCMF UIJT JG ZPV XBOU GBJMPWFS UP USBOTGFS JNNFEJBUFMZ UP UIF OFYU FOEQPJOU. 0O UIF PUIFS IBOE, JG ZPV IBWF UIJT PQUJPO FOBCMFE, UIFO $BNFM XJMM GJSTU MFU UIF &SSPS )BOEMFS USZ UP QSPDFTT UIF NFTTBHF. 5IF &SSPS )BOEMFS NBZ IBWF CFFO DPOGJHVSFE UP SFEFMJWFS BOE VTF EFMBZT CFUXFFO BUUFNQUT. *G ZPV IBWF FOBCMFE B OVNCFS PG SFEFMJWFSJFT UIFO $BNFM XJMM USZ UP SFEFMJWFS UP UIF P>JB FOEQPJOU, BOE POMZ GBJM PWFS UP UIF OFYU FOEQPJOU, XIFO UIF &SSPS )BOEMFS JT FYIBVTUFE. ">JBI 2.3: " WBMVF UP JOEJDBUF BGUFS 9 GBJMPWFS BUUFNQUT XF TIPVME FYIBVTU (HJWF VQ). 6TF -1 UP JOEJDBUF OFWFS HJWF VQ BOE DPOUJOVPVTMZ USZ UP GBJMPWFS. 6TF 0 UP OFWFS GBJMPWFS. "OE VTF F.H. 3 UP GBJMPWFS BU NPTU 3 UJNFT CFGPSF HJWJOH VQ. 5IJT PQUJPO DBO CF VTFE XIFUIFS PS OPU SPVOE3PCJO JT FOBCMFE PS OPU.

JOIFSJU&SSPS)BOEMFS

CPPMFBO

USVF

NBYJNVN'BJMPWFS"UUFNQUT

JOU

-1

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

471

$K>?IB PQOB>J @>@EFKD FC RPFKD PQOB>JP *G ZPV VTF TUSFBNJOH UIFO ZPV TIPVME FOBCMF 4USFBN DBDIJOH XIFO VTJOH UIF GBJMPWFS MPBE CBMBODFS. 5IJT JT OFFEFE TP UIF TUSFBN DBO CF SF-SFBE BGUFS GBJMJOH PWFS UP UIF OFYU QSPDFTTPS.

SPVOE3PCJO

CPPMFBO

GBMTF

">JBI 2.3: 8IFUIFS PS OPU UIF failover MPBE CBMBODFS TIPVME PQFSBUF JO SPVOE SPCJO NPEF PS OPU. *G OPU, UIFO JU XJMM >IT>VP TUBSU GSPN UIF GJSTU FOEQPJOU XIFO B OFX NFTTBHF JT UP CF QSPDFTTFE. *O PUIFS XPSET JU SFTUBSU GSPN UIF UPQ GPS FWFSZ NFTTBHF. *G SPVOE SPCJO JT FOBCMFE, UIFO JU LFFQT TUBUF BOE XJMM DPOUJOVF XJUI UIF OFYU FOEQPJOU JO B SPVOE SPCJO GBTIJPO. 8IFO VTJOH SPVOE SPCJO JU XJMM OPU stick UP MBTU LOPXO HPPE FOEQPJOU, JU XJMM BMXBZT QJDL UIF OFYU FOEQPJOU UP VTF.

">JBI 2.2 LO LIABO ?BE>SFLO 5IF DVSSFOU JNQMFNFOUBUJPO PG GBJMPWFS MPBE CBMBODFS VTFT TJNQMF MPHJD XIJDI >IT>VP USJFT UIF GJSTU FOEQPJOU, BOE JO DBTF PG BO FYDFQUJPO CFJOH UISPXO JU USJFT UIF OFYU JO UIF MJTU, BOE TP GPSUI. *U IBT OP TUBUF, BOE UIF OFYU NFTTBHF XJMM UIVT >IT>VP TUBSU XJUI UIF GJSTU FOEQPJOU. ">JBI 2.3 LKT>OAP ?BE>SFLO 5IF failover MPBE CBMBODFS OPX TVQQPSUT SPVOE SPCJO NPEF, XIJDI BMMPXT ZPV UP GBJMPWFS JO B SPVOE SPCJO GBTIJPO. 4FF UIF roundRobin PQUJPO. )FSF JT B TBNQMF UP GBJMPWFS POMZ JG B IOException SFMBUFE FYDFQUJPO XBT UISPXO:
from("direct:start") // here we will load balance if IOException was thrown // any other kind of exception will result in the Exchange as failed // to failover over any kind of exception we can just omit the exception // in the failOver DSL .loadBalance().failover(IOException.class) .to("direct:x", "direct:y", "direct:z");

:PV DBO TQFDJGZ NVMUJQMF FYDFQUJPOT UP GBJMPWFS BT UIF PQUJPO JT WBSBSHT, GPS JOTUBODF:
// enable redelivery so failover can react errorHandler(defaultErrorHandler().maximumRedeliveries(5)); from("direct:foo").

472

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

1BABIFSBOV JRPQ ?B BK>?IBA *O $BNFM 2.2 PS PMEFS UIF GBJMPWFS MPBE CBMBODFS SFRVJSFT ZPV IBWF FOBCMFE $BNFM &SSPS )BOEMFS UP VTF SFEFMJWFSZ. *O $BNFM 2.3 POXBSET UIJT JT OPU SFRVJSFE BT TVDI, BT ZPV DBO NJY BOE NBUDI. 4FF UIF inheritErrorHandler PQUJPO.

loadBalance().failover(IOException.class, MyOtherException.class) .to("direct:a", "direct:b");

4PFKD C>FILSBO FK 2MOFKD #2+


'BJMPWFS DBO BMTP CF VTFE GSPN 4QSJOH %4- BOE ZPV DPOGJHVSF JU BT:
<route errorHandlerRef="myErrorHandler"> <from uri="direct:foo"/> <loadBalance> <failover> <exception>java.io.IOException</exception> <exception>com.mycompany.MyOtherException</exception> </failover> <to uri="direct:a"/> <to uri="direct:b"/> </loadBalance> </route>

4PFKD C>FILSBO FK OLRKA OL?FK JLAB


"O FYBNQMF VTJOH +BWB %4-:
from("direct:start") // Use failover load balancer in stateful round robin mode // which mean it will failover immediately in case of an exception // as it does NOT inherit error handler. It will also keep retrying as // its configured to newer exhaust. .loadBalance().failover(-1, false, true). to("direct:bad", "direct:bad2", "direct:good", "direct:good2");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<route> <from uri="direct:start"/> <loadBalance>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

473

<!-- failover using stateful round robin, which will keep retrying forever those 4 endpoints until success. You can set the maximumFailoverAttempt to break out after X attempts --> <failover roundRobin="true"/> <to uri="direct:bad"/> <to uri="direct:bad2"/> <to uri="direct:good"/> <to uri="direct:good2"/> </loadBalance> </route>

6BFDEQBA 1LRKA-1L?FK >KA 1>KALJ +L>A !>I>K@FKD S>FI>?IB >P LC ">JBI 2.5 *O NBOZ FOUFSQSJTF FOWJSPONFOUT XIFSF TFSWFS OPEFT PG VOFRVBM QSPDFTTJOH QPXFS & QFSGPSNBODF DIBSBDUFSJTUJDT BSF VUJMJ[FE UP IPTU TFSWJDFT BOE QSPDFTTJOH FOEQPJOUT, JU JT GSFRVFOUMZ OFDFTTBSZ UP EJTUSJCVUF QSPDFTTJOH MPBE CBTFE PO UIFJS JOEJWJEVBM TFSWFS DBQBCJMJUJFT TP UIBU TPNF FOEQPJOUT BSF OPU VOGBJSMZ CVSEFOFE XJUI SFRVFTUT. 0CWJPVTMZ TJNQMF SPVOE-SPCJO PS SBOEPN MPBE CBMBODJOH EP OPU BMMFWJBUF QSPCMFNT PG UIJT OBUVSF. " 8FJHIUFE 3PVOE-3PCJO BOE/ PS 8FJHIUFE 3BOEPN MPBE CBMBODFS DBO CF VTFE UP BEESFTT UIJT QSPCMFN. 5IF XFJHIUFE MPBE CBMBODJOH QPMJDZ BMMPXT ZPV UP TQFDJGZ B QSPDFTTJOH MPBE EJTUSJCVUJPO SBUJP GPS FBDI TFSWFS XJUI SFTQFDU UP PUIFST. :PV DBO TQFDJGZ UIJT BT B QPTJUJWF QSPDFTTJOH XFJHIU GPS FBDI TFSWFS. " MBSHFS OVNCFS JOEJDBUFT UIBU UIF TFSWFS DBO IBOEMF B MBSHFS MPBE. 5IF XFJHIU JT VUJMJ[FE UP EFUFSNJOF UIF QBZMPBE EJTUSJCVUJPO SBUJP UP EJGGFSFOU QSPDFTTJOH FOEQPJOUT XJUI SFTQFDU UP PUIFST. 5IF QBSBNFUFST UIBU DBO CF VTFE BSF (K ">JBI 2.5 .MQFLK SPVOE3PCJO 3VMB CPPMFBO #BC>RIQ GBMTF #BP@OFMQFLK 5IF EFGBVMU WBMVF GPS SPVOE-SPCJO JT GBMTF. *O UIF BCTFODF PG UIJT TFUUJOH PS QBSBNFUFS UIF MPBE CBMBODJOH BMHPSJUIN VTFE JT SBOEPN. 5IF EJTUSJCVUJPO3BUJP JT B MJTU DPOTJTUJOH PO JOUFHFS XFJHIUT QBTTFE JO BT B QBSBNFUFS. 5IF EJTUSJCVUJPO3BUJP NVTU NBUDI UIF OVNCFS PG FOEQPJOUT BOE/PS QSPDFTTPST TQFDJGJFE JO UIF MPBE CBMBODFS MJTU. *O $BNFM 2.5 JG FOEQPJOUT EP OPU NBUDI SBUJPT, UIFO B CFTU FGGPSU EJTUSJCVUJPO JT BUUFNQUFE. #BP@OFMQFLK

EJTUSJCVUJPO3BUJP

-JTU<*OUFHFS>

OPOF

S>FI>?IB (K ">JBI 2.6 .MQFLK 3VMB #BC>RIQ

474

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

#FP>?IBA FKEBOFQ$OOLO'>KAIBO :PV DBO DPOGJHVSF inheritErrorHandler=false JG ZPV XBOU UP GBJMPWFS UP UIF OFYU FOEQPJOU BT GBTU BT QPTTJCMF. #Z EJTBCMJOH UIF &SSPS )BOEMFS ZPV FOTVSF JU EPFT OPU intervene XIJDI BMMPXT UIF failover MPBE CBMBODFS UP IBOEMF GBJMPWFS BTBQ. #Z BMTP FOBCMJOH roundRobin NPEF, UIFO JU XJMM LFFQ SFUSZJOH VOUJM JU TVDDFTT. :PV DBO UIFO DPOGJHVSF UIF maximumFailoverAttempts PQUJPO UP B IJHI WBMVF UP MFU JU FWFOUVBMMZ FYIBVTU (HJWF VQ) BOE GBJM.

#FP>?IBA FKEBOFQ$OOLO'>KAIBO "T PG $BNFM 2.6, UIF 8FJHIUFE -PBE CBMBODFS VTBHF IBT CFFO GVSUIFS TJNQMJGJFE, UIFSF JT OP OFFE UP TFOE JO EJTUSJCVUJPO3BUJP BT B -JTU<*OUFHFS>. *U DBO CF TJNQMZ TFOU BT B EFMJNJUFE 4USJOH PG JOUFHFS XFJHIUT TFQBSBUFE CZ B EFMJNJUFS PG DIPJDF.

SPVOE3PCJO

CPPMFBO

GBMTF

5IF EFGBVMU WBMVF GPS SPVOE-SPCJO JT GBMTF. *O UIF BCTFODF PG UIJT TFUUJOH PS QBSBNFUFS UIF MPBE CBMBODJOH BMHPSJUIN VTFE JT SBOEPN. 5IF EJTUSJCVUJPO3BUJP JT B EFMJNJUFE 4USJOH DPOTJTUJOH PO JOUFHFS XFJHIUT TFQBSBUFE CZ EFMJNJUFST GPS FYBNQMF "2,3,5". 5IF EJTUSJCVUJPO3BUJP NVTU NBUDI UIF OVNCFS PG FOEQPJOUT BOE/PS QSPDFTTPST TQFDJGJFE JO UIF MPBE CBMBODFS MJTU. 5IF EJTUSJCVUJPO3BUJP%FMJNJUFS JT UIF EFMJNJUFS VTFE UP TQFDJGZ UIF EJTUSJCVUJPO3BUJP. *G UIJT BUUSJCVUF JT OPU TQFDJGJFE B EFGBVMU EFMJNJUFS "," JT FYQFDUFE BT UIF EFMJNJUFS VTFE GPS TQFDJGZJOH UIF EJTUSJCVUJPO3BUJP.

EJTUSJCVUJPO3BUJP

4USJOH

OPOF

EJTUSJCVUJPO3BUJP%FMJNJUFS

4USJOH

4PFKD 6BFDEQBA OLRKA-OL?FK & O>KALJ IL>A ?>I>K@FKD


(K ">JBI 2.5 "O FYBNQMF VTJOH +BWB %4-:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

475

ArrayList<integer> distributionRatio = new ArrayList<integer>(); distributionRatio.add(4); distributionRatio.add(2); distributionRatio.add(1); // round-robin from("direct:start") .loadBalance().weighted(true, distributionRatio) .to("mock:x", "mock:y", "mock:z"); //random from("direct:start") .loadBalance().weighted(false, distributionRatio) .to("mock:x", "mock:y", "mock:z");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<route> <from uri="direct:start"/> <loadBalance> <weighted roundRobin="false" distributionRatio="4 2 1"/> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route>

S>FI>?IB (K ">JBI 2.6 "O FYBNQMF VTJOH +BWB %4-:


// round-robin from("direct:start") .loadBalance().weighted(true, "4:2:1" distributionRatioDelimiter=":") .to("mock:x", "mock:y", "mock:z"); //random from("direct:start") .loadBalance().weighted(false, "4,2,1") .to("mock:x", "mock:y", "mock:z");

"OE UIF TBNF FYBNQMF VTJOH 4QSJOH 9.-:


<route> <from uri="direct:start"/> <loadBalance> <weighted roundRobin="false" distributionRatio="4-2-1" distributionRatioDelimiter="-" /> <to uri="mock:x"/> <to uri="mock:y"/>

476

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<to uri="mock:z"/> </loadBalance> </route>

"RPQLJ +L>A !>I>K@BO :PV DBO VTF B DVTUPN MPBE CBMBODFS (FH ZPVS PXO JNQMFNFOUBUJPO) BMTP. "O FYBNQMF VTJOH +BWB %4-:
from("direct:start") // using our custom load balancer .loadBalance(new MyLoadBalancer()) .to("mock:x", "mock:y", "mock:z");

"OE UIF TBNF FYBNQMF VTJOH 9.- %4-:


<!-- this is the implementation of our custom load balancer --> <bean id="myBalancer" class="org.apache.camel.processor.CustomLoadBalanceTest$MyLoadBalancer"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <loadBalance> <!-- refer to my custom load balancer --> <custom ref="myBalancer"/> <!-- these are the endpoints to balancer --> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance> </route> </camelContext>

/PUJDF JO UIF 9.- %4- BCPWF XF VTF <DVTUPN> XIJDI JT POMZ BWBJMBCMF JO ">JBI 2.8 POXBSET. *O PMEFS SFMFBTFT ZPV XPVME IBWF UP EP BT GPMMPXT JOTUFBE:
<loadBalance ref="myBalancer"> <!-- these are the endpoints to balancer --> <to uri="mock:x"/> <to uri="mock:y"/> <to uri="mock:z"/> </loadBalance>

5P JNQMFNFOU B DVTUPN MPBE CBMBODFS ZPV DBO FYUFOE TPNF TVQQPSU DMBTTFT TVDI BT LoadBalancerSupport BOE SimpleLoadBalancerSupport. 5IF GPSNFS TVQQPSUT UIF BTZODISPOPVT SPVUJOH FOHJOF, BOE UIF MBUUFS EPFT OPU. )FSF JT BO FYBNQMF:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

477

Listing 1. Custom load balancer implementation


public static class MyLoadBalancer extends LoadBalancerSupport { public boolean process(Exchange exchange, AsyncCallback callback) { String body = exchange.getIn().getBody(String.class); try { if ("x".equals(body)) { getProcessors().get(0).process(exchange); } else if ("y".equals(body)) { getProcessors().get(1).process(exchange); } else { getProcessors().get(2).process(exchange); } } catch (Throwable e) { exchange.setException(e); } callback.done(true); return true; } }

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,RIQF@>PQ 5IF .VMUJDBTU BMMPXT UP SPVUF UIF TBNF NFTTBHF UP B OVNCFS PG FOEQPJOUT BOE QSPDFTT UIFN JO B EJGGFSFOU XBZ. 5IF NBJO EJGGFSFODF CFUXFFO UIF .VMUJDBTU BOE 4QMJUUFS JT UIBU 4QMJUUFS XJMM TQMJU UIF NFTTBHF JOUP TFWFSBM QJFDFT CVU UIF .VMUJDBTU XJMM OPU NPEJGZ UIF SFRVFTU NFTTBHF. .MQFLKP
->JB
strategyRef

#BC>RIQ 5>IRB
c

#BP@OFMQFLK
3FGFST UP BO "HHSFHBUJPO4USBUFHZ UP CF VTFE UP BTTFNCMF UIF SFQMJFT GSPN UIF NVMUJDBTUT, JOUP B TJOHMF PVUHPJOH NFTTBHF GSPN UIF .VMUJDBTU. #Z EFGBVMU $BNFM XJMM VTF UIF MBTU SFQMZ BT UIF PVUHPJOH NFTTBHF. *G FOBCMFT UIFO TFOEJOH NFTTBHFT UP UIF NVMUJDBTUT PDDVST DPODVSSFOUMZ. /PUF UIF DBMMFS UISFBE XJMM TUJMM XBJU VOUJM BMM NFTTBHFT IBT CFFO GVMMZ QSPDFTTFE, CFGPSF JU DPOUJOVFT. *UT POMZ UIF TFOEJOH BOE QSPDFTTJOH UIF SFQMJFT GSPN UIF NVMUJDBTUT XIJDI IBQQFOT DPODVSSFOUMZ. 3FGFST UP B DVTUPN 5ISFBE 1PPM UP CF VTFE GPS QBSBMMFM QSPDFTTJOH. /PUJDF JG ZPV TFU UIJT PQUJPO, UIFO QBSBMMFM QSPDFTTJOH JT BVUPNBUJD JNQMJFE, BOE ZPV EP OPU IBWF UP FOBCMF UIBU PQUJPO BT XFMM. ">JBI 2.2: 8IFUIFS PS OPU UP TUPQ DPOUJOVF QSPDFTTJOH JNNFEJBUFMZ XIFO BO FYDFQUJPO PDDVSSFE. *G EJTBCMF, UIFO $BNFM XJMM TFOE UIF NFTTBHF UP BMM NVMUJDBTUT SFHBSEMFTT JG POF PG UIFN GBJMFE. :PV DBO EFBM XJUI FYDFQUJPOT JO UIF "HHSFHBUJPO4USBUFHZ DMBTT XIFSF ZPV IBWF GVMM DPOUSPM IPX UP IBOEMF UIBU. *G FOBCMFE UIFO $BNFM XJMM QSPDFTT SFQMJFT PVU-PG-PSEFS, FH JO UIF PSEFS UIFZ DPNF CBDL. *G EJTBCMFE, $BNFM XJMM QSPDFTT SFQMJFT JO UIF TBNF PSEFS BT NVMUJDBTUFE.

parallelProcessing

false

executorServiceRef

stopOnException

false

streaming

false

478

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

timeout

">JBI 2.5: 4FUT B UPUBM UJNFPVU TQFDJGJFE JO NJMMJT. *G UIF .VMUJDBTU IBTO'U CFFO BCMF UP TFOE BOE QSPDFTT BMM SFQMJFT XJUIJO UIF HJWFO UJNFGSBNF, UIFO UIF UJNFPVU USJHHFST BOE UIF .VMUJDBTU CSFBLT PVU BOE DPOUJOVFT. /PUJDF JG ZPV QSPWJEF B 5JNFPVU"XBSF"HHSFHBUJPO4USBUFHZ UIFO UIF timeout NFUIPE JT JOWPLFE CFGPSF CSFBLJOH PVU. *G UIF UJNFPVU JT SFBDIFE XJUI SVOOJOH UBTLT TUJMM SFNBJOJOH, DFSUBJO UBTLT GPS XIJDI JU JT EJGGJDVMU GPS $BNFM UP TIVU EPXO JO B HSBDFGVM NBOOFS NBZ DPOUJOVF UP SVO. 4P VTF UIJT PQUJPO XJUI B CJU PG DBSF. 8F NBZ CF BCMF UP JNQSPWF UIJT GVODUJPOBMJUZ JO GVUVSF $BNFM SFMFBTFT. ">JBI 2.8: 3FGFST UP B DVTUPN 1SPDFTTPS UP QSFQBSF UIF DPQZ PG UIF &YDIBOHF FBDI NVMUJDBTU XJMM SFDFJWF. 5IJT BMMPXT ZPV UP EP BOZ DVTUPN MPHJD, TVDI BT EFFQ-DMPOJOH UIF NFTTBHF QBZMPBE JG UIBU'T OFFEFE FUD. ">JBI 2.8: 8IFUIFS UIF VOJU PG XPSL TIPVME CF TIBSFE. 4FF UIF TBNF PQUJPO PO 4QMJUUFS GPS NPSF EFUBJMT.

onPrepareRef shareUnitOfWork

c false

$U>JMIB
5IF GPMMPXJOH FYBNQMF TIPXT IPX UP UBLF B SFRVFTU GSPN UIF AFOB@Q:> FOEQPJOU , UIFO NVMUJDBTU UIFTF SFRVFTU UP AFOB@Q:U, AFOB@Q:V, AFOB@Q:W. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:a").multicast().to("direct:x", "direct:y", "direct:z");

#Z EFGBVMU .VMUJDBTU JOWPLFT FBDI FOEQPJOU TFRVFOUJBMMZ. *G QBSBMMFM QSPDFTTJOH JT EFTJSFE, TJNQMZ VTF
from("direct:a").multicast().parallelProcessing().to("direct:x", "direct:y", "direct:z");

*O DBTF PG VTJOH *O0VU .&1, BO "HHSFHBUJPO4USBUFHZ JT VTFE GPS BHHSFHBUJOH BMM SFQMZ NFTTBHFT. 5IF EFGBVMU JT UP POMZ VTF UIF MBUFTU SFQMZ NFTTBHF BOE EJTDBSE BOZ FBSMJFS SFQMJFT. 5IF BHHSFHBUJPO TUSBUFHZ JT DPOGJHVSBCMF:
from("direct:start") .multicast(new MyAggregationStrategy()) .parallelProcessing().timeout(500).to("direct:a", "direct:b", "direct:c") .end() .to("mock:result");

2QLM MOL@BPPFKD FK @>PB LC BU@BMQFLK S>FI>?IB >P LC ">JBI 2.1 5IF .VMUJDBTU XJMM CZ EFGBVMU DPOUJOVF UP QSPDFTT UIF FOUJSF &YDIBOHF FWFO JO DBTF POF PG UIF NVMUJDBTUFE NFTTBHFT XJMM UISPXO BO FYDFQUJPO EVSJOH SPVUJOH. 'PS FYBNQMF JG ZPV XBOU UP NVMUJDBTU UP 3 EFTUJOBUJPOT BOE UIF 2OE EFTUJOBUJPO GBJMT CZ BO FYDFQUJPO. 8IBU $BNFM EPFT CZ EFGBVMU JT UP QSPDFTT UIF SFNBJOEFS EFTUJOBUJPOT. :PV IBWF UIF DIBODF UP SFNFEZ PS IBOEMF UIJT JO UIF AggregationStrategy. #VU TPNFUJNFT ZPV KVTU XBOU $BNFM UP TUPQ BOE MFU UIF FYDFQUJPO CF QSPQBHBUFE CBDL, BOE MFU UIF $BNFM FSSPS IBOEMFS IBOEMF JU. :PV DBO EP UIJT JO $BNFM 2.1 CZ TQFDJGZJOH UIBU JU TIPVME TUPQ JO DBTF PG BO FYDFQUJPO PDDVSSFE. 5IJT JT EPOF CZ UIF stopOnException PQUJPO BT TIPXO CFMPX:

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

479

from("direct:start") .multicast() .stopOnException().to("direct:foo", "direct:bar", "direct:baz") .end() .to("mock:result"); from("direct:foo").to("mock:foo"); from("direct:bar").process(new MyProcessor()).to("mock:bar"); from("direct:baz").to("mock:baz");

"OE VTJOH 9.- %4- ZPV TQFDJGZ JU BT GPMMPXT:


<route> <from uri="direct:start"/> <multicast stopOnException="true"> <to uri="direct:foo"/> <to uri="direct:bar"/> <to uri="direct:baz"/> </multicast> <to uri="mock:result"/> </route> <route> <from uri="direct:foo"/> <to uri="mock:foo"/> </route> <route> <from uri="direct:bar"/> <process ref="myProcessor"/> <to uri="mock:bar"/> </route> <route> <from uri="direct:baz"/> <to uri="mock:baz"/> </route>

4PFKD LK/OBM>OB QL BUB@RQB @RPQLJ ILDF@ TEBK MOBM>OFKD JBPP>DBP S>FI>?IB >P LC ">JBI 2.8 5IF .VMUJDBTU XJMM DPQZ UIF TPVSDF &YDIBOHF BOE NVMUJDBTU FBDI DPQZ. )PXFWFS UIF DPQZ JT B TIBMMPX DPQZ, TP JO DBTF ZPV IBWF NVUBUFBCMF NFTTBHF CPEJFT, UIFO BOZ DIBOHFT XJMM CF WJTJCMF CZ UIF PUIFS DPQJFE NFTTBHFT. *G ZPV XBOU UP VTF B EFFQ DMPOF DPQZ UIFO ZPV OFFE UP VTF B DVTUPN onPrepare XIJDI BMMPXT ZPV UP EP UIJT VTJOH UIF 1SPDFTTPS JOUFSGBDF. /PUJDF UIF onPrepare DBO CF VTFE GPS BOZ LJOE PG DVTUPN MPHJD XIJDI ZPV XPVME MJLF UP FYFDVUF CFGPSF UIF &YDIBOHF JT CFJOH NVMUJDBTUFE.

480

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

#BPFDK CLO FJJRQ>?IB *UT CFTU QSBDUJDF UP EFTJHO GPS JNNVUBCMF PCKFDUT. 'PS FYBNQMF JG ZPV IBWF B NVUBCMF NFTTBHF CPEZ BT UIJT "OJNBM DMBTT:
Listing 1. Animal
public class Animal implements Serializable { private static final long serialVersionUID = 1L; private int id; private String name; public Animal() { } public Animal(int id, String name) { this.id = id; this.name = name; } public Animal deepClone() { Animal clone = new Animal(); clone.setId(getId()); clone.setName(getName()); return clone; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return id + " " + name; } }

5IFO XF DBO DSFBUF B EFFQ DMPOF QSPDFTTPS XIJDI DMPOFT UIF NFTTBHF CPEZ:
Listing 1. AnimalDeepClonePrepare

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

481

public class AnimalDeepClonePrepare implements Processor { public void process(Exchange exchange) throws Exception { Animal body = exchange.getIn().getBody(Animal.class); // do a deep clone of the body which wont affect when doing multicasting Animal clone = body.deepClone(); exchange.getIn().setBody(clone); } }

5IFO XF DBO VTF UIF "OJNBM%FFQ$MPOF1SFQBSF DMBTT JO UIF .VMUJDBTU SPVUF VTJOH UIF onPrepare PQUJPO BT TIPXO:
Listing 1. Multicast using onPrepare
from("direct:start") .multicast().onPrepare(new AnimalDeepClonePrepare()).to("direct:a").to("direct:b");

"OE UIF TBNF FYBNQMF JO 9.- %4Listing 1. Multicast using onPrepare


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <!-- use on prepare with multicast --> <multicast onPrepareRef="animalDeepClonePrepare"> <to uri="direct:a"/> <to uri="direct:b"/> </multicast> </route> <route> <from uri="direct:a"/> <process ref="processorA"/> <to uri="mock:a"/> </route> <route> <from uri="direct:b"/> <process ref="processorB"/> <to uri="mock:b"/> </route> </camelContext> <!-- the on prepare Processor which performs the deep cloning --> <bean id="animalDeepClonePrepare" class="org.apache.camel.processor.AnimalDeepClonePrepare"/> <!-- processors used for the last two routes, as part of unit test --> <bean id="processorA" class="org.apache.camel.processor.MulticastOnPrepareTest$ProcessorA"/>

482

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<bean id="processorB" class="org.apache.camel.processor.MulticastOnPrepareTest$ProcessorB"/>

/PUJDF UIF onPrepare PQUJPO JT BMTP BWBJMBCMF PO PUIFS &*1T TVDI BT 4QMJUUFS, 3FDJQJFOU -JTU, BOE 8JSF 5BQ.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

+../
5IF -PPQ BMMPXT GPS QSPDFTTJOH B NFTTBHF B OVNCFS PG UJNFT, QPTTJCMZ JO B EJGGFSFOU XBZ GPS FBDI JUFSBUJPO. 6TFGVM NPTUMZ EVSJOH UFTUJOH. .MQFLKP ->JB #BC>RIQ 5>IRB #BP@OFMQFLK ">JBI 2.8: 8IFUIFS PS OPU DPQZ NPEF JT VTFE. *G false UIFO UIF TBNF &YDIBOHF XJMM CF VTFE GPS FBDI JUFSBUJPO. 4P UIF SFTVMU GSPN UIF QSFWJPVT JUFSBUJPO XJMM CF visible GPS UIF OFYU JUFSBUJPO. *OTUFBE ZPV DBO FOBCMF DPQZ NPEF, BOE UIFO FBDI JUFSBUJPO restarts XJUI B GSFTI DPQZ PG UIF JOQVU &YDIBOHF.

copy

false

$U@E>KDB MOLMBOQFBP 'PS FBDI JUFSBUJPO UXP QSPQFSUJFT BSF TFU PO UIF Exchange. 1SPDFTTPST DBO SFMZ PO UIFTF QSPQFSUJFT UP QSPDFTT UIF .FTTBHF JO EJGGFSFOU XBZT. /OLMBOQV CamelLoopSize CamelLoopIndex #BP@OFMQFLK 5PUBM OVNCFS PG MPPQT *OEFY PG UIF DVSSFOU JUFSBUJPO (0 CBTFE)

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

483

#BC>RIQ JLAB /PUJDF CZ EFGBVMU UIF MPPQ VTFT UIF TBNF FYDIBOHF UISPVHIPVU UIF MPPQJOH. 4P UIF SFTVMU GSPN UIF QSFWJPVT JUFSBUJPO XJMM CF VTFE GPS UIF OFYU (FH 1JQFT BOE 'JMUFST). 'SPN ">JBI 2.8 POXBSET ZPV DBO FOBCMF DPQZ NPEF JOTUFBE. 4FF UIF PQUJPOT UBCMF GPS NPSF EFUBJMT.

$U>JMIBP
5IF GPMMPXJOH FYBNQMF TIPXT IPX UP UBLF B SFRVFTU GSPN UIF AFOB@Q:U FOEQPJOU, UIFO TFOE UIF NFTTBHF SFQFUJUJWFMZ UP JL@H:OBPRIQ. 5IF OVNCFS PG UJNFT UIF NFTTBHF JT TFOU JT FJUIFS QBTTFE BT BO BSHVNFOU UP loop(), PS EFUFSNJOFE BU SVOUJNF CZ FWBMVBUJOH BO FYQSFTTJPO. 5IF FYQSFTTJPO JRPQ FWBMVBUF UP BO int, PUIFSXJTF B RuntimeCamelException JT UISPXO. 4PFKD QEB %IRBKQ !RFIABOP 1BTT MPPQ DPVOU BT BO BSHVNFOU
from("direct:a").loop(8).to("mock:result");

6TF FYQSFTTJPO UP EFUFSNJOF MPPQ DPVOU


from("direct:b").loop(header("loop")).to("mock:result");

6TF FYQSFTTJPO UP EFUFSNJOF MPPQ DPVOU


from("direct:c").loop().xpath("/hello/@times").to("mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP 1BTT MPPQ DPVOU BT BO BSHVNFOU


<route> <from uri="direct:a"/> <loop> <constant>8</constant> <to uri="mock:result"/> </loop> </route>

6TF FYQSFTTJPO UP EFUFSNJOF MPPQ DPVOU


<route> <from uri="direct:b"/> <loop> <header>loop</header>

484

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<to uri="mock:result"/> </loop> </route>

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU POF PG UIF KVOJU UFTU DBTF

4PFKD @LMV JLAB


S>FI>?IB >P LC ">JBI 2.8 /PX TVQQPTF XF TFOE B NFTTBHF UP "EJSFDU:TUBSU" FOEQPJOU DPOUBJOJOH UIF MFUUFS ". 5IF PVUQVU PG QSPDFTTJOH UIJT SPVUF XJMM CF UIBU, FBDI "NPDL:MPPQ" FOEQPJOU XJMM SFDFJWF ""#" BT NFTTBHF.
from("direct:start") // instruct loop to use copy mode, which mean it will use a copy of the input exchange // for each loop iteration, instead of keep using the same exchange all over .loop(3).copy() .transform(body().append("B")) .to("mock:loop") .end() .to("mock:result");

)PXFWFS JG XF EP KLQ FOBCMF DPQZ NPEF UIFO "NPDL:MPPQ" XJMM SFDFJWF ""#", ""##", ""###", FUD. NFTTBHFT.
from("direct:start") // by default loop will keep using the same exchange so on the 2nd and 3rd iteration its // the same exchange that was previous used that are being looped all over .loop(3) .transform(body().append("B")) .to("mock:loop") .end() .to("mock:result");

5IF FRVJWBMFOU FYBNQMF JO 9.- %4- JO DPQZ NPEF JT BT GPMMPXT:


<route> <from uri="direct:start"/> <!-- enable copy mode for loop eip --> <loop copy="true"> <constant>3</constant> <transform> <simple>${body}B</simple> </transform> <to uri="mock:loop"/>

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

485

</loop> <to uri="mock:result"/> </route>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

,$22 &$ 31 -2%.1, 3(."LKQBKQ $KOF@EBO $BNFM TVQQPSUT UIF $POUFOU &OSJDIFS GSPN UIF &*1 QBUUFSOT VTJOH B .FTTBHF 5SBOTMBUPS, BO BSCJUSBSZ 1SPDFTTPS JO UIF SPVUJOH MPHJD, PS VTJOH UIF FOSJDI %4- FMFNFOU UP FOSJDI UIF NFTTBHF.

"LKQBKQ BKOF@EJBKQ RPFKD > ,BPP>DB 3O>KPI>QLO LO > /OL@BPPLO


4PFKD QEB %IRBKQ !RFIABOP :PV DBO VTF 5FNQMBUJOH UP DPOTVNF B NFTTBHF GSPN POF EFTUJOBUJPO, USBOTGPSN JU XJUI TPNFUIJOH MJLF 7FMPDJUZ PS 92VFSZ, BOE UIFO TFOE JU PO UP BOPUIFS EFTUJOBUJPO. 'PS FYBNQMF VTJOH *O0OMZ (POF XBZ NFTTBHJOH)
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm"). to("activemq:Another.Queue");

*G ZPV XBOU UP VTF *O0VU (SFRVFTU-SFQMZ) TFNBOUJDT UP QSPDFTT SFRVFTUT PO UIF ,V.0RBRB RVFVF PO "DUJWF.2 XJUI B UFNQMBUF HFOFSBUFE SFTQPOTF, UIFO TFOEJOH SFTQPOTFT CBDL UP UIF +.43FQMZ5P %FTUJOBUJPO ZPV DPVME VTF UIJT:

486

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm");

)FSF JT B TJNQMF FYBNQMF VTJOH UIF %4- EJSFDUMZ UP USBOTGPSN UIF NFTTBHF CPEZ
from("direct:start").setBody(body().append(" World!")).to("mock:result");

*O UIJT FYBNQMF XF BEE PVS PXO 1SPDFTTPS VTJOH FYQMJDJU +BWB DPEF
from("direct:start").process(new Processor() { public void process(Exchange exchange) { Message in = exchange.getIn(); in.setBody(in.getBody(String.class) + " World!"); } }).to("mock:result");

'JOBMMZ XF DBO VTF #FBO *OUFHSBUJPO UP VTF BOZ +BWB NFUIPE PO BOZ CFBO UP BDU BT UIF USBOTGPSNFS
from("activemq:My.Queue"). beanRef("myBeanName", "myMethodName"). to("activemq:Another.Queue");

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU POF PG UIF +6OJU UFTUT ` 5SBOTGPSN5FTU ` 5SBOTGPSN7JB%4-5FTU 4PFKD 2MOFKD 7,+
<route> <from uri="activemq:Input"/> <bean ref="myBeanName" method="doTransform"/> <to uri="activemq:Output"/> </route>

"LKQBKQ BKOF@EJBKQ RPFKD QEB enrich #2+ BIBJBKQ $BNFM DPNFT XJUI UXP GMBWPST PG DPOUFOU FOSJDIFS JO UIF %4 enrich pollEnrich enrich VTFT B Producer UP PCUBJO UIF BEEJUJPOBM EBUB. *U JT VTVBMMZ VTFE GPS 3FRVFTU 3FQMZ NFTTBHJOH, GPS JOTUBODF UP JOWPLF BO FYUFSOBM XFC TFSWJDF. pollEnrich PO UIF PUIFS IBOE VTFT B 1PMMJOH $POTVNFS UP PCUBJO UIF BEEJUJPOBM EBUB. *U JT VTVBMMZ VTFE GPS &WFOU .FTTBHF NFTTBHJOH, GPS JOTUBODF UP SFBE B GJMF PS EPXOMPBE B '51 GJMF.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

487

$KOF@E .MQFLKP
->JB
uri ref strategyRef

#BC>RIQ 5>IRB
c c c

#BP@OFMQFLK
5IF FOEQPJOU VSJ GPS UIF FYUFSOBM TFSWJDF UP FOSJDI GSPN. :PV NVTU VTF FJUIFS uri PS ref. 3FGFST UP UIF FOEQPJOU GPS UIF FYUFSOBM TFSWJDF UP FOSJDI GSPN. :PV NVTU VTF FJUIFS uri PS ref. 3FGFST UP BO "HHSFHBUJPO4USBUFHZ UP CF VTFE UP NFSHF UIF SFQMZ GSPN UIF FYUFSOBM TFSWJDF, JOUP B TJOHMF PVUHPJOH NFTTBHF. #Z EFGBVMU $BNFM XJMM VTF UIF SFQMZ GSPN UIF FYUFSOBM TFSWJDF BT PVUHPJOH NFTTBHF.

4PFKD QEB %IRBKQ !RFIABOP


AggregationStrategy aggregationStrategy = ... from("direct:start") .enrich("direct:resource", aggregationStrategy) .to("direct:result"); from("direct:resource") ...

5IF DPOUFOU FOSJDIFS (enrich) SFUSJFWFT BEEJUJPOBM EBUB GSPN B resource endpoint JO PSEFS UP FOSJDI BO JODPNJOH NFTTBHF (DPOUBJOFE JO UIF original exchange). "O BHHSFHBUJPO TUSBUFHZ JT VTFE UP DPNCJOF UIF PSJHJOBM FYDIBOHF BOE UIF resource exchange. 5IF GJSTU QBSBNFUFS PG UIF AggregationStrategy.aggregate(Exchange, Exchange) NFUIPE DPSSFTQPOET UP UIF UIF PSJHJOBM FYDIBOHF, UIF TFDPOE QBSBNFUFS UIF SFTPVSDF FYDIBOHF. 5IF SFTVMUT GSPN UIF SFTPVSDF FOEQPJOU BSF TUPSFE JO UIF SFTPVSDF FYDIBOHF'T PVU-NFTTBHF. )FSF'T BO FYBNQMF UFNQMBUF GPS JNQMFNFOUJOH BO BHHSFHBUJPO TUSBUFHZ:
public class ExampleAggregationStrategy implements AggregationStrategy { public Exchange aggregate(Exchange original, Exchange resource) { Object originalBody = original.getIn().getBody(); Object resourceResponse = resource.getIn().getBody(); Object mergeResult = ... // combine original body and resource response if (original.getPattern().isOutCapable()) { original.getOut().setBody(mergeResult); } else { original.getIn().setBody(mergeResult); } return original; } }

6TJOH UIJT UFNQMBUF UIF PSJHJOBM FYDIBOHF DBO CF PG BOZ QBUUFSO. 5IF SFTPVSDF FYDIBOHF DSFBUFE CZ UIF FOSJDIFS JT BMXBZT BO JO-PVU FYDIBOHF. 4PFKD 2MOFKD 7,+ 5IF TBNF FYBNQMF JO UIF 4QSJOH %4-

488

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <enrich uri="direct:resource" strategyRef="aggregationStrategy"/> <to uri="direct:result"/> </route> <route> <from uri="direct:resource"/> ... </route> </camelContext> <bean id="aggregationStrategy" class="..." />

DDOBD>QFLK PQO>QBDV FP LMQFLK>I


5IF BHHSFHBUJPO TUSBUFHZ JT PQUJPOBM. *G ZPV EP OPU QSPWJEF JU $BNFM XJMM CZ EFGBVMU KVTU VTF UIF CPEZ PCUBJOFE GSPN UIF SFTPVSDF.
from("direct:start") .enrich("direct:resource") .to("direct:result");

*O UIF SPVUF BCPWF UIF NFTTBHF TFOU UP UIF direct:result FOEQPJOU XJMM DPOUBJO UIF PVUQVU GSPN UIF direct:resource BT XF EP OPU VTF BOZ DVTUPN BHHSFHBUJPO. "OE GPS 4QSJOH %4- KVTU PNJU UIF strategyRef BUUSJCVUF:
<route> <from uri="direct:start"/> <enrich uri="direct:resource"/> <to uri="direct:result"/> </route>

"LKQBKQ BKOF@EJBKQ RPFKD pollEnrich 5IF pollEnrich XPSLT KVTU BT UIF enrich IPXFWFS BT JU VTFT B 1PMMJOH $POTVNFS XF IBWF 3 NFUIPET XIFO QPMMJOH SFDFJWF SFDFJWF/P8BJU SFDFJWF(UJNFPVU)

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

489

/LII$KOF@E .MQFLKP
->JB
uri ref strategyRef timeout

#BC>RIQ 5>IRB
c c c -1

#BP@OFMQFLK
5IF FOEQPJOU VSJ GPS UIF FYUFSOBM TFSWJDF UP FOSJDI GSPN. :PV NVTU VTF FJUIFS uri PS ref. 3FGFST UP UIF FOEQPJOU GPS UIF FYUFSOBM TFSWJDF UP FOSJDI GSPN. :PV NVTU VTF FJUIFS uri PS ref. 3FGFST UP BO "HHSFHBUJPO4USBUFHZ UP CF VTFE UP NFSHF UIF SFQMZ GSPN UIF FYUFSOBM TFSWJDF, JOUP B TJOHMF PVUHPJOH NFTTBHF. #Z EFGBVMU $BNFM XJMM VTF UIF SFQMZ GSPN UIF FYUFSOBM TFSWJDF BT PVUHPJOH NFTTBHF. 5JNFPVU JO NJMMJT XIFO QPMMJOH GSPN UIF FYUFSOBM TFSWJDF. 4FF CFMPX GPS JNQPSUBOU EFUBJMT BCPVU UIF UJNFPVU.

*G UIFSF JT OP EBUB UIFO UIF newExchange JO UIF BHHSFHBUJPO TUSBUFHZ JT null. :PV DBO QBTT JO B UJNFPVU WBMVF UIBU EFUFSNJOFT XIJDI NFUIPE UP VTF JG UJNFPVU JT -1 PS PUIFS OFHBUJWF OVNCFS UIFO receive JT TFMFDUFE ((JMLOQ>KQ: UIF receive NFUIPE NBZ CMPDL JG UIFSF JT OP NFTTBHF) JG UJNFPVU JT 0 UIFO receiveNoWait JT TFMFDUFE PUIFSXJTF receive(timeout) JT TFMFDUFE 5IF UJNFPVU WBMVFT JT JO NJMMJT.

$U>JMIB
*O UIJT FYBNQMF XF FOSJDI UIF NFTTBHF CZ MPBEJOH UIF DPOUFOU GSPN UIF GJMF OBNFE JOCPY/ EBUB.UYU.
from("direct:start") .pollEnrich("file:inbox?fileName=data.txt") .to("direct:result");

"OE JO 9.- %4- ZPV EP:


<route> <from uri="direct:start"/> <pollEnrich uri="file:inbox?fileName=data.txt"/> <to uri="direct:result"/> </route>

*G UIFSF JT OP GJMF UIFO UIF NFTTBHF JT FNQUZ. 8F DBO VTF B UJNFPVU UP FJUIFS XBJU (QPUFOUJBMMZ GPSFWFS) VOUJM B GJMF FYJTUT, PS VTF B UJNFPVU UP XBJU B DFSUBJO QFSJPE. 'PS FYBNQMF UP XBJU VQ UP 5 TFDPOET ZPV DBO EP:
<route> <from uri="direct:start"/> <pollEnrich uri="file:inbox?fileName=data.txt" timeout="5000"/> <to uri="direct:result"/> </route>

490

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

&LLA MO>@QF@B QL RPB QFJBLRQ S>IRB #Z EFGBVMU $BNFM XJMM VTF UIF receive. 8IJDI NBZ CMPDL VOUJM UIFSF JT B NFTTBHF BWBJMBCMF. *U JT UIFSFGPSF SFDPNNFOEFE UP BMXBZT QSPWJEF B UJNFPVU WBMVF, UP NBLF UIJT DMFBS UIBU XF NBZ XBJU GPS B NFTTBHF, VOUJM UIF UJNFPVU JT IJU.

#>Q> COLJ @ROOBKQ $U@E>KDB KLQ RPBA pollEnrich EPFT KLQ BDDFTT BOZ EBUB GSPN UIF DVSSFOU &YDIBOHF XIJDI NFBOT XIFO QPMMJOH JU DBOOPU VTF BOZ PG UIF FYJTUJOH IFBEFST ZPV NBZ IBWF TFU PO UIF &YDIBOHF. 'PS FYBNQMF ZPV DBOOPU TFU B GJMFOBNF JO UIF Exchange.FILE_NAME IFBEFS BOE VTF pollEnrich UP DPOTVNF POMZ UIBU GJMF. 'PS UIBU ZPV JRPQ TFU UIF GJMFOBNF JO UIF FOEQPJOU 63*.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. "LKQBKQ %FIQBO $BNFM TVQQPSUT UIF $POUFOU 'JMUFS GSPN UIF &*1 QBUUFSOT VTJOH POF PG UIF GPMMPXJOH NFDIBOJTNT JO UIF SPVUJOH MPHJD UP USBOTGPSN DPOUFOU GSPN UIF JOCPVOE NFTTBHF. ` .FTTBHF 5SBOTMBUPS ` JOWPLJOH B +BWB CFBO ` 1SPDFTTPS PCKFDU

" DPNNPO XBZ UP GJMUFS NFTTBHFT JT UP VTF BO &YQSFTTJPO JO UIF %4- MJLF 92VFSZ, 42- PS POF PG UIF TVQQPSUFE 4DSJQUJOH -BOHVBHFT. 4PFKD QEB %IRBKQ !RFIABOP )FSF JT B TJNQMF FYBNQMF VTJOH UIF %4- EJSFDUMZ
from("direct:start").setBody(body().append(" World!")).to("mock:result");

*O UIJT FYBNQMF XF BEE PVS PXO 1SPDFTTPS

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

491

from("direct:start").process(new Processor() { public void process(Exchange exchange) { Message in = exchange.getIn(); in.setBody(in.getBody(String.class) + " World!"); } }).to("mock:result");

'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU POF PG UIF +6OJU UFTUT ` 5SBOTGPSN5FTU ` 5SBOTGPSN7JB%4-5FTU 4PFKD 2MOFKD 7,+
<route> <from uri="activemq:Input"/> <bean ref="myBeanName" method="doTransform"/> <to uri="activemq:Output"/> </route>

:PV DBO BMTP VTF 91BUI UP GJMUFS PVU QBSU PG UIF NFTTBHF ZPV BSF JOUFSFTUFE JO:
<route> <from uri="activemq:Input"/> <setBody><xpath resultType="org.w3c.dom.Document">//foo:bar</xpath></setBody> <to uri="activemq:Output"/> </route>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. "I>FJ "EB@H 5IF $MBJN $IFDL GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP SFQMBDF NFTTBHF DPOUFOU XJUI B DMBJN DIFDL (B VOJRVF LFZ), XIJDI DBO CF VTFE UP SFUSJFWF UIF NFTTBHF DPOUFOU BU B MBUFS UJNF. 5IF NFTTBHF DPOUFOU JT TUPSFE UFNQPSBSJMZ JO B QFSTJTUFOU TUPSF MJLF B EBUBCBTF PS GJMF TZTUFN. 5IJT QBUUFSO JT WFSZ VTFGVM XIFO NFTTBHF DPOUFOU JT WFSZ MBSHF (UIVT JU XPVME CF FYQFOTJWF UP TFOE BSPVOE) BOE OPU BMM DPNQPOFOUT SFRVJSF BMM JOGPSNBUJPO. *U DBO BMTP CF VTFGVM JO TJUVBUJPOT XIFSF ZPV DBOOPU USVTU UIF JOGPSNBUJPO XJUI BO PVUTJEF QBSUZ; JO UIJT DBTF, ZPV DBO VTF UIF $MBJN $IFDL UP IJEF UIF TFOTJUJWF QPSUJPOT PG EBUB.

492

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

$U>JMIB
*O UIJT FYBNQMF XF XBOU UP SFQMBDF B NFTTBHF CPEZ XJUI B DMBJN DIFDL, BOE SFTUPSF UIF CPEZ BU B MBUFS TUFQ. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:start").to("bean:checkLuggage", "mock:testCheckpoint", "bean:dataEnricher", "mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP

<route> <from uri="direct:start"/> <pipeline> <to uri="bean:checkLuggage"/> <to uri="mock:testCheckpoint"/> <to uri="bean:dataEnricher"/> <to uri="mock:result"/> </pipeline> </route>

5IF FYBNQMF SPVUF JT QSFUUZ TJNQMF - JUT KVTU B 1JQFMJOF. *O B SFBM BQQMJDBUJPO ZPV XPVME IBWF TPNF PUIFS TUFQT XIFSF UIF mock:testCheckpoint FOEQPJOU JT JO UIF FYBNQMF. 5IF NFTTBHF JT GJSTU TFOU UP UIF checkLuggage CFBO XIJDI MPPLT MJLF
public static final class CheckLuggageBean { public void checkLuggage(Exchange exchange, @Body String body, @XPath("/order/@custId") String custId) { // store the message body into the data store, using the custId as the claim check dataStore.put(custId, body); // add the claim check as a header exchange.getIn().setHeader("claimCheck", custId); // remove the body from the message

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

493

exchange.getIn().setBody(null); } }

5IJT CFBO TUPSFT UIF NFTTBHF CPEZ JOUP UIF EBUB TUPSF, VTJOH UIF custId BT UIF DMBJN DIFDL. *O UIJT FYBNQMF, XF'SF KVTU VTJOH B HashMap UP TUPSF UIF NFTTBHF CPEZ; JO B SFBM BQQMJDBUJPO ZPV XPVME VTF B EBUBCBTF PS GJMF TZTUFN, FUD. /FYU UIF DMBJN DIFDL JT BEEFE BT B NFTTBHF IFBEFS GPS VTF MBUFS. 'JOBMMZ XF SFNPWF UIF CPEZ GSPN UIF NFTTBHF BOE QBTT JU EPXO UIF QJQFMJOF. 5IF OFYU TUFQ JO UIF QJQFMJOF JT UIF mock:testCheckpoint FOEQPJOU XIJDI JT KVTU VTFE UP DIFDL UIBU UIF NFTTBHF CPEZ JT SFNPWFE, DMBJN DIFDL BEEFE, FUD. 5P BEE UIF NFTTBHF CPEZ CBDL JOUP UIF NFTTBHF, XF VTF UIF dataEnricher CFBO XIJDI MPPLT MJLF
public static final class DataEnricherBean { public void addDataBackIn(Exchange exchange, @Header("claimCheck") String claimCheck) { // query the data store using the claim check as the key and add the data // back into the message body exchange.getIn().setBody(dataStore.get(claimCheck)); // remove the message data from the data store dataStore.remove(claimCheck); // remove the claim check header exchange.getIn().removeHeader("claimCheck"); } }

5IJT CFBO RVFSJFT UIF EBUB TUPSF VTJOH UIF DMBJN DIFDL BT UIF LFZ BOE UIFO BEET UIF EBUB CBDL JOUP UIF NFTTBHF. 5IF NFTTBHF CPEZ JT UIFO SFNPWFE GSPN UIF EBUB TUPSF BOE GJOBMMZ UIF DMBJN DIFDL JT SFNPWFE. /PX UIF NFTTBHF JT CBDL UP XIBU XF TUBSUFE XJUI! 'PS GVMM EFUBJMT, DIFDL UIF FYBNQMF TPVSDF IFSF: DBNFM-DPSF/TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/QSPDFTTPS/$MBJN$IFDL5FTU.KBWB

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. -LOJ>IFWBO $BNFM TVQQPSUT UIF /PSNBMJ[FS GSPN UIF &*1 QBUUFSOT CZ VTJOH B .FTTBHF 3PVUFS JO GSPOU PG B OVNCFS PG .FTTBHF 5SBOTMBUPS JOTUBODFT.

494

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

$U>JMIB
5IJT FYBNQMF TIPXT B .FTTBHF /PSNBMJ[FS UIBU DPOWFSUT UXP UZQFT PG 9.- NFTTBHFT JOUP B DPNNPO GPSNBU. .FTTBHFT JO UIJT DPNNPO GPSNBU BSF UIFO GJMUFSFE. 4PFKD QEB %IRBKQ !RFIABOP
// we need to normalize two types of incoming messages from("direct:start") .choice() .when().xpath("/employee").to("bean:normalizer?method=employeeToPerson") .when().xpath("/customer").to("bean:normalizer?method=customerToPerson") .end() .to("mock:result");

*O UIJT DBTF XF'SF VTJOH B +BWB CFBO BT UIF OPSNBMJ[FS. 5IF DMBTT MPPLT MJLF UIJT
public class MyNormalizer { public void employeeToPerson(Exchange exchange, @XPath("/employee/name/text()") String name) { exchange.getOut().setBody(createPerson(name)); } public void customerToPerson(Exchange exchange, @XPath("/customer/@name") String name) { exchange.getOut().setBody(createPerson(name)); } private String createPerson(String name) { return "<person name=\"" + name + "\"/>"; } }

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP 5IF TBNF FYBNQMF JO UIF 4QSJOH %4-

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

495

<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <choice> <when> <xpath>/employee</xpath> <to uri="bean:normalizer?method=employeeToPerson"/> </when> <when> <xpath>/customer</xpath> <to uri="bean:normalizer?method=customerToPerson"/> </when> </choice> <to uri="mock:result"/> </route> </camelContext> <bean id="normalizer" class="org.apache.camel.processor.MyNormalizer"/>

2BB

IPL
` .FTTBHF 3PVUFS ` $POUFOU #BTFE 3PVUFS ` .FTTBHF 5SBOTMBUPS

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

2.13
4PSU DBO CF VTFE UP TPSU B NFTTBHF. *NBHJOF ZPV DPOTVNF UFYU GJMFT BOE CFGPSF QSPDFTTJOH FBDI GJMF ZPV XBOU UP CF TVSF UIF DPOUFOU JT TPSUFE. 4PSU XJMM CZ EFGBVMU TPSU UIF CPEZ VTJOH B EFGBVMU DPNQBSBUPS UIBU IBOEMFT OVNFSJD WBMVFT PS VTFT UIF TUSJOH SFQSFTFOUBUJPO. :PV DBO QSPWJEF ZPVS PXO DPNQBSBUPS, BOE FWFO BO FYQSFTTJPO UP SFUVSO UIF WBMVF UP CF TPSUFE. 4PSU SFRVJSFT UIF WBMVF SFUVSOFE GSPN UIF FYQSFTTJPO FWBMVBUJPO JT DPOWFSUJCMF UP java.util.List BT UIJT JT SFRVJSFE CZ UIF +%, TPSU PQFSBUJPO.

496

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

.MQFLKP
->JB
comparatorRef

#BC>RIQ 5>IRB
c

#BP@OFMQFLK
3FGFST UP B DVTUPN java.util.Comparator UP VTF GPS TPSUJOH UIF NFTTBHF CPEZ. $BNFM XJMM CZ EFGBVMU VTF B DPNQBSBUPS XIJDI EPFT B "..; TPSUJOH.

4PFKD COLJ )>S> #2+ *O UIF SPVUF CFMPX JU XJMM SFBE UIF GJMF DPOUFOU BOE UPLFOJ[F CZ MJOF CSFBLT TP FBDI MJOF DBO CF TPSUFE.
from("file://inbox").sort(body().tokenize("\n")).to("bean:MyServiceBean.processLine");

:PV DBO QBTT JO ZPVS PXO DPNQBSBUPS BT B 2OE BSHVNFOU:


from("file://inbox").sort(body().tokenize("\n"), new MyReverseComparator()).to("bean:MyServiceBean.processLine");

4PFKD COLJ 2MOFKD #2+ *O UIF SPVUF CFMPX JU XJMM SFBE UIF GJMF DPOUFOU BOE UPLFOJ[F CZ MJOF CSFBLT TP FBDI MJOF DBO CF TPSUFE.
Listing 1. Camel 2.7 or better
<route> <from uri="file://inbox"/> <sort> <simple>body</simple> </sort> <beanRef ref="myServiceBean" method="processLine"/> </route>

Listing 1. Camel 2.6 or older


<route> <from uri="file://inbox"/> <sort> <expression> <simple>body</simple> </expression> </sort> <beanRef ref="myServiceBean" method="processLine"/> </route>

"OE UP VTF PVS PXO DPNQBSBUPS XF DBO SFGFS UP JU BT B TQSJOH CFBO:


Listing 1. Camel 2.7 or better

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

497

<route> <from uri="file://inbox"/> <sort comparatorRef="myReverseComparator"> <simple>body</simple> </sort> <beanRef ref="MyServiceBean" method="processLine"/> </route> <bean id="myReverseComparator" class="com.mycompany.MyReverseComparator"/>

Listing 1. Camel 2.6 or older


<route> <from uri="file://inbox"/> <sort comparatorRef="myReverseComparator"> <expression> <simple>body</simple> </expression> </sort> <beanRef ref="MyServiceBean" method="processLine"/> </route> <bean id="myReverseComparator" class="com.mycompany.MyReverseComparator"/>

#FTJEFT <simple>, ZPV DBO TVQQMZ BO FYQSFTTJPO VTJOH BOZ MBOHVBHF ZPV MJLF, TP MPOH BT JU SFUVSOT B MJTU.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

,$22 &(-& $-#/.(-32


,BPP>DFKD ,>MMBO $BNFM TVQQPSUT UIF .FTTBHJOH .BQQFS GSPN UIF &*1 QBUUFSOT CZ VTJOH FJUIFS .FTTBHF 5SBOTMBUPS QBUUFSO PS UIF 5ZQF $POWFSUFS NPEVMF.

498

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2BB >IPL
` ` ` ` ` .FTTBHF 5SBOTMBUPS 5ZQF $POWFSUFS $9' GPS +"9-84 TVQQPSU GPS CJOEJOH CVTJOFTT MPHJD UP NFTTBHJOH & XFC TFSWJDFT 1PKP #FBO

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. $SBKQ #OFSBK "LKPRJBO $BNFM TVQQPSUT UIF &WFOU %SJWFO $POTVNFS GSPN UIF &*1 QBUUFSOT. 5IF EFGBVMU DPOTVNFS NPEFM JT FWFOU CBTFE (J.F. BTZODISPOPVT) BT UIJT NFBOT UIBU UIF $BNFM DPOUBJOFS DBO UIFO NBOBHF QPPMJOH, UISFBEJOH BOE DPODVSSFODZ GPS ZPV JO B EFDMBSBUJWF NBOOFS.

5IF &WFOU %SJWFO $POTVNFS JT JNQMFNFOUFE CZ DPOTVNFST JNQMFNFOUJOH UIF 1SPDFTTPS JOUFSGBDF XIJDI JT JOWPLFE CZ UIF .FTTBHF &OEQPJOU XIFO B .FTTBHF JT BWBJMBCMF GPS QSPDFTTJOH. 'PS NPSF EFUBJMT TFF ` .FTTBHF ` .FTTBHF &OEQPJOU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. /LIIFKD "LKPRJBO $BNFM TVQQPSUT JNQMFNFOUJOH UIF 1PMMJOH $POTVNFS GSPN UIF &*1 QBUUFSOT VTJOH UIF 1PMMJOH$POTVNFS JOUFSGBDF XIJDI DBO CF DSFBUFE WJB UIF &OEQPJOU.DSFBUF1PMMJOH$POTVNFS() NFUIPE.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

499

4P JO ZPVS +BWB DPEF ZPV DBO EP


Endpoint endpoint = context.getEndpoint("activemq:my.queue"); PollingConsumer consumer = endpoint.createPollingConsumer(); Exchange exchange = consumer.receive();

5IF ConsumerTemplate (EJTDVTTFE CFMPX) JT BMTP BWBJMBCMF. 5IFSF BSF 3 NBJO QPMMJOH NFUIPET PO 1PMMJOH$POTVNFS ,BQELA K>JB SFDFJWF() #BP@OFMQFLK 8BJUT VOUJM B NFTTBHF JT BWBJMBCMF BOE UIFO SFUVSOT JU; QPUFOUJBMMZ CMPDLJOH GPSFWFS "UUFNQUT UP SFDFJWF B NFTTBHF FYDIBOHF, XBJUJOH VQ UP UIF HJWFO UJNFPVU BOE SFUVSOJOH OVMM JG OP NFTTBHF FYDIBOHF DPVME CF SFDFJWFE XJUIJO UIF UJNF BWBJMBCMF "UUFNQUT UP SFDFJWF B NFTTBHF FYDIBOHF JNNFEJBUFMZ XJUIPVU XBJUJOH BOE SFUVSOJOH OVMM JG B NFTTBHF FYDIBOHF JT OPU BWBJMBCMF ZFU

SFDFJWF(MPOH)

SFDFJWF/P8BJU()

"LKPRJBO3BJMI>QB 5IF ConsumerTemplate JT B UFNQMBUF NVDI MJLF 4QSJOH'T +NT5FNQMBUF PS +ECD5FNQMBUF TVQQPSUJOH UIF 1PMMJOH $POTVNFS &*1. 8JUI UIF UFNQMBUF ZPV DBO DPOTVNF &YDIBOHFT GSPN BO &OEQPJOU. 5IF UFNQMBUF TVQQPSUT UIF 3 PQFSBUJPOT BCPWF, CVU BMTP JODMVEJOH DPOWFOJFOU NFUIPET GPS SFUVSOJOH UIF CPEZ, FUD consumeBody. 5IF FYBNQMF GSPN BCPWF VTJOH $POTVNFS5FNQMBUF JT:
Exchange exchange = consumerTemplate.receive("activemq:my.queue");

0S UP FYUSBDU BOE HFU UIF CPEZ ZPV DBO EP:


Object body = consumerTemplate.receiveBody("activemq:my.queue");

"OE ZPV DBO QSPWJEF UIF CPEZ UZQF BT B QBSBNFUFS BOE IBWF JU SFUVSOFE BT UIF UZQF:

500

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

String body = consumerTemplate.receiveBody("activemq:my.queue", String.class);

:PV HFU IPME PG B ConsumerTemplate GSPN UIF CamelContext XJUI UIF createConsumerTemplate PQFSBUJPO:
ConsumerTemplate consumer = context.createConsumerTemplate();

4PFKD "LKPRJBO3BJMI>QB TFQE 2MOFKD #2+


8JUI UIF 4QSJOH %4- XF DBO EFDMBSF UIF DPOTVNFS JO UIF $BNFM$POUFYU XJUI UIF @LKPRJBO3BJMI>QB UBH, KVTU MJLF UIF 1SPEVDFS5FNQMBUF. 5IF FYBNQMF CFMPX JMMVTUSBUFT UIJT:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- define a producer template --> <template id="producer"/> <!-- define a consumer template --> <consumerTemplate id="consumer"/> <route> <from uri="seda:foo"/> <to id="result" uri="mock:result"/> </route> </camelContext>

5IFO XF DBO HFU MFWFSBHF 4QSJOH UP JOKFDU UIF ConsumerTemplate JO PVS KBWB DMBTT. 5IF DPEF CFMPX JT QBSU PG BO VOJU UFTU CVU JU TIPXT IPX UIF DPOTVNFS BOE QSPEVDFS DBO XPSL UPHFUIFS.
@ContextConfiguration public class SpringConsumerTemplateTest extends SpringRunWithTestSupport { @Autowired private ProducerTemplate producer; @Autowired private ConsumerTemplate consumer; @EndpointInject(ref = "result") private MockEndpoint mock; @Test public void testConsumeTemplate() throws Exception { // we expect Hello World received in our mock endpoint mock.expectedBodiesReceived("Hello World"); // we use the producer template to send a message to the seda:start endpoint

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

501

producer.sendBody("seda:start", "Hello World"); // we consume the body from seda:start String body = consumer.receiveBody("seda:start", String.class); assertEquals("Hello World", body); // and then we send the body again to seda:foo so it will be routed to the mock // endpoint so our unit test can complete producer.sendBody("seda:foo", body); // assert mock received the body mock.assertIsSatisfied(); } }

3FJBO ?>PBA MLIIFKD @LKPRJBO


*O UIJT TBNQMF XF VTF B 5JNFS UP TDIFEVMF B SPVUF UP CF TUBSUFE FWFSZ 5UI TFDPOE BOE JOWPLF PVS CFBO ,V"LLI!B>K XIFSF XF JNQMFNFOU UIF CVTJOFTT MPHJD GPS UIF 1PMMJOH $POTVNFS. )FSF XF XBOU UP DPOTVNF BMM NFTTBHFT GSPN B +.4 RVFVF, QSPDFTT UIF NFTTBHF BOE TFOE UIFN UP UIF OFYU RVFVF. 'JSTU XF TFUVQ PVS SPVUF BT:
MyCoolBean cool = new MyCoolBean(); cool.setProducer(template); cool.setConsumer(consumer); from("timer://foo?period=5000").bean(cool, "someBusinessLogic"); from("activemq:queue.foo").to("mock:result");

"OE UIFO XF IBWF PVU MPHJD JO PVS CFBO:


public static class MyCoolBean { private int count; private ConsumerTemplate consumer; private ProducerTemplate producer; public void setConsumer(ConsumerTemplate consumer) { this.consumer = consumer; } public void setProducer(ProducerTemplate producer) { this.producer = producer; }

502

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

public void someBusinessLogic() { // loop to empty queue while (true) { // receive the message from the queue, wait at most 3 sec String msg = consumer.receiveBody("activemq:queue.inbox", 3000, String.class); if (msg == null) { // no more messages in queue break; } // do something with body msg = "Hello " + msg; // send it to the next queue producer.sendBodyAndHeader("activemq:queue.foo", msg, "number", count++); } } }

2@EBARIBA /LII "LJMLKBKQP 2VJUF B GFX JOCPVOE $BNFM FOEQPJOUT VTF B TDIFEVMFE QPMM QBUUFSO UP SFDFJWF NFTTBHFT BOE QVTI UIFN UISPVHI UIF $BNFM QSPDFTTJOH SPVUFT. 5IBU JT UP TBZ FYUFSOBMMZ GSPN UIF DMJFOU UIF FOEQPJOU BQQFBST UP VTF BO &WFOU %SJWFO $POTVNFS CVU JOUFSOBMMZ B TDIFEVMFE QPMM JT VTFE UP NPOJUPS TPNF LJOE PG TUBUF PS SFTPVSDF BOE UIFO GJSF NFTTBHF FYDIBOHFT. 4JODF UIJT B TVDI B DPNNPO QBUUFSO, QPMMJOH DPNQPOFOUT DBO FYUFOE UIF 4DIFEVMFE1PMM$POTVNFS CBTF DMBTT XIJDI NBLFT JU TJNQMFS UP JNQMFNFOU UIJT QBUUFSO. 5IFSF JT BMTP UIF 2VBSU[ $PNQPOFOU XIJDI QSPWJEFT TDIFEVMFE EFMJWFSZ PG NFTTBHFT VTJOH UIF 2VBSU[ FOUFSQSJTF TDIFEVMFS. 'PS NPSF EFUBJMT TFF: ` 1PMMJOH$POTVNFS ` 4DIFEVMFE 1PMMJOH $PNQPOFOUT 4DIFEVMFE1PMM$POTVNFS "UPN 'JMF '51 ICBTF J#"5*4 +1" .BJM .Z#BUJT 2VBSU[ 4/.1 "84-43

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

503

"84-424 2@EBARIBA/LII"LKPRJBO .MQFLKP 5IF 4DIFEVMFE1PMM$POTVNFS TVQQPSUT UIF GPMMPXJOH PQUJPOT:


.MQFLK #BC>RIQ #BP@OFMQFLK
" QMVHHBCMF org.apache.camel.PollingConsumerPollingStrategy BMMPXJOH ZPV UP QSPWJEF ZPVS DVTUPN JNQMFNFOUBUJPO UP DPOUSPM FSSPS IBOEMJOH VTVBMMZ PDDVSSFE EVSJOH UIF poll PQFSBUJPO ?BCLOB BO &YDIBOHF IBWF CFFO DSFBUFE BOE CFJOH SPVUFE JO $BNFM. *O PUIFS XPSET UIF FSSPS PDDVSSFE XIJMF UIF QPMMJOH XBT HBUIFSJOH JOGPSNBUJPO, GPS JOTUBODF BDDFTT UP B GJMF OFUXPSL GBJMFE TP $BNFM DBOOPU BDDFTT JU UP TDBO GPS GJMFT. 5IF EFGBVMU JNQMFNFOUBUJPO XJMM MPH UIF DBVTFE FYDFQUJPO BU WARN MFWFM BOE JHOPSF JU. ">JBI 2.9: *G UIF QPMMJOH DPOTVNFS EJE OPU QPMM BOZ GJMFT, ZPV DBO FOBCMF UIJT PQUJPO UP TFOE BO FNQUZ NFTTBHF (OP CPEZ) JOTUFBE. 8IFUIFS UIF TDIFEVMFS TIPVME CF BVUP TUBSUFE. .JMMJTFDPOET CFGPSF UIF GJSTU QPMM TUBSUT. .JMMJTFDPOET CFGPSF UIF OFYU QPMM. $POUSPMT JG GJYFE EFMBZ PS GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT. *O ">JBI 2.7.U PS PMEFS UIF EFGBVMU WBMVF JT false. 'SPN ">JBI 2.8 POXBSET UIF EFGBVMU WBMVF JT true. UJNF VOJU GPS initialDelay BOE delay PQUJPOT. ">JBI 2.8: 5IF DPOTVNFS MPHT B TUBSU/DPNQMFUF MPH MJOF XIFO JU QPMMT. 5IJT PQUJPO BMMPXT ZPV UP DPOGJHVSF UIF MPHHJOH MFWFM GPS UIBU. ">JBI 2.10: "MMPXT GPS DPOGJHVSJOH B DVTUPN/TIBSFE UISFBE QPPM UP VTF GPS UIF DPOTVNFS. #Z EFGBVMU FBDI DPOTVNFS IBT JUT PXO TJOHMF UISFBEFE UISFBE QPPM. 5IJT PQUJPO BMMPXT ZPV UP TIBSF B UISFBE QPPM BNPOH NVMUJQMF DPOTVNFST.

pollStrategy

sendEmptyMessageWhenIdle startScheduler initialDelay delay useFixedDelay UJNF6OJU runLoggingLevel

false true 1000 500 c TimeUnit.MILLISECONDS TRACE

scheduledExecutorService

null

?LRQ BOOLO E>KAIFKD >KA P@EBARIBA MLIIFKD @LKPRJBOP 4DIFEVMFE1PMM$POTVNFS JT TDIFEVMFE CBTFE BOE JUT run NFUIPE JT JOWPLFE QFSJPEJDBMMZ CBTFE PO TDIFEVMF TFUUJOHT. #VU FSSPST DBO BMTP PDDVS XIFO B QPMM JT CFJOH FYFDVUFE. 'PS JOTUBODF JG $BNFM TIPVME QPMM B GJMF OFUXPSL, BOE UIJT OFUXPSL SFTPVSDF JT OPU BWBJMBCMF UIFO B java.io.IOException DPVME PDDVS. "T UIJT FSSPS IBQQFOT ?BCLOB BOZ &YDIBOHF IBT CFFO DSFBUFE BOE QSFQBSFE GPS SPVUJOH, UIFO UIF SFHVMBS &SSPS IBOEMJOH JO $BNFM EPFT OPU BQQMZ. 4P XIBU EPFT UIF DPOTVNFS EP UIFO 8FMM UIF FYDFQUJPO JT QSPQBHBUFE CBDL UP UIF run NFUIPE XIFSF JUT IBOEMFE. $BNFM XJMM CZ EFGBVMU MPH UIF FYDFQUJPO BU WARN MFWFM BOE UIFO JHOPSF JU. "U OFYU TDIFEVMF UIF FSSPS DPVME IBWF CFFO SFTPMWFE BOE UIVT CFJOH BCMF UP QPMM UIF FOEQPJOU TVDDFTTGVMMZ.

"LKQOLIIFKD QEB BOOLO E>KAIFKD RPFKD /LIIFKD"LKPRJBO/LII2QO>QBDV


org.apache.camel.PollingConsumerPollStrategy JT B QMVHHBCMF TUSBUFHZ UIBU ZPV DBO DPOGJHVSF PO UIF ScheduledPollConsumer. 5IF EFGBVMU JNQMFNFOUBUJPO org.apache.camel.impl.DefaultPollingConsumerPollStrategy XJMM MPH UIF DBVTFE FYDFQUJPO BU WARN MFWFM BOE UIFO JHOPSF UIJT JTTVF. 5IF TUSBUFHZ JOUFSGBDF QSPWJEFT UIF GPMMPXJOH 3 NFUIPET CFHJO

504

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

void begin(Consumer consumer, Endpoint endpoint) CFHJO (">JBI 2.3) boolean begin(Consumer consumer, Endpoint endpoint) DPNNJU void commit(Consumer consumer, Endpoint endpoint) DPNNJU (">JBI 2.6) void commit(Consumer consumer, Endpoint endpoint, int polledMessages) SPMMCBDL boolean rollback(Consumer consumer, Endpoint endpoint, int retryCounter, Exception e) throws Exception *O ">JBI 2.3 POXBSET UIF CFHJO NFUIPE SFUVSOT B CPPMFBO XIJDI JOEJDBUFT XIFUIFS PS OPU UP TLJQQJOH QPMMJOH. 4P ZPV DBO JNQMFNFOU ZPVS DVTUPN MPHJD BOE SFUVSO false JG ZPV EP OPU XBOU UP QPMM UIJT UJNF. *O ">JBI 2.6 POXBSET UIF DPNNJU NFUIPE IBT BO BEEJUJPOBM QBSBNFUFS DPOUBJOJOH UIF OVNCFS PG NFTTBHF UIBU XBT BDUVBMMZ QPMMFE. 'PS FYBNQMF JG UIFSF XBT OP NFTTBHFT QPMMFE, UIF WBMVF XPVME CF [FSP, BOE ZPV DBO SFBDU BDDPSEJOHMZ. 5IF NPTU JOUFSFTUJOH JT UIF rollback BT JU BMMPXT ZPV EP IBOEMF UIF DBVTFE FYDFQUJPO BOE EFDJEF XIBU UP EP. 'PS JOTUBODF JG XF XBOU UP QSPWJEF B SFUSZ GFBUVSF UP B TDIFEVMFE DPOTVNFS XF DBO JNQMFNFOU UIF PollingConsumerPollStrategy NFUIPE BOE QVU UIF SFUSZ MPHJD JO UIF rollback NFUIPE. -FUT KVTU SFUSZ VQ UJMM 3 UJNFT:
public boolean rollback(Consumer consumer, Endpoint endpoint, int retryCounter, Exception e) throws Exception { if (retryCounter < 3) { // return true to tell Camel that it should retry the poll immediately return true; } // okay we give up do not retry anymore return false; }

/PUJDF UIBU XF BSF HJWFO UIF Consumer BT B QBSBNFUFS. 8F DPVME VTF UIJT UP restart UIF DPOTVNFS BT XF DBO JOWPLF TUPQ BOE TUBSU:
// error occurred lets restart the consumer, that could maybe resolve the issue consumer.stop(); consumer.start();

-LQF@B: *G ZPV JNQMFNFOU UIF begin PQFSBUJPO NBLF TVSF UP BWPJE UISPXJOH FYDFQUJPOT BT JO TVDI B DBTF UIF poll PQFSBUJPO JT OPU JOWPLFE BOE $BNFM XJMM JOWPLF UIF rollback EJSFDUMZ.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

505

"LKCFDROFKD >K $KAMLFKQ QL RPB PollingConsumerPollStrategy


5P DPOGJHVSF BO &OEQPJOU UP VTF B DVTUPN PollingConsumerPollStrategy ZPV VTF UIF PQUJPO pollStrategy. 'PS FYBNQMF JO UIF GJMF DPOTVNFS CFMPX XF XBOU UP VTF PVS DVTUPN TUSBUFHZ EFGJOFE JO UIF 3FHJTUSZ XJUI UIF CFBO JE myPoll:
from("file://inbox/?pollStrategy=#myPoll").to("activemq:queue:inbox")

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2BB IPL 10+0 $POTVNJOH #BUDI $POTVNFS "LJMBQFKD "LKPRJBOP $BNFM TVQQPSUT UIF $PNQFUJOH $POTVNFST GSPN UIF &*1 QBUUFSOT VTJOH B GFX EJGGFSFOU DPNQPOFOUT.

:PV DBO VTF UIF GPMMPXJOH DPNQPOFOUT UP JNQMFNFOU DPNQFUJOH DPOTVNFST:` 4&%" GPS 4&%" CBTFE DPODVSSFOU QSPDFTTJOH VTJOH B UISFBE QPPM ` +.4 GPS EJTUSJCVUFE 4&%" CBTFE DPODVSSFOU QSPDFTTJOH XJUI RVFVFT XIJDI TVQQPSU SFMJBCMF MPBE CBMBODJOH, GBJMPWFS BOE DMVTUFSJOH.

506

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

$K>?IFKD "LJMBQFKD "LKPRJBOP TFQE ),2 5P FOBCMF $PNQFUJOH $POTVNFST ZPV KVTU OFFE UP TFU UIF @LK@ROOBKQ"LKPRJBOP QSPQFSUZ PO UIF +.4 FOEQPJOU. 'PS FYBNQMF
from("jms:MyQueue?concurrentConsumers=5").bean(SomeBean.class);

PS JO 4QSJOH %4<route> <from uri="jms:MyQueue?concurrentConsumers=5"/> <to uri="bean:someBean"/> </route>

0S KVTU SVO NVMUJQMF +7.T PG BOZ "DUJWF.2 PS +.4 SPVUF

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DB #FPM>Q@EBO $BNFM TVQQPSUT UIF .FTTBHF %JTQBUDIFS GSPN UIF &*1 QBUUFSOT VTJOH WBSJPVT BQQSPBDIFT.

:PV DBO VTF B DPNQPOFOU MJLF +.4 XJUI TFMFDUPST UP JNQMFNFOU B 4FMFDUJWF $POTVNFS BT UIF .FTTBHF %JTQBUDIFS JNQMFNFOUBUJPO. 0S ZPV DBO VTF BO &OEQPJOU BT UIF .FTTBHF %JTQBUDIFS JUTFMG BOE UIFO VTF B $POUFOU #BTFE 3PVUFS BT UIF .FTTBHF %JTQBUDIFS.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

507

2BB
` ` ` `

IPL
+.4 4FMFDUJWF $POTVNFS $POUFOU #BTFE 3PVUFS &OEQPJOU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2BIB@QFSB "LKPRJBO 5IF 4FMFDUJWF $POTVNFS GSPN UIF &*1 QBUUFSOT DBO CF JNQMFNFOUFE JO UXP XBZT

5IF GJSTU TPMVUJPO JT UP QSPWJEF B .FTTBHF 4FMFDUPS UP UIF VOEFSMZJOH 63*T XIFO DSFBUJOH ZPVS DPOTVNFS. 'PS FYBNQMF XIFO VTJOH +.4 ZPV DBO TQFDJGZ B TFMFDUPS QBSBNFUFS TP UIBU UIF NFTTBHF CSPLFS XJMM POMZ EFMJWFS NFTTBHFT NBUDIJOH ZPVS DSJUFSJB. 5IF PUIFS BQQSPBDI JT UP VTF B .FTTBHF 'JMUFS XIJDI JT BQQMJFE; UIFO JG UIF GJMUFS NBUDIFT UIF NFTTBHF ZPVS DPOTVNFS JT JOWPLFE BT TIPXO JO UIF GPMMPXJOH FYBNQMF 4PFKD QEB %IRBKQ !RFIABOP
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .filter(header("foo").isEqualTo("bar")) .process(myProcessor); } };

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<bean id="myProcessor" class="org.apache.camel.builder.MyProcessor"/> <camelContext errorHandlerRef="errorHandler" xmlns="http://camel.apache.org/schema/ spring">

508

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<route> <from uri="direct:a"/> <filter> <xpath>$foo = 'bar'</xpath> <process ref="myProcessor"/> </filter> </route> </camelContext>

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. #RO>?IB 2R?P@OF?BO $BNFM TVQQPSUT UIF %VSBCMF 4VCTDSJCFS GSPN UIF &*1 QBUUFSOT VTJOH UIF +.4 DPNQPOFOU XIJDI TVQQPSUT QVCMJTI & TVCTDSJCF VTJOH 5PQJDT XJUI TVQQPSU GPS OPO-EVSBCMF BOE EVSBCMF TVCTDSJCFST.

"OPUIFS BMUFSOBUJWF JT UP DPNCJOF UIF .FTTBHF %JTQBUDIFS PS $POUFOU #BTFE 3PVUFS XJUI 'JMF PS +1" DPNQPOFOUT GPS EVSBCMF TVCTDSJCFST UIFO TPNFUIJOH MJLF 4&%" GPS OPO-EVSBCMF. )FSF JT B TJNQMF FYBNQMF PG DSFBUJOH EVSBCMF TVCTDSJCFST UP B +.4 UPQJD 4PFKD QEB %IRBKQ !RFIABOP
from("direct:start").to("activemq:topic:foo"); from("activemq:topic:foo?clientId=1&durableSubscriptionName=bar1").to("mock:result1"); from("activemq:topic:foo?clientId=2&durableSubscriptionName=bar2").to("mock:result2");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

509

<route> <from uri="direct:start"/> <to uri="activemq:topic:foo"/> </route> <route> <from uri="activemq:topic:foo?clientId=1&durableSubscriptionName=bar1"/> <to uri="mock:result1"/> </route> <route> <from uri="activemq:topic:foo?clientId=2&durableSubscriptionName=bar2"/> <to uri="mock:result2"/> </route>

)FSF JT BOPUIFS FYBNQMF PG +.4 EVSBCMF TVCTDSJCFST, CVU UIJT UJNF VTJOH WJSUVBM UPQJDT (SFDPNNFOEFE CZ ".2 PWFS EVSBCMF TVCTDSJQUJPOT) 4PFKD QEB %IRBKQ !RFIABOP
from("direct:start").to("activemq:topic:VirtualTopic.foo"); from("activemq:queue:Consumer.1.VirtualTopic.foo").to("mock:result1"); from("activemq:queue:Consumer.2.VirtualTopic.foo").to("mock:result2");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:start"/> <to uri="activemq:topic:VirtualTopic.foo"/> </route> <route> <from uri="activemq:queue:Consumer.1.VirtualTopic.foo"/> <to uri="mock:result1"/> </route> <route> <from uri="activemq:queue:Consumer.2.VirtualTopic.foo"/> <to uri="mock:result2"/> </route>

2BB
` ` ` `

IPL
+.4 'JMF +1" .FTTBHF %JTQBUDIFS

510

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

` 4FMFDUJWF $POTVNFS ` $POUFOU #BTFE 3PVUFS ` &OEQPJOU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. (ABJMLQBKQ "LKPRJBO 5IF *EFNQPUFOU $POTVNFS GSPN UIF &*1 QBUUFSOT JT VTFE UP GJMUFS PVU EVQMJDBUF NFTTBHFT. 5IJT QBUUFSO JT JNQMFNFOUFE VTJOH UIF *EFNQPUFOU$POTVNFS DMBTT. 5IJT VTFT BO &YQSFTTJPO UP DBMDVMBUF B VOJRVF NFTTBHF *% TUSJOH GPS B HJWFO NFTTBHF FYDIBOHF; UIJT *% DBO UIFO CF MPPLFE VQ JO UIF *EFNQPUFOU3FQPTJUPSZ UP TFF JG JU IBT CFFO TFFO CFGPSF; JG JU IBT UIF NFTTBHF JT DPOTVNFE; JG JUT OPU UIFO UIF NFTTBHF JT QSPDFTTFE BOE UIF *% JT BEEFE UP UIF SFQPTJUPSZ. 5IF *EFNQPUFOU $POTVNFS FTTFOUJBMMZ BDUT MJLF B .FTTBHF 'JMUFS UP GJMUFS PVU EVQMJDBUFT. $BNFM XJMM BEE UIF NFTTBHF JE FBHFSMZ UP UIF SFQPTJUPSZ UP EFUFDU EVQMJDBUJPO BMTP GPS &YDIBOHFT DVSSFOUMZ JO QSPHSFTT. 0O DPNQMFUJPO $BNFM XJMM SFNPWF UIF NFTTBHF JE GSPN UIF SFQPTJUPSZ JG UIF &YDIBOHF GBJMFE, PUIFSXJTF JU TUBZT UIFSF. $BNFM QSPWJEFT UIF GPMMPXJOH *EFNQPUFOU $POTVNFS JNQMFNFOUBUJPOT: .FNPSZ*EFNQPUFOU3FQPTJUPSZ 'JMF*EFNQPUFOU3FQPTJUPSZ )B[FMDBTU*EFNQPUFOU3FQPTJUPSZ ( S>FI>?IB >P LC ">JBI 2.8) +ECD.FTTBHF*E3FQPTJUPSZ ( S>FI>?IB >P LC ">JBI 2.7) +QB.FTTBHF*E3FQPTJUPSZ .MQFLKP 5IF *EFNQPUFOU $POTVNFS IBT UIF GPMMPXJOH PQUJPOT: .MQFLK #BC>RIQ #BP@OFMQFLK &BHFS DPOUSPMT XIFUIFS $BNFM BEET UIF NFTTBHF UP UIF SFQPTJUPSZ CFGPSF PS BGUFS UIF FYDIBOHF IBT CFFO QSPDFTTFE. *G FOBCMFE CFGPSF UIFO $BNFM XJMM CF BCMF UP EFUFDU EVQMJDBUF NFTTBHFT FWFO XIFO NFTTBHFT BSF DVSSFOUMZ JO QSPHSFTT. #Z EJTBCMJOH $BNFM XJMM POMZ EFUFDU EVQMJDBUFT XIFO B NFTTBHF IBT TVDDFTTGVMMZ CFFO QSPDFTTFE.

FBHFS

USVF

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

511

NFTTBHF*E3FQPTJUPSZ3FG

null

" SFGFSFODF UP B IdempotentRepository UP MPPLVQ JO UIF SFHJTUSZ. 5IJT PQUJPO JT NBOEBUPSZ XIFO VTJOH 9.- %4-. ">JBI 2.8: 4FUT XIFUIFS UP TLJQ EVQMJDBUF NFTTBHFT. *G TFU UP false UIFO UIF NFTTBHF XJMM CF DPOUJOVFE. )PXFWFS UIF &YDIBOHF IBT CFFO NBSLFE BT B EVQMJDBUF CZ IBWJOH UIF Exchange.DUPLICATE_MESSAG FYDIBOHF QSPQFSUZ TFU UP B Boolean.TRUE WBMVF. ">JBI 2.9: 4FUT XIFUIFS UP SFNPWF UIF JE PG BO &YDIBOHF UIBU GBJMFE.

TLJQ%VQMJDBUF

USVF

SFNPWF0O'BJMVSF

USVF

4PFKD QEB %IRBKQ !RFIABOP 5IF GPMMPXJOH FYBNQMF XJMM VTF UIF IFBEFS JV,BPP>DB(A UP GJMUFS PVU EVQMJDBUFT
RouteBuilder builder = new RouteBuilder() { public void configure() { errorHandler(deadLetterChannel("mock:error")); from("direct:a") .idempotentConsumer(header("myMessageId"), MemoryIdempotentRepository.memoryIdempotentRepository(200)) .to("direct:b"); } };

5IF BCPWF FYBNQMF XJMM VTF BO JO-NFNPSZ CBTFE .FTTBHF*E3FQPTJUPSZ XIJDI DBO FBTJMZ SVO PVU PG NFNPSZ BOE EPFTO'U XPSL JO B DMVTUFSFE FOWJSPONFOU. 4P ZPV NJHIU QSFGFS UP VTF UIF +1" CBTFE JNQMFNFOUBUJPO XIJDI VTFT B EBUBCBTF UP TUPSF UIF NFTTBHF *%T XIJDI IBWF CFFO QSPDFTTFE
from("direct:start").idempotentConsumer( header("messageId"), jpaMessageIdRepository(lookup(JpaTemplate.class), PROCESSOR_NAME) ).to("mock:result");

*O UIF BCPWF FYBNQMF XF BSF VTJOH UIF IFBEFS JBPP>DB(A UP GJMUFS PVU EVQMJDBUFT BOE VTJOH UIF DPMMFDUJPO JV/OL@BPPLO->JB UP JOEJDBUF UIF .FTTBHF *% 3FQPTJUPSZ UP VTF. 5IJT OBNF JT JNQPSUBOU BT ZPV DPVME QSPDFTT UIF TBNF NFTTBHF CZ NBOZ EJGGFSFOU QSPDFTTPST; TP FBDI NBZ SFRVJSF JUT PXO MPHJDBM .FTTBHF *% 3FQPTJUPSZ. 'PS GVSUIFS FYBNQMFT PG UIJT QBUUFSO JO VTF ZPV DPVME MPPL BU UIF KVOJU UFTU DBTF

512

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

2MOFKD 7,+ BU>JMIB 5IF GPMMPXJOH FYBNQMF XJMM VTF UIF IFBEFS JV,BPP>DB(A UP GJMUFS PVU EVQMJDBUFT
<!-- repository for the idempotent consumer --> <bean id="myRepo" class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <idempotentConsumer messageIdRepositoryRef="myRepo"> <!-- use the messageId header as key for identifying duplicate messages --> <header>messageId</header> <!-- if not a duplicate send it to this mock endpoint --> <to uri="mock:result"/> </idempotentConsumer> </route> </camelContext>

'LT QL E>KAIB ARMIF@>QB JBPP>DBP FK QEB OLRQB S>FI>?IB >P LC ">JBI 2.8 :PV DBO OPX TFU UIF skipDuplicate PQUJPO UP false XIJDI JOTUSVDUT UIF JEFNQPUFOU DPOTVNFS UP SPVUF EVQMJDBUF NFTTBHFT BT XFMM. )PXFWFS UIF EVQMJDBUF NFTTBHF IBT CFFO NBSLFE BT EVQMJDBUF CZ IBWJOH B QSPQFSUZ PO UIF &YDIBOHF TFU UP USVF. 8F DBO MFWFSBHF UIJT GBDU CZ VTJOH B $POUFOU #BTFE 3PVUFS PS .FTTBHF 'JMUFS UP EFUFDU UIJT BOE IBOEMF EVQMJDBUF NFTTBHFT. 'PS FYBNQMF JO UIF GPMMPXJOH FYBNQMF XF VTF UIF .FTTBHF 'JMUFS UP TFOE UIF NFTTBHF UP B EVQMJDBUF FOEQPJOU, BOE UIFO TUPQ DPOUJOVF SPVUJOH UIBU NFTTBHF.
Listing 1. Filter duplicate messages
from("direct:start") // instruct idempotent consumer to not skip duplicates as we will filter then our self .idempotentConsumer(header("messageId")).messageIdRepository(repo).skipDuplicate(false) .filter(property(Exchange.DUPLICATE_MESSAGE).isEqualTo(true)) // filter out duplicate messages by sending them to someplace else and then stop .to("mock:duplicate") .stop() .end() // and here we process only new messages (no duplicates) .to("mock:result");

5IF TBNQMF FYBNQMF JO 9.- %4- XPVME CF:


Listing 1. Filter duplicate messages

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

513

<!-- idempotent repository, just use a memory based for testing --> <bean id="myRepo" class="org.apache.camel.processor.idempotent.MemoryIdempotentRepository"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <!-- we do not want to skip any duplicate messages --> <idempotentConsumer messageIdRepositoryRef="myRepo" skipDuplicate="false"> <!-- use the messageId header as key for identifying duplicate messages --> <header>messageId</header> <!-- we will to handle duplicate messages using a filter --> <filter> <!-- the filter will only react on duplicate messages, if this property is set on the Exchange --> <property>CamelDuplicateMessage</property> <!-- and send the message to this mock, due its part of an unit test --> <!-- but you can of course do anything as its part of the route --> <to uri="mock:duplicate"/> <!-- and then stop --> <stop/> </filter> <!-- here we route only new messages --> <to uri="mock:result"/> </idempotentConsumer> </route> </camelContext>

'LT QL E>KAIB ARMIF@>QB JBPP>DB FK > @IRPQBOBA BKSFOLKJBKQ TFQE > A>Q> DOFA S>FI>?IB >P LC ">JBI 2.8 *G ZPV IBWF SVOOJOH $BNFM JO B DMVTUFSFE FOWJSPONFOU, B JO NFNPSZ JEFNQPUFOU SFQPTJUPSZ EPFTO'U XPSL (TFF BCPWF). :PV DBO TFUVQ FJUIFS B DFOUSBM EBUBCBTF PS VTF UIF JEFNQPUFOU DPOTVNFS JNQMFNFOUBUJPO CBTFE PO UIF )B[FMDBTU EBUB HSJE. )B[FMDBTU GJOET UIF OPEFT PWFS NVMUJDBTU (XIJDI JT EFGBVMU - DPOGJHVSF )B[FMDBTU GPS UDQ-JQ) BOE DSFBUFT BVUPNBUJDBMMZ B NBQ CBTFE SFQPTJUPSZ:
HazelcastIdempotentRepository idempotentRepo = new HazelcastIdempotentRepository("myrepo"); from("direct:in").idempotentConsumer(header("messageId"), idempotentRepo).to("mock:out");

:PV IBWF UP EFGJOF IPX MPOH UIF SFQPTJUPSZ TIPVME IPME FBDI NFTTBHF JE (EFGBVMU JT UP EFMFUF JU OFWFS). 5P BWPJE UIBU ZPV SVO PVU PG NFNPSZ ZPV TIPVME DSFBUF BO FWJDUJPO TUSBUFHZ CBTFE PO UIF )B[FMDBTU DPOGJHVSBUJPO. 'PS BEEJUJPOBM JOGPSNBUJPO TFF DBNFM-IB[FMDBTU.

514

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4FF UIJT MJUUMF UVUPSJBM, IPX TFUVQ TVDI BO JEFNQPUFOU SFQPTJUPSZ PO UXP DMVTUFS OPEFT VTJOH "QBDIF ,BSBG.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 3O>KP>@QFLK>I "IFBKQ $BNFM SFDPNNFOET TVQQPSUJOH UIF 5SBOTBDUJPOBM $MJFOU GSPN UIF &*1 QBUUFSOT VTJOH TQSJOH USBOTBDUJPOT.

5SBOTBDUJPO 0SJFOUFE &OEQPJOUT ($BNFM 5PFT) MJLF +.4 TVQQPSU VTJOH B USBOTBDUJPO GPS CPUI JOCPVOE BOE PVUCPVOE NFTTBHF FYDIBOHFT. &OEQPJOUT UIBU TVQQPSU USBOTBDUJPOT XJMM QBSUJDJQBUF JO UIF DVSSFOU USBOTBDUJPO DPOUFYU UIBU UIFZ BSF DBMMFE GSPN. :PV TIPVME VTF UIF 4QSJOH3PVUF#VJMEFS UP TFUVQ UIF SPVUFT TJODF ZPV XJMM OFFE UP TFUVQ UIF TQSJOH DPOUFYU XJUI UIF 5SBOTBDUJPO5FNQMBUFT UIBU XJMM EFGJOF UIF USBOTBDUJPO NBOBHFS DPOGJHVSBUJPO BOE QPMJDJFT. 'PS JOCPVOE FOEQPJOU UP CF USBOTBDUFE, UIFZ OPSNBMMZ OFFE UP CF DPOGJHVSFE UP VTF B 4QSJOH 1MBUGPSN5SBOTBDUJPO.BOBHFS. *O UIF DBTF PG UIF +.4 DPNQPOFOU, UIJT DBO CF EPOF CZ MPPLJOH JU VQ JO UIF TQSJOH DPOUFYU. :PV GJSTU EFGJOF OFFEFE PCKFDU JO UIF TQSJOH DPOGJHVSBUJPO.
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager"> <property name="connectionFactory" ref="jmsConnectionFactory" /> </bean> <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> </bean>

5IFO ZPV MPPL UIFN VQ BOE VTF UIFN UP DSFBUF UIF +NT$PNQPOFOU.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

515

"LKCFDRO>QFLK LC 1BABIFSBOV 5IF SFEFMJWFSZ JO USBOTBDUFE NPEF JT KLQ IBOEMFE CZ $BNFM CVU CZ UIF CBDLJOH TZTUFN (UIF USBOTBDUJPO NBOBHFS). *O TVDI DBTFT ZPV TIPVME SFTPSU UP UIF CBDLJOH TZTUFN IPX UP DPOGJHVSF UIF SFEFMJWFSZ.

PlatformTransactionManager transactionManager = (PlatformTransactionManager) spring.getBean("jmsTransactionManager"); ConnectionFactory connectionFactory = (ConnectionFactory) spring.getBean("jmsConnectionFactory"); JmsComponent component = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager); component.getConfiguration().setConcurrentConsumers(1); ctx.addComponent("activemq", component);

3O>KP>@QFLK /LIF@FBP
0VUCPVOE FOEQPJOUT XJMM BVUPNBUJDBMMZ FOMJTU JO UIF DVSSFOU USBOTBDUJPO DPOUFYU. #VU XIBU JG ZPV EP OPU XBOU ZPVS PVUCPVOE FOEQPJOU UP FOMJTU JO UIF TBNF USBOTBDUJPO BT ZPVS JOCPVOE FOEQPJOU 5IF TPMVUJPO JT UP BEE B 5SBOTBDUJPO 1PMJDZ UP UIF QSPDFTTJOH SPVUF. :PV GJSTU IBWF UP EFGJOF USBOTBDUJPO QPMJDJFT UIBU ZPV XJMM CF VTJOH. 5IF QPMJDJFT VTF B TQSJOH 5SBOTBDUJPO5FNQMBUF VOEFS UIF DPWFST GPS EFDMBSJOH UIF USBOTBDUJPO EFNBSDBUJPO UP VTF. 4P ZPV XJMM OFFE UP BEE TPNFUIJOH MJLF UIF GPMMPXJOH UP ZPVS TQSJOH YNM:
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="jmsTransactionManager"/> </bean> <bean id="PROPAGATION_REQUIRES_NEW" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="jmsTransactionManager"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/> </bean>

5IFO JO ZPVS 4QSJOH3PVUF#VJMEFS, ZPV KVTU OFFE UP DSFBUF OFX 4QSJOH5SBOTBDUJPO1PMJDZ PCKFDUT GPS FBDI PG UIF UFNQMBUFT.
public void configure() { ... Policy requried = bean(SpringTransactionPolicy.class, "PROPAGATION_REQUIRED")); Policy requirenew = bean(SpringTransactionPolicy.class, "PROPAGATION_REQUIRES_NEW"));

516

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

... }

0ODF DSFBUFE, ZPV DBO VTF UIF 1PMJDZ PCKFDUT JO ZPVS QSPDFTTJOH SPVUFT:

// Send to bar in a new transaction from("activemq:queue:foo").policy(requirenew).to("activemq:queue:bar"); // Send to bar without a transaction. from("activemq:queue:foo").policy(notsupported ).to("activemq:queue:bar");

.2&F !IRBMOFKQ
*G ZPV BSF VTJOH 04(J #MVFQSJOU UIFO ZPV NPTU MJLFMZ IBWF UP FYQMJDJU EFDMBSF B QPMJDZ BOE SFGFS UP UIF QPMJDZ GSPN UIF USBOTBDUFE JO UIF SPVUF.
<bean id="required" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="jmsTransactionManager"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/> </bean>

"OE UIFO SFGFS UP "SFRVJSFE" GSPN UIF SPVUF:


<route> <from uri="activemq:queue:foo"/> <transacted ref="required"/> <to uri="activemq:queue:bar"/> </route>

#>Q>?>PB 2>JMIB *O UIJT TBNQMF XF XBOU UP FOTVSF UIBU UXP FOEQPJOUT JT VOEFS USBOTBDUJPO DPOUSPM. 5IFTF UXP FOEQPJOUT JOTFSUT EBUB JOUP B EBUBCBTF. 5IF TBNQMF JT JO JUT GVMM BT B VOJU UFTU. 'JSTU PG BMM XF TFUVQ UIF VTVBM TQSJOH TUVGG JO JUT DPOGJHVSBUJPO GJMF. )FSF XF IBWF EFGJOFE B %BUB4PVSDF UP UIF )42-%# BOE B NPTU JNQPSUBOUMZ UIF 4QSJOH %BUB4PSVDF 5SBOTBDUJPO.BOBHFS UIBU JT EPJOH UIF IFBWZ MJGUJOH PG FOTVSJOH PVS USBOTBDUJPOBM QPMJDJFT. :PV BSF PG DPVSTF GSFF UP VTF BOZ PG UIF 4QSJOH CBTFE 5SBOTBDUJPO.BOBOHFS, FH. JG ZPV BSF JO B GVMM CMPXO +2&& DPOUBJOFS ZPV DPVME VTF +5" PS UIF 8FC-PHJD PS 8FC4QIFSF TQFDJGJD NBOBHFST.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

517

"T XF VTF UIF OFX DPOWFOUJPO PWFS DPOGJHVSBUJPO XF EP KLQ OFFE UP DPOGJHVSF B USBOTBDUJPO QPMJDZ CFBO, TP XF EP OPU IBWF BOZ PROPAGATION_REQUIRED CFBOT. "MM UIF CFBOT OFFEFE UP CF DPOGJHVSFE JT PQ>KA>OA 4QSJOH CFBOT POMZ, FH. UIFSF BSF OP $BNFM TQFDJGJD DPOGJHVSBUJPO BU BMM.
<!-- this example uses JDBC so we define a data source --> <jdbc:embedded-database id="dataSource" type="DERBY"> <jdbc:script location="classpath:sql/init.sql" /> </jdbc:embedded-database> <!-- spring transaction manager --> <!-- this is the transaction manager Camel will use for transacted routes --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- bean for book business logic --> <bean id="bookService" class="org.apache.camel.spring.interceptor.BookService"> <property name="dataSource" ref="dataSource"/> </bean>

5IFO XF BSF SFBEZ UP EFGJOF PVS $BNFM SPVUFT. 8F IBWF UXP SPVUFT: 1 GPS TVDDFTT DPOEJUJPOT, BOE 1 GPS B GPSDFE SPMMCBDL DPOEJUJPO. 5IJT JT BGUFS BMM CBTFE PO B VOJU UFTU. /PUJDF UIBU XF NBSL FBDI SPVUF BT USBOTBDUFE VTJOH UIF QO>KP>@QBA UBH.
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:okay"/> <!-- we mark this route as transacted. Camel will lookup the spring transaction manager and use it by default. We can optimally pass in arguments to specify a policy to use that is configured with a spring transaction manager of choice. However Camel supports convention over configuration as we can just use the defaults out of the box and Camel that suites in most situations --> <transacted/> <setBody> <constant>Tiger in Action</constant> </setBody> <bean ref="bookService"/> <setBody> <constant>Elephant in Action</constant> </setBody> <bean ref="bookService"/> </route> <route>

518

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<from uri="direct:fail"/> <!-- we mark this route as transacted. See comments above. --> <transacted/> <setBody> <constant>Tiger in Action</constant> </setBody> <bean ref="bookService"/> <setBody> <constant>Donkey in Action</constant> </setBody> <bean ref="bookService"/> </route> </camelContext>

5IBU JT BMM UIBU JT OFFEFE UP DPOGJHVSF B $BNFM SPVUF BT CFJOH USBOTBDUFE. +VTU SFNFNCFS UP VTF UIF QO>KP>@QBA %4-. 5IF SFTU JT TUBOEBSE 4QSJOH 9.- UP TFUVQ UIF USBOTBDUJPO NBOBHFS. ),2 2>JMIB *O UIJT TBNQMF XF XBOU UP MJTUFO GPS NFTTBHFT PO B RVFVF BOE QSPDFTT UIF NFTTBHFT XJUI PVS CVTJOFTT MPHJD KBWB DPEF BOE TFOE UIFN BMPOH. 4JODF JUT CBTFE PO B VOJU UFTU UIF EFTUJOBUJPO JT B NPDL FOEQPJOU. 'JSTU XF DPOGJHVSF UIF TUBOEBSE 4QSJOH 9.- UP EFDMBSF B +.4 DPOOFDUJPO GBDUPSZ, B +.4 USBOTBDUJPO NBOBHFS BOE PVS "DUJWF.2 DPNQPOFOU UIBU XF VTF JO PVS SPVUJOH.
<!-- setup JMS connection factory --> <bean id="poolConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="maxConnections" value="8"/> <property name="connectionFactory" ref="jmsConnectionFactory"/> </bean> <bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="vm://localhost?broker.persistent=false&amp;broker.useJmx=false"/> </bean> <!-- setup spring jms TX manager --> <bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager"> <property name="connectionFactory" ref="poolConnectionFactory"/> </bean> <!-- define our activemq component --> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="connectionFactory" ref="poolConnectionFactory"/> <!-- define the jms consumer/producer as transacted --> <property name="transacted" value="true"/> <!-- setup the transaction manager to use --> <!-- if not provided then Camel will automatic use a JmsTransactionManager,

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

519

however if you for instance use a JTA transaction manager then you must configure it --> <property name="transactionManager" ref="jmsTransactionManager"/> </bean>

"OE UIFO XF DPOGJHVSF PVS SPVUFT. /PUJDF UIBU BMM XF IBWF UP EP JT NBSL UIF SPVUF BT USBOTBDUFE VTJOH UIF QO>KP>@QBA UBH.
<camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- disable JMX during testing --> <jmxAgent id="agent" disabled="true"/> <route> <!-- 1: from the jms queue --> <from uri="activemq:queue:okay"/> <!-- 2: mark this route as transacted --> <transacted/> <!-- 3: call our business logic that is myProcessor --> <process ref="myProcessor"/> <!-- 4: if success then send it to the mock --> <to uri="mock:result"/> </route> </camelContext> <bean id="myProcessor" class="org.apache.camel.component.jms.tx.JMSTransactionalClientTest$MyProcessor"/>

42(-& ,4+3(/+$ 1.43$2 6(3' #(%%$1$-3 /1./ & 3(.- !$' 5(.12
S>FI>?IB >P LC ">JBI 2.2 4VQQPTF ZPV XBOU UP SPVUF B NFTTBHF UISPVHI UXP SPVUFT BOE CZ XIJDI UIF 2OE SPVUF TIPVME SVO JO JUT PXO USBOTBDUJPO. )PX EP ZPV EP UIBU :PV VTF QSPQBHBUJPO CFIBWJPST GPS UIBU XIFSF ZPV DPOGJHVSF JU BT GPMMPXT: 5IF GJSTU SPVUF VTF PROPAGATION_REQUIRED 5IF TFDPOE SPVUF VTF PROPAGATION_REQUIRES_NEW 5IJT JT DPOGJHVSFE JO UIF 4QSJOH 9.- GJMF:
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="txManager"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/> </bean> <bean id="PROPAGATION_REQUIRES_NEW" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="txManager"/>

520

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

3O>KP>@QFLK BOOLO E>KAIBO 8IFO B SPVUF JT NBSLFE BT USBOTBDUFE VTJOH QO>KP>@QBA $BNFM XJMM BVUPNBUJD VTF UIF 5SBOTBDUJPO&SSPS)BOEMFS BT &SSPS )BOEMFS. *U TVQQPSUT CBTJDBMMZ UIF TBNF GFBUVSF TFU BT UIF %FGBVMU&SSPS)BOEMFS, TP ZPV DBO GPS JOTUBODF VTF &YDFQUJPO $MBVTF BT XFMM.

<property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/> </bean>

5IFO JO UIF SPVUFT ZPV VTF USBOTBDUFE %4- UP JOEJDBUF XIJDI PG UIFTF UXP QSPQBHBUJPOT JU VTFT.
from("direct:mixed") // using required .transacted("PROPAGATION_REQUIRED") // all these steps will be okay .setBody(constant("Tiger in Action")).beanRef("bookService") .setBody(constant("Elephant in Action")).beanRef("bookService") // continue on route 2 .to("direct:mixed2"); from("direct:mixed2") // tell Camel that if this route fails then only rollback this last route // by using (rollback only *last*) .onException(Exception.class).markRollbackOnlyLast().end() // using a different propagation which is requires new .transacted("PROPAGATION_REQUIRES_NEW") // this step will be okay .setBody(constant("Lion in Action")).beanRef("bookService") // this step will fail with donkey .setBody(constant("Donkey in Action")).beanRef("bookService");

/PUJDF IPX XF IBWF DPOGJHVSFE UIF onException JO UIF 2OE SPVUF UP JOEJDBUF JO DBTF PG BOZ FYDFQUJPOT XF TIPVME IBOEMF JU BOE KVTU SPMMCBDL UIJT USBOTBDUJPO. 5IJT JT EPOF VTJOH UIF markRollbackOnlyLast XIJDI UFMMT $BNFM UP POMZ EP JU GPS UIF DVSSFOU USBOTBDUJPO BOE OPU HMPCBMMZ.

2BB
` ` ` `

IPL
&SSPS IBOEMJOH JO $BNFM 5SBOTBDUJPO&SSPS)BOEMFS &SSPS )BOEMFS +.4

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

521

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. ,BPP>DFKD &>QBT>V $BNFM IBT TFWFSBM FOEQPJOU DPNQPOFOUT UIBU TVQQPSU UIF .FTTBHJOH (BUFXBZ GSPN UIF &*1 QBUUFSOT.

$PNQPOFOUT MJLF #FBO BOE $9' QSPWJEF B B XBZ UP CJOE B +BWB JOUFSGBDF UP UIF NFTTBHF FYDIBOHF. )PXFWFS ZPV NBZ XBOU UP SFBE UIF 6TJOH $BNFM1SPYZ EPDVNFOUBUJPO BT B USVF .FTTBHJOH (BUFXBZ &*1 TPMVUJPO. "OPUIFS BQQSPBDI JT UP VTF @Produce XIJDI ZPV DBO SFBE BCPVU JO 10+0 1SPEVDJOH XIJDI BMTP DBO CF VTFE BT B .FTTBHJOH (BUFXBZ &*1 TPMVUJPO.

2BB
` ` ` ` `

IPL
#FBO $9' 6TJOH $BNFM1SPYZ 10+0 1SPEVDJOH 4QSJOH 3FNPUJOH

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 2BOSF@B @QFS>QLO

$BNFM IBT TFWFSBM FOEQPJOU DPNQPOFOUT UIBU TVQQPSU UIF 4FSWJDF "DUJWBUPS GSPN UIF &*1 QBUUFSOT.

522

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

$PNQPOFOUT MJLF #FBO, $9' BOE 1PKP QSPWJEF B B XBZ UP CJOE UIF NFTTBHF FYDIBOHF UP B +BWB JOUFSGBDF/TFSWJDF XIFSF UIF SPVUF EFGJOFT UIF FOEQPJOUT BOE XJSFT JU VQ UP UIF CFBO. *O BEEJUJPO ZPV DBO VTF UIF #FBO *OUFHSBUJPO UP XJSF NFTTBHFT UP B CFBO VTJOH BOOPUBUJPO. )FSF JT B TJNQMF FYBNQMF PG VTJOH B %JSFDU FOEQPJOU UP DSFBUF B NFTTBHJOH JOUFSGBDF UP B 1PKP #FBO TFSWJDF. 4PFKD QEB %IRBKQ !RFIABOP
from("direct:invokeMyService").to("bean:myService");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:invokeMyService"/> <to uri="bean:myService"/> </route>

2BB

IPL
` #FBO ` 1PKP ` $9'

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

523

2823$, , - &$,$-3
#BQLRO 5IF %FUPVS GSPN UIF &*1 QBUUFSOT BMMPXT ZPV UP TFOE NFTTBHFT UISPVHI BEEJUJPOBM TUFQT JG B DPOUSPM DPOEJUJPO JT NFU. *U DBO CF VTFGVM GPS UVSOJOH PO FYUSB WBMJEBUJPO, UFTUJOH, EFCVHHJOH DPEF XIFO OFFEFE.

$U>JMIB
*O UIJT FYBNQMF XF FTTFOUJBMMZ IBWF B SPVUF MJLF from("direct:start").to("mock:result") XJUI B DPOEJUJPOBM EFUPVS UP UIF mock:detour FOEQPJOU JO UIF NJEEMF PG UIF SPVUF..
from("direct:start").choice() .when().method("controlBean", "isDetour").to("mock:detour").end() .to("mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:start"/> <choice> <when> <method bean="controlBean" method="isDetour"/> <to uri="mock:detour"/> </when> </choice> <to uri="mock:result"/> </route>

XIFUIFS UIF EFUPVS JT UVSOFE PO PS PGG JT EFDJEFE CZ UIF ControlBean. 4P, XIFO UIF EFUPVS JT PO UIF NFTTBHF JT SPVUFE UP mock:detour BOE UIFO mock:result. 8IFO UIF EFUPVS JT PGG, UIF NFTTBHF JT SPVUFE UP mock:result. 'PS GVMM EFUBJMT, DIFDL UIF FYBNQMF TPVSDF IFSF: DBNFM-DPSF/TSD/UFTU/KBWB/PSH/BQBDIF/DBNFM/QSPDFTTPS/%FUPVS5FTU.KBWB

524

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU. 6FOB 3>M 8JSF 5BQ (GSPN UIF &*1 QBUUFSOT) BMMPXT ZPV UP SPVUF NFTTBHFT UP B TFQBSBUF MPDBUJPO XIJMF UIFZ BSF CFJOH GPSXBSEFE UP UIF VMUJNBUF EFTUJOBUJPO.

.MQFLKP
->JB
uri ref executorServiceRef processorRef copy onPrepareRef

#BC>RIQ 5>IRB
c c c c true c

#BP@OFMQFLK
5IF 63* PG UIF FOEQPJOU UP XIJDI UIF XJSF-UBQQFE NFTTBHF XJMM CF TFOU. :PV TIPVME VTF FJUIFS uri PS ref. 3FGFSFODF JEFOUJGJFS PG UIF FOEQPJOU UP XIJDI UIF XJSF-UBQQFE NFTTBHF XJMM CF TFOU. :PV TIPVME VTF FJUIFS uri PS ref. 3FGFSFODF JEFOUJGJFS PG B DVTUPN 5ISFBE 1PPM UP VTF XIFO QSPDFTTJOH UIF XJSF-UBQQFE NFTTBHFT. *G OPU TFU, $BNFM XJMM VTF B EFGBVMU UISFBE QPPM. 3FGFSFODF JEFOUJGJFS PG B DVTUPN 1SPDFTTPS UP VTF GPS DSFBUJOH B OFX NFTTBHF (F.H., UIF "TFOE B OFX NFTTBHF" NPEF). 4FF CFMPX. ">JBI 2.3: 8IFUIFS UP DPQZ UIF &YDIBOHF CFGPSF XJSF-UBQQJOH UIF NFTTBHF. ">JBI 2.8: 3FGFSFODF JEFOUJGJFS PG B DVTUPN 1SPDFTTPS UP QSFQBSF UIF DPQZ PG UIF &YDIBOHF UP CF XJSF-UBQQFE. 5IJT BMMPXT ZPV UP EP BOZ DVTUPN MPHJD, TVDI BT EFFQ-DMPOJOH UIF NFTTBHF QBZMPBE.

6FOB3>M QEOB>A MLLI 5IF 8JSF 5BQ VTFT B UISFBE QPPM UP QSPDFTT UIF UBQQFE NFTTBHFT. 5IJT UISFBE QPPM XJMM CZ EFGBVMU VTF UIF TFUUJOHT EFUBJMFE BU 5ISFBEJOH .PEFM. *O QBSUJDVMBS, XIFO UIF QPPM JT FYIBVTUFE (XJUI BMM UISFBET VUJMJ[FE), GVSUIFS XJSFUBQT XJMM CF FYFDVUFE TZODISPOPVTMZ CZ UIF DBMMJOH UISFBE. 5P SFNFEZ UIJT, ZPV DBO DPOGJHVSF BO FYQMJDJU UISFBE QPPM PO UIF 8JSF 5BQ IBWJOH FJUIFS B EJGGFSFOU SFKFDUJPO QPMJDZ, B MBSHFS XPSLFS RVFVF, PS NPSF XPSLFS UISFBET. 6FOB3>M KLAB $BNFM'T 8JSF 5BQ OPEF TVQQPSUT UXP GMBWPST XIFO UBQQJOH BO &YDIBOHF: -8JUI UIF USBEJUJPOBM 8JSF 5BQ, $BNFM XJMM DPQZ UIF PSJHJOBM &YDIBOHF BOE TFU JUT &YDIBOHF 1BUUFSO UP (K.KIV, BT XF XBOU UIF UBQQFE &YDIBOHF UP CF TFOU JO B fire and forget TUZMF. 5IF UBQQFE &YDIBOHF JT UIFO TFOU JO B TFQBSBUF UISFBE TP JU DBO SVO JO QBSBMMFM XJUI UIF PSJHJOBM.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

525

2QOB>JP *G ZPV 8JSF 5BQ B TUSFBN NFTTBHF CPEZ UIFO ZPV TIPVME DPOTJEFS FOBCMJOH 4USFBN DBDIJOH UP FOTVSF UIF NFTTBHF CPEZ DBO CF SFBE BU FBDI FOEQPJOU. 4FF NPSF EFUBJMT BU 4USFBN DBDIJOH. -$BNFM BMTP QSPWJEFT BO PQUJPO PG TFOEJOH B OFX &YDIBOHF BMMPXJOH ZPV UP QPQVMBUF JU XJUI OFX WBMVFT.

2BKAFKD > @LMV (QO>AFQFLK>I TFOBQ>M)


4PFKD QEB %IRBKQ !RFIABOP
from("direct:start") .to("log:foo") .wireTap("direct:tap") .to("mock:result");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP


<route> <from uri="direct:start"/> <to uri="log:foo"/> <wireTap uri="direct:tap"/> <to uri="mock:result"/> </route>

2BKAFKD > KBT $U@E>KDB


4PFKD QEB %IRBKQ !RFIABOP $BNFM TVQQPSUT FJUIFS B QSPDFTTPS PS BO &YQSFTTJPO UP QPQVMBUF UIF OFX &YDIBOHF. 6TJOH B QSPDFTTPS HJWFT ZPV GVMM QPXFS PWFS IPX UIF &YDIBOHF JT QPQVMBUFE BT ZPV DBO TFU QSPQFSUJFT, IFBEFST, FU DFUFSB. "O &YQSFTTJPO DBO POMZ CF VTFE UP TFU UIF */ CPEZ. 'SPN ">JBI 2.3 POXBSET UIF &YQSFTTJPO PS 1SPDFTTPS JT QSF-QPQVMBUFE XJUI B DPQZ PG UIF PSJHJOBM &YDIBOHF, XIJDI BMMPXT ZPV UP BDDFTT UIF PSJHJOBM NFTTBHF XIFO ZPV QSFQBSF B OFX &YDIBOHF UP CF TFOU. :PV DBO VTF UIF copy PQUJPO (FOBCMFE CZ EFGBVMU) UP JOEJDBUF XIFUIFS ZPV XBOU UIJT. *G ZPV TFU copy=false, UIFO JU XPSLT BT JO $BNFM 2.2 PS PMEFS XIFSF UIF &YDIBOHF XJMM CF FNQUZ. #FMPX JT UIF QSPDFTTPS WBSJBUJPO. 5IJT FYBNQMF JT GSPN $BNFM 2.3, XIFSF XF EJTBCMF copy CZ QBTTJOH JO false UP DSFBUF B OFX, FNQUZ &YDIBOHF.

526

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

from("direct:start") .wireTap("direct:foo", false, new Processor() { public void process(Exchange exchange) throws Exception { exchange.getIn().setBody("Bye World"); exchange.getIn().setHeader("foo", "bar"); } }).to("mock:result");

from("direct:foo").to("mock:foo");

)FSF JT UIF &YQSFTTJPO WBSJBUJPO. 5IJT FYBNQMF JT GSPN $BNFM 2.3, XIFSF XF EJTBCMF copy CZ QBTTJOH JO false UP DSFBUF B OFX, FNQUZ &YDIBOHF.
from("direct:start") .wireTap("direct:foo", false, constant("Bye World")) .to("mock:result"); from("direct:foo").to("mock:foo");

4PFKD QEB 2MOFKD 7,+ $UQBKPFLKP 5IF QSPDFTTPS WBSJBUJPO, XIJDI VTFT B MOL@BPPLO1BC BUUSJCVUF UP SFGFS UP B 4QSJOH CFBO CZ *%:
<route> <from uri="direct:start2"/> <wireTap uri="direct:foo" processorRef="myProcessor"/> <to uri="mock:result"/> </route>

)FSF JT UIF &YQSFTTJPO WBSJBUJPO, XIFSF UIF FYQSFTTJPO JT EFGJOFE JO UIF ?LAV UBH:
<route> <from uri="direct:start"/> <wireTap uri="direct:foo"> <body><constant>Bye World</constant></body> </wireTap> <to uri="mock:result"/> </route>

5IJT WBSJBUJPO BDDFTTFT UIF CPEZ PG UIF PSJHJOBM NFTTBHF BOE DSFBUFT B OFX &YDIBOHF CBTFE PO UIF &YQSFTTJPO. *U XJMM DSFBUF B OFX &YDIBOHF BOE IBWF UIF CPEZ DPOUBJO "Bye ORIGINAL BODY MESSAGE HERE"
<route> <from uri="direct:start"/> <wireTap uri="direct:foo">

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

527

<body><simple>Bye ${body}</simple></body> </wireTap> <to uri="mock:result"/> </route>

%ROQEBO $U>JMIB
'PS BOPUIFS FYBNQMF PG UIJT QBUUFSO, SFGFS UP UIF XJSF UBQ UFTU DBTF. 2BKAFKD > KBT $U@E>KDB >KA PBQ EB>ABOP FK #2+ S>FI>?IB >P LC ">JBI 2.8 *G ZPV TFOE B OFX NFTTBHF VTJOH 8JSF 5BQ, UIFO ZPV DPVME POMZ TFU UIF NFTTBHF CPEZ VTJOH BO &YQSFTTJPO GSPN UIF %4-. *G ZPV BMTP OFFE UP TFU IFBEFST, ZPV XPVME IBWF UP VTF B 1SPDFTTPS. *O $BNFM 2.8 POXBSET, ZPV DBO OPX TFU IFBEFST BT XFMM JO UIF %4-. 5IF GPMMPXJOH FYBNQMF TFOET B OFX NFTTBHF XIJDI IBT "#ZF 8PSME" BT NFTTBHF CPEZ B IFBEFS XJUI LFZ "JE" XJUI UIF WBMVF 123 B IFBEFS XJUI LFZ "EBUF" XIJDI IBT DVSSFOU EBUF BT WBMVF

)>S> #2+
from("direct:start") // tap a new message and send it to direct:tap // the new message should be Bye World with 2 headers .wireTap("direct:tap") // create the new tap message body and headers .newExchangeBody(constant("Bye World")) .newExchangeHeader("id", constant(123)) .newExchangeHeader("date", simple("${date:now:yyyyMMdd}")) .end() // here we continue routing the original messages .to("mock:result"); // this is the tapped route from("direct:tap") .to("mock:tap");

7,+ #2+
5IF 9.- %4- JT TMJHIUMZ EJGGFSFOU UIBO +BWB %4- JO IPX ZPV DPOGJHVSF UIF NFTTBHF CPEZ BOE IFBEFST VTJOH <CPEZ> BOE <TFU)FBEFS>:

528

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

<route> <from uri="direct:start"/> <!-- tap a new message and send it to direct:tap --> <!-- the new message should be Bye World with 2 headers --> <wireTap uri="direct:tap"> <!-- create the new tap message body and headers --> <body><constant>Bye World</constant></body> <setHeader headerName="id"><constant>123</constant></setHeader> <setHeader headerName="date"><simple>${date:now:yyyyMMdd}</simple></setHeader> </wireTap> <!-- here we continue routing the original message --> <to uri="mock:result"/> </route>

4PFKD LK/OBM>OB QL BUB@RQB @RPQLJ ILDF@ TEBK MOBM>OFKD JBPP>DBP S>FI>?IB >P LC ">JBI 2.8 4FF EFUBJMT BU .VMUJDBTU

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

+.&
)PX DBO * MPH QSPDFTTJOH B .FTTBHF $BNFM QSPWJEFT NBOZ XBZT UP MPH QSPDFTTJOH B NFTTBHF. )FSF JT KVTU TPNF FYBNQMFT: :PV DBO VTF UIF -PH DPNQPOFOU XIJDI MPHT UIF .FTTBHF DPOUFOU. :PV DBO VTF UIF 5SBDFS XIJDI USBDF MPHT NFTTBHF GMPX. :PV DBO BMTP VTF B 1SPDFTTPS PS #FBO BOE MPH GSPN +BWB DPEF. :PV DBO VTF UIF log %4-. 4PFKD ILD #2+ "OE JO ">JBI 2.2 ZPV DBO VTF UIF log %4- XIJDI BMMPXT ZPV UP VTF 4JNQMF MBOHVBHF UP DPOTUSVDU B EZOBNJD NFTTBHF XIJDI HFUT MPHHFE. 'PS FYBNQMF ZPV DBO EP
from("direct:start").log("Processing ${id}").to("bean:foo");

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

529

8IJDI XJMM DPOTUSVDU B 4USJOH NFTTBHF BU SVOUJNF VTJOH UIF 4JNQMF MBOHVBHF. 5IF MPH NFTTBHF XJMM CZ MPHHFE BU INFO MFWFM VTJOH UIF SPVUF JE BT UIF MPH OBNF. #Z EFGBVMU B SPVUF JT OBNFE route-1, route-2 FUD. #VU ZPV DBO VTF UIF routeId("myCoolRoute") UP TFU B SPVUF OBNF PG DIPJDF. 5IF MPH %4- IBWF PWFSMPBEFE NFUIPET UP TFU UIF MPHHJOH MFWFM BOE/PS OBNF BT XFMM.
from("direct:start").log(LoggingLevel.DEBUG, "Processing ${id}").to("bean:foo");

'PS FYBNQMF ZPV DBO VTF UIJT UP MPH UIF GJMF OBNF CFJOH QSPDFTTFE JG ZPV DPOTVNF GJMFT.
from("file://target/files").log(LoggingLevel.DEBUG, "Processing file ${file:name}").to("bean:foo");

4PFKD ILD #2+ COLJ 2MOFKD


*O 4QSJOH %4- JUT BMTP FBTZ UP VTF MPH %4- BT TIPXO CFMPX:
<route id="foo"> <from uri="direct:foo"/> <log message="Got ${body}"/> <to uri="mock:foo"/> </route>

5IF MPH UBH IBT BUUSJCVUFT UP TFU UIF message, loggingLevel BOE logName. 'PS FYBNQMF:
<route id="baz"> <from uri="direct:baz"/> <log message="Me Got ${body}" loggingLevel="FATAL" logName="cool"/> <to uri="mock:baz"/> </route>

4PFKD PIC4G ,>OHBO


S>FI>?IB >P LC ">JBI 2.9 :PV DBO TQFDJGZ B NBSLFS OBNF JO UIF %4<route id="baz"> <from uri="direct:baz"/> <log message="Me Got ${body}" loggingLevel="FATAL" logName="cool" marker="myMarker"/> <to uri="mock:baz"/> </route>

530

$) " 15& 3 1 0 - 1 " 5 5 & 3 / " 1 1 & /% * 9

#FCCBOBK@B ?BQTBBK ILD FK QEB #2+ >KA +LD @LJMLKBKQ 5IF log %4- JT NVDI MJHIUFS BOE NFBOU GPS MPHHJOH IVNBO MPHT TVDI BT Starting to do ... FUD. *U DBO POMZ MPH B NFTTBHF CBTFE PO UIF 4JNQMF MBOHVBHF. 0O UIF PUIFS IBOE -PH DPNQPOFOU JT B GVMM GMFEHFE DPNQPOFOU XIJDI JOWPMWFT VTJOH FOEQPJOUT BOE FUD. 5IF -PH DPNQPOFOU JT NFBOU GPS MPHHJOH UIF .FTTBHF JUTFMG BOE ZPV IBWF NBOZ 63* PQUJPOT UP DPOUSPM XIBU ZPV XPVME MJLF UP CF MPHHFE.

4PFKD 3EFP />QQBOK


*G ZPV XPVME MJLF UP VTF UIJT &*1 1BUUFSO UIFO QMFBTF SFBE UIF (FUUJOH 4UBSUFE, ZPV NBZ BMTP GJOE UIF "SDIJUFDUVSF VTFGVM QBSUJDVMBSMZ UIF EFTDSJQUJPO PG &OEQPJOU BOE 63*T. 5IFO ZPV DPVME USZ PVU TPNF PG UIF &YBNQMFT GJSTU CFGPSF USZJOH UIJT QBUUFSO PVU.

$) "15 &3 10 - 1"5 5 &3 / "11&/ %*9

531

"' YYYY

/3$1

11

"LJMLKBKQ

MMBKAFU

5IFSF OPX GPMMPXT UIF EPDVNFOUBUJPO PO FBDI $BNFM DPNQPOFOU.

"3(5$,0 ".,/.-$-3
5IF "DUJWF.2 DPNQPOFOU BMMPXT NFTTBHFT UP CF TFOU UP B +.4 2VFVF PS 5PQJD PS NFTTBHFT UP CF DPOTVNFE GSPN B +.4 2VFVF PS 5PQJD VTJOH "QBDIF "DUJWF.2. 5IJT DPNQPOFOU JT CBTFE PO +.4 $PNQPOFOU BOE VTFT 4QSJOH'T +.4 TVQQPSU GPS EFDMBSBUJWF USBOTBDUJPOT, VTJOH 4QSJOH'T JmsTemplate GPS TFOEJOH BOE B MessageListenerContainer GPS DPOTVNJOH. "MM UIF PQUJPOT GSPN UIF +.4 DPNQPOFOU BMTP BQQMJFT GPS UIJT DPNQPOFOU. 5P VTF UIJT DPNQPOFOU NBLF TVSF ZPV IBWF UIF activemq.jar PS activemqcore.jar PO ZPVS DMBTTQBUI BMPOH XJUI BOZ $BNFM EFQFOEFODJFT TVDI BT camel-core.jar, camel-spring.jar BOE camel-jms.jar. 41( CLOJ>Q
activemq:[queue:|topic:]destinationName

8IFSF ABPQFK>QFLK->JB JT BO "DUJWF.2 RVFVF PS UPQJD OBNF. #Z EFGBVMU, UIF ABPQFK>QFLK->JB JT JOUFSQSFUFE BT B RVFVF OBNF. 'PS FYBNQMF, UP DPOOFDU UP UIF RVFVF, FOO.BAR, VTF:
activemq:FOO.BAR

:PV DBO JODMVEF UIF PQUJPOBM queue: QSFGJY, JG ZPV QSFGFS:


activemq:queue:FOO.BAR

5P DPOOFDU UP B UPQJD, ZPV NVTU JODMVEF UIF topic: QSFGJY. 'PS FYBNQMF, UP DPOOFDU UP UIF UPQJD, Stocks.Prices, VTF:

532

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

3O>KP>@QBA >KA @>@EFKD 4FF TFDUJPO Transactions and Cache Levels CFMPX PO +.4 QBHF JG ZPV BSF VTJOH USBOTBDUJPOT XJUI +.4 BT JU DBO JNQBDU QFSGPSNBODF.

activemq:topic:Stocks.Prices

.MQFLKP 4FF 0QUJPOT PO UIF +.4 DPNQPOFOU BT BMM UIFTF PQUJPOT BMTP BQQMZ GPS UIJT DPNQPOFOU. "LKCFDROFKD QEB "LKKB@QFLK %>@QLOV 5IJT UFTU DBTF TIPXT IPX UP BEE BO "DUJWF.2$PNQPOFOU UP UIF $BNFM$POUFYU VTJOH UIF activeMQComponent() NFUIPE XIJMF TQFDJGZJOH UIF CSPLFS63- VTFE UP DPOOFDU UP "DUJWF.2.
camelContext.addComponent("activemq", activeMQComponent("vm://localhost?broker.persistent=false"));

"LKCFDROFKD QEB "LKKB@QFLK %>@QLOV RPFKD 2MOFKD 7,+ :PV DBO DPOGJHVSF UIF "DUJWF.2 CSPLFS 63- PO UIF "DUJWF.2$PNQPOFOU BT GPMMPXT
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> </camelContext> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="brokerURL" value="tcp://somehost:61616"/> </bean> </beans>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

533

4PFKD @LKKB@QFLK MLLIFKD 8IFO TFOEJOH UP BO "DUJWF.2 CSPLFS VTJOH $BNFM JU'T SFDPNNFOEFE UP VTF B QPPMFE DPOOFDUJPO GBDUPSZ UP FGGJDJFOUMZ IBOEMF QPPMJOH PG +.4 DPOOFDUJPOT, TFTTJPOT BOE QSPEVDFST. 5IJT JT EPDVNFOUFE PO UIF "DUJWF.2 4QSJOH 4VQQPSU QBHF. :PV DBO HSBC "DUJWF.2'T org.apache.activemq.pool.PooledConnectionFactory XJUI .BWFO:
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.6.0</version> </dependency>

"OE UIFO TFUVQ UIF >@QFSBJN $BNFM DPNQPOFOU BT GPMMPXT:


<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> </bean> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop"> <property name="maxConnections" value="8" /> <property name="connectionFactory" ref="jmsConnectionFactory" /> </bean> <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration"> <property name="connectionFactory" ref="pooledConnectionFactory"/> <property name="concurrentConsumers" value="10"/> </bean> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="configuration" ref="jmsConfig"/> </bean>

5IF PooledConnectionFactory XJMM UIFO DSFBUF B DPOOFDUJPO QPPM XJUI VQ UP 8 DPOOFDUJPOT JO VTF BU UIF TBNF UJNF. &BDI DPOOFDUJPO DBO CF TIBSFE CZ NBOZ TFTTJPOT. 5IFSF JT BO PQUJPO OBNFE maxActive ZPV DBO VTF UP DPOGJHVSF UIF NBYJNVN OVNCFS PG TFTTJPOT QFS DPOOFDUJPO; UIF EFGBVMU WBMVF JT 500. 'SPN @QFSB,0 5.7 POXBSET UIF PQUJPO IBT CFFO SFOBNFE UP CFUUFS SFGMFDU JUT QVSQPTF, CFJOH OBNFE BT maxActiveSessionPerConnection. /PUJDF UIF concurrentConsumers JT TFU UP B IJHIFS WBMVF UIBO maxConnections JT. 5IJT JT PLBZ, BT FBDI DPOTVNFS JT VTJOH B TFTTJPO, BOE BT B TFTTJPO DBO TIBSF UIF TBNF DPOOFDUJPO, XF BSF JO UIF TBGF. *O UIJT FYBNQMF XF DBO IBWF 8 * 500 = 4000 BDUJWF TFTTJPOT BU UIF TBNF UJNF.

534

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

/PUJDF UIF FKFQ BOE ABPQOLV NFUIPET PO UIF QPPMFE DPOOFDUJPO GBDUPSZ. 5IJT JT JNQPSUBOU UP FOTVSF UIF DPOOFDUJPO QPPM JT QSPQFSMZ TUBSUFE BOE TIVUEPXO. (KSLHFKD ,BPP>DB+FPQBKBO /.).P FK > ">JBI OLRQB 5IF "DUJWF.2 DPNQPOFOU BMTP QSPWJEFT B IFMQFS 5ZQF $POWFSUFS GSPN B +.4 .FTTBHF-JTUFOFS UP B 1SPDFTTPS. 5IJT NFBOT UIBU UIF #FBO DPNQPOFOU JT DBQBCMF PG JOWPLJOH BOZ +.4 .FTTBHF-JTUFOFS CFBO EJSFDUMZ JOTJEF BOZ SPVUF. 4P GPS FYBNQMF ZPV DBO DSFBUF B .FTTBHF-JTUFOFS JO +.4 MJLF UIJT:
public class MyListener implements MessageListener { public void onMessage(Message jmsMessage) { // ... } }

5IFO VTF JU JO ZPVS $BNFM SPVUF BT GPMMPXT


from("file://foo/bar"). bean(MyListener.class);

5IBU JT, ZPV DBO SFVTF BOZ PG UIF $BNFM $PNQPOFOUT BOE FBTJMZ JOUFHSBUF UIFN JOUP ZPVS +.4 MessageListener 10+0! 4PFKD @QFSB,0 #BPQFK>QFLK .MQFLKP

S>FI>?IB >P LC @QFSB,0 5.6 :PV DBO DPOGJHVSF UIF %FTUJOBUJPO 0QUJPOT JO UIF FOEQPJOU VSJ, VTJOH UIF "EFTUJOBUJPO." QSFGJY. 'PS FYBNQMF UP NBSL B DPOTVNFS BT FYDMVTJWF, BOE TFU JUT QSFGFUDI TJ[F UP 50, ZPV DBO EP BT GPMMPXT:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file://src/test/data?noop=true"/> <to uri="activemq:queue:foo"/> </route> <route> <!-- use consumer.exclusive ActiveMQ destination option, notice we have to prefix with destination. --> <from uri="activemq:foo?destination.consumer.exclusive=true&amp;destination.consumer.prefetchSize=50"/> <to uri="mock:results"/> </route> </camelContext>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

535

"LKPRJFKD

ASFPLOV ,BPP>DBP

"DUJWF.2 DBO HFOFSBUF "EWJTPSZ NFTTBHFT XIJDI BSF QVU JO UPQJDT UIBU ZPV DBO DPOTVNF. 4VDI NFTTBHFT DBO IFMQ ZPV TFOE BMFSUT JO DBTF ZPV EFUFDU TMPX DPOTVNFST PS UP CVJME TUBUJTUJDT (OVNCFS PG NFTTBHFT/QSPEVDFE QFS EBZ, FUD.) 5IF GPMMPXJOH 4QSJOH %4- FYBNQMF TIPXT ZPV IPX UP SFBE NFTTBHFT GSPN B UPQJD. 5IF CFMPX SPVUF TUBSUT CZ SFBEJOH UIF UPQJD ActiveMQ.Advisory.Connection. 5P XBUDI BOPUIFS UPQJD, TJNQMZ DIBOHF UIF OBNF BDDPSEJOH UP UIF OBNF QSPWJEFE JO "DUJWF.2 "EWJTPSZ .FTTBHFT EPDVNFOUBUJPO. 5IF QBSBNFUFS NBQ+NT.FTTBHF=GBMTF BMMPXT GPS DPOWFSUJOH UIF PSH.BQBDIF.BDUJWFNR.DPNNBOE."DUJWF.R.FTTBHF PCKFDU GSPN UIF KNT RVFVF. /FYU, UIF CPEZ SFDFJWFE JT DPOWFSUFE JOUP B 4USJOH GPS UIF QVSQPTFT PG UIJT FYBNQMF BOE B DBSSJBHF SFUVSO JT BEEFE. 'JOBMMZ, UIF TUSJOH JT BEEFE UP B GJMF
<route> <from uri="activemq:topic:ActiveMQ.Advisory.Connection?mapJmsMessage=false" /> <convertBodyTo type="java.lang.String"/> <transform> <simple>${in.body}&#13;</simple> </transform> <to uri="file://data/ activemq/?fileExist=Append&amp;fileName=advisoryConnection-${date:now:yyyyMMdd}.txt" /> </route>

*G ZPV DPOTVNF B NFTTBHF PO B RVFVF, ZPV TIPVME TFF UIF GPMMPXJOH GJMFT VOEFS UIF EBUB/ BDUJWFNR GPMEFS : BEWJTPSZ$POOFDUJPO-20100312.UYU BEWJTPSZ1SPEVDFS-20100312.UYU BOE DPOUBJOJOH TUSJOH:
ActiveMQMessage {commandId = 0, responseRequired = false, messageId = ID:dell-charles-3258-1268399815140 -1:0:0:0:221, originalDestination = null, originalTransactionId = null, producerId = ID:dell-charles-3258-1268399815140-1:0:0:0, destination = topic://ActiveMQ.Advisory.Connection, transactionId = null, expiration = 0, timestamp = 0, arrival = 0, brokerInTime = 1268403383468, brokerOutTime = 1268403383468, correlationId = null, replyTo = null, persistent = false, type = Advisory, priority = 0, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = null, marshalledProperties = org.apache.activemq.util.ByteSequence@17e2705, dataStructure = ConnectionInfo {commandId = 1, responseRequired = true, connectionId = ID:dell-charles-3258-1268399815140-2:50, clientId = ID:dell-charles-3258-1268399815140-14:0, userName = , password = *****, brokerPath = null, brokerMasterConnector = false, manageable = true, clientMaster = true}, redeliveryCounter = 0, size = 0, properties = {originBrokerName=master, originBrokerId=ID:dell-charles-3258-1268399815140-0:0, originBrokerURL=vm://master}, readOnlyProperties = true, readOnlyBody = true, droppable = false}

536

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

&BQQFKD "LJMLKBKQ ) 1 :PV XJMM OFFE UIJT EFQFOEFODZ activemq-camel "DUJWF.2 JT BO FYUFOTJPO PG UIF +.4 DPNQPOFOU SFMFBTFE XJUI UIF "DUJWF.2 QSPKFDU.
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-camel</artifactId> <version>5.6.0</version> </dependency>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

"3(5$,0 ).41- + ".,/.-$-3


5IF "DUJWF.2 +PVSOBM $PNQPOFOU BMMPXT NFTTBHFT UP CF TUPSFE JO B SPMMJOH MPH GJMF BOE UIFO DPOTVNFE GSPN UIBU MPH GJMF. 5IF KPVSOBM BHHSFHBUFT BOE CBUDIFT VQ DPODVSSFOU XSJUFT TP UIBU UIF PWFSIFBE PG XSJUJOH BOE XBJUJOH GPS UIF EJTL TZOD JT SFMBUJWFMZ DPOTUBOU SFHBSEMFTT PG IPX NBOZ DPODVSSFOU XSJUFT BSF CFJOH EPOF. 5IFSFGPSF, UIJT DPNQPOFOU TVQQPSUT BOE FODPVSBHFT ZPV UP VTF NVMUJQMF DPODVSSFOU QSPEVDFST UP UIF TBNF KPVSOBM FOEQPJOU. &BDI KPVSOBM FOEQPJOU VTFT B EJGGFSFOU MPH GJMF BOE UIFSFGPSF XSJUF CBUDIJOH (BOE UIF BTTPDJBUFE QFSGPSNBODF CPPTU) EPFT OPU PDDVS CFUXFFO NVMUJQMF FOEQPJOUT. 5IJT DPNQPOFOU POMZ TVQQPSUT POF BDUJWF DPOTVNFS PO UIF FOEQPJOU. "GUFS UIF NFTTBHF JT QSPDFTTFE CZ UIF DPOTVNFS'T QSPDFTTPS, UIF MPH GJMF JT NBSLFE BOE POMZ TVCTFRVFOU NFTTBHFT JO UIF MPH GJMF XJMM HFU EFMJWFSFE UP DPOTVNFST. 41( CLOJ>Q
activemq.journal:directoryName[?options]

4P GPS FYBNQMF, UP TFOE UP UIF KPVSOBM MPDBUFE JO UIF /tmp/data EJSFDUPSZ ZPV XPVME VTF UIF GPMMPXJOH 63*:
activemq.journal:/tmp/data

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

537

.MQFLKP
->JB
syncConsume syncProduce

#BC>RIQ 5>IRB
false true

#BP@OFMQFLK
*G TFU UP true, XIFO UIF KPVSOBM JT NBSLFE BGUFS B NFTTBHF JT DPOTVNFE, XBJU UJMM UIF 0QFSBUJOH 4ZTUFN IBT WFSJGJFE UIF NBSL VQEBUF JT TBGFMZ TUPSFE PO EJTL. *G TFU UP true, XBJU UJMM UIF 0QFSBUJOH 4ZTUFN IBT WFSJGJFE UIF NFTTBHF JT TBGFMZ TUPSFE PO EJTL.

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... $UMB@QBA $U@E>KDB #>Q> 3VMBP 5IF DPOTVNFS PG B +PVSOBM FOEQPJOU HFOFSBUFT %FGBVMU&YDIBOHF PCKFDUT XJUI UIF JO NFTTBHF : ` IFBEFS "KPVSOBM" : TFU UP UIF FOEQPJOU VSJ PG UIF KPVSOBM UIF NFTTBHF DBNF GSPN ` IFBEFS "MPDBUJPO" : TFU UP B -PDBUJPO XIJDI JEFOUJGJFT XIFSF UIF SFDPSFE XBT TUPSFE PO EJTL ` CPEZ : TFU UP #ZUF4FRVFODF XIJDI DPOUBJOT UIF CZUF BSSBZ EBUB PG UIF TUPSFE NFTTBHF 5IF QSPEVDFS UP B +PVSOBM FOEQPJOU FYQFDUT BO &YDIBOHF XJUI BO *O NFTTBHF XIFSF UIF CPEZ DBO CF DPOWFSUFE UP B #ZUF4FRVFODF PS B CZUF<>. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

,0/
5IF >JNM: DPNQPOFOU TVQQPSUT UIF ".21 QSPUPDPM VTJOH UIF $MJFOU "1* PG UIF 2QJE QSPKFDU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-amqp</artifactId> <version>${camel.version}</version> <!-- use the same version as your Camel core version --> </dependency>

538

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( CLOJ>Q
amqp:[queue:|topic:]destinationName[?options]

:PV DBO TQFDJGZ BMM PG UIF WBSJPVT DPOGJHVSBUJPO PQUJPOT PG UIF +.4 DPNQPOFOU BGUFS UIF EFTUJOBUJPO OBNF. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

202 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.6 5IF TRT DPNQPOFOU TVQQPSUT TFOEJOH BOE SFDFJWJOH NFTTBHFT UP "NB[PO'T 424 TFSWJDF. 41( %LOJ>Q
aws-sqs://queue-name[?options]

5IF RVFVF XJMM CF DSFBUFE JG UIFZ EPO'U BMSFBEZ FYJTUT. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, PQUJPOT=WBMVF&PQUJPO2=WBMVF&... 41( .MQFLKP
->JB
BNB[PO424$MJFOU BDDFTT,FZ TFDSFU,FZ BNB[PO424&OEQPJOU BUUSJCVUF/BNFT EFGBVMU7JTJCJMJUZ5JNFPVU EFMFUF"GUFS3FBE NBY.FTTBHFT1FS1PMM

#BC>RIQ 5>IRB
null null null null null null true null

"LKQBUQ
4IBSFE 4IBSFE 4IBSFE 4IBSFE $POTVNFS 4IBSFE $POTVNFS $POTVNFS

#BP@OFMQFLK
3FGFSFODF UP B com.amazonaws.services.sqs.AmazonSQS JO UIF 3FHJTUSZ. "NB[PO "84 "DDFTT ,FZ "NB[PO "84 4FDSFU ,FZ 5IF SFHJPO XJUI XIJDI UIF "84-424 DMJFOU XBOUT UP XPSL XJUI. " MJTU PG BUUSJCVUFT UP TFU JO UIF com.amazonaws.services.sqs.model.ReceiveMessageRequest. 5IF WJTJCJMJUZ UJNFPVU (JO TFDPOET) UP TFU JO UIF com.amazonaws.services.sqs.model.CreateQueueRequest. %FMFUF NFTTBHF GSPN 424 BGUFS JU IBT CFFO SFBE 5IF NBYJNVN OVNCFS PG NFTTBHFT XIJDI DBO CF SFDFJWFE JO POF QPMM UP TFU JO UIF com.amazonaws.services.sqs.model.ReceiveMessageRequest.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

539

/OBOBNRFPFQBP :PV NVTU IBWF B WBMJE "NB[PO 8FC 4FSWJDFT EFWFMPQFS BDDPVOU, BOE CF TJHOFE VQ UP VTF "NB[PO 424. .PSF JOGPSNBUJPO BSF BWBJMBCMF BU "NB[PO 424.
5IF EVSBUJPO (JO TFDPOET) UIBU UIF SFDFJWFE NFTTBHFT BSF IJEEFO GSPN TVCTFRVFOU SFUSJFWF SFRVFTUT BGUFS CFJOH SFUSJFWFE CZ B 3FDFJWF.FTTBHF SFRVFTU UP TFU JO UIF com.amazonaws.services.sqs.model.SetQueueAttributesRequest. 5IJT POMZ NBLF TFOTF JG JUT EJGGFSFOU GSPN defaultVisibilityTimeout. *U DIBOHFT UIF RVFVF WJTJCJMJUZ UJNFPVU BUUSJCVUF QFSNBOFOUMZ. ">JBI 2.8: 5IF EVSBUJPO (JO TFDPOET) UIBU UIF SFDFJWFE NFTTBHFT BSF IJEEFO GSPN TVCTFRVFOU SFUSJFWF SFRVFTUT BGUFS CFJOH SFUSJFWFE CZ B 3FDFJWF.FTTBHF SFRVFTU UP TFU JO UIF com.amazonaws.services.sqs.model.ReceiveMessageRequest. *U EPFT -.3 DIBOHF UIF RVFVF WJTJCJMJUZ UJNFPVU BUUSJCVUF QFSNBOFOUMZ. ">JBI 2.10: *G FOBCMFE UIFO B TDIFEVMFE CBDLHSPVOE UBTL XJMM LFFQ FYUFOEJOH UIF NFTTBHF WJTJCJMJUZ PO 424. 5IJT JT OFFEFE JG JU UBLT B MPOH UJNF UP QSPDFTT UIF NFTTBHF. *G TFU UP USVF defaultVisibilityTimeout NVTU CF TFU. 4FF EFUBJMT BU "NB[PO EPDT. ">JBI 2.8: 5IF NBYJNVN.FTTBHF4J[F (JO CZUFT) BO 424 NFTTBHF DBO DPOUBJO GPS UIJT RVFVF, UP TFU JO UIF com.amazonaws.services.sqs.model.SetQueueAttributesRequest. ">JBI 2.8: 5IF NFTTBHF3FUFOUJPO1FSJPE (JO TFDPOET) B NFTTBHF XJMM CF SFUBJOFE CZ 424 GPS UIJT RVFVF, UP TFU JO UIF com.amazonaws.services.sqs.model.SetQueueAttributesRequest. ">JBI 2.8: 5IF QPMJDZ GPS UIJT RVFVF UP TFU JO UIF com.amazonaws.services.sqs.model.SetQueueAttributesRequest. ">JBI 2.9.3: %FMBZ TFOEJOH NFTTBHFT GPS B OVNCFS PG TFDPOET. ">JBI 2.11: %VSBUJPO JO TFDPOET (0 UP 20) UIBU UIF 3FDFJWF.FTTBHF BDUJPO DBMM XJMM XBJU VOUJM B NFTTBHF JT JO UIF RVFVF UP JODMVEF JO UIF SFTQPOTF. ">JBI 2.11: *G ZPV EP OPU TQFDJGZ 8BJU5JNF4FDPOET JO UIF SFRVFTU, UIF RVFVF BUUSJCVUF 3FDFJWF.FTTBHF8BJU5JNF4FDPOET JT VTFE UP EFUFSNJOF IPX MPOH UP XBJU.

WJTJCJMJUZ5JNFPVU

null

4IBSFE

NFTTBHF7JTJCJMJUZ5JNFPVU

null

$POTVNFS

FYUFOE.FTTBHF7JTJCJMJUZ

false

$POTVNFS

NBYJNVN.FTTBHF4J[F

null

4IBSFE

NFTTBHF3FUFOUJPO1FSJPE

null

4IBSFE

QPMJDZ EFMBZ4FDPOET XBJU5JNF4FDPOET SFDFJWF.FTTBHF8BJU5JNF4FDPOET

null null 0 0

4IBSFE 1SPEVDFS 1SPEVDFS 4IBSFE

!>Q@E "LKPRJBO 5IJT DPNQPOFOU JNQMFNFOUT UIF #BUDI $POTVNFS. 5IJT BMMPXT ZPV GPS JOTUBODF UP LOPX IPX NBOZ NFTTBHFT FYJTUT JO UIJT CBUDI BOE GPS JOTUBODF MFU UIF "HHSFHBUPS BHHSFHBUF UIJT OVNCFS PG NFTTBHFT. 4P>DB

,BPP>DB EB>ABOP PBQ ?V QEB 202 MOLAR@BO


'B>ABO
CamelAwsSqsMD5OfBody CamelAwsSqsMessageId CamelAwsSqsDelaySeconds

3VMB
String String Integer

#BP@OFMQFLK
5IF .%5 DIFDLTVN PG UIF "NB[PO 424 NFTTBHF. 5IF "NB[PO 424 NFTTBHF *%. 4JODF ">JBI 2.11, UIF EFMBZ TFDPOET UIBU UIF "NB[PO 424 NFTTBHF DBO CF TFF CZ PUIFST.

,BPP>DB EB>ABOP PBQ ?V QEB 202 @LKPRJBO


'B>ABO 3VMB #BP@OFMQFLK

540

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

1BNRFOBA 202 @LJMLKBKQ LMQFLKP :PV IBWF UP QSPWJEF UIF BNB[PO424$MJFOU JO UIF 3FHJTUSZ PS ZPVS BDDFTT,FZ BOE TFDSFU,FZ UP BDDFTT UIF "NB[PO'T 424.
CamelAwsSqsMD5OfBody CamelAwsSqsMessageId CamelAwsSqsReceiptHandle CamelAwsSqsAttributes String String String Map<String, String> 5IF .%5 DIFDLTVN PG UIF "NB[PO 424 NFTTBHF. 5IF "NB[PO 424 NFTTBHF *%. 5IF "NB[PO 424 NFTTBHF SFDFJQU IBOEMF. 5IF "NB[PO 424 NFTTBHF BUUSJCVUFT.

AS>K@BA

J>WLK202 @LKCFDRO>QFLK

*G ZPVS $BNFM "QQMJDBUJPO JT SVOOJOH CFIJOE B GJSFXBMM PS JG ZPV OFFE UP IBWF NPSF DPOUSPM PWFS UIF "NB[PO424 JOTUBODF DPOGJHVSBUJPO, ZPV DBO DSFBUF ZPVS PXO JOTUBODF:
AWSCredentials awsCredentials = new BasicAWSCredentials("myAccessKey", "mySecretKey"); ClientConfiguration clientConfiguration = new ClientConfiguration(); clientConfiguration.setProxyHost("http://myProxyHost"); clientConfiguration.setProxyPort(8080); AmazonSQS client = new AmazonSQSClient(awsCredentials, clientConfiguration); registry.bind("client", client);

BOE SFGFS UP JU JO ZPVS $BNFM BXT-TRT DPNQPOFOU DPOGJHVSBUJPO:


from("aws-sqs://MyQueue?amazonSQSClient=#client&delay=5000&maxMessagesPerPoll=5") .to("mock:result");

#BMBKABK@FBP .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS QPN.YNM.
Listing 1. pom.xml
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-aws</artifactId> <version>${camel-version}</version> </dependency>

XIFSF ${camel-version^ NVTU CF SFQMBDFE CZ UIF BDUVBM WFSTJPO PG $BNFM (2.6 PS IJHIFS).

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

541

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE "84 $PNQPOFOU

3., ".,/.-$-3
5IF >QLJ: DPNQPOFOU JT VTFE GPS QPMMJOH "UPN GFFET. $BNFM XJMM QPMM UIF GFFE FWFSZ 60 TFDPOET CZ EFGBVMU. -LQB: 5IF DPNQPOFOU DVSSFOUMZ POMZ TVQQPSUT QPMMJOH (DPOTVNJOH) GFFET. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-atom</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
atom://atomUri[?options]

8IFSF >QLJ4OF JT UIF 63* UP UIF "UPN GFFE UP QPMM. .MQFLKP


/OLMBOQV
splitEntries

#BC>RIQ
true

#BP@OFMQFLK
*G true $BNFM XJMM QPMM UIF GFFE BOE GPS UIF TVCTFRVFOU QPMMT SFUVSO FBDI FOUSZ QPMM CZ QPMM. *G UIF GFFE DPOUBJOT 7 FOUSJFT UIFO $BNFM XJMM SFUVSO UIF GJSTU FOUSZ PO UIF GJSTU QPMM, UIF 2OE FOUSZ PO UIF OFYU QPMM, VOUJM OP NPSF FOUSJFT XIFSF BT $BNFM XJMM EP B OFX VQEBUF PO UIF GFFE. *G false UIFO $BNFM XJMM QPMM B GSFTI GFFE PO FWFSZ JOWPDBUJPO. *T POMZ VTFE CZ UIF TQMJU FOUSJFT UP GJMUFS UIF FOUSJFT UP SFUVSO. $BNFM XJMM EFGBVMU VTF UIF UpdateDateFilter UIBU POMZ SFUVSO OFX FOUSJFT GSPN UIF GFFE. 4P UIF DMJFOU DPOTVNJOH GSPN UIF GFFE OFWFS SFDFJWFT UIF TBNF FOUSZ NPSF UIBO PODF. 5IF GJMUFS XJMM SFUVSO UIF FOUSJFT PSEFSFE CZ UIF OFXFTU MBTU. *T POMZ VTFE CZ UIF GJMUFS, BT UIF TUBSUJOH UJNFTUBNQ GPS TFMFDUJPO OFWFS FOUSJFT (VTFT UIF entry.updated UJNFTUBNQ). 4ZOUBY GPSNBU JT: yyyy-MM-ddTHH:MM:ss. &YBNQMF: 2007-12-24T17:45:59. ">JBI 2.5: 4FUT XIFUIFS BMM FOUSJFT JEFOUJGJFE JO B TJOHMF GFFE QPMM TIPVME CF EFMJWFSFE JNNFEJBUFMZ. *G true, POMZ POF FOUSZ JT QSPDFTTFE QFS consumer.delay. 0OMZ BQQMJDBCMF XIFO splitEntries JT TFU UP true. 4FUT XIFUIFS UP BEE UIF "CEFSB 'FFE PCKFDU BT B IFBEFS. *G splitEntries JT true, UIJT TFUT XIFUIFS UP TPSU UIPTF FOUSJFT CZ VQEBUFE EBUF. %FMBZ JO NJMMJT CFUXFFO FBDI QPMM. .JMMJT CFGPSF QPMMJOH TUBSUT.

filter

true

lastUpdate throttleEntries feedHeader sortEntries consumer.delay consumer.initialDelay

null true true false 60000 1000

542

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

consumer.userFixedDelay

false

*G true, VTF GJYFE EFMBZ CFUXFFO QPPMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT.

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... $U@E>KDB A>Q> CLOJ>Q $BNFM XJMM TFU UIF *O CPEZ PO UIF SFUVSOFE Exchange XJUI UIF FOUSJFT. %FQFOEJOH PO UIF splitEntries GMBH $BNFM XJMM FJUIFS SFUVSO POF Entry PS B List<Entry>.
.MQFLK
splitEntries splitEntries

5>IRB
true false

!BE>SFLO
0OMZ B TJOHMF FOUSZ GSPN UIF DVSSFOUMZ CFJOH QSPDFTTFE GFFE JT TFU: exchange.in.body(Entry) 5IF FOUJSF MJTU PG FOUSJFT GSPN UIF GFFE JT TFU: exchange.in.body(List<Entry>)

$BNFM DBO TFU UIF Feed PCKFDU PO UIF *O IFBEFS (TFF feedHeader PQUJPO UP EJTBCMF UIJT): ,BPP>DB 'B>ABOP $BNFM BUPN VTFT UIFTF IFBEFST.
'B>ABO
CamelAtomFeed

#BP@OFMQFLK
8IFO DPOTVNJOH UIF org.apache.abdera.model.Feed PCKFDU JT TFU UP UIJT IFBEFS.

2>JMIBP *O UIJT TBNQMF XF QPMM +BNFT 4USBDIBO'T CMPH.


from("atom://http://macstrac.blogspot.com/feeds/posts/default").to("seda:feeds");

*O UIJT TBNQMF XF XBOU UP GJMUFS POMZ HPPE CMPHT XF MJLF UP B 4&%" RVFVF. 5IF TBNQMF BMTP TIPXT IPX UP TFUVQ $BNFM TUBOEBMPOF, OPU SVOOJOH JO BOZ $POUBJOFS PS VTJOH 4QSJOH.
// This is the CamelContext that is the heart of Camel private CamelContext context; protected CamelContext createCamelContext() throws Exception { // First we register a blog service in our bean registry SimpleRegistry registry = new SimpleRegistry(); registry.put("blogService", new BlogService()); // Then we create the camel context with our bean registry context = new DefaultCamelContext(registry); // Then we add all the routes we need using the route builder DSL syntax context.addRoutes(createMyRoutes()); return context; }

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

543

/** * This is the route builder where we create our routes using the Camel DSL */ protected RouteBuilder createMyRoutes() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // We pool the atom feeds from the source for further processing in the seda queue // we set the delay to 1 second for each pool as this is a unit test also and we can // not wait the default poll interval of 60 seconds. // Using splitEntries=true will during polling only fetch one Atom Entry at any given time. // As the feed.atom file contains 7 entries, using this will require 7 polls to fetch the entire // content. When Camel have reach the end of entries it will refresh the atom feed from URI source // and restart - but as Camel by default uses the UpdatedDateFilter it will only deliver new // blog entries to "seda:feeds". So only when James Straham updates his blog with a new entry // Camel will create an exchange for the seda:feeds. from("atom:file:src/test/data/ feed.atom?splitEntries=true&consumer.delay=1000").to("seda:feeds"); // From the feeds we filter each blot entry by using our blog service class from("seda:feeds").filter().method("blogService", "isGoodBlog").to("seda:goodBlogs"); // And the good blogs is moved to a mock queue as this sample is also used for unit testing // this is one of the strengths in Camel that you can also use the mock endpoint for your // unit tests from("seda:goodBlogs").to("mock:result"); } }; } /** * This is the actual junit test method that does the assertion that our routes is working as expected */ @Test public void testFiltering() throws Exception { // create and start Camel context = createCamelContext(); context.start(); // Get the mock endpoint MockEndpoint mock = context.getEndpoint("mock:result", MockEndpoint.class); // There should be at least two good blog entries from the feed mock.expectedMinimumMessageCount(2);

544

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

// Asserts that the above expectations is true, will throw assertions exception if it failed // Camel will default wait max 20 seconds for the assertions to be true, if the conditions // is true sooner Camel will continue mock.assertIsSatisfied(); // stop Camel after use context.stop(); } /** * Services for blogs */ public class BlogService { /** * Tests the blogs if its a good blog entry or not */ public boolean isGoodBlog(Exchange exchange) { Entry entry = exchange.getIn().getBody(Entry.class); String title = entry.getTitle(); // We like blogs about Camel boolean good = title.toLowerCase().contains("camel"); return good; } }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 344

!$ - ".,/.-$-3
5IF ?B>K: DPNQPOFOU CJOET CFBOT UP $BNFM NFTTBHF FYDIBOHFT. 41( CLOJ>Q
bean:beanID[?options]

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

545

8IFSF ?B>K(# DBO CF BOZ TUSJOH XIJDI JT VTFE UP MPPL VQ UIF CFBO JO UIF 3FHJTUSZ .MQFLKP
->JB
method

3VMB
String

#BC>RIQ
null

#BP@OFMQFLK
5IF NFUIPE OBNF GSPN UIF CFBO UIBU XJMM CF JOWPLFE. *G OPU QSPWJEFE, $BNFM XJMM USZ UP EFUFSNJOF UIF NFUIPE JUTFMG. *O DBTF PG BNCJHVJUZ BO FYDFQUJPO XJMM CF UISPXO. 4FF #FBO #JOEJOH GPS NPSF EFUBJMT. 'SPN ">JBI 2.8 POXBSET ZPV DBO TQFDJGZ UZQF RVBMJGJFST UP QJO-QPJOU UIF FYBDU NFUIPE UP VTF GPS PWFSMPBEFE NFUIPET. 'SPN ">JBI 2.9 POXBSET ZPV DBO TQFDJGZ QBSBNFUFS WBMVFT EJSFDUMZ JO UIF NFUIPE TZOUBY. 4FF NPSF EFUBJMT BU #FBO #JOEJOH. *G FOBCMFE, $BNFM XJMM DBDIF UIF SFTVMU PG UIF GJSTU 3FHJTUSZ MPPL-VQ. $BDIF DBO CF FOBCMFE JG UIF CFBO JO UIF 3FHJTUSZ JT EFGJOFE BT B TJOHMFUPO TDPQF. )PX UP USFBU UIF QBSBNFUFST XIJDI BSF QBTTFE GSPN UIF NFTTBHF CPEZ; JG JU JT true, UIF *O NFTTBHF CPEZ TIPVME CF BO BSSBZ PG QBSBNFUFST.

cache multiParameterArray

boolean boolean

false false

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 4PFKD 5IF PCKFDU JOTUBODF UIBU JT VTFE UP DPOTVNF NFTTBHFT NVTU CF FYQMJDJUMZ SFHJTUFSFE XJUI UIF 3FHJTUSZ. 'PS FYBNQMF, JG ZPV BSF VTJOH 4QSJOH ZPV NVTU EFGJOF UIF CFBO JO UIF 4QSJOH DPOGJHVSBUJPO, spring.xml; PS JG ZPV EPO'U VTF 4QSJOH, CZ SFHJTUFSJOH UIF CFBO JO +/%*.
// lets populate the context with the services we need // note that we could just use a spring.xml file to avoid this step JndiContext context = new JndiContext(); context.bind("bye", new SayService("Good Bye!")); CamelContext camelContext = new DefaultCamelContext(context);

0ODF BO FOEQPJOU IBT CFFO SFHJTUFSFE, ZPV DBO CVJME $BNFM SPVUFT UIBU VTF JU UP QSPDFTT FYDIBOHFT.
// lets add simple route camelContext.addRoutes(new RouteBuilder() { public void configure() { from("direct:hello").to("bean:bye"); } });

" ?B>K: FOEQPJOU DBOOPU CF EFGJOFE BT UIF JOQVU UP UIF SPVUF; J.F. ZPV DBOOPU DPOTVNF GSPN JU, ZPV DBO POMZ SPVUF GSPN TPNF JOCPVOE NFTTBHF &OEQPJOU UP UIF CFBO FOEQPJOU BT PVUQVU. 4P DPOTJEFS VTJOH B AFOB@Q: PS NRBRB: FOEQPJOU BT UIF JOQVU. :PV DBO VTF UIF createProxy() NFUIPET PO 1SPYZ)FMQFS UP DSFBUF B QSPYZ UIBU XJMM HFOFSBUF #FBO&YDIBOHFT BOE TFOE UIFN UP BOZ FOEQPJOU:

546

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

Endpoint endpoint = camelContext.getEndpoint("direct:hello"); ISay proxy = ProxyHelper.createProxy(endpoint, ISay.class); String rc = proxy.say(); assertEquals("Good Bye!", rc);

"OE UIF TBNF SPVUF VTJOH 4QSJOH %4-:


<route> <from uri="direct:hello"> <to uri="bean:bye"/> </route>

!B>K >P BKAMLFKQ $BNFM BMTP TVQQPSUT JOWPLJOH #FBO BT BO &OEQPJOU. *O UIF SPVUF CFMPX:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <to uri="myBean"/> <to uri="mock:results"/> </route> </camelContext> <bean id="myBean" class="org.apache.camel.spring.bind.ExampleBean"/>

8IBU IBQQFOT JT UIBU XIFO UIF FYDIBOHF JT SPVUFE UP UIF myBean $BNFM XJMM VTF UIF #FBO #JOEJOH UP JOWPLF UIF CFBO. 5IF TPVSDF GPS UIF CFBO JT KVTU B QMBJO 10+0:
public class ExampleBean { public String sayHello(String name) { return "Hello " + name + "!"; } }

$BNFM XJMM VTF #FBO #JOEJOH UP JOWPLF UIF sayHello NFUIPE, CZ DPOWFSUJOH UIF &YDIBOHF'T *O CPEZ UP UIF String UZQF BOE TUPSJOH UIF PVUQVU PG UIF NFUIPE PO UIF &YDIBOHF 0VU CPEZ. )>S> #2+ ?B>K PVKQ>U +BWB %4- DPNFT XJUI TZOUBDUJD TVHBS GPS UIF #FBO DPNQPOFOU. *OTUFBE PG TQFDJGZJOH UIF CFBO FYQMJDJUMZ BT UIF FOEQPJOU (J.F. to("bean:beanName")) ZPV DBO VTF UIF GPMMPXJOH TZOUBY:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

547

// Send message to the bean endpoint // and invoke method resolved using Bean Binding. from("direct:start").beanRef("beanName"); // Send message to the bean endpoint // and invoke given method. from("direct:start").beanRef("beanName", "methodName");

*OTUFBE PG QBTTJOH OBNF PG UIF SFGFSFODF UP UIF CFBO (TP UIBU $BNFM XJMM MPPLVQ GPS JU JO UIF SFHJTUSZ), ZPV DBO TQFDJGZ UIF CFBO JUTFMG:
// Send message to the given bean instance. from("direct:start").bean(new ExampleBean()); // Explicit selection of bean method to be invoked. from("direct:start").bean(new ExampleBean(), "methodName"); // Camel will create the instance of bean and cache it for you. from("direct:start").bean(ExampleBean.class);

!B>K !FKAFKD )PX CFBO NFUIPET UP CF JOWPLFE BSF DIPTFO (JG UIFZ BSF OPU TQFDJGJFE FYQMJDJUMZ UISPVHI UIF JBQELA QBSBNFUFS) BOE IPX QBSBNFUFS WBMVFT BSF DPOTUSVDUFE GSPN UIF .FTTBHF BSF BMM EFGJOFE CZ UIF #FBO #JOEJOH NFDIBOJTN XIJDI JT VTFE UISPVHIPVU BMM PG UIF WBSJPVT #FBO *OUFHSBUJPO NFDIBOJTNT JO $BNFM. 2BB IPL ` ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE $MBTT DPNQPOFOU #FBO #JOEJOH #FBO *OUFHSBUJPO

!$ - 5 +(# 3(.- ".,/.-$-3


S>FI>?IB >P LC ">JBI 2.3 5IF 7BMJEBUJPO DPNQPOFOU QFSGPSNT CFBO WBMJEBUJPO PG UIF NFTTBHF CPEZ VTJOH UIF +BWB #FBO 7BMJEBUJPO "1* (+43 303). $BNFM VTFT UIF SFGFSFODF JNQMFNFOUBUJPO, XIJDI JT )JCFSOBUF 7BMJEBUPS.

548

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-bean-validator</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
bean-validator:something[?options]

PS
bean-validator://something[?options]

8IFSF PLJBQEFKD NVTU CF QSFTFOU UP QSPWJEF B WBMJE VSM :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, PQUJPO=WBMVF&PQUJPO=WBMVF&... 41( .MQFLKP
.MQFLK
group messageInterpolator traversableResolver

#BC>RIQ
javax.validation.groups.Default org.hibernate.validator.engine. ResourceBundleMessageInterpolator org.hibernate.validator.engine.resolver. DefaultTraversableResolver org.hibernate.validator.engine. ConstraintValidatorFactoryImpl

#BP@OFMQFLK
5IF DVTUPN WBMJEBUJPO HSPVQ UP VTF. 3FGFSFODF UP B DVTUPN javax.validation.MessageInterpolator JO UIF 3FHJTUSZ. 3FGFSFODF UP B DVTUPN javax.validation.TraversableResolver JO UIF 3FHJTUSZ. 3FGFSFODF UP B DVTUPN javax.validation.ConstraintValidatorFactory JO UIF 3FHJTUSZ.

constraintValidatorFactory

2BOSF@B,FU4/.2&F #BMILVJBKQ. 5IF CFBO-WBMJEBUPS XIFO EFQMPZFE JO BO 04(J FOWJSPONFOU SFRVJSFT B MJUUMF IFMQ UP BDDPNNPEBUF UIF SFTPVSDF MPBEJOH TQFDJGJFE JO +43303, UIJT XBT GJYFE JO 4FSWJDFNJY-4QFDT 1.6-4/"14)05. $U>JMIB "TTVNFE XF IBWF B KBWB CFBO XJUI UIF GPMMPXJOH BOOPUBUJPOT
Listing 1. Car.java

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

549

public class Car { @NotNull private String manufacturer; @NotNull @Size(min = 5, max = 14, groups = OptionalChecks.class) private String licensePlate; // getter and setter }

BOE BO JOUFSGBDF EFGJOJUJPO GPS PVS DVTUPN WBMJEBUJPO HSPVQ


Listing 1. OptionalChecks.java
public interface OptionalChecks { }

XJUI UIF GPMMPXJOH $BNFM SPVUF, POMZ UIF @-LQ-RII DPOTUSBJOUT PO UIF BUUSJCVUFT NBOVGBDUVSFS BOE MJDFOTF1MBUF XJMM CF WBMJEBUFE ($BNFM VTFT UIF EFGBVMU HSPVQ javax.validation.groups.Default).
from("direct:start") .to("bean-validator://x") .to("mock:end")

*G ZPV XBOU UP DIFDL UIF DPOTUSBJOUT GSPN UIF HSPVQ OptionalChecks, ZPV IBWF UP EFGJOF UIF SPVUF MJLF UIJT
from("direct:start") .to("bean-validator://x?group=OptionalChecks") .to("mock:end")

*G ZPV XBOU UP DIFDL UIF DPOTUSBJOUT GSPN CPUI HSPVQT, ZPV IBWF UP EFGJOF B OFX JOUFSGBDF GJSTU
Listing 1. AllChecks.java
@GroupSequence({Default.class, OptionalChecks.class}) public interface AllChecks { }

BOE UIFO ZPVS SPVUF EFGJOJUJPO TIPVME MPPLT MJLF UIJT


from("direct:start") .to("bean-validator://x?group=AllChecks") .to("mock:end")

550

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"OE JG ZPV IBWF UP QSPWJEF ZPVS PXO NFTTBHF JOUFSQPMBUPS, USBWFSTBCMF SFTPMWFS BOE DPOTUSBJOU WBMJEBUPS GBDUPSZ, ZPV IBWF UP XSJUF B SPVUF MJLF UIJT
<bean id="myMessageInterpolator" class="my.ConstraintValidatorFactory" /> <bean id="myTraversableResolver" class="my.TraversableResolver" /> <bean id="myConstraintValidatorFactory" class="my.ConstraintValidatorFactory" />

from("direct:start") .to("bean-validator://x?group=AllChecks&messageInterpolator=#myMessageInterpolator &traversableResolver=#myTraversableResolver&constraintValidatorFactory=#myConstraintValidatorFactory") .to("mock:end")

*U'T BMTP QPTTJCMF UP EFTDSJCF ZPVS DPOTUSBJOUT BT 9.- BOE OPU BT +BWB BOOPUBUJPOT. *O UIJT DBTF, ZPV IBWF UP QSPWJEF UIF GJMF META-INF/validation.xml XIJDI DPVME MPPLT MJLF UIJT
Listing 1. validation.xml
<?xml version="1.0" encoding="UTF-8"?> <validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration"> <default-provider>org.hibernate.validator.HibernateValidator</default-provider>

<message-interpolator>org.hibernate.validator.engine.ResourceBundleMessageInterpolator</message-interp

<traversable-resolver>org.hibernate.validator.engine.resolver.DefaultTraversableResolver</traversable-

<constraint-validator-factory>org.hibernate.validator.engine.ConstraintValidatorFactoryImpl</constrain <constraint-mapping>/constraints-car.xml</constraint-mapping> </validation-config>

BOE UIF constraints-car.xml GJMF


Listing 1. constraints-car.xml
<?xml version="1.0" encoding="UTF-8"?> <constraint-mappings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd" xmlns="http://jboss.org/xml/ns/javax/validation/mapping"> <default-package>org.apache.camel.component.bean.validator</default-package> <bean class="CarWithoutAnnotations" ignore-annotations="true"> <field name="manufacturer"> <constraint annotation="javax.validation.constraints.NotNull" /> </field> <field name="licensePlate"> <constraint annotation="javax.validation.constraints.NotNull" />

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

551

<constraint annotation="javax.validation.constraints.Size"> <groups> <value>org.apache.camel.component.bean.validator.OptionalChecks</value> </groups> <element name="min">5</element> <element name="max">14</element> </constraint> </field> </bean> </constraint-mappings>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

!1.62$ ".,/.-$-3
5IF #SPXTF DPNQPOFOU QSPWJEFT B TJNQMF #SPXTBCMF&OEQPJOU XIJDI DBO CF VTFGVM GPS UFTUJOH, WJTVBMJTBUJPO UPPMT PS EFCVHHJOH. 5IF FYDIBOHFT TFOU UP UIF FOEQPJOU BSF BMM BWBJMBCMF UP CF CSPXTFE. 41( CLOJ>Q
browse:someName

8IFSF PLJB->JB DBO CF BOZ TUSJOH UP VOJRVFMZ JEFOUJGZ UIF FOEQPJOU. 2>JMIB *O UIF SPVUF CFMPX, XF JOTFSU B browse: DPNQPOFOU UP CF BCMF UP CSPXTF UIF &YDIBOHFT UIBU BSF QBTTJOH UISPVHI:
from("activemq:order.in").to("browse:orderReceived").to("bean:processOrder");

8F DBO OPX JOTQFDU UIF SFDFJWFE FYDIBOHFT GSPN XJUIJO UIF +BWB DPEF:

552

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

private CamelContext context; public void inspectRecievedOrders() { BrowsableEndpoint browse = context.getEndpoint("browse:orderReceived", BrowsableEndpoint.class); List<Exchange> exchanges = browse.getExchanges(); ... // then we can inspect the list of received exchanges from Java for (Exchange exchange : exchanges) { String payload = exchange.getIn().getBody(); ... } }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

" "'$ ".,/.-$-3


S>FI>?IB >P LC ">JBI 2.1 5IF @>@EB DPNQPOFOU FOBCMFT ZPV UP QFSGPSN DBDIJOH PQFSBUJPOT VTJOH &)$BDIF BT UIF $BDIF *NQMFNFOUBUJPO. 5IF DBDIF JUTFMG JT DSFBUFE PO EFNBOE PS JG B DBDIF PG UIBU OBNF BMSFBEZ FYJTUT UIFO JU JT TJNQMZ VUJMJ[FE XJUI JUT PSJHJOBM TFUUJOHT. 5IJT DPNQPOFOU TVQQPSUT QSPEVDFS BOE FWFOU CBTFE DPOTVNFS FOEQPJOUT. 5IF $BDIF DPOTVNFS JT BO FWFOU CBTFE DPOTVNFS BOE DBO CF VTFE UP MJTUFO BOE SFTQPOE UP TQFDJGJD DBDIF BDUJWJUJFT. *G ZPV OFFE UP QFSGPSN TFMFDUJPOT GSPN B QSF-FYJTUJOH DBDIF, VTF UIF QSPDFTTPST EFGJOFE GPS UIF DBDIF DPNQPOFOU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cache</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

553

41( CLOJ>Q
cache://cacheName[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=#beanRef&... .MQFLKP
->JB
maxElementsInMemory

#BC>RIQ 5>IRB
1000

#BP@OFMQFLK
5IF OVNCFS PG FMFNFOUT UIBU NBZ CF TUPSFE JO UIF EFGJOFE DBDIF 5IF OVNCFS PG FMFNFOUT UIBU NBZ CF TUPSFE JO UIF EFGJOFE DBDIF. 0QUJPOT JODMVEF .FNPSZ4UPSF&WJDUJPO1PMJDZ.-'6 - -FBTU GSFRVFOUMZ VTFE .FNPSZ4UPSF&WJDUJPO1PMJDZ.-36 - -FBTU SFDFOUMZ VTFE .FNPSZ4UPSF&WJDUJPO1PMJDZ.'*'0 - GJSTU JO GJSTU PVU, UIF PMEFTU FMFNFOU CZ DSFBUJPO UJNF 4QFDJGJFT XIFUIFS DBDIF NBZ PWFSGMPX UP EJTL 4FUT XIFUIFS FMFNFOUT BSF FUFSOBM. *G FUFSOBM, UJNFPVUT BSF JHOPSFE BOE UIF FMFNFOU OFWFS FYQJSFT. 5IF NBYJNVN UJNF CFUXFFO DSFBUJPO UJNF BOE XIFO BO FMFNFOU FYQJSFT. *T VTFE POMZ JG UIF FMFNFOU JT OPU FUFSOBM 5IF NBYJNVN BNPVOU PG UJNF CFUXFFO BDDFTTFT CFGPSF BO FMFNFOU FYQJSFT 8IFUIFS UIF EJTL TUPSF QFSTJTUT CFUXFFO SFTUBSUT PG UIF 7JSUVBM .BDIJOF. 5IF OVNCFS PG TFDPOET CFUXFFO SVOT PG UIF EJTL FYQJSZ UISFBE. ">JBI 2.8: *G ZPV XBOU UP VTF B DVTUPN GBDUPSZ XIJDI JOTUBOUJBUFT BOE DSFBUFT UIF &)$BDIF net.sf.ehcache.CacheManager. Type: BCTUSBDU PSH.BQBDIF.DBNFM.DPNQPOFOU.DBDIF.$BDIF.BOBHFS'BDUPSZ ">JBI 2.8: 4FUT B MJTU PG &)$BDIF net.sf.ehcache.event.CacheEventListener GPS BMM OFX DBDIFT- OP OFFE UP EFGJOF JU QFS DBDIF JO &)$BDIF YNM DPOGJH BOZNPSF. Type: PSH.BQBDIF.DBNFM.DPNQPOFOU.DBDIF.$BDIF&WFOU-JTUFOFS3FHJTUSZ ">JBI 2.8: 4FUT B MJTU PG org.apache.camel.component.cache.CacheLoaderWrapper UIBU FYUFOET &)$BDIF net.sf.ehcache.loader.CacheLoader GPS BMM OFX DBDIFT- OP OFFE UP EFGJOF JU QFS DBDIF JO &)$BDIF YNM DPOGJH BOZNPSF. Type: PSH.BQBDIF.DBNFM.DPNQPOFOU.DBDIF.$BDIF-PBEFS3FHJTUSZ

memoryStoreEvictionPolicy

MemoryStoreEvictionPolicy.LFU

overflowToDisk eternal timeToLiveSeconds timeToIdleSeconds diskPersistent diskExpiryThreadIntervalSeconds

true false 300 300 false 120

cacheManagerFactory

null

eventListenerRegistry

null

cacheLoaderRegistry

null

key operation

null null

">JBI 2.10: 5P DPOGJHVSF VTJOH B DBDIF LFZ CZ EFGBVMU. *G B LFZ JT QSPWJEFE JO UIF NFTTBHF IFBEFS, UIFO UIF LFZ GSPN UIF IFBEFS UBLFT QSFDFEFODF. ">JBI 2.10: 5P DPOGJHVSF VTJOH BO DBDIF PQFSBUJPO CZ EFGBVMU. *G BO PQFSBUJPO JO UIF NFTTBHF IFBEFS, UIFO UIF PQFSBUJPO GSPN UIF IFBEFS UBLFT QSFDFEFODF.

2BKAFKD/1B@BFSFKD ,BPP>DBP QL/COLJ QEB @>@EB

,BPP>DB 'B>ABOP RM QL ">JBI 2.7


'B>ABO #BP@OFMQFLK

554

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

CACHE_OPERATION

5IF PQFSBUJPO UP CF QFSGPSNFE PO UIF DBDIF. 7BMJE PQUJPOT BSF (&5 $)&$, "%% 61%"5& %&-&5& %&-&5&"-GET BOE CHECK SFRVJSFT ">JBI 2.3 POXBSET. 5IF DBDIF LFZ VTFE UP TUPSF UIF .FTTBHF JO UIF DBDIF. 5IF DBDIF LFZ JT PQUJPOBM JG UIF $"$)&@01&3"5*0/ JT %&-&5&"--

CACHE_KEY

,BPP>DB 'B>ABOP ">JBI 2.8+


'B>ABO #BP@OFMQFLK
5IF PQFSBUJPO UP CF QFSGPSNFE PO UIF DBDIF. 5IF WBMJE PQUJPOT BSF $BNFM$BDIF(FU $BNFM$BDIF$IFDL $BNFM$BDIF"EE $BNFM$BDIF6QEBUF $BNFM$BDIF%FMFUF $BNFM$BDIF%FMFUF"MM 5IF DBDIF LFZ VTFE UP TUPSF UIF .FTTBHF JO UIF DBDIF. 5IF DBDIF LFZ JT PQUJPOBM JG UIF $BNFM$BDIF0QFSBUJPO JT $BNFM$BDIF%FMFUF"MM

CamelCacheOperation

CamelCacheKey

5IF CamelCacheAdd BOE CamelCacheUpdate PQFSBUJPOT TVQQPSU BEEJUJPOBM IFBEFST:


'B>ABO
CamelCacheTimeToLive CamelCacheTimeToIdle CamelCacheEternal

3VMB
Integer Integer Boolean

#BP@OFMQFLK
">JBI 2.11: 5JNF UP MJWF JO TFDPOET. ">JBI 2.11: 5JNF UP JEMF JO TFDPOET. ">JBI 2.11: 8IFUIFS UIF DPOUFOU JT FUFSOBM.

">@EB /OLAR@BO
4FOEJOH EBUB UP UIF DBDIF JOWPMWFT UIF BCJMJUZ UP EJSFDU QBZMPBET JO FYDIBOHFT UP CF TUPSFE JO B QSF-FYJTUJOH PS DSFBUFE-PO-EFNBOE DBDIF. 5IF NFDIBOJDT PG EPJOH UIJT JOWPMWF TFUUJOH UIF .FTTBHF &YDIBOHF )FBEFST TIPXO BCPWF. FOTVSJOH UIBU UIF .FTTBHF &YDIBOHF #PEZ DPOUBJOT UIF NFTTBHF EJSFDUFE UP UIF DBDIF

">@EB "LKPRJBO
3FDFJWJOH EBUB GSPN UIF DBDIF JOWPMWFT UIF BCJMJUZ PG UIF $BDIF$POTVNFS UP MJTUFO PO B QSFFYJTUJOH PS DSFBUFE-PO-EFNBOE $BDIF VTJOH BO FWFOU -JTUFOFS BOE SFDFJWF BVUPNBUJD OPUJGJDBUJPOT XIFO BOZ DBDIF BDUJWJUZ UBLF QMBDF (J.F $BNFM$BDIF(FU/$BNFM$BDIF6QEBUF/ $BNFM$BDIF%FMFUF/$BNFM$BDIF%FMFUF"MM). 6QPO TVDI BO BDUJWJUZ UBLJOH QMBDF BO FYDIBOHF DPOUBJOJOH .FTTBHF &YDIBOHF )FBEFST BOE B .FTTBHF &YDIBOHF #PEZ DPOUBJOJOH UIF KVTU BEEFE/VQEBUFE QBZMPBE JT QMBDFE BOE TFOU. JO DBTF PG B $BNFM$BDIF%FMFUF"MM PQFSBUJPO, UIF .FTTBHF &YDIBOHF )FBEFS $BNFM$BDIF,FZ BOE UIF .FTTBHF &YDIBOHF #PEZ BSF OPU QPQVMBUFE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

555

'B>ABO @E>KDBP FK ">JBI 2.8 5IF IFBEFS OBNFT BOE TVQQPSUFE WBMVFT IBWF DIBOHFE UP CF QSFGJYFE XJUI '$BNFM$BDIF' BOE VTF NJYFE DBTF. 5IJT NBLFT UIFN FBTJFS UP JEFOUJGZ BOE LFFQ TFQBSBUF GSPN PUIFS IFBEFST. 5IF $BDIF$POTUBOUT WBSJBCMF OBNFT SFNBJO VODIBOHFE, KVTU UIFJS WBMVFT IBWF CFFO DIBOHFE. "MTP, UIFTF IFBEFST BSF OPX SFNPWFE GSPN UIF FYDIBOHF BGUFS UIF DBDIF PQFSBUJPO JT QFSGPSNFE.

">@EB /OL@BPPLOP
5IFSF BSF B TFU PG OJDF QSPDFTTPST XJUI UIF BCJMJUZ UP QFSGPSN DBDIF MPPLVQT BOE TFMFDUJWFMZ SFQMBDF QBZMPBE DPOUFOU BU UIF CPEZ UPLFO YQBUI MFWFM ">@EB 4P>DB 2>JMIBP

$U>JMIB 1: "LKCFDROFKD QEB @>@EB


from("cache://MyApplicationCache" + "?maxElementsInMemory=1000" + "&memoryStoreEvictionPolicy=" + "MemoryStoreEvictionPolicy.LFU" + "&overflowToDisk=true" + "&eternal=true" + "&timeToLiveSeconds=300" + "&timeToIdleSeconds=true" + "&diskPersistent=true" + "&diskExpiryThreadIntervalSeconds=300")

$U>JMIB 2:

AAFKD HBVP QL QEB @>@EB

RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") } };

556

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

$U>JMIB 2: 4MA>QFKD BUFPQFKD HBVP FK > @>@EB


RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_UPDATE)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") } };

$U>JMIB 3: #BIBQFKD BUFPQFKD HBVP FK > @>@EB


RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_DELETE)) .setHeader(CacheConstants.CACHE_KEY", constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") } };

$U>JMIB 4: #BIBQFKD >II BUFPQFKD HBVP FK > @>@EB


RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start") .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_DELETEALL)) .to("cache://TestCache1"); } };

$U>JMIB 5: -LQFCVFKD >KV @E>KDBP OBDFPQBOFKD FK > ">@EB QL /OL@BPPLOP >KA LQEBO /OLAR@BOP
RouteBuilder builder = new RouteBuilder() { public void configure() { from("cache://TestCache1") .process(new Processor() { public void process(Exchange exchange)

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

557

throws Exception { String operation = (String) exchange.getIn().getHeader(CacheConstants.CACHE_OPERATION); String key = (String) exchange.getIn().getHeader(CacheConstants.CACHE_KEY); Object body = exchange.getIn().getBody(); // Do something } }) } };

$U>JMIB 6: 4PFKD /OL@BPPLOP QL PBIB@QFSBIV OBMI>@B M>VIL>A TFQE @>@EB S>IRBP


RouteBuilder builder = new RouteBuilder() { public void configure() { //Message Body Replacer from("cache://TestCache1") .filter(header(CacheConstants.CACHE_KEY).isEqualTo("greeting")) .process(new CacheBasedMessageBodyReplacer("cache://TestCache1","farewell")) .to("direct:next"); //Message Token replacer from("cache://TestCache1") .filter(header(CacheConstants.CACHE_KEY).isEqualTo("quote")) .process(new CacheBasedTokenReplacer("cache://TestCache1","novel","#novel#")) .process(new CacheBasedTokenReplacer("cache://TestCache1","author","#author#")) .process(new CacheBasedTokenReplacer("cache://TestCache1","number","#number#")) .to("direct:next"); //Message XPath replacer from("cache://TestCache1"). .filter(header(CacheConstants.CACHE_KEY).isEqualTo("XML_FRAGMENT")) .process(new CacheBasedXPathReplacer("cache://TestCache1","book1","/books/book1")) .process (new CacheBasedXPathReplacer("cache://TestCache1","book2","/books/book2")) .to("direct:next"); } };

$U>JMIB 7: &BQQFKD >K BKQOV COLJ QEB ">@EB


from("direct:start") // Prepare headers .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_GET)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")).

558

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.to("cache://TestCache1"). // Check if entry was not found .choice().when(header(CacheConstants.CACHE_ELEMENT_WAS_FOUND).isNull()). // If not found, get the payload and put it to cache .to("cxf:bean:someHeavyweightOperation"). .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") .end() .to("direct:nextPhase");

$U>JMIB 8: "EB@HFKD CLO >K BKQOV FK QEB ">@EB


/PUF: 5IF $)&$, DPNNBOE UFTUT FYJTUFODF PG BO FOUSZ JO UIF DBDIF CVU EPFTO'U QMBDF B NFTTBHF JO UIF CPEZ.
from("direct:start") // Prepare headers .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_CHECK)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")). .to("cache://TestCache1"). // Check if entry was not found .choice().when(header(CacheConstants.CACHE_ELEMENT_WAS_FOUND).isNull()). // If not found, get the payload and put it to cache .to("cxf:bean:someHeavyweightOperation"). .setHeader(CacheConstants.CACHE_OPERATION, constant(CacheConstants.CACHE_OPERATION_ADD)) .setHeader(CacheConstants.CACHE_KEY, constant("Ralph_Waldo_Emerson")) .to("cache://TestCache1") .end();

,>K>DBJBKQ LC $'">@EB &)$BDIF IBT JUT PXO TUBUJTUJDT BOE NBOBHFNFOU GSPN +.9. )FSF'T B TOJQQFU PO IPX UP FYQPTF UIFN WJB +.9 JO B 4QSJOH BQQMJDBUJPO DPOUFYU:
<bean id="ehCacheManagementService" class="net.sf.ehcache.management.ManagementService" init-method="init" lazy-init="false"> <constructor-arg> <bean class="net.sf.ehcache.CacheManager" factory-method="getInstance"/> </constructor-arg> <constructor-arg> <bean class="org.springframework.jmx.support.JmxUtils" factory-method="locateMBeanServer"/>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

559

</constructor-arg> <constructor-arg value="true"/> <constructor-arg value="true"/> <constructor-arg value="true"/> <constructor-arg value="true"/> </bean>

0G DPVSTF ZPV DBO EP UIF TBNF UIJOH JO TUSBJHIU +BWB:


ManagementService.registerMBeans(CacheManager.getInstance(), mbeanServer, true, true, true, true);

:PV DBO HFU DBDIF IJUT, NJTTFT, JO-NFNPSZ IJUT, EJTL IJUT, TJ[F TUBUT UIJT XBZ. :PV DBO BMTP DIBOHF $BDIF$POGJHVSBUJPO QBSBNFUFST PO UIF GMZ. ">@EB OBMIF@>QFLK ">JBI 2.8+ 5IF $BNFM $BDIF DPNQPOFOU JT BCMF UP EJTUSJCVUF B DBDIF BDSPTT TFSWFS OPEFT VTJOH TFWFSBM EJGGFSFOU SFQMJDBUJPO NFDIBOJTNT JODMVEJOH: 3.*, +(SPVQT, +.4 BOE $BDIF 4FSWFS. 5IFSF BSF UXP EJGGFSFOU XBZT UP NBLF JU XPSL: 1. :PV DBO DPOGJHVSF ehcache.xml NBOVBMMZ 03 2. :PV DBO DPOGJHVSF UIFTF UISFF PQUJPOT: DBDIF.BOBHFS'BDUPSZ FWFOU-JTUFOFS3FHJTUSZ DBDIF-PBEFS3FHJTUSZ $POGJHVSJOH $BNFM $BDIF SFQMJDBUJPO VTJOH UIF GJSTU PQUJPO JT B CJU PG IBSE XPSL BT ZPV IBWF UP DPOGJHVSF BMM DBDIFT TFQBSBUFMZ. 4P JO B TJUVBUJPO XIFO UIF BMM OBNFT PG DBDIFT BSF OPU LOPXO, VTJOH ehcache.xml JT OPU B HPPE JEFB. 5IF TFDPOE PQUJPO JT NVDI CFUUFS XIFO ZPV XBOU UP VTF NBOZ EJGGFSFOU DBDIFT BT ZPV EP OPU OFFE UP EFGJOF PQUJPOT QFS DBDIF. 5IJT JT CFDBVTF SFQMJDBUJPO PQUJPOT BSF TFU QFS CacheManager BOE QFS CacheEndpoint. "MTP JU JT UIF POMZ XBZ XIFO DBDIF OBNFT BSF OPU LOPX BU UIF EFWFMPQNFOU QIBTF.

$U>JMIB: ),2 @>@EB OBMIF@>QFLK


+.4 SFQMJDBUJPO JT UIF NPTU QPXFSGVM BOE TFDVSFE SFQMJDBUJPO NFUIPE. 6TFE UPHFUIFS XJUI $BNFM $BDIF SFQMJDBUJPO NBLFT JU BMTP SBUIFS TJNQMF. "O FYBNQMF JT BWBJMBCMF PO B TFQBSBUF QBHF.

560

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*U NJHIU CF VTFGVM UP SFBE UIF &)$BDIF NBOVBM UP HFU B CFUUFS VOEFSTUBOEJOH PG UIF $BNFM $BDIF SFQMJDBUJPO NFDIBOJTN.

"+ 22 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.4 5IF @I>PP: DPNQPOFOU CJOET CFBOT UP $BNFM NFTTBHF FYDIBOHFT. *U XPSLT JO UIF TBNF XBZ BT UIF #FBO DPNQPOFOU CVU JOTUFBE PG MPPLJOH VQ CFBOT GSPN B 3FHJTUSZ JU DSFBUFT UIF CFBO CBTFE PO UIF DMBTT OBNF. 41( CLOJ>Q
class:className[?options]

8IFSF @I>PP->JB JT UIF GVMMZ RVBMJGJFE DMBTT OBNF UP DSFBUF BOE VTF BT CFBO. .MQFLKP
->JB
method multiParameterArray

3VMB
String boolean

#BC>RIQ
null false

#BP@OFMQFLK
5IF NFUIPE OBNF UIBU CFBO XJMM CF JOWPLFE. *G OPU QSPWJEFE, $BNFM XJMM USZ UP QJDL UIF NFUIPE JUTFMG. *O DBTF PG BNCJHVJUZ BO FYDFQUJPO JT UISPXO. 4FF #FBO #JOEJOH GPS NPSF EFUBJMT. )PX UP USFBU UIF QBSBNFUFST XIJDI BSF QBTTFE GSPN UIF NFTTBHF CPEZ; JG JU JT true, UIF *O NFTTBHF CPEZ TIPVME CF BO BSSBZ PG QBSBNFUFST.

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 4PFKD :PV TJNQMZ VTF UIF @I>PP DPNQPOFOU KVTU BT UIF #FBO DPNQPOFOU CVU CZ TQFDJGZJOH UIF GVMMZ RVBMJGJFE DMBTTOBNF JOTUFBE. 'PS FYBNQMF UP VTF UIF MyFooBean ZPV IBWF UP EP BT GPMMPXT:

from("direct:start").to("class:org.apache.camel.component.bean.MyFooBean").to("mock:result");

:PV DBO BMTP TQFDJGZ XIJDI NFUIPE UP JOWPLF PO UIF MyFooBean, GPS FYBNQMF hello:

from("direct:start").to("class:org.apache.camel.component.bean.MyFooBean?method=hello").to("mock:resul

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

561

2$33(-& /1./$13($2 .- 3'$ "1$ 3$# (-23 -"$


*O UIF FOEQPJOU VSJ ZPV DBO TQFDJGZ QSPQFSUJFT UP TFU PO UIF DSFBUFE JOTUBODF, GPS FYBNQMF JG JU IBT B setPrefix NFUIPE:
from("direct:start") .to("class:org.apache.camel.component.bean.MyPrefixBean?prefix=Bye") .to("mock:result");

"OE ZPV DBO BMTP VTF UIF # TZOUBY UP SFGFS UP QSPQFSUJFT UP CF MPPLFE VQ JO UIF 3FHJTUSZ.
from("direct:start") .to("class:org.apache.camel.component.bean.MyPrefixBean?cool=#foo") .to("mock:result");

8IJDI XJMM MPPLVQ B CFBO GSPN UIF 3FHJTUSZ XJUI UIF JE foo BOE JOWPLF UIF setCool NFUIPE PO UIF DSFBUFE JOTUBODF PG UIF MyPrefixBean DMBTT. 2BB IPL ` ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE #FBO #FBO #JOEJOH #FBO *OUFHSBUJPO

".,$3# ".,/.-$-3
5IF @LJBQA: DPNQPOFOU JT B USBOTQPSU GPS XPSLJOH XJUI UIF KFUUZ JNQMFNFOUBUJPO PG UIF DPNFUE/CBZFVY QSPUPDPM. 6TJOH UIJT DPNQPOFOU JO DPNCJOBUJPO XJUI UIF EPKP UPPMLJU MJCSBSZ JU'T QPTTJCMF UP QVTI $BNFM NFTTBHFT EJSFDUMZ JOUP UIF CSPXTFS VTJOH BO "+"9 CBTFE NFDIBOJTN. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cometd</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

562

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2BB JLOB 4FF NPSF EFUBJMT BU UIF #FBO DPNQPOFOU BT UIF @I>PP DPNQPOFOU XPSLT JO NVDI UIF TBNF XBZ. 41( CLOJ>Q
cometd://host:port/channelName[?options]

5IF @E>KKBI->JB SFQSFTFOUT B UPQJD UIBU DBO CF TVCTDSJCFE UP CZ UIF $BNFM FOEQPJOUT. $U>JMIBP cometd://localhost:8080/service/mychannel cometds://localhost:8443/service/mychannel XIFSF cometds: SFQSFTFOUT BO 44- DPOGJHVSFE FOEQPJOU. 4FF UIJT CMPH FOUSZ CZ %BWJE (SFDP XIP DPOUSJCVUFE UIJT DPNQPOFOU UP "QBDIF $BNFM, GPS B GVMM TBNQMF. .MQFLKP
->JB
resourceBase

#BC>RIQ 5>IRB
c

#BP@OFMQFLK
5IF SPPU EJSFDUPSZ GPS UIF XFC SFTPVSDFT PS DMBTTQBUI. 6TF UIF QSPUPDPM GJMF: PS DMBTTQBUI: EFQFOEJOH JG ZPV XBOU UIBU UIF DPNQPOFOU MPBET UIF SFTPVSDF GSPN GJMF TZTUFN PS DMBTTQBUI. $MBTTQBUI JT SFRVJSFE GPS 04(* EFQMPZNFOU XIFSF UIF SFTPVSDFT BSF QBDLBHFE JO UIF KBS. /PUJDF UIJT PQUJPO IBT CFFO SFOBNFE UP baseResource GSPN ">JBI 2.7 POXBSET. ">JBI 2.7: 5IF SPPU EJSFDUPSZ GPS UIF XFC SFTPVSDFT PS DMBTTQBUI. 6TF UIF QSPUPDPM GJMF: PS DMBTTQBUI: EFQFOEJOH JG ZPV XBOU UIBU UIF DPNQPOFOU MPBET UIF SFTPVSDF GSPN GJMF TZTUFN PS DMBTTQBUI. $MBTTQBUI JT SFRVJSFE GPS 04(* EFQMPZNFOU XIFSF UIF SFTPVSDFT BSF QBDLBHFE JO UIF KBS 5IF TFSWFS TJEF QPMM UJNFPVU JO NJMMJTFDPOET. 5IJT JT IPX MPOH UIF TFSWFS XJMM IPME B SFDPOOFDU SFRVFTU CFGPSF SFTQPOEJOH. 5IF DMJFOU TJEF QPMM UJNFPVU JO NJMMJTFDPOET. )PX MPOH B DMJFOU XJMM XBJU CFUXFFO SFDPOOFDUT 5IF NBY DMJFOU TJEF QPMM UJNFPVU JO NJMMJTFDPOET. " DMJFOU XJMM CF SFNPWFE JG B DPOOFDUJPO JT OPU SFDFJWFE JO UIJT UJNF. 5IF DMJFOU TJEF QPMM UJNFPVU, JG NVMUJQMF DPOOFDUJPOT BSF EFUFDUFE GSPN UIF TBNF CSPXTFS. *G true, UIF TFSWFS XJMM BDDFQU +40/ XSBQQFE JO B DPNNFOU BOE XJMM HFOFSBUF +40/ XSBQQFE JO B DPNNFOU. 5IJT JT B EFGFODF BHBJOTU "KBY )JKBDLJOH. 0=OPOF, 1=JOGP, 2=EFCVH. ">JBI 2.9: 3FGFSFODF UP B org.apache.camel.util.jsse.SSLContextParameters JO UIF 3FHJTUSZ.c 5IJT SFGFSFODF PWFSSJEFT BOZ DPOGJHVSFE 44-$POUFYU1BSBNFUFST BU UIF DPNQPOFOU MFWFM.c 4FF 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ. ">JBI 2.10: *G true, UIF TFSWFS XJMM TVQQPSU GPS DSPTT-EPNBJO GJMUFSJOH ">JBI 2.10: 5IF PSJHJOT EPNBJO UIBU TVQQPSU UP DSPTT, JG UIF crosssOriginFilterOn JT true ">JBI 2.10: 5IF GJMUFS1BUI XJMM CF VTFE CZ UIF $SPTT0SJHJO'JMUFS, JG UIF crosssOriginFilterOn JT true

baseResource timeout interval maxInterval multiFrameInterval jsonCommented logLevel TTM$POUFYU1BSBNFUFST crossOriginFilterOn allowedOrigins filterPath

c 240000 0 30000 1500 true 1 c false * c

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... )FSF JT TPNF FYBNQMFT PO )PX UP QBTT UIF QBSBNFUFST

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

563

'PS GJMF (GPS XFCBQQ SFTPVSDFT MPDBUFE JO UIF 8FC "QQMJDBUJPO EJSFDUPSZ --> DPNFUE://MPDBMIPTU:8080 SFTPVSDF#BTF=GJMF./XFCBQQ 'PS DMBTTQBUI (XIFO CZ FYBNQMF UIF XFC SFTPVSDFT BSF QBDLBHFE JOTJEF UIF XFCBQQ GPMEFS --> DPNFUE://MPDBMIPTU:8080 SFTPVSDF#BTF=DMBTTQBUI:XFCBQQ RQEBKQF@>QFLK S>FI>?IB >P LC ">JBI 2.8 :PV DBO DPOGJHVSF DVTUPN SecurityPolicy BOE Extension'T UP UIF CometdComponent XIJDI BMMPXT ZPV UP VTF BVUIFOUJDBUJPO BT EPDVNFOUFE IFSF 2BQQFKD RM 22+ CLO "LJBQA "LJMLKBKQ

4PFKD QEB )22$ "LKCFDRO>QFLK 4QFIFQV


"T PG $BNFM 2.9, UIF $PNFUE DPNQPOFOU TVQQPSUT 44-/5-4 DPOGJHVSBUJPO UISPVHI UIF $BNFM +44& $POGJHVSBUJPO 6UJMJUZ.c 5IJT VUJMJUZ HSFBUMZ EFDSFBTFT UIF BNPVOU PG DPNQPOFOU TQFDJGJD DPEF ZPV OFFE UP XSJUF BOE JT DPOGJHVSBCMF BU UIF FOEQPJOU BOE DPNQPOFOU MFWFMT.c 5IF GPMMPXJOH FYBNQMFT EFNPOTUSBUF IPX UP VTF UIF VUJMJUZ XJUI UIF $PNFUE DPNQPOFOU. /OLDO>JJ>QF@ @LKCFDRO>QFLK LC QEB @LJMLKBKQ
KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/keystore.jks"); ksp.setPassword("keystorePassword"); KeyManagersParameters kmp = new KeyManagersParameters(); kmp.setKeyStore(ksp); kmp.setKeyPassword("keyPassword"); TrustManagersParameters tmp = new TrustManagersParameters(); tmp.setKeyStore(ksp); SSLContextParameters scp = new SSLContextParameters(); scp.setKeyManagers(kmp); scp.setTrustManagers(tmp); CometdComponent commetdComponent = getContext().getComponent("cometds", CometdComponent.class); commetdComponent.setSslContextParameters(scp);

564

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2MOFKD #2+ ?>PBA @LKCFDRO>QFLK LC BKAMLFKQ

... <camel:sslContextParameters id="sslContextParameters"> <camel:keyManagers keyPassword="keyPassword"> <camel:keyStore resource="/users/home/server/keystore.jks" password="keystorePassword"/> </camel:keyManagers> <camel:trustManagers> <camel:keyStore resource="/users/home/server/keystore.jks" password="keystorePassword"/> </camel:keyManagers> </camel:sslContextParameters>... ... <to uri="cometds://127.0.0.1:443/service/test?baseResource=file:./target/ test-classes/ webapp&timeout=240000&interval=0&maxInterval=30000&multiFrameInterval=1500&jsonCommented=true&logLevel

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

".-3$73 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.7 5IF @LKQBUQ DPNQPOFOU BMMPXT ZPV UP DSFBUF OFX $BNFM $PNQPOFOUT GSPN B $BNFM$POUFYU XJUI B OVNCFS PG SPVUFT XIJDI JT UIFO USFBUFE BT B CMBDL CPY, BMMPXJOH ZPV UP SFGFS UP UIF MPDBM FOEQPJOUT XJUIJO UIF DPNQPOFOU GSPN PUIFS $BNFM$POUFYUT. *U JT TJNJMBS UP UIF 3PVUFCPY DPNQPOFOU JO JEFB, UIPVHI UIF $POUFYU DPNQPOFOU USJFT UP CF SFBMMZ TJNQMF GPS FOE VTFST; KVTU B TJNQMF DPOWFOUJPO PWFS DPOGJHVSBUJPO BQQSPBDI UP SFGFS UP MPDBM FOEQPJOUT JOTJEF UIF $BNFM$POUFYU $PNQPOFOU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-context</artifactId> <version>x.x.x</version>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

565

<!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
context:camelContextId:localEndpointName[?options]

0S ZPV DBO PNJU UIF "DPOUFYU:" QSFGJY.


camelContextId:localEndpointName[?options]

` @>JBI"LKQBUQ(A JT UIF *% ZPV VTFE UP SFHJTUFS UIF $BNFM$POUFYU JOUP UIF 3FHJTUSZ. ` IL@>I$KAMLFKQ->JB DBO CF B WBMJE $BNFM 63* FWBMVBUFE XJUIJO UIF CMBDL CPY $BNFM$POUFYU. 0S JU DBO CF B MPHJDBM OBNF XIJDI JT NBQQFE UP BOZ MPDBM FOEQPJOUT. 'PS FYBNQMF JG ZPV MPDBMMZ IBWF FOEQPJOUT MJLF AFOB@Q:FKSLF@BP BOE PBA>:MRO@E>PB.OABOP JOTJEF B $BNFM$POUFYU PG JE PRMMIV"E>FK, UIFO ZPV DBO KVTU VTF UIF 63*T PRMMIV"E>FK:FKSLF@BP PS PRMMIV"E>FK:MRO@E>PB.OABOP UP PNJU UIF QIZTJDBM FOEQPJOU LJOE BOE VTF QVSF MPHJDBM 63*T. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... $U>JMIB *O UIJT FYBNQMF XF'MM DSFBUF B CMBDL CPY DPOUFYU, UIFO XF'MM VTF JU GSPN BOPUIFS $BNFM$POUFYU.

#BCFKFKD QEB @LKQBUQ @LJMLKBKQ


'JSTU ZPV OFFE UP DSFBUF B $BNFM$POUFYU, BEE TPNF SPVUFT JO JU, TUBSU JU BOE UIFO SFHJTUFS UIF $BNFM$POUFYU JOUP UIF 3FHJTUSZ (+/%*, 4QSJOH, (VJDF PS 04(J FUD). 5IJT DBO CF EPOF JO UIF VTVBM $BNFM XBZ GSPN UIJT UFTU DBTF (TFF UIF DSFBUF3FHJTUSZ() NFUIPE); UIJT FYBNQMF TIPXT +BWB BOE +/%* CFJOH VTFE...
// lets create our black box as a camel context and a set of routes DefaultCamelContext blackBox = new DefaultCamelContext(registry); blackBox.setName("blackBox"); blackBox.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { // receive purchase orders, lets process it in some way then send an invoice // to our invoice endpoint

566

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("direct:purchaseOrder"). setHeader("received").constant("true"). to("direct:invoice"); } }); blackBox.start(); registry.bind("accounts", blackBox);

/PUJDF JO UIF BCPWF SPVUF XF BSF VTJOH QVSF MPDBM FOEQPJOUT (AFOB@Q BOE PBA>). "MTP OPUF XF FYQPTF UIJT $BNFM$POUFYU VTJOH UIF >@@LRKQP *%. 8F DBO EP UIF TBNF UIJOH JO 4QSJOH WJB
<camelContext id="accounts" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:purchaseOrder"/> ... <to uri="direct:invoice"/> </route> </camelContext>

4PFKD QEB @LKQBUQ @LJMLKBKQ


5IFO JO BOPUIFS $BNFM$POUFYU XF DBO UIFO SFGFS UP UIJT "BDDPVOUT CMBDL CPY" CZ KVTU TFOEJOH UP >@@LRKQP:MRO@E>PB.OABO BOE DPOTVNJOH GSPN >@@LRKQP:FKSLF@B. *G ZPV QSFGFS UP CF NPSF WFSCPTF BOE FYQMJDJU ZPV DPVME VTF @LKQBUQ:>@@LRKQP:MRO@E>PB.OABO PS FWFO @LKQBUQ:>@@LRKQP:AFOB@Q://MRO@E>PB.OABO JG ZPV QSFGFS. #VU VTJOH MPHJDBM FOEQPJOU 63*T JT QSFGFSSFE BT JU IJEFT UIF JNQMFNFOUBUJPO EFUBJM BOE QSPWJEFT B TJNQMF MPHJDBM OBNJOH TDIFNF. 'PS FYBNQMF JG XF XJTI UP UIFO FYQPTF UIJT BDDPVOUT CMBDL CPY PO TPNF NJEEMFXBSF (PVUTJEF PG UIF CMBDL CPY) XF DBO EP UIJOHT MJLF...
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <!-- consume from an ActiveMQ into the black box --> <from uri="activemq:Accounts.PurchaseOrders"/> <to uri="accounts:purchaseOrders"/> </route> <route> <!-- lets send invoices from the black box to a different ActiveMQ Queue --> <from uri="accounts:invoice"/> <to uri="activemq:UK.Accounts.Invoices"/> </route> </camelContext>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

567

->JFKD BKAMLFKQP
" DPOUFYU DPNQPOFOU JOTUBODF DBO IBWF NBOZ QVCMJD JOQVU BOE PVUQVU FOEQPJOUT UIBU DBO CF BDDFTTFE GSPN PVUTJEF JU'T $BNFM$POUFYU. 8IFO UIFSF BSF NBOZ JU JT SFDPNNFOEFE UIBU ZPV VTF MPHJDBM OBNFT GPS UIFN UP IJEF UIF NJEEMFXBSF BT TIPXO BCPWF. )PXFWFS XIFO UIFSF JT POMZ POF JOQVU, PVUQVU PS FSSPS/EFBE MFUUFS FOEQPJOU JO B DPNQPOFOU XF SFDPNNFOE VTJOH UIF DPNNPO QPTJY TIFMM OBNFT FK, LRQ BOE BOO

"18/3. ".,/.-$-3 %.1 #(&(3 + 2(&- 341$2


S>FI>?IB >P LC ">JBI 2.3 8JUI $BNFM DSZQUPHSBQIJD FOEQPJOUT BOE +BWB'T $SZQUPHSBQIJD FYUFOTJPO JU JT FBTZ UP DSFBUF %JHJUBM 4JHOBUVSFT GPS &YDIBOHFT. $BNFM QSPWJEFT B QBJS PG GMFYJCMF FOEQPJOUT XIJDI HFU VTFE JO DPODFSU UP DSFBUF B TJHOBUVSF GPS BO FYDIBOHF JO POF QBSU PG UIF FYDIBOHF'T XPSLGMPX BOE UIFO WFSJGZ UIF TJHOBUVSF JO B MBUFS QBSU PG UIF XPSLGMPX. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-crypto</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

(KQOLAR@QFLK %JHJUBM TJHOBUVSFT NBLF VTF PG "TZNNFUSJD $SZQUPHSBQIJD UFDIOJRVFT UP TJHO NFTTBHFT. 'SPN B (WFSZ) IJHI MFWFM, UIF BMHPSJUINT VTF QBJST PG DPNQMJNFOUBSZ LFZT XJUI UIF TQFDJBM QSPQFSUZ UIBU EBUB FODSZQUFE XJUI POF LFZ DBO POMZ CF EFDSZQUFE XJUI UIF PUIFS. 0OF, UIF QSJWBUF LFZ, JT DMPTFMZ HVBSEFE BOE VTFE UP 'TJHO' UIF NFTTBHF XIJMF UIF PUIFS, QVCMJD LFZ, JT TIBSFE BSPVOE UP BOZPOF JOUFSFTUFE JO WFSJGZJOH UIF TJHOFE NFTTBHFT. .FTTBHFT BSF TJHOFE CZ VTJOH UIF QSJWBUF LFZ UP FODSZQUJOH B EJHFTU PG UIF NFTTBHF. 5IJT FODSZQUFE EJHFTU JT USBOTNJUUFE BMPOH XJUI UIF NFTTBHF. 0O UIF PUIFS TJEF UIF WFSJGJFS SFDBMDVMBUFT UIF NFTTBHF EJHFTU BOE VTFT UIF QVCMJD LFZ UP EFDSZQU UIF UIF EJHFTU JO UIF TJHOBUVSF. *G CPUI EJHFTUT NBUDI UIF WFSJGJFS LOPXT POMZ UIF IPMEFS PG UIF QSJWBUF LFZ DPVME IBWF DSFBUFE UIF TJHOBUVSF. $BNFM VTFT UIF 4JHOBUVSF TFSWJDF GSPN UIF +BWB $SZQUPHSBQIJD &YUFOTJPO UP EP BMM UIF IFBWZ DSZQUPHSBQIJD MJGUJOH SFRVJSFE UP DSFBUF FYDIBOHF TJHOBUVSFT. 5IF GPMMPXJOH BSF TPNF FYDFMMFOU SFTPVSDFT GPS FYQMBJOJOH UIF NFDIBOJDT PG $SZQUPHSBQIZ, .FTTBHF EJHFTUT BOE %JHJUBM 4JHOBUVSFT BOE IPX UP MFWFSBHF UIFN XJUI UIF +$&. #SVDF 4DIOFJFS'T "QQMJFE $SZQUPHSBQIZ #FHJOOJOH $SZQUPHSBQIZ XJUI +BWB CZ %BWJE )PPL 5IF FWFS JOTJHIUGVM 8JLJQFEJB %JHJUBM@TJHOBUVSFT

568

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( CLOJ>Q "T NFOUJPOFE $BNFM QSPWJEFT B QBJS PG DSZQUP FOEQPJOUT UP DSFBUF BOE WFSJGZ TJHOBUVSFT
crypto:sign:name[?options] crypto:verify:name[?options]

` crypto:sign DSFBUFT UIF TJHOBUVSF BOE TUPSFT JU JO UIF )FBEFS LFZFE CZ UIF DPOTUBOU Exchange.SIGNATURE, J.F. "CamelDigitalSignature". ` crypto:verify XJMM SFBE JO UIF DPOUFOUT PG UIJT IFBEFS BOE EP UIF WFSJGJDBUJPO DBMDVMBUJPO. *O PSEFS UP DPSSFDUMZ GVODUJPO, UIF TJHO BOE WFSJGZ QSPDFTT OFFET B QBJS PG LFZT UP CF TIBSFE, TJHOJOH SFRVJSJOH B PrivateKey BOE WFSJGZJOH B PublicKey (PS B Certificate DPOUBJOJOH POF). 6TJOH UIF +$& JU JT WFSZ TJNQMF UP HFOFSBUF UIFTF LFZ QBJST CVU JU JT VTVBMMZ NPTU TFDVSF UP VTF B ,FZ4UPSF UP IPVTF BOE TIBSF ZPVS LFZT. 5IF %4- JT WFSZ GMFYJCMF BCPVU IPX LFZT BSF TVQQMJFE BOE QSPWJEFT B OVNCFS PG NFDIBOJTNT. /PUF B crypto:sign FOEQPJOU JT UZQJDBMMZ EFGJOFE JO POF SPVUF BOE UIF DPNQMJNFOUBSZ crypto:verify JO BOPUIFS, UIPVHI GPS TJNQMJDJUZ JO UIF FYBNQMFT UIFZ BQQFBS POF BGUFS UIF PUIFS. *U HPFT XJUIPVU TBZJOH UIBU CPUI TJHOJOH BOE WFSJGZJOH TIPVME CF DPOGJHVSFE JEFOUJDBMMZ. .MQFLKP
->JB
algorithm alias bufferSize certificate keystore provider privateKey publicKey secureRandom password clearHeaders

3VMB
String String Integer Certificate KeyStore String PrivatKey PublicKey secureRandom char[] String

#BC>RIQ
DSA null 2048 null null null null null null null true

#BP@OFMQFLK
5IF OBNF PG UIF +$& 4JHOBUVSF BMHPSJUIN UIBU XJMM CF VTFE. "O BMJBT OBNF UIBU XJMM CF VTFE UP TFMFDU B LFZ GSPN UIF LFZTUPSF. UIF TJ[F PG UIF CVGGFS VTFE JO UIF TJHOBUVSF QSPDFTT. " $FSUJGJDBUF VTFE UP WFSJGZ UIF TJHOBUVSF PG UIF FYDIBOHF'T QBZMPBE. &JUIFS UIJT PS B 1VCMJD ,FZ JT SFRVJSFE. " SFGFSFODF UP B +$& ,FZTUPSF UIBU TUPSFT LFZT BOE DFSUJGJDBUFT VTFE UP TJHO BOE WFSJGZ. 5IF OBNF PG UIF +$& 4FDVSJUZ 1SPWJEFS UIBU TIPVME CF VTFE. 5IF QSJWBUF LFZ VTFE UP TJHO UIF FYDIBOHF'T QBZMPBE. 5IF QVCMJD LFZ VTFE UP WFSJGZ UIF TJHOBUVSF PG UIF FYDIBOHF'T QBZMPBE. " SFGFSFODF UP B SecureRandom PCKFDU UIBU XJMM CF VTFE UP JOJUJBMJ[F UIF 4JHOBUVSF TFSWJDF. 5IF QBTTXPSE GPS UIF LFZTUPSF. 3FNPWF DBNFM DSZQUP IFBEFST GSPN .FTTBHF BGUFS B WFSJGZ PQFSBUJPO (WBMVF DBO CF "true"/"false").

4PFKD

1) 1>T HBVP
5IF NPTU CBTJD XBZ UP XBZ UP TJHO BOE WFSJGZ BO FYDIBOHF JT XJUI B ,FZ1BJS BT GPMMPXT.
from("direct:keypair").to("crypto:sign://basic?privateKey=#myPrivateKey", "crypto:verify://basic?publicKey=#myPublicKey", "mock:result");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

569

5IF TBNF DBO CF BDIJFWFE XJUI UIF 4QSJOH 9.- &YUFOTJPOT VTJOH SFGFSFODFT UP LFZT
<route> <from uri="direct:keypair"/> <to uri="crypto:sign://basic?privateKey=#myPrivateKey" /> <to uri="crypto:verify://basic?publicKey=#myPublicKey" /> <to uri="mock:result"/> </route>

2) *BV2QLOBP >KA

IF>PBP.

5IF +$& QSPWJEFT B WFSZ WFSTBUJMF LFZTUPSF DPODFQU GPS IPVTJOH QBJST PG QSJWBUF LFZT BOE DFSUJGJDBUFT, LFFQJOH UIFN FODSZQUFE BOE QBTTXPSE QSPUFDUFE. 5IFZ DBO CF SFUSJFWFE CZ BQQMZJOH BO BMJBT UP UIF SFUSJFWBM "1*T. 5IFSF BSF B OVNCFS PG XBZT UP HFU LFZT BOE $FSUJGJDBUFT JOUP B LFZTUPSF, NPTU PGUFO UIJT JT EPOF XJUI UIF FYUFSOBM 'LFZUPPM' BQQMJDBUJPO. 5IJT JT B HPPE FYBNQMF PG VTJOH LFZUPPM UP DSFBUF B ,FZ4UPSF XJUI B TFMG TJHOFE $FSU BOE 1SJWBUF LFZ. 5IF FYBNQMFT VTF B ,FZTUPSF XJUI B LFZ BOE DFSU BMJBTFE CZ 'CPC'. 5IF QBTTXPSE GPS UIF LFZTUPSF BOE UIF LFZ JT 'MFUNFJO' 5IF GPMMPXJOH TIPXT IPX UP VTF B ,FZTUPSF WJB UIF 'MVFOU CVJMEFST, JU BMTP TIPXT IPX UP MPBE BOE JOJUJBMJ[F UIF LFZTUPSF.
from("direct:keystore").to("crypto:sign://keystore?keystore=#keystore&alias=bob&password=letmein", "crypto:verify://keystore?keystore=#keystore&alias=bob", "mock:result");

"HBJO JO 4QSJOH B SFG JT VTFE UP MPPLVQ BO BDUVBM LFZTUPSF JOTUBODF.


<route> <from uri="direct:keystore"/> <to uri="crypto:sign://keystore?keystore=#keystore&amp;alias=bob&amp;password=letmein" /> <to uri="crypto:verify://keystore?keystore=#keystore&amp;alias=bob" /> <to uri="mock:result"/> </route>

3) "E>KDFKD )"$ /OLSFABO >KA

IDLOFQEJ

$IBOHJOH UIF 4JHOBUVSF BMHPSJUIN PS UIF 4FDVSJUZ QSPWJEFS JT B TJNQMF NBUUFS PG TQFDJGZJOH UIFJS OBNFT. :PV XJMM OFFE UP BMTP VTF ,FZT UIBU BSF DPNQBUJCMF XJUI UIF BMHPSJUIN ZPV DIPPTF.
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(512, new SecureRandom()); keyPair = keyGen.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate();

570

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

PublicKey publicKey = keyPair.getPublic(); // we can set the keys explicitly on the endpoint instances. context.getEndpoint("crypto:sign://rsa?algorithm=MD5withRSA", DigitalSignatureEndpoint.class).setPrivateKey(privateKey); context.getEndpoint("crypto:verify://rsa?algorithm=MD5withRSA", DigitalSignatureEndpoint.class).setPublicKey(publicKey); from("direct:algorithm").to("crypto:sign://rsa?algorithm=MD5withRSA", "crypto:verify://rsa?algorithm=MD5withRSA", "mock:result");

from("direct:provider").to("crypto:sign://provider?privateKey=#myPrivateKey&provider=SUN", "crypto:verify://provider?publicKey=#myPublicKey&provider=SUN", "mock:result");

PS
<route> <from uri="direct:algorithm"/> <to uri="crypto:sign://rsa?algorithm=MD5withRSA&amp;privateKey=#rsaPrivateKey" /> <to uri="crypto:verify://rsa?algorithm=MD5withRSA&amp;publicKey=#rsaPublicKey" /> <to uri="mock:result"/> </route>

<route> <from uri="direct:provider"/> <to uri="crypto:sign://provider?privateKey=#myPrivateKey&amp;provider=SUN" /> <to uri="crypto:verify://provider?publicKey=#myPublicKey&amp;provider=SUN" /> <to uri="mock:result"/> </route>

4) "E>KDFKD QEB 2FDK>QROB ,BP>PDB 'B>ABO


*U NBZ CF EFTJSBCMF UP DIBOHF UIF NFTTBHF IFBEFS VTFE UP TUPSF UIF TJHOBUVSF. " EJGGFSFOU IFBEFS OBNF DBO CF TQFDJGJFE JO UIF SPVUF EFGJOJUJPO BT GPMMPXT

from("direct:signature-header").to("crypto:sign://another?privateKey=#myPrivateKey&signatureHeader=Ano "crypto:verify://another?publicKey=#myPublicKey&signatureHeader=AnotherDigitalSignature", "mock:result");

PS
<route> <from uri="direct:signature-header"/> <to

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

571

uri="crypto:sign://another?privateKey=#myPrivateKey&amp;signatureHeader=AnotherDigitalSignature" /> <to uri="crypto:verify://another?publicKey=#myPublicKey&amp;signatureHeader=AnotherDigitalSignature" /> <to uri="mock:result"/> </route>

5) "E>KDFKD QEB ?RCCBOPFWB


*O DBTF ZPV OFFE UP VQEBUF UIF TJ[F PG UIF CVGGFS...
from("direct:buffersize").to("crypto:sign://buffer?privateKey=#myPrivateKey&buffersize=1024", "crypto:verify://buffer?publicKey=#myPublicKey&buffersize=1024", "mock:result");

PS
<route> <from uri="direct:buffersize" /> <to uri="crypto:sign://buffer?privateKey=#myPrivateKey&amp;buffersize=1024" /> <to uri="crypto:verify://buffer?publicKey=#myPublicKey&amp;buffersize=1024" /> <to uri="mock:result"/> </route>

6) 2RMMIVFKD *BVP AVK>JF@>IIV.


8IFO VTJOH B 3FDJQJFOU MJTU PS TJNJMBS &*1 UIF SFDJQJFOU PG BO FYDIBOHF DBO WBSZ EZOBNJDBMMZ. 6TJOH UIF TBNF LFZ BDSPTT BMM SFDJQJFOUT NBZ CF OFJUIFS GFBTJCMF OPS EFTJSBCMF. *U XPVME CF VTFGVM UP CF BCMF UP TQFDJGZ TJHOBUVSF LFZT EZOBNJDBMMZ PO B QFS-FYDIBOHF CBTJT. 5IF FYDIBOHF DPVME UIFO CF EZOBNJDBMMZ FOSJDIFE XJUI UIF LFZ PG JUT UBSHFU SFDJQJFOU QSJPS UP TJHOJOH. 5P GBDJMJUBUF UIJT UIF TJHOBUVSF NFDIBOJTNT BMMPX GPS LFZT UP CF TVQQMJFE EZOBNJDBMMZ WJB UIF NFTTBHF IFBEFST CFMPX ` Exchange.SIGNATURE_PRIVATE_KEY, "CamelSignaturePrivateKey" ` Exchange.SIGNATURE_PUBLIC_KEY_OR_CERT, "CamelSignaturePublicKeyOrCert"
from("direct:headerkey-sign").to("crypto:sign://alias"); from("direct:headerkey-verify").to("crypto:verify://alias", "mock:result");

PS

572

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<route> <from uri="direct:headerkey-sign"/> <to uri="crypto:sign://headerkey" /> </route> <route> <from uri="direct:headerkey-verify"/> <to uri="crypto:verify://headerkey" /> <to uri="mock:result"/> </route>

&WFO CFUUFS XPVME CF UP EZOBNJDBMMZ TVQQMZ B LFZTUPSF BMJBT. "HBJO UIF BMJBT DBO CF TVQQMJFE JO B NFTTBHF IFBEFS ` Exchange.KEYSTORE_ALIAS, "CamelSignatureKeyStoreAlias"
from("direct:alias-sign").to("crypto:sign://alias?keystore=#keystore"); from("direct:alias-verify").to("crypto:verify://alias?keystore=#keystore", "mock:result");

PS
<route> <from uri="direct:alias-sign"/> <to uri="crypto:sign://alias?keystore=#keystore" /> </route> <route> <from uri="direct:alias-verify"/> <to uri="crypto:verify://alias?keystore=#keystore" /> <to uri="mock:result"/> </route>

5IF IFBEFS XPVME CF TFU BT GPMMPXT


Exchange unsigned = getMandatoryEndpoint("direct:alias-sign").createExchange(); unsigned.getIn().setBody(payload); unsigned.getIn().setHeader(DigitalSignatureConstants.KEYSTORE_ALIAS, "bob"); unsigned.getIn().setHeader(DigitalSignatureConstants.KEYSTORE_PASSWORD, "letmein".toCharArray()); template.send("direct:alias-sign", unsigned); Exchange signed = getMandatoryEndpoint("direct:alias-sign").createExchange(); signed.getIn().copyFrom(unsigned.getOut()); signed.getIn().setHeader(KEYSTORE_ALIAS, "bob"); template.send("direct:alias-verify", signed);

2BB

IPL ` $POGJHVSJOH $BNFM ` $PNQPOFOU ` &OEQPJOU


$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9 573

` (FUUJOH 4UBSUFE ` $SZQUP $SZQUP JT BMTP BWBJMBCMF BT B %BUB 'PSNBU

"7% ".,/.-$-3
5IF @UC: DPNQPOFOU QSPWJEFT JOUFHSBUJPO XJUI "QBDIF $9' GPS DPOOFDUJOH UP +"9-84 TFSWJDFT IPTUFE JO $9'. ` $9' $PNQPOFOU ` 63* GPSNBU ` 0QUJPOT ` 5IF EFTDSJQUJPOT PG UIF EBUBGPSNBUT ` )PX UP FOBCMF $9''T -PHHJOH0VU*OUFSDFQUPS JO .&44"(& NPEF ` %FTDSJQUJPO PG SFMBZ)FBEFST PQUJPO ` "WBJMBCMF POMZ JO 10+0 NPEF ` $IBOHFT TJODF 3FMFBTF 2.0 ` $POGJHVSF UIF $9' FOEQPJOUT XJUI 4QSJOH ` $POGJHVSJOH UIF $9' &OEQPJOUT XJUI "QBDIF "SJFT #MVFQSJOU. ` )PX UP NBLF UIF DBNFM-DYG DPNQPOFOU VTF MPH4K JOTUFBE PG KBWB.VUJM.MPHHJOH ` )PX UP MFU DBNFM-DYG SFTQPOTF NFTTBHF XJUI YNM TUBSU EPDVNFOU ` )PX UP DPOTVNF B NFTTBHF GSPN B DBNFM-DYG FOEQPJOU JO 10+0 EBUB GPSNBU ` )PX UP QSFQBSF UIF NFTTBHF GPS UIF DBNFM-DYG FOEQPJOU JO 10+0 EBUB GPSNBU ` )PX UP EFBM XJUI UIF NFTTBHF GPS B DBNFM-DYG FOEQPJOU JO 1":-0"% EBUB GPSNBU ` )PX UP HFU BOE TFU 40"1 IFBEFST JO 10+0 NPEF ` )PX UP HFU BOE TFU 40"1 IFBEFST JO 1":-0"% NPEF ` 40"1 IFBEFST BSF OPU BWBJMBCMF JO .&44"(& NPEF ` )PX UP UISPX B 40"1 'BVMU GSPN $BNFM ` )PX UP QSPQBHBUF B DBNFM-DYG FOEQPJOU'T SFRVFTU BOE SFTQPOTF DPOUFYU ` "UUBDINFOU 4VQQPSU ` 4USFBNJOH 4VQQPSU JO 1":-0"% NPEF ` 4FF "MTP .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cxf</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
cxf:bean:cxfEndpoint[?options]

574

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

8IFO VTJOH $9' BT B DPOTVNFS, UIF $9' #FBO $PNQPOFOU BMMPXT ZPV UP GBDUPS PVU IPX NFTTBHF QBZMPBET BSF SFDFJWFE GSPN UIFJS QSPDFTTJOH BT B 3&45GVM PS 40"1 XFC TFSWJDF. 5IJT IBT UIF QPUFOUJBM PG VTJOH B NVMUJUVEF PG USBOTQPSUT UP DPOTVNF XFC TFSWJDFT. 5IF CFBO DPNQPOFOU'T DPOGJHVSBUJPO JT BMTP TJNQMFS BOE QSPWJEFT UIF GBTUFTU NFUIPE UP JNQMFNFOU XFC TFSWJDFT VTJOH $BNFM BOE $9'.

8IFO VTJOH $9' JO TUSFBNJOH NPEFT (TFF %BUB'PSNBU PQUJPO), UIFO BMTP SFBE BCPVU 4USFBN DBDIJOH.

"7% ABMBKABK@FBP *G ZPV XBOU UP MFBSO BCPVU $9' EFQFOEFODJFT ZPV DBO DIFDLPVU UIF WHICH-JARS UFYU GJMF. 8IFSF @UC$KAMLFKQ SFQSFTFOUT B CFBO *% UIBU SFGFSFODFT B CFBO JO UIF 4QSJOH CFBO SFHJTUSZ. 8JUI UIJT 63* GPSNBU, NPTU PG UIF FOEQPJOU EFUBJMT BSF TQFDJGJFE JO UIF CFBO EFGJOJUJPO.
cxf://someAddress[?options]

8IFSF PLJB AAOBPP TQFDJGJFT UIF $9' FOEQPJOU'T BEESFTT. 8JUI UIJT 63* GPSNBU, NPTU PG UIF FOEQPJOU EFUBJMT BSF TQFDJGJFE VTJOH PQUJPOT. 'PS FJUIFS TUZMF BCPWF, ZPV DBO BQQFOE PQUJPOT UP UIF 63* BT GPMMPXT:
cxf:bean:cxfEndpoint?wsdlURL=wsdl/hello_world.wsdl&dataFormat=PAYLOAD

.MQFLKP
->JB
wsdlURL

1BNRFOBA
/P

#BP@OFMQFLK
5IF MPDBUJPO PG UIF 84%-. *U JT PCUBJOFE GSPN FOEQPJOU BEESFTT CZ EFGBVMU. Example: GJMF://MPDBM/XTEM/IFMMP.XTEM PS wsdl/hello.wsdl

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

575

serviceClass

:FT

5IF OBNF PG UIF 4&* (4FSWJDF &OEQPJOU *OUFSGBDF) DMBTT. 5IJT DMBTT DBO IBWF, CVU EPFT OPU SFRVJSF, +43181 BOOPUBUJPOT. 5IJT PQUJPO JT POMZ SFRVJSFE CZ 10+0 NPEF. *G UIF XTEM63- PQUJPO JT QSPWJEFE, TFSWJDF$MBTT JT OPU SFRVJSFE GPS 1":-0"% BOE .&44"(& NPEF. 8IFO XTEM63- PQUJPO JT VTFE XJUIPVU TFSWJDF$MBTT, UIF TFSWJDF/BNF BOE QPSU/BNF (FOEQPJOU/BNF GPS 4QSJOH DPOGJHVSBUJPO) PQUJPOT ,423 CF QSPWJEFE. *U JT QPTTJCMF UP VTF # OPUBUJPO UP SFGFSFODF B serviceClass PCKFDU JOTUBODF GSPN UIF SFHJTUSZ. &.H. serviceClass=#beanName. 5IF serviceClass GPS B $9' QSPEVDFS (UIBU JT, UIF to FOEQPJOU) TIPVME CF B +BWB JOUFSGBDF. 2FK@B 2.8, JU JT QPTTJCMF UP PNJU CPUI XTEM63- BOE TFSWJDF$MBTT PQUJPOT GPS 1":-0"% BOE .&44"(& NPEF. 8IFO UIFZ BSF PNJUUFE, BSCJUSBSZ 9.- FMFNFOUT DBO CF QVU JO $YG1BZMPBE'T CPEZ JO 1":-0"% NPEF UP GBDJMJUBUF $9' %JTQBUDI .PEF. 1MFBTF CF BEWJTFE UIBU UIF OBCBOBK@BA L?GB@Q @>KKLQ ?B > /OLUV (4QSJOH "01 1SPYZ JT 0,) BT JU SFMJFT PO Object.getClass().getName() NFUIPE GPS OPO 4QSJOH "01 1SPYZ. Example: org.apache.camel.Hello 5IF TFSWJDF OBNF UIJT TFSWJDF JT JNQMFNFOUJOH, JU NBQT UP UIF wsdl:service@name.

serviceName

/P

1BNRFOBA GPS DBNFM-DYG DPOTVNFS TJODF DBNFM-2.2.0 PS JG NPSF UIBO POF serviceName JT QSFTFOU JO 84%-. Example: \IUUQ: //PSH.BQBDIF.DBNFM^4FSWJDF/BNF 5IF QPSU OBNF UIJT TFSWJDF JT JNQMFNFOUJOH, JU NBQT UP UIF wsdl:port@name.

portName

/P

1BNRFOBA GPS DBNFM-DYG DPOTVNFS TJODF DBNFM-2.2.0 PS JG NPSF UIBO POF portName JT QSFTFOU VOEFS serviceName. Example: \IUUQ: //PSH.BQBDIF.DBNFM^1PSU/BNF 5IF EBUB UZQF NFTTBHFT TVQQPSUFE CZ UIF $9' FOEQPJOU.

dataFormat

/P

Default: POJO Example: POJO, PAYLOAD, MESSAGE 1MFBTF TFF UIF #BP@OFMQFLK LC relayHeaders LMQFLK TFDUJPO GPS UIJT PQUJPO. 4IPVME B $9' FOEQPJOU SFMBZ IFBEFST BMPOH UIF SPVUF. $VSSFOUMZ POMZ BWBJMBCMF XIFO dataFormat=POJO

relayHeaders

/P Default: true Example: true, false 8IJDI LJOE PG PQFSBUJPO UIBU $9' FOEQPJOU QSPEVDFS XJMM JOWPLF

wrapped

/P

Default: false Example: true, false -BT FK 2.5.0 5IF 84%- TUZMF UIBU EFTDSJCFT IPX QBSBNFUFST BSF SFQSFTFOUFE JO UIF 40"1 CPEZ. *G UIF WBMVF JT GBMTF, $9' XJMM DIPTF UIF EPDVNFOU-MJUFSBM VOXSBQQFE TUZMF, *G UIF WBMVF JT USVF, $9' XJMM DIPTF UIF EPDVNFOU-MJUFSBM XSBQQFE TUZMF Default: Null Example: true, false 8JMM TFU UIF EFGBVMU CVT XIFO $9' FOEQPJOU DSFBUF B CVT CZ JUTFMG

wrappedStyle

/P

setDefaultBus

/P

Default: false Example: true, false " EFGBVMU CVT DSFBUFE CZ $9' #VT 'BDUPSZ. 6TF # OPUBUJPO UP SFGFSFODF B CVT PCKFDU GSPN UIF SFHJTUSZ. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.cxf.Bus. Example: bus=#busName 6TF # OPUBUJPO UP SFGFSFODF B $9' CJOEJOH PCKFDU GSPN UIF SFHJTUSZ. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.camel.component.cxf.CxfBinding (VTF BO JOTUBODF PG org.apache.camel.component.cxf.DefaultCxfBinding). Example: cxfBinding=#bindingName 6TF # OPUBUJPO UP SFGFSFODF B IFBEFS GJMUFS TUSBUFHZ PCKFDU GSPN UIF SFHJTUSZ. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.camel.spi.HeaderFilterStrategy (VTF BO JOTUBODF PG org.apache.camel.component.cxf.CxfHeaderFilterStrategy). Example: headerFilterStrategy=#strategyName /FX JO 2.3. 5IJT PQUJPO FOBCMFT $9' -PHHJOH 'FBUVSF XIJDI XSJUFT JOCPVOE BOE PVUCPVOE 40"1 NFTTBHFT UP MPH.

bus

/P

cxfBinding

/P

headerFilterStrategy

/P

loggingFeatureEnabled

/P

Default: false Example: loggingFeatureEnabled=true /FX JO 2.4, UIJT PQUJPO XJMM TFU UIF EFGBVMU PQFSBUJPO/BNF UIBU XJMM CF VTFE CZ UIF $YG1SPEVDFS XIJDI JOWPLFT UIF SFNPUF TFSWJDF.

defaultOperationName

/P Default: null Example: defaultOperationName=greetMe

576

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

/FX JO 2.4. 5IJT PQUJPO XJMM TFU UIF EFGBVMU PQFSBUJPO/BNFTQBDF UIBU XJMM CF VTFE CZ UIF $YG1SPEVDFS XIJDI JOWPLFT UIF SFNPUF TFSWJDF. defaultOperationNamespace /P Default: null Example: defaultOperationNamespace=http://apache.org/hello_world_soap_http /FX JO 2.5. 5IJT PQUJPO XJMM MFU DYG FOEQPJOU EFDJEF UP VTF TZOD PS BTZOD "1* UP EP UIF VOEFSMZJOH XPSL. 5IF EFGBVMU WBMVF JT GBMTF XIJDI NFBOT DBNFM-DYG FOEQPJOU XJMM USZ UP VTF BTZOD "1* CZ EFGBVMU. synchronous /P Default: false Example: TZODISPOPVT=USVF /FX JO 2.5. 5IJT PQUJPO DBO PWFSSJEF UIF FOEQPJOU6SM UIBU QVCMJTIFE GSPN UIF 84%- XIJDI DBO CF BDDFTTFE XJUI TFSWJDF BEESFTT VSM QMVT XTEM. publishedEndpointUrl /P Default: null Example: QVCMTIFE&OEQPJOU6SM=IUUQ://FYBNQMF.DPN/TFSWJDF properties.XXX /P ">JBI 2.8: "MMPXT UP TFU DVTUPN QSPQFSUJFT UP $9' JO UIF FOEQPJOU VSJ. 'PS FYBNQMF TFUUJOH properties.mtom-enabled=true UP FOBCMF .50.. /FX JO 2.8.2. 5IJT PQUJPO DPOUSPMT XIFUIFS UIF $9' DPNQPOFOU, XIFO SVOOJOH JO 1":-0"% NPEF (TFF CFMPX), XJMM %0. QBSTF UIF JODPNJOH NFTTBHFT JOUP %0. &MFNFOUT PS LFFQ UIF QBZMPBE BT B KBWBY.YNM.USBOTGPSN.4PVSDF PCKFDU UIBU XPVME BMMPX TUSFBNJOH JO TPNF DBTFT. /FX JO 2.11. 5IJT PQUJPO DPOUSPMT XIFUIFS UIF 1IBTF*OUFSDFQUPS$IBJO TLJQT MPHHJOH UIF 'BVMU UIBU JU DBUDIFT.

allowStreaming skipFaultLogging

/P /P

5IF serviceName BOE portName BSF 2/BNFT, TP JG ZPV QSPWJEF UIFN CF TVSF UP QSFGJY UIFN XJUI UIFJS \OBNFTQBDF^ BT TIPXO JO UIF FYBNQMFT BCPWF.

3EB ABP@OFMQFLKP LC QEB A>Q>CLOJ>QP


#>Q>%LOJ>Q
POJO PAYLOAD

#BP@OFMQFLK
10+0T (1MBJO PME +BWB PCKFDUT) BSF UIF +BWB QBSBNFUFST UP UIF NFUIPE CFJOH JOWPLFE PO UIF UBSHFU TFSWFS. #PUI 1SPUPDPM BOE -PHJDBM +"9-84 IBOEMFST BSF TVQQPSUFE. PAYLOAD JT UIF NFTTBHF QBZMPBE (UIF DPOUFOUT PG UIF soap:body) BGUFS NFTTBHF DPOGJHVSBUJPO JO UIF $9' FOEQPJOU JT BQQMJFE. 0OMZ 1SPUPDPM +"984 IBOEMFS JT TVQQPSUFE. -PHJDBM +"9-84 IBOEMFS JT OPU TVQQPSUFE. MESSAGE JT UIF SBX NFTTBHF UIBU JT SFDFJWFE GSPN UIF USBOTQPSU MBZFS. *U JT OPU TVQQPTF UP UPVDI PS DIBOHF 4USFBN, TPNF PG UIF $9' JOUFSDFQUPS XJMM CF SFNPWFE JG ZPV BSF VTJOH UIJT LJOE PG %BUB'PSNBU TP ZPV DBO'U TFF BOZ TPBQ IFBEFST BGUFS UIF DBNFM-DYG DPOTVNFS BOE +"9-84 IBOEMFS JT OPU TVQQPSUFE. /FX JO ">JBI 2.8.2, CXF_MESSAGE BMMPXT GPS JOWPLJOH UIF GVMM DBQBCJMJUJFT PG $9' JOUFSDFQUPST CZ DPOWFSUJOH UIF NFTTBHF GSPN UIF USBOTQPSU MBZFS JOUP B SBX 40"1 NFTTBHF

MESSAGE

CXF_MESSAGE

:PV DBO EFUFSNJOF UIF EBUB GPSNBU NPEF PG BO FYDIBOHF CZ SFUSJFWJOH UIF FYDIBOHF QSPQFSUZ, CamelCXFDataFormat. 5IF FYDIBOHF LFZ DPOTUBOU JT EFGJOFE JO org.apache.camel.component.cxf.CxfConstants.DATA_FORMAT_PROPERTY. 'LT QL BK>?IB "7%'P +LDDFKD.RQ(KQBO@BMQLO FK ,$22 &$ JLAB $9''T LoggingOutInterceptor PVUQVUT PVUCPVOE NFTTBHF UIBU HPFT PO UIF XJSF UP MPHHJOH TZTUFN (+BWB 6UJM -PHHJOH). 4JODF UIF LoggingOutInterceptor JT JO PRE_STREAM QIBTF (CVU PRE_STREAM QIBTF JT SFNPWFE JO MESSAGE NPEF), ZPV IBWF UP DPOGJHVSF LoggingOutInterceptor UP CF SVO EVSJOH UIF WRITE QIBTF. 5IF GPMMPXJOH JT BO FYBNQMF.
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"> <!-- it really should have been user-prestream but CXF does have such phase! --> <constructor-arg value="target/write"/> </bean>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

577

<cxf:cxfEndpoint id="serviceEndpoint" address="http://localhost:${CXFTestSupport.port2}/LoggingInterceptorInMessageModeTest/ helloworld" serviceClass="org.apache.camel.component.cxf.HelloService"> <cxf:outInterceptors> <ref bean="loggingOutInterceptor"/> </cxf:outInterceptors> <cxf:properties> <entry key="dataFormat" value="MESSAGE"/> </cxf:properties> </cxf:cxfEndpoint>

#BP@OFMQFLK LC OBI>V'B>ABOP LMQFLK


5IFSF BSF in-band BOE out-of-band PO-UIF-XJSF IFBEFST GSPN UIF QFSTQFDUJWF PG B +"984 84%--GJSTU EFWFMPQFS. 5IF in-band IFBEFST BSF IFBEFST UIBU BSF FYQMJDJUMZ EFGJOFE BT QBSU PG UIF 84%- CJOEJOH DPOUSBDU GPS BO FOEQPJOU TVDI BT 40"1 IFBEFST. 5IF out-of-band IFBEFST BSF IFBEFST UIBU BSF TFSJBMJ[FE PWFS UIF XJSF, CVU BSF OPU FYQMJDJUMZ QBSU PG UIF 84%- CJOEJOH DPOUSBDU. )FBEFST SFMBZJOH/GJMUFSJOH JT CJ-EJSFDUJPOBM. 8IFO B SPVUF IBT B $9' FOEQPJOU BOE UIF EFWFMPQFS OFFET UP IBWF PO-UIF-XJSF IFBEFST, TVDI BT 40"1 IFBEFST, CF SFMBZFE BMPOH UIF SPVUF UP CF DPOTVNFE TBZ CZ BOPUIFS +"984 FOEQPJOU, UIFO relayHeaders TIPVME CF TFU UP true, XIJDI JT UIF EFGBVMU WBMVF. S>FI>?IB LKIV FK /.). JLAB 5IF relayHeaders=true FYQSFTT BO JOUFOU UP SFMBZ UIF IFBEFST. 5IF BDUVBM EFDJTJPO PO XIFUIFS B HJWFO IFBEFS JT SFMBZFE JT EFMFHBUFE UP B QMVHHBCMF JOTUBODF UIBU JNQMFNFOUT UIF MessageHeadersRelay JOUFSGBDF. " DPODSFUF JNQMFNFOUBUJPO PG MessageHeadersRelay XJMM CF DPOTVMUFE UP EFDJEF JG B IFBEFS OFFET UP CF SFMBZFE PS OPU. 5IFSF JT BMSFBEZ BO JNQMFNFOUBUJPO PG SoapMessageHeadersRelay XIJDI CJOET JUTFMG UP XFMM-LOPXO 40"1 OBNF TQBDFT. $VSSFOUMZ POMZ PVU-PG-CBOE IFBEFST BSF GJMUFSFE, BOE JO-CBOE IFBEFST XJMM BMXBZT CF SFMBZFE XIFO relayHeaders=true. *G UIFSF JT B IFBEFS PO UIF XJSF, XIPTF OBNF TQBDF JT VOLOPXO UP UIF SVOUJNF, UIFO B GBMM CBDL DefaultMessageHeadersRelay XJMM CF VTFE, XIJDI TJNQMZ BMMPXT BMM IFBEFST UP CF SFMBZFE. 5IF relayHeaders=false TFUUJOH BTTFSUT UIBU BMM IFBEFST JO-CBOE BOE PVU-PG-CBOE XJMM CF ESPQQFE. :PV DBO QMVHJO ZPVS PXO MessageHeadersRelay JNQMFNFOUBUJPOT PWFSSJEJOH PS BEEJOH BEEJUJPOBM POFT UP UIF MJTU PG SFMBZT. *O PSEFS UP PWFSSJEF B QSFMPBEFE SFMBZ JOTUBODF KVTU NBLF

578

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

TVSF UIBU ZPVS MessageHeadersRelay JNQMFNFOUBUJPO TFSWJDFT UIF TBNF OBNF TQBDFT BT UIF POF ZPV MPPLJOH UP PWFSSJEF. "MTP OPUF, UIBU UIF PWFSSJEJOH SFMBZ IBT UP TFSWJDF BMM PG UIF OBNF TQBDFT BT UIF POF ZPV MPPLJOH UP PWFSSJEF, PS FMTF B SVOUJNF FYDFQUJPO PO SPVUF TUBSU VQ XJMM CF UISPXO BT UIJT XPVME JOUSPEVDF BO BNCJHVJUZ JO OBNF TQBDFT UP SFMBZ JOTUBODF NBQQJOHT.
<cxf:cxfEndpoint ...> <cxf:properties> <entry key="org.apache.camel.cxf.message.headers.relays"> <list> <ref bean="customHeadersRelay"/> </list> </entry> </cxf:properties> </cxf:cxfEndpoint> <bean id="customHeadersRelay" class="org.apache.camel.component.cxf.soap.headers.CustomHeadersRelay"/>

5BLF B MPPL BU UIF UFTUT UIBU TIPX IPX ZPV'E CF BCMF UP SFMBZ/ESPQ IFBEFST IFSF: IUUQT://TWO.BQBDIF.PSH/SFQPT/BTG/DBNFM/CSBODIFT/DBNFM-1.Y/DPNQPOFOUT/DBNFM-DYG/TSD/UFTU/ KBWB/PSH/BQBDIF/DBNFM/DPNQPOFOU/DYG/TPBQ/IFBEFST/$YG.FTTBHF)FBEFST3FMBZ5FTU.KBWB "E>KDBP PFK@B 1BIB>PB 2.0 ` POJO BOE PAYLOAD NPEFT BSF TVQQPSUFE. *O POJO NPEF, POMZ PVU-PG-CBOE NFTTBHF IFBEFST BSF BWBJMBCMF GPS GJMUFSJOH BT UIF JO-CBOE IFBEFST IBWF CFFO QSPDFTTFE BOE SFNPWFE GSPN IFBEFS MJTU CZ $9'. 5IF JO-CBOE IFBEFST BSF JODPSQPSBUFE JOUP UIF MessageContentList JO 10+0 NPEF. 5IF camel-cxf DPNQPOFOU EPFT NBLF BOZ BUUFNQU UP SFNPWF UIF JO-CBOE IFBEFST GSPN UIF MessageContentList. *G GJMUFSJOH PG JO-CBOE IFBEFST JT SFRVJSFE, QMFBTF VTF PAYLOAD NPEF PS QMVH JO B (QSFUUZ TUSBJHIUGPSXBSE) $9' JOUFSDFQUPS/+"984 )BOEMFS UP UIF $9' FOEQPJOU. ` 5IF .FTTBHF )FBEFS 3FMBZ NFDIBOJTN IBT CFFO NFSHFE JOUP CxfHeaderFilterStrategy. 5IF relayHeaders PQUJPO, JUT TFNBOUJDT, BOE EFGBVMU WBMVF SFNBJO UIF TBNF, CVU JU JT B QSPQFSUZ PG CxfHeaderFilterStrategy. )FSF JT BO FYBNQMF PG DPOGJHVSJOH JU.
<bean id="dropAllMessageHeadersStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy"> <!-- Set relayHeaders to false to drop all SOAP headers --> <property name="relayHeaders" value="false"/> </bean>

5IFO, ZPVS FOEQPJOU DBO SFGFSFODF UIF CxfHeaderFilterStrategy.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

579

<route> <from uri="cxf:bean:routerNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/> <to uri="cxf:bean:serviceNoRelayEndpoint?headerFilterStrategy=#dropAllMessageHeadersStrategy"/> </route>

` 5IF MessageHeadersRelay JOUFSGBDF IBT DIBOHFE TMJHIUMZ BOE IBT CFFO SFOBNFE UP MessageHeaderFilter. *U JT B QSPQFSUZ PG CxfHeaderFilterStrategy. )FSF JT BO FYBNQMF PG DPOGJHVSJOH VTFS EFGJOFE .FTTBHF )FBEFS 'JMUFST:
<bean id="customMessageFilterStrategy" class="org.apache.camel.component.cxf.common.header.CxfHeaderFilterStrategy"> <property name="messageHeaderFilters"> <list> <!-- SoapMessageHeaderFilter is the built in filter. It can be removed by omitting it. --> <bean class="org.apache.camel.component.cxf.common.header.SoapMessageHeaderFilter"/> <!-- Add custom filter here --> <bean class="org.apache.camel.component.cxf.soap.headers.CustomHeaderFilter"/> </list> </property> </bean>

` 0UIFS UIBO relayHeaders, UIFSF BSF OFX QSPQFSUJFT UIBU DBO CF DPOGJHVSFE JO CxfHeaderFilterStrategy.
->JB
relayHeaders

1BNRFOBA
/P

#BP@OFMQFLK
"MM NFTTBHF IFBEFST XJMM CF QSPDFTTFE CZ .FTTBHF )FBEFS 'JMUFST Type: boolean Default: true "MM NFTTBHF IFBEFST XJMM CF QSPQBHBUFE (XJUIPVU QSPDFTTJOH CZ .FTTBHF )FBEFS 'JMUFST)

relayAllMessageHeaders

/P

Type: boolean Default: false *G UXP GJMUFST PWFSMBQ JO BDUJWBUJPO OBNFTQBDF, UIF QSPQFSUZ DPOUSPM IPX JU TIPVME CF IBOEMFE. *G UIF WBMVF JT true, MBTU POF XJOT. *G UIF WBMVF JT false, JU XJMM UISPX BO FYDFQUJPO

allowFilterNamespaceClash

/P Type: boolean Default: false

"LKCFDROB QEB "7% BKAMLFKQP TFQE 2MOFKD :PV DBO DPOGJHVSF UIF $9' FOEQPJOU XJUI UIF 4QSJOH DPOGJHVSBUJPO GJMF TIPXO CFMPX, BOE ZPV DBO BMTP FNCFE UIF FOEQPJOU JOUP UIF camelContext UBHT. 8IFO ZPV BSF JOWPLJOH UIF TFSWJDF FOEQPJOU, ZPV DBO TFU UIF operationName BOE operationNamespace IFBEFST UP FYQMJDJUMZ TUBUF XIJDI PQFSBUJPO ZPV BSF DBMMJOH.

580

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/ camel-cxf.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/ spring/camel-spring.xsd"> <cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:9003/ CamelContext/RouterPort" serviceClass="org.apache.hello_world_soap_http.GreeterImpl"/> <cxf:cxfEndpoint id="serviceEndpoint" address="http://localhost:9000/ SoapContext/SoapPort" wsdlURL="testutils/hello_world.wsdl" serviceClass="org.apache.hello_world_soap_http.Greeter" endpointName="s:SoapPort" serviceName="s:SOAPService" xmlns:s="http://apache.org/hello_world_soap_http" /> <camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/ spring"> <route> <from uri="cxf:bean:routerEndpoint" /> <to uri="cxf:bean:serviceEndpoint" /> </route> </camelContext> </beans>

#F TVSF UP JODMVEF UIF +"9-84 schemaLocation BUUSJCVUF TQFDJGJFE PO UIF SPPU CFBOT FMFNFOU. 5IJT BMMPXT $9' UP WBMJEBUF UIF GJMF BOE JT SFRVJSFE. "MTP OPUF UIF OBNFTQBDF EFDMBSBUJPOT BU UIF FOE PG UIF <cxf:cxfEndpoint/> UBH--UIFTF BSF SFRVJSFE CFDBVTF UIF DPNCJOFE \namespace}localName TZOUBY JT QSFTFOUMZ OPU TVQQPSUFE GPS UIJT UBH'T BUUSJCVUF WBMVFT. 5IF cxf:cxfEndpoint FMFNFOU TVQQPSUT NBOZ BEEJUJPOBM BUUSJCVUFT:
->JB
PortName serviceName wsdlURL bindingId address bus serviceClass

5>IRB
5IF FOEQPJOU OBNF UIJT TFSWJDF JT JNQMFNFOUJOH, JU NBQT UP UIF wsdl:port@name. *O UIF GPSNBU PG ns:PORT_NAME XIFSF ns JT B OBNFTQBDF QSFGJY WBMJE BU UIJT TDPQF. 5IF TFSWJDF OBNF UIJT TFSWJDF JT JNQMFNFOUJOH, JU NBQT UP UIF wsdl:service@name. *O UIF GPSNBU PG ns:SERVICE_NAME XIFSF ns JT B OBNFTQBDF QSFGJY WBMJE BU UIJT TDPQF. 5IF MPDBUJPO PG UIF 84%-. $BO CF PO UIF DMBTTQBUI, GJMF TZTUFN, PS CF IPTUFE SFNPUFMZ. 5IF bindingId GPS UIF TFSWJDF NPEFM UP VTF. 5IF TFSWJDF QVCMJTI BEESFTT. 5IF CVT OBNF UIBU XJMM CF VTFE JO UIF +"9-84 FOEQPJOU. 5IF DMBTT OBNF PG UIF 4&* (4FSWJDF &OEQPJOU *OUFSGBDF) DMBTT XIJDI DPVME IBWF +43181 BOOPUBUJPO PS OPU.

*U BMTP TVQQPSUT NBOZ DIJME FMFNFOUT:


->JB
cxf:inInterceptors cxf:inFaultInterceptors

5>IRB
5IF JODPNJOH JOUFSDFQUPST GPS UIJT FOEQPJOU. " MJTU PG <bean> PS <ref>. 5IF JODPNJOH GBVMU JOUFSDFQUPST GPS UIJT FOEQPJOU. " MJTU PG <bean> PS <ref>.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

581

cxf:outInterceptors cxf:outFaultInterceptors cxf:properties cxf:handlers cxf:dataBinding cxf:binding cxf:features cxf:schemaLocations cxf:serviceFactory

5IF PVUHPJOH JOUFSDFQUPST GPS UIJT FOEQPJOU. " MJTU PG <bean> PS <ref>. 5IF PVUHPJOH GBVMU JOUFSDFQUPST GPS UIJT FOEQPJOU. " MJTU PG <bean> PS <ref>. " QSPQFSUJFT NBQ XIJDI TIPVME CF TVQQMJFE UP UIF +"9-84 FOEQPJOU. 4FF CFMPX. " +"9-84 IBOEMFS MJTU XIJDI TIPVME CF TVQQMJFE UP UIF +"9-84 FOEQPJOU. 4FF CFMPX. :PV DBO TQFDJGZ UIF XIJDI DataBinding XJMM CF VTF JO UIF FOEQPJOU. 5IJT DBO CF TVQQMJFE VTJOH UIF 4QSJOH <bean class="MyDataBinding"/> TZOUBY. :PV DBO TQFDJGZ UIF BindingFactory GPS UIJT FOEQPJOU UP VTF. 5IJT DBO CF TVQQMJFE VTJOH UIF 4QSJOH <bean class="MyBindingFactory"/> TZOUBY. 5IF GFBUVSFT UIBU IPME UIF JOUFSDFQUPST GPS UIJT FOEQPJOU. " MJTU PG \\<CFBO>^^T PS \\<SFG>^^T 5IF TDIFNB MPDBUJPOT GPS FOEQPJOU UP VTF. " MJTU PG \\<TDIFNB-PDBUJPO>^^T 5IF TFSWJDF GBDUPSZ GPS UIJT FOEQPJOU UP VTF. 5IJT DBO CF TVQQMJFE VTJOH UIF 4QSJOH <bean class="MyServiceFactory"/> TZOUBY

:PV DBO GJOE NPSF BEWBODFE FYBNQMFT XIJDI TIPX IPX UP QSPWJEF JOUFSDFQUPST , QSPQFSUJFT BOE IBOEMFST IFSF: IUUQ://DXJLJ.BQBDIF.PSH/$9'20%0$/KBY-XT-DPOGJHVSBUJPO.IUNM -.3$ :PV DBO VTF DYG:QSPQFSUJFT UP TFU UIF DBNFM-DYG FOEQPJOU'T EBUB'PSNBU BOE TFU%FGBVMU#VT QSPQFSUJFT GSPN TQSJOH DPOGJHVSBUJPO GJMF.
<cxf:cxfEndpoint id="testEndpoint" address="http://localhost:9000/router" serviceClass="org.apache.camel.component.cxf.HelloService" endpointName="s:PortName" serviceName="s:ServiceName" xmlns:s="http://www.example.com/test"> <cxf:properties> <entry key="dataFormat" value="MESSAGE"/> <entry key="setDefaultBus" value="true"/> </cxf:properties> </cxf:cxfEndpoint>

"LKCFDROFKD QEB "7% $KAMLFKQP TFQE

M>@EB

OFBP !IRBMOFKQ.

4JODF DBNFM 2.8 UIFSF JT TVQQPSU GPS VUJMJ[JOH BSJFT CMVFQSJOU EFQFOEFODZ JOKFDUJPO GPS ZPVS $9' FOEQPJOUT. 5IF TDIFNB VUJMJ[FE JT WFSZ TJNJMBS UP UIF TQSJOH TDIFNB TP UIF USBOTJUJPO JT GBJSMZ USBOTQBSFOU. &YBNQMF

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf" xmlns:cxfcore="http://cxf.apache.org/blueprint/core" xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd"> <camel-cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:9001/router"

582

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

serviceClass="org.apache.servicemix.examples.cxf.HelloWorld"> <camel-cxf:properties> <entry key="dataFormat" value="MESSAGE"/> </camel-cxf:properties> </camel-cxf:cxfEndpoint> <camel-cxf:cxfEndpoint id="serviceEndpoint" address="http://localhost:9000/SoapContext/SoapPort" serviceClass="org.apache.servicemix.examples.cxf.HelloWorld"> </camel-cxf:cxfEndpoint> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="routerEndpoint"/> <to uri="log:request"/> </route> </camelContext> </blueprint>

$VSSFOUMZ UIF FOEQPJOU FMFNFOU JT UIF GJSTU TVQQPSUFE $9' OBNFTQBDFIBOEMFS. :PV DBO BMTP VTF UIF CFBO SFGFSFODFT KVTU BT JO TQSJOH

<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xmlns:jaxws="http://cxf.apache.org/blueprint/jaxws" xmlns:cxf="http://cxf.apache.org/blueprint/core" xmlns:camel="http://camel.apache.org/schema/blueprint" xmlns:camelcxf="http://camel.apache.org/schema/blueprint/cxf" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/ blueprint/v1.0.0/blueprint.xsd http://cxf.apache.org/blueprint/jaxws http://cxf.apache.org/schemas/ blueprint/jaxws.xsd http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/ blueprint/core.xsd "> <camelcxf:cxfEndpoint id="reportIncident" address="/camel-example-cxf-blueprint/webservices/incident" wsdlURL="META-INF/wsdl/report_incident.wsdl" serviceClass="org.apache.camel.example.reportincident.ReportIncidentEndpoint"> </camelcxf:cxfEndpoint> <bean id="reportIncidentRoutes" class="org.apache.camel.example.reportincident.ReportIncidentRoutes" /> <camelContext xmlns="http://camel.apache.org/schema/blueprint">

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

583

<routeBuilder ref="reportIncidentRoutes"/> </camelContext> </blueprint>

'LT QL J>HB QEB @>JBI-@UC @LJMLKBKQ RPB ILD4G FKPQB>A LC G>S>.RQFI.ILDDFKD $9''T EFGBVMU MPHHFS JT java.util.logging. *G ZPV XBOU UP DIBOHF JU UP MPH4K, QSPDFFE BT GPMMPXT. $SFBUF B GJMF, JO UIF DMBTTQBUI, OBNFE META-INF/cxf/ org.apache.cxf.logger. 5IJT GJMF TIPVME DPOUBJO UIF GVMMZ-RVBMJGJFE OBNF PG UIF DMBTT, org.apache.cxf.common.logging.Log4jLogger, XJUI OP DPNNFOUT, PO B TJOHMF MJOF. 'LT QL IBQ @>JBI-@UC OBPMLKPB JBPP>DB TFQE UJI PQ>OQ AL@RJBKQ *G ZPV BSF VTJOH TPNF TPBQ DMJFOU TVDI BT 1)1, ZPV XJMM HFU UIJT LJOE PG FSSPS, CFDBVTF $9' EPFTO'U BEE UIF 9.- TUBSU EPDVNFOU "< YNM WFSTJPO="1.0" FODPEJOH="VUG-8" >"
Error:sendSms: SoapFault exception: [Client] looks like we got no XML document in [...]

5P SFTPMWFE UIJT JTTVF, ZPV KVTU OFFE UP UFMM 4UBY0VU*OUFSDFQUPS UP XSJUF UIF 9.- TUBSU EPDVNFOU GPS ZPV.
public class WriteXmlDeclarationInterceptor extends AbstractPhaseInterceptor<SoapMessage> { public WriteXmlDeclarationInterceptor() { super(Phase.PRE_STREAM); addBefore(StaxOutInterceptor.class.getName()); } public void handleMessage(SoapMessage message) throws Fault { message.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE); } }

:PV DBO BEE B DVTUPNFS JOUFSDFQUPS MJLF UIJT BOE DPOGJHVSF JU JOUP ZPV DBNFM-DYG FOEQPOU
<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port2}/CXFGreeterRouterTest/CamelContext/ RouterPort" serviceClass="org.apache.hello_world_soap_http.GreeterImpl" skipFaultLogging="true"> <cxf:outInterceptors>

584

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<!-- This interceptor will force the CXF server send the XML start document to client --> <bean class="org.apache.camel.component.cxf.WriteXmlDeclarationInterceptor"/> </cxf:outInterceptors> <cxf:properties> <!-- Set the publishedEndpointUrl which could override the service address from generated WSDL as you want --> <entry key="publishedEndpointUrl" value="http://www.simple.com/services/ test" /> </cxf:properties> </cxf:cxfEndpoint>

0S BEEJOH B NFTTBHF IFBEFS GPS JU MJLF UIJT JG ZPV BSF VTJOH ">JBI 2.4.
// set up the response context which force start document Map<String, Object> map = new HashMap<String, Object>(); map.put("org.apache.cxf.stax.force-start-document", Boolean.TRUE); exchange.getOut().setHeader(Client.RESPONSE_CONTEXT, map);

'LT QL @LKPRJB > JBPP>DB COLJ > @>JBI-@UC BKAMLFKQ FK /.). A>Q> CLOJ>Q 5IF camel-cxf FOEQPJOU DPOTVNFS 10+0 EBUB GPSNBU JT CBTFE PO UIF DYG JOWPLFS, TP UIF NFTTBHF IFBEFS IBT B QSPQFSUZ XJUI UIF OBNF PG CxfConstants.OPERATION_NAME BOE UIF NFTTBHF CPEZ JT B MJTU PG UIF 4&* NFUIPE QBSBNFUFST.
public class PersonProcessor implements Processor { private static final transient Logger LOG = LoggerFactory.getLogger(PersonProcessor.class); @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { LOG.info("processing exchange in camel"); BindingOperationInfo boi = (BindingOperationInfo)exchange.getProperty(BindingOperationInfo.class.toString()); if (boi != null) { LOG.info("boi.isUnwrapped" + boi.isUnwrapped()); } // Get the parameters list which element is the holder. MessageContentsList msgList = (MessageContentsList)exchange.getIn().getBody(); Holder<String> personId = (Holder<String>)msgList.get(0); Holder<String> ssn = (Holder<String>)msgList.get(1); Holder<String> name = (Holder<String>)msgList.get(2); if (personId.value == null || personId.value.length() == 0) { LOG.info("person id 123, so throwing exception"); // Try to throw out the soap fault message org.apache.camel.wsdl_first.types.UnknownPersonFault personFault =

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

585

new org.apache.camel.wsdl_first.types.UnknownPersonFault(); personFault.setPersonId(""); org.apache.camel.wsdl_first.UnknownPersonFault fault = new org.apache.camel.wsdl_first.UnknownPersonFault("Get the null value of person name", personFault); // Since camel has its own exception handler framework, we can't throw the exception to trigger it // We just set the fault message in the exchange for camel-cxf component handling and return exchange.getOut().setFault(true); exchange.getOut().setBody(fault); return; } name.value = "Bonjour"; ssn.value = "123"; LOG.info("setting Bonjour as the response"); // Set the response message, first element is the return value of the operation, // the others are the holders of method parameters exchange.getOut().setBody(new Object[] {null, personId, ssn, name}); } }

'LT QL MOBM>OB QEB JBPP>DB CLO QEB @>JBI-@UC BKAMLFKQ FK /.). A>Q> CLOJ>Q 5IF camel-cxf FOEQPJOU QSPEVDFS JT CBTFE PO UIF DYG DMJFOU "1*. 'JSTU ZPV OFFE UP TQFDJGZ UIF PQFSBUJPO OBNF JO UIF NFTTBHF IFBEFS, UIFO BEE UIF NFUIPE QBSBNFUFST UP B MJTU, BOE JOJUJBMJ[F UIF NFTTBHF XJUI UIJT QBSBNFUFS MJTU. 5IF SFTQPOTF NFTTBHF'T CPEZ JT B NFTTBHF$POUFOUT-JTU, ZPV DBO HFU UIF SFTVMU GSPN UIBU MJTU. *G ZPV XBOU UP HFU UIF PCKFDU BSSBZ GSPN UIF NFTTBHF CPEZ, ZPV DBO HFU UIF CPEZ VTJOH message.getbody(Object[].class), BT GPMMPXT:
Exchange senderExchange = new DefaultExchange(context, ExchangePattern.InOut); final List<String> params = new ArrayList<String>(); // Prepare the request message for the camel-cxf procedure params.add(TEST_MESSAGE); senderExchange.getIn().setBody(params); senderExchange.getIn().setHeader(CxfConstants.OPERATION_NAME, ECHO_OPERATION); Exchange exchange = template.send("direct:EndpointA", senderExchange); org.apache.camel.Message out = exchange.getOut(); // The response message's body is an MessageContentsList which first element is the return value of the operation, // If there are some holder parameters, the holder parameter will be filled in the reset of List.

586

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

// The result will be extract from the MessageContentsList with the String class type MessageContentsList result = (MessageContentsList)out.getBody(); LOG.info("Received output text: " + result.get(0)); Map<String, Object> responseContext = CastUtils.cast((Map<?, ?>)out.getHeader(Client.RESPONSE_CONTEXT)); assertNotNull(responseContext); assertEquals("We should get the response context here", "UTF-8", responseContext.get(org.apache.cxf.message.Message.ENCODING)); assertEquals("Reply body on Camel is wrong", "echo " + TEST_MESSAGE, result.get(0));

'LT QL AB>I TFQE QEB JBPP>DB CLO > @>JBI-@UC BKAMLFKQ FK / 8+. # A>Q> CLOJ>Q PAYLOAD NFBOT UIBU ZPV QSPDFTT UIF QBZMPBE NFTTBHF GSPN UIF 40"1 FOWFMPQF. :PV DBO VTF UIF Header.HEADER_LIST BT UIF LFZ UP TFU PS HFU UIF 40"1 IFBEFST BOE VTF UIF List<Element> UP TFU PS HFU 40"1 CPEZ FMFNFOUT. Message.getBody() XJMM SFUVSO BO org.apache.camel.component.cxf.CxfPayload PCKFDU, XIJDI IBT HFUUFST GPS 40"1 NFTTBHF IFBEFST BOE #PEZ FMFNFOUT. 5IJT DIBOHF FOBCMFT EFDPVQMJOH UIF OBUJWF $9' NFTTBHF GSPN UIF $BNFM NFTTBHF.
protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from(simpleEndpointURI + "&dataFormat=PAYLOAD").to("log:info").process(new Processor() { @SuppressWarnings("unchecked") public void process(final Exchange exchange) throws Exception { CxfPayload<SoapHeader> requestPayload = exchange.getIn().getBody(CxfPayload.class); List<Source> inElements = requestPayload.getBodySources(); List<Source> outElements = new ArrayList<Source>(); // You can use a customer toStringConverter to turn a CxfPayLoad message into String as you want String request = exchange.getIn().getBody(String.class); XmlConverter converter = new XmlConverter(); String documentString = ECHO_RESPONSE; Element in = new XmlConverter().toDOMElement(inElements.get(0)); // Just check the element namespace if (!in.getNamespaceURI().equals(ELEMENT_NAMESPACE)) { throw new IllegalArgumentException("Wrong element namespace"); } if (in.getLocalName().equals("echoBoolean")) { documentString = ECHO_BOOLEAN_RESPONSE; checkRequest("ECHO_BOOLEAN_REQUEST", request); } else { documentString = ECHO_RESPONSE; checkRequest("ECHO_REQUEST", request);

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

587

} Document outDocument = converter.toDOMDocument(documentString); outElements.add(new DOMSource(outDocument.getDocumentElement())); // set the payload header with null CxfPayload<SoapHeader> responsePayload = new CxfPayload<SoapHeader>(null, outElements, null); exchange.getOut().setBody(responsePayload); } }); } }; }

'LT QL DBQ >KA PBQ 2. / EB>ABOP FK /.). JLAB POJO NFBOT UIBU UIF EBUB GPSNBU JT B "MJTU PG +BWB PCKFDUT" XIFO UIF $BNFM-DYG FOEQPJOU QSPEVDFT PS DPOTVNFT $BNFM FYDIBOHFT. &WFO UIPVHI $BNFM FYQPTF NFTTBHF CPEZ BT 10+0T JO UIJT NPEF, $BNFM-DYG TUJMM QSPWJEFT BDDFTT UP SFBE BOE XSJUF 40"1 IFBEFST. )PXFWFS, TJODF $9' JOUFSDFQUPST SFNPWF JO-CBOE 40"1 IFBEFST GSPN )FBEFS MJTU BGUFS UIFZ IBWF CFFO QSPDFTTFE, POMZ PVU-PG-CBOE 40"1 IFBEFST BSF BWBJMBCMF UP $BNFM-DYG JO 10+0 NPEF. 5IF GPMMPXJOH FYBNQMF JMMVTUSBUF IPX UP HFU/TFU 40"1 IFBEFST. 4VQQPTF XF IBWF B SPVUF UIBU GPSXBSET GSPN POF $BNFM-DYG FOEQPJOU UP BOPUIFS. 5IBU JT, 40"1 $MJFOU -> $BNFM -> $9' TFSWJDF. 8F DBO BUUBDI UXP QSPDFTTPST UP PCUBJO/JOTFSU 40"1 IFBEFST BU (1) CFGPSF SFRVFTU HPFT PVU UP UIF $9' TFSWJDF BOE (2) CFGPSF SFTQPOTF DPNFT CBDL UP UIF 40"1 $MJFOU. 1SPDFTTPS (1) BOE (2) JO UIJT FYBNQMF BSF *OTFSU3FRVFTU0VU)FBEFS1SPDFTTPS BOE *OTFSU3FTQPOTF0VU)FBEFS1SPDFTTPS. 0VS SPVUF MPPLT MJLF UIJT:
<route> <from uri="cxf:bean:routerRelayEndpointWithInsertion"/> <process ref="InsertRequestOutHeaderProcessor" /> <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/> <process ref="InsertResponseOutHeaderProcessor" /> </route>

40"1 IFBEFST BSF QSPQBHBUFE UP BOE GSPN $BNFM .FTTBHF IFBEFST. 5IF $BNFM NFTTBHF IFBEFS OBNF JT "PSH.BQBDIF.DYG.IFBEFST.)FBEFS.MJTU" XIJDI JT B DPOTUBOU EFGJOFE JO $9' (PSH.BQBDIF.DYG.IFBEFST.)FBEFS.)&"%&3@-*45). 5IF IFBEFS WBMVF JT B -JTU PG $9' 4PBQ)FBEFS PCKFDUT (PSH.BQBDIF.DYG.CJOEJOH.TPBQ.4PBQ)FBEFS). 5IF GPMMPXJOH TOJQQFU JT UIF *OTFSU3FTQPOTF0VU)FBEFS1SPDFTTPS (UIBU JOTFSU B OFX 40"1 IFBEFS JO UIF SFTQPOTF NFTTBHF). 5IF XBZ UP BDDFTT 40"1 IFBEFST JO CPUI *OTFSU3FTQPOTF0VU)FBEFS1SPDFTTPS BOE *OTFSU3FRVFTU0VU)FBEFS1SPDFTTPS BSF BDUVBMMZ UIF TBNF. 5IF POMZ EJGGFSFODF CFUXFFO UIF UXP QSPDFTTPST JT TFUUJOH UIF EJSFDUJPO PG UIF JOTFSUFE 40"1 IFBEFS.
public static class InsertResponseOutHeaderProcessor implements Processor {

588

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

public void process(Exchange exchange) throws Exception { // You should be able to get the header if exchange is routed from camel-cxf endpoint List<SoapHeader> soapHeaders = CastUtils.cast((List<?>)exchange.getIn().getHeader(Header.HEADER_LIST)); if (soapHeaders == null) { // we just create a new soap headers in case the header is null soapHeaders = new ArrayList<SoapHeader>(); } // Insert a new header String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><outofbandHeader " + "xmlns=\"http://cxf.apache.org/outofband/Header\" hdrAttribute=\"testHdrAttribute\" " + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" soap:mustUnderstand=\"1\">" + "<name>New_testOobHeader</name><value>New_testOobHeaderValue</value></outofbandHeader>"; SoapHeader newHeader = new SoapHeader(soapHeaders.get(0).getName(), DOMUtils.readXml(new StringReader(xml)).getDocumentElement()); // make sure direction is OUT since it is a response message. newHeader.setDirection(Direction.DIRECTION_OUT); //newHeader.setMustUnderstand(false); soapHeaders.add(newHeader); } }

'LT QL DBQ >KA PBQ 2. / EB>ABOP FK / 8+. # JLAB 8F'WF BMSFBEZ TIPXO IPX UP BDDFTT 40"1 NFTTBHF ($YG1BZMPBE PCKFDU) JO 1":-0"% NPEF (4FF ")PX UP EFBM XJUI UIF NFTTBHF GPS B DBNFM-DYG FOEQPJOU JO 1":-0"% EBUB GPSNBU"). 0ODF ZPV PCUBJO B $YG1BZMPBE PCKFDU, ZPV DBO JOWPLF UIF $YG1BZMPBE.HFU)FBEFST() NFUIPE UIBU SFUVSOT B -JTU PG %0. &MFNFOUT (40"1 IFBEFST).
from(getRouterEndpointURI()).process(new Processor() { @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { CxfPayload<SoapHeader> payload = exchange.getIn().getBody(CxfPayload.class); List<Source> elements = payload.getBodySources(); assertNotNull("We should get the elements here", elements); assertEquals("Get the wrong elements size", 1, elements.size()); Element el = new XmlConverter().toDOMElement(elements.get(0)); elements.set(0, new DOMSource(el)); assertEquals("Get the wrong namespace URI", "http://camel.apache.org/pizza/ types", el.getNamespaceURI());

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

589

List<SoapHeader> headers = payload.getHeaders(); assertNotNull("We should get the headers here", headers); assertEquals("Get the wrong headers size", headers.size(), 1); assertEquals("Get the wrong namespace URI", ((Element)(headers.get(0).getObject())).getNamespaceURI(), "http://camel.apache.org/pizza/types"); } }) .to(getServiceEndpointURI());

2. / EB>ABOP >OB KLQ >S>FI>?IB FK ,$22 &$ JLAB 40"1 IFBEFST BSF OPU BWBJMBCMF JO .&44"(& NPEF BT 40"1 QSPDFTTJOH JT TLJQQFE. 'LT QL QEOLT > 2. / %>RIQ COLJ ">JBI *G ZPV BSF VTJOH B camel-cxf FOEQPJOU UP DPOTVNF UIF 40"1 SFRVFTU, ZPV NBZ OFFE UP UISPX UIF 40"1 'BVMU GSPN UIF DBNFM DPOUFYU. #BTJDBMMZ, ZPV DBO VTF UIF throwFault %4- UP EP UIBU; JU XPSLT GPS POJO, PAYLOAD BOE MESSAGE EBUB GPSNBU. :PV DBO EFGJOF UIF TPBQ GBVMU MJLF UIJT
SOAP_FAULT = new SoapFault(EXCEPTION_MESSAGE, SoapFault.FAULT_CODE_CLIENT); Element detail = SOAP_FAULT.getOrCreateDetail(); Document doc = detail.getOwnerDocument(); Text tn = doc.createTextNode(DETAIL_TEXT); detail.appendChild(tn);

5IFO UISPX JU BT ZPV MJLF


from(routerEndpointURI).setFaultBody(constant(SOAP_FAULT));

*G ZPVS $9' FOEQPJOU JT XPSLJOH JO UIF MESSAGE EBUB GPSNBU, ZPV DPVME TFU UIF UIF 40"1 'BVMU NFTTBHF JO UIF NFTTBHF CPEZ BOE TFU UIF SFTQPOTF DPEF JO UIF NFTTBHF IFBEFS.
from(routerEndpointURI).process(new Processor() { public void process(Exchange exchange) throws Exception { Message out = exchange.getOut(); // Set the message body with the out.setBody(this.getClass().getResourceAsStream("SoapFaultMessage.xml")); // Set the response code here out.setHeader(org.apache.cxf.message.Message.RESPONSE_CODE, new Integer(500)); }

590

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

});

4BNF GPS VTJOH 10+0 EBUB GPSNBU. :PV DBO TFU UIF 40"1'BVMU PO UIF PVU CPEZ BOE BMTP JOEJDBUF JU'T B GBVMU CZ DBMMJOH .FTTBHF.TFU'BVMU(USVF):
from("direct:start").onException(SoapFault.class).maximumRedeliveries(0).handled(true) .process(new Processor() { public void process(Exchange exchange) throws Exception { SoapFault fault = exchange .getProperty(Exchange.EXCEPTION_CAUGHT, SoapFault.class); exchange.getOut().setFault(true); exchange.getOut().setBody(fault); } }).end().to(serviceURI);

'LT QL MOLM>D>QB > @>JBI-@UC BKAMLFKQ'P OBNRBPQ >KA OBPMLKPB @LKQBUQ DYG DMJFOU "1* QSPWJEFT B XBZ UP JOWPLF UIF PQFSBUJPO XJUI SFRVFTU BOE SFTQPOTF DPOUFYU. *G ZPV BSF VTJOH B camel-cxf FOEQPJOU QSPEVDFS UP JOWPLF UIF PVUTJEF XFC TFSWJDF, ZPV DBO TFU UIF SFRVFTU DPOUFYU BOE HFU SFTQPOTF DPOUFYU XJUI UIF GPMMPXJOH DPEF:
CxfExchange exchange = (CxfExchange)template.send(getJaxwsEndpointUri(), new Processor() { public void process(final Exchange exchange) { final List<String> params = new ArrayList<String>(); params.add(TEST_MESSAGE); // Set the request context to the inMessage Map<String, Object> requestContext = new HashMap<String, Object>(); requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, JAXWS_SERVER_ADDRESS); exchange.getIn().setBody(params); exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext); exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, GREET_ME_OPERATION); } }); org.apache.camel.Message out = exchange.getOut(); // The output is an object array, the first element of the array is the return value Object\[\] output = out.getBody(Object\[\].class); LOG.info("Received output text: " + output\[0\]); // Get the response context form outMessage Map<String, Object> responseContext = CastUtils.cast((Map)out.getHeader(Client.RESPONSE_CONTEXT)); assertNotNull(responseContext); assertEquals("Get the wrong wsdl opertion name", "{http://apache.org/

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

591

hello_world_soap_http}greetMe", responseContext.get("javax.xml.ws.wsdl.operation").toString());

QQ>@EJBKQ 2RMMLOQ /.). ,LAB: #PUI 40"1 XJUI "UUBDINFOU BOE .50. BSF TVQQPSUFE (TFF FYBNQMF JO 1BZMPBE .PEF GPS FOBCMJOH .50.).c )PXFWFS, 40"1 XJUI "UUBDINFOU JT OPU UFTUFE.c 4JODF BUUBDINFOUT BSF NBSTIBMMFE BOE VONBSTIBMMFE JOUP 10+0T, VTFST UZQJDBMMZ EP OPU OFFE UP EFBM XJUI UIF BUUBDINFOU UIFNTFMG.c "UUBDINFOUT BSF QSPQBHBUFE UP $BNFM NFTTBHF'T BUUBDINFOUT TJODF 2.1.c 4P, JU JT QPTTJCMF UP SFUSFJWF BUUBDINFOUT CZ $BNFM .FTTBHF "1*
DataHandler Message.getAttachment(String id)

. />VIL>A ,LAB: .50. JT TVQQPSUFE TJODF 2.1. "UUBDINFOUT DBO CF SFUSJFWFE CZ $BNFM .FTTBHF "1*T NFOUJPOFE BCPWF. 40"1 XJUI "UUBDINFOU (4X") JT TVQQPSUFE BOE BUUBDINFOUT DBO CF SFUSJFWFE TJODF 2.5. 4X" JT UIF EFGBVMU (TBNF BT TFUUJOH UIF $9' FOEQPJOU QSPQFSUZ "NUPN-FOBCMFE" UP GBMTF).c 5P FOBCMF .50., TFU UIF $9' FOEQPJOU QSPQFSUZ "NUPN-FOBCMFE" UP true. (* CFMJFWF ZPV DBO POMZ EP JU XJUI 4QSJOH.)
<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port1}/CxfMtomRouterPayloadModeTest/ jaxws-mtom/hello" wsdlURL="mtom.wsdl" serviceName="ns:HelloService" endpointName="ns:HelloPort" xmlns:ns="http://apache.org/camel/cxf/mtom_feature"> <cxf:properties> <!-- enable mtom by setting this property to true --> <entry key="mtom-enabled" value="true"/> <!-- set the camel-cxf endpoint data fromat to PAYLOAD mode --> <entry key="dataFormat" value="PAYLOAD"/> </cxf:properties>

:PV DBO QSPEVDF B $BNFM NFTTBHF XJUI BUUBDINFOU UP TFOE UP B $9' FOEQPJOU JO 1BZMPBE NPEF.
Exchange exchange = context.createProducerTemplate().send("direct:testEndpoint", new Processor() { public void process(Exchange exchange) throws Exception {

592

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

exchange.setPattern(ExchangePattern.InOut); List<Source> elements = new ArrayList<Source>(); elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement())); CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(), elements, null); exchange.getIn().setBody(body); exchange.getIn().addAttachment(MtomTestHelper.REQ_PHOTO_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.REQ_PHOTO_DATA, "application/octet-stream"))); exchange.getIn().addAttachment(MtomTestHelper.REQ_IMAGE_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.requestJpeg, "image/ jpeg"))); } }); // process response CxfPayload<SoapHeader> out = exchange.getOut().getBody(CxfPayload.class); Assert.assertEquals(1, out.getBody().size()); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS); ns.put("xop", MtomTestHelper.XOP_NS); XPathUtils xu = new XPathUtils(ns); Element oute = new XmlConverter().toDOMElement(out.getBody().get(0)); Element ele = (Element)xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", oute, XPathConstants.NODE); String photoId = ele.getAttribute("href").substring(4); // skip "cid:" ele = (Element)xu.getValue("//ns:DetailResponse/ns:image/xop:Include", oute, XPathConstants.NODE); String imageId = ele.getAttribute("href").substring(4); // skip "cid:" DataHandler dr = exchange.getOut().getAttachment(photoId); Assert.assertEquals("application/octet-stream", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.RESP_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream())); dr = exchange.getOut().getAttachment(imageId); Assert.assertEquals("image/jpeg", dr.getContentType()); BufferedImage image = ImageIO.read(dr.getInputStream()); Assert.assertEquals(560, image.getWidth()); Assert.assertEquals(300, image.getHeight());

:PV DBO BMTP DPOTVNF B $BNFM NFTTBHF SFDFJWFE GSPN B $9' FOEQPJOU JO 1BZMPBE NPEF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

593

public static class MyProcessor implements Processor { @SuppressWarnings("unchecked") public void process(Exchange exchange) throws Exception { CxfPayload<SoapHeader> in = exchange.getIn().getBody(CxfPayload.class); // verify request assertEquals(1, in.getBody().size()); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", MtomTestHelper.SERVICE_TYPES_NS); ns.put("xop", MtomTestHelper.XOP_NS); XPathUtils xu = new XPathUtils(ns); Element body = new XmlConverter().toDOMElement(in.getBody().get(0)); Element ele = (Element)xu.getValue("//ns:Detail/ns:photo/xop:Include", body, XPathConstants.NODE); String photoId = ele.getAttribute("href").substring(4); // skip "cid:" assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId); ele = (Element)xu.getValue("//ns:Detail/ns:image/xop:Include", body, XPathConstants.NODE); String imageId = ele.getAttribute("href").substring(4); // skip "cid:" assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId); DataHandler dr = exchange.getIn().getAttachment(photoId); assertEquals("application/octet-stream", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.REQ_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream())); dr = exchange.getIn().getAttachment(imageId); assertEquals("image/jpeg", dr.getContentType()); MtomTestHelper.assertEquals(MtomTestHelper.requestJpeg, IOUtils.readBytesFromStream(dr.getInputStream())); // create response List<Source> elements = new ArrayList<Source>(); elements.add(new DOMSource(DOMUtils.readXml(new StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement())); CxfPayload<SoapHeader> sbody = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(), elements, null); exchange.getOut().setBody(sbody); exchange.getOut().addAttachment(MtomTestHelper.RESP_PHOTO_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.RESP_PHOTO_DATA, "application/octet-stream"))); exchange.getOut().addAttachment(MtomTestHelper.RESP_IMAGE_CID, new DataHandler(new ByteArrayDataSource(MtomTestHelper.responseJpeg, "image/jpeg"))); } }

594

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

,BPP>DB ,LAB: "UUBDINFOUT BSF OPU TVQQPSUFE BT JU EPFT OPU QSPDFTT UIF NFTTBHF BU BMM. 2QOB>JFKD 2RMMLOQ FK / 8+. # JLAB *O 2.8.2, UIF DBNFM-DYG DPNQPOFOU OPX TVQQPSUT TUSFBNJOH PG JODPNJOH NFTTBHFT XIFO VTJOH 1":-0"% NPEF. 1SFWJPVTMZ, UIF JODPNJOH NFTTBHFT XPVME IBWF CFFO DPNQMFUFMZ %0. QBSTFE. 'PS MBSHF NFTTBHFT, UIJT JT UJNF DPOTVNJOH BOE VTFT B TJHOJGJDBOU BNPVOU PG NFNPSZ. 4UBSUJOH JO 2.8.2, UIF JODPNJOH NFTTBHFT DBO SFNBJO BT B KBWBY.YNM.USBOTGPSN.4PVSDF XIJMF CFJOH SPVUFE BOE, JG OPUIJOH NPEJGJFT UIF QBZMPBE, DBO UIFO CF EJSFDUMZ TUSFBNFE PVU UP UIF UBSHFU EFTUJOBUJPO. 'PS DPNNPO "TJNQMF QSPYZ" VTF DBTFT (FYBNQMF: GSPN("DYG:...").UP("DYG:...")), UIJT DBO QSPWJEF WFSZ TJHOJGJDBOU QFSGPSNBODF JODSFBTFT BT XFMM BT TJHOJGJDBOUMZ MPXFSFE NFNPSZ SFRVJSFNFOUT. )PXFWFS, UIFSF BSF DBTFT XIFSF TUSFBNJOH NBZ OPU CF BQQSPQSJBUF PS EFTJSFE. %VF UP UIF TUSFBNJOH OBUVSF, JOWBMJE JODPNJOH 9.- NBZ OPU CF DBVHIU VOUJM MBUFS JO UIF QSPDFTTJOH DIBJO. "MTP, DFSUBJO BDUJPOT NBZ SFRVJSF UIF NFTTBHF UP CF %0. QBSTFE BOZXBZ (MJLF 84-4FDVSJUZ PS NFTTBHF USBDJOH BOE TVDI) JO XIJDI DBTF UIF BEWBOUBHFT PG UIF TUSFBNJOH JT MJNJUFE. "U UIJT QPJOU, UIFSF BSF UXP XBZT UP DPOUSPM UIF TUSFBNJOH: ` &OEQPJOU QSPQFSUZ: ZPV DBO BEE "BMMPX4USFBNJOH=GBMTF" BT BO FOEQPJOU QSPQFSUZ UP UVSO UIF TUSFBNJOH PO/PGG. ` $PNQPOFOU QSPQFSUZ: UIF $YG$PNQPOFOU PCKFDU BMTP IBT BO BMMPX4USFBNJOH QSPQFSUZ UIBU DBO TFU UIF EFGBVMU GPS FOEQPJOUT DSFBUFE GSPN UIBU DPNQPOFOU. ` (MPCBM TZTUFN QSPQFSUZ: ZPV DBO BEE B TZTUFN QSPQFSUZ PG "PSH.BQBDIF.DBNFM.DPNQPOFOU.DYG.TUSFBNJOH" UP "GBMTF" UP UVSO JG PGG. 5IBU TFUT UIF HMPCBM EFGBVMU, CVU TFUUJOH UIF FOEQPJOU QSPQFSUZ BCPWF XJMM PWFSSJEF UIJT WBMVF GPS UIBU FOEQPJOU. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

"7% !$ - ".,/.-$-3
5IF @UC?B>K: DPNQPOFOU BMMPXT PUIFS $BNFM FOEQPJOUT UP TFOE FYDIBOHF BOE JOWPLF 8FC TFSWJDF CFBO PCKFDUT. ("ROOBKQIV, FQ LKIV PRMMLOQP ) 712, ) 762(KBT QL @>JBI2.1) >KKLQ>QBA PBOSF@B ?B>K.)

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

595

CxfBeanEndpoint JT B ProcessorEndpoint TP JU IBT OP DPOTVNFST. *U XPSLT TJNJMBSMZ UP B #FBO DPNQPOFOU. 41( CLOJ>Q
cxfbean:serviceBeanRef

8IFSF PBOSF@B!B>K1BC JT B SFHJTUSZ LFZ UP MPPL VQ UIF TFSWJDF CFBO PCKFDU. *G serviceBeanRef SFGFSFODFT B List PCKFDU, FMFNFOUT PG UIF List BSF UIF TFSWJDF CFBO PCKFDUT BDDFQUFE CZ UIF FOEQPJOU. .MQFLKP
->JB
cxfBeanBinding

#BP@OFMQFLK
$9' CFBO CJOEJOH TQFDJGJFE CZ UIF # OPUBUJPO. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.camel.component.cxf.cxfbean.CxfBeanBinding. $9' CVT SFGFSFODF TQFDJGJFE CZ UIF # OPUBUJPO. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.cxf.Bus. )FBEFS GJMUFS TUSBUFHZ TQFDJGJFE CZ UIF # OPUBUJPO. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.camel.spi.HeaderFilterStrategy. 8JMM TFU UIF EFGBVMU CVT XIFO $9' FOEQPJOU DSFBUF B CVT CZ JUTFMG. 4JODF 2.3, UIF XTEM-PDBUJPO BOOPUBUFE JO UIF 10+0 JT JHOPSFE (CZ EFGBVMU) VOMFTT UIJT PQUJPO JT TFU UPc false. 1SJPS UP 2.3, UIF XTEM-PDBUJPO BOOPUBUFE JO UIF 10+0 JT BMXBZT IPOPSFE BOE JU JT OPU QPTTJCMF UP JHOPSF. 4JODF 2.5, TFUUJOH UIF QSPWJEFST GPS UIF $9'34 FOEQPJOU.

$U>JMIB
cxfBinding=#bindingName

1BNRFOBA?
/P

#BC>RI

DefaultCx

bus headerFilterStrategy setDefaultBus populateFromClass providers

bus=#busName headerFilterStrategy=#strategyName true, false true, false providers=#providerRef1,#providerRef2

/P /P /P /P /P

%FGBVMU CVT D 'BDUPSZ

CxfHeader false true null

'B>ABOP
->JB
CamelHttpCharacterEncoding (CFGPSF 2.0-N2: CamelCxfBeanCharacterEncoding) CamelContentType (CFGPSF 2.0-N2: CamelCxfBeanContentType)

#BP@OFMQFLK
$IBSBDUFS FODPEJOH

3VMB
String

1BNRFOBA?
/P

#BC>RIQ 5>IRB
/POF

(K/ .RQ
*O

$U>JMIBP
*40-8859-1

$POUFOU UZQF 5IF WBMVF PG UIJT IFBEFS XJMM CF TFU JO UIF $9' NFTTBHF BT UIF Message.BASE_PATH QSPQFSUZ. *U JT OFFEFE CZ $9' +"9-34 QSPDFTTJOH. #BTJDBMMZ, JU JT UIF TDIFNF, IPTU BOE QPSU QPSUJPO PG UIF SFRVFTU 63*. 3FRVFTU 63*'T QBUI 3&45GVM SFRVFTU WFSC )551 SFTQPOTF DPEF

String

/P

*/* 5IF &OEQPJOU 63* PG UIF TPVSDF FOEQPJOU JO UIF $BNFM FYDIBOHF /POF /POF /POF

*O

text/xml

$BNFM)UUQ#BTF6SJ (2.0-N3 BOE CFGPSF: CamelCxfBeanRequestBasePath)

String

:FT

*O

IUUQ://MPDBMIPTU:9000

CamelHttpPath (CFGPSF 2.0-N2: CamelCxfBeanRequestPatI) CamelHttpMethod (CFGPSF 2.0-N2: CamelCxfBeanVerb) CamelHttpResponseCode

String String Integer

:FT :FT /P

*O *O 0VU

consumer/123 GET, PUT, POST, DELETE 200

596

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

$VSSFOUMZ, $9' #FBO DPNQPOFOU IBT (POMZ) CFFO UFTUFE XJUI +FUUZ )551 DPNQPOFOU JU DBO VOEFSTUBOE IFBEFST GSPN +FUUZ )551 DPNQPOFOU XJUIPVU SFRVJSJOH DPOWFSTJPO. 6LOHFKD 2>JMIB 5IJT TBNQMF TIPXT IPX UP DSFBUF B SPVUF UIBU TUBSUT B +FUUZ )551 TFSWFS. 5IF SPVUF TFOET SFRVFTUT UP B $9' #FBO BOE JOWPLFT B +"934 BOOPUBUFE TFSWJDF. 'JSTU, DSFBUF B SPVUF BT GPMMPXT. 5IF from FOEQPJOU JT B +FUUZ )551 FOEQPJOU UIBU JT MJTUFOJOH PO QPSU 9000. /PUJDF UIBU UIF matchOnUriPrefix PQUJPO NVTU CF TFU UP true CFDBVTF 3&45GVM SFRVFTU 63* XJMM OPU NBUDI UIF FOEQPJOU'T 63* IUUQ: //MPDBMIPTU:9000 FYBDUMZ.
<route> <from ref="ep1" /> <to uri="cxfbean:customerServiceBean" /> <to uri="mock:endpointA" /> </route>

5IF to FOEQPJOU JT B $9' #FBO XJUI CFBO OBNF customerServiceBean. 5IF OBNF XJMM CF MPPLFE VQ GSPN UIF SFHJTUSZ. /FYU, XF NBLF TVSF PVS TFSWJDF CFBO JT BWBJMBCMF JO 4QSJOH SFHJTUSZ. 8F DSFBUF B CFBO EFGJOJUJPO JO UIF 4QSJOH DPOGJHVSBUJPO. *O UIJT FYBNQMF, XF DSFBUF B -JTU PG TFSWJDF CFBOT (PG POF FMFNFOU). 8F DPVME IBWF DSFBUFE KVTU B TJOHMF CFBO XJUIPVU B -JTU.
<util:list id="customerServiceBean"> <bean class="org.apache.camel.component.cxf.jaxrs.testbean.CustomerService" /> </util:list> <bean class="org.apache.camel.wsdl_first.PersonImpl" id="jaxwsBean" />

5IBU'T JU. 0ODF UIF SPVUF JT TUBSUFE, UIF XFC TFSWJDF JT SFBEZ GPS CVTJOFTT. " )551 DMJFOU DBO NBLF B SFRVFTU BOE SFDFJWF SFTQPOTF.

"7%12 ".,/.-$-3
5IF @UCOP: DPNQPOFOU QSPWJEFT JOUFHSBUJPO XJUI "QBDIF $9' GPS DPOOFDUJOH UP +"9-34 TFSWJDFT IPTUFE JO $9'. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS QPN.YNM GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

597

8IFO VTJOH $9' BT B DPOTVNFS, UIF $9' #FBO $PNQPOFOU BMMPXT ZPV UP GBDUPS PVU IPX NFTTBHF QBZMPBET BSF SFDFJWFE GSPN UIFJS QSPDFTTJOH BT B 3&45GVM PS 40"1 XFC TFSWJDF. 5IJT IBT UIF QPUFOUJBM PG VTJOH B NVMUJUVEF PG USBOTQPSUT UP DPOTVNF XFC TFSWJDFT. 5IF CFBO DPNQPOFOU'T DPOGJHVSBUJPO JT BMTP TJNQMFS BOE QSPWJEFT UIF GBTUFTU NFUIPE UP JNQMFNFOU XFC TFSWJDFT VTJOH $BNFM BOE $9'.

<artifactId>camel-cxf</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
cxfrs://address?options

8IFSF >AAOBPP SFQSFTFOUT UIF $9' FOEQPJOU'T BEESFTT


cxfrs:bean:rsEndpoint

8IFSF OP$KAMLFKQ SFQSFTFOUT UIF TQSJOH CFBO'T OBNF XIJDI QSFTFOUT UIF $9'34 DMJFOU PS TFSWFS 'PS FJUIFS TUZMF BCPWF, ZPV DBO BQQFOE PQUJPOT UP UIF 63* BT GPMMPXT:
cxfrs:bean:cxfEndpoint?resourceClasses=org.apache.camel.rs.Example

.MQFLKP
->JB
resourceClasses

#BP@OFMQFLK
5IF SFTPVSDF DMBTTFT XIJDI ZPV XBOU UP FYQPSU BT 3&45 TFSWJDF. .VMUJQMF DMBTTFT DBO CF TFQBSBUFE CZ DPNNB. #BMOB@>QBA: 6TF resourceClasses 5IF SFTPVSDF DMBTT XIJDI ZPV XBOU UP FYQPSU BT 3&45 TFSWJDF. KBT QL ">JBI 2.1 *G JU JT USVF, UIF $YG3T1SPEVDFS XJMM VTF UIF )UUQ$MJFOU"1* UP JOWPLF UIF TFSWJDF *G JU JT GBMTF, UIF $YG3T1SPEVDFS XJMM VTF UIF 1SPYZ$MJFOU"1* UP JOWPLF UIF TFSWJDF /FX JO 2.5, UIJT PQUJPO XJMM MFU $YG3T$POTVNFS EFDJEF UP VTF TZOD PS BTZOD "1* UP EP UIF VOEFSMZJOH XPSL. 5IF EFGBVMU WBMVF JT GBMTF XIJDI NFBOT JU XJMM USZ UP VTF BTZOD "1* CZ EFGBVMU.

$U>JMIB
resourceClasses=org.apache.camel.rs.Example1, org.apache.camel.rs.Exchange2

1BNRFOBA?
/P

ABC>RIQ S>IRB
None

resourceClass

resourceClass =org.apache.camel.rs.Example1

/P

None

httpClientAPI

IUUQ$MJFOU"1*=USVF

/P

true

TZODISPOPVT

TZODISPOPVT=USVF

/P

GBMTF

598

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

UISPX&YDFQUJPO0O'BJMVSF

/FX JO 2.6, UIJT PQUJPO UFMMT UIF $YG3T1SPEVDFS UP JOTQFDU SFUVSO DPEFT BOE XJMM HFOFSBUF BO &YDFQUJPO JG UIF SFUVSO DPEF JT MBSHFS UIBO 207. /FX JO 2.6, ZPV DBO TFU B */ NFTTBHF IFBEFS $BNFM%FTUJOBUJPO0WFSSJEF6SM UP EZOBNJDBMMZ PWFSSJEF UIF UBSHFU EFTUJOBUJPO 8FC 4FSWJDF PS 3&45 4FSWJDF EFGJOFE JO ZPVS SPVUFT.c 5IF JNQMFNFOUBUJPO DBDIFT $9' DMJFOUT PS $MJFOU'BDUPSZ#FBO JO $YG1SPWJEFS BOE $YG3T1SPWJEFS.c 5IJT PQUJPO BMMPXT ZPV UP DPOGJHVSF UIF NBYJNVN TJ[F PG UIF DBDIF. /FX JO 2.9.0. 8JMM TFU UIF EFGBVMU CVT XIFO $9' FOEQPJOU DSFBUF B CVT CZ JUTFMG /FX JO 2.9.0. " EFGBVMU CVT DSFBUFE CZ $9' #VT 'BDUPSZ. 6TF # OPUBUJPO UP SFGFSFODF B CVT PCKFDU GSPN UIF SFHJTUSZ. 5IF SFGFSFODFE PCKFDU NVTU CF BO JOTUBODF PG org.apache.cxf.Bus. P LC 2.11. 4FUT IPX SFRVFTUT BOE SFTQPOTFT XJMM CF NBQQFE UP/GSPN $BNFM. 5XP WBMVFT BSF QPTTJCMF: SimpleConsumer => TFF UIF $POTVNJOH B 3&45 3FRVFTU XJUI UIF 4JNQMF #JOEJOH 4UZMF CFMPX. Default => UIF EFGBVMU TUZMF. 'PS DPOTVNFST UIJT QBTTFT PO B MessageContentsList UP UIF SPVUF, SFRVJSJOH MPXMFWFM QSPDFTTJOH JO UIF SPVUF.

UISPX&YDFQUJPO0O'BJMVSF=USVF

/P

USVF

maxClientCacheSize

NBY$MJFOU$BDIF4J[F=5

/P

10

setDefaultBus

setDefaultBus=true

/P

false

bus

bus=#busName

/P

None

bindingStyle

bindingStyle=SimpleConsumer

/P

Default

:PV DBO BMTP DPOGJHVSF UIF $9' 3&45 FOEQPJOU UISPVHI UIF TQSJOH DPOGJHVSBUJPO. 4JODF UIFSF BSF MPUT PG EJGGFSFODF CFUXFFO UIF $9' 3&45 DMJFOU BOE $9' 3&45 4FSWFS, XF QSPWJEF EJGGFSFOU DPOGJHVSBUJPO GPS UIFN. 1MFBTF DIFDL PVU UIF TDIFNB GJMF BOE $9' 3&45 VTFS HVJEF GPS NPSF JOGPSNBUJPO. 'LT QL @LKCFDROB QEB 1$23 BKAMLFKQ FK ">JBI *O DBNFM-DYG TDIFNB GJMF, UIFSF BSF UXP FMFNFOUT GPS UIF 3&45 FOEQPJOU EFGJOJUJPO. @UC:OP2BOSBO GPS 3&45 DPOTVNFS, @UC:OP"IFBKQ GPS 3&45 QSPEVDFS. :PV DBO GJOE B $BNFM 3&45 TFSWJDF SPVUF DPOGJHVSBUJPO FYBNQMF IFSF.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/ camel-cxf.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd "> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

599

<!-- Defined the real JAXRS back end service <jaxrs:server id="restService"

-->

address="http://localhost:${CXFTestSupport.port2}/CxfRsRouterTest/rest" staticSubresourceResolution="true"> <jaxrs:serviceBeans> <ref bean="customerService"/> </jaxrs:serviceBeans> </jaxrs:server> <!-bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider"/-->

<bean id="customerService" class="org.apache.camel.component.cxf.jaxrs.testbean.CustomerService" /> <!-- Defined the server endpoint to create the cxf-rs consumer --> <cxf:rsServer id="rsServer" address="http://localhost:${CXFTestSupport.port1}/CxfRsRouterTest/route" serviceClass="org.apache.camel.component.cxf.jaxrs.testbean.CustomerService" loggingFeatureEnabled="true" loggingSizeLimit="20" skipFaultLogging="true"/> <!-- Defined the client endpoint to create the cxf-rs consumer --> <cxf:rsClient id="rsClient" address="http://localhost:${CXFTestSupport.port2}/CxfRsRouterTest/rest" serviceClass="org.apache.camel.component.cxf.jaxrs.testbean.CustomerService" loggingFeatureEnabled="true" skipFaultLogging="true"/> <!-- The camel route context --> <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="cxfrs://bean://rsServer"/> <!-- We can remove this configure as the CXFRS producer is using the HttpAPI by default --> <setHeader headerName="CamelCxfRsUsingHttpAPI"> <constant>True</constant> </setHeader> <to uri="cxfrs://bean://rsClient"/> </route> </camelContext> </beans>

"LKPRJFKD > 1$23 1BNRBPQ - 2FJMIB !FKAFKD 2QVIB S>FI>?IB >P LC ">JBI 2.11 5IF Default CJOEJOH TUZMF JT SBUIFS MPX-MFWFM, SFRVJSJOH UIF VTFS UP NBOVBMMZ QSPDFTT UIF MessageContentsList PCKFDU DPNJOH JOUP UIF SPVUF. 5IVT, JU UJHIUMZ DPVQMFT UIF SPVUF MPHJD XJUI UIF NFUIPE TJHOBUVSF BOE QBSBNFUFS JOEJDFT PG UIF +"9-34 PQFSBUJPO. 4PNFXIBU JOFMFHBOU, EJGGJDVMU BOE FSSPS-QSPOF.

600

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*O DPOUSBTU, UIF SimpleConsumer CJOEJOH TUZMF QFSGPSNT UIF GPMMPXJOH NBQQJOHT, JO PSEFS UP J>HB QEB OBNRBPQ A>Q> JLOB >@@BPPF?IB UP ZPV XJUIJO UIF $BNFM .FTTBHF: ` +"9-34 1BSBNFUFST (!)FBEFS1BSBN, !2VFSZ1BSBN, FUD.) BSF JOKFDUFE BT */ NFTTBHF IFBEFST. 5IF IFBEFS OBNF NBUDIFT UIF WBMVF PG UIF BOOPUBUJPO. ` 5IF SFRVFTU FOUJUZ (10+0 PS PUIFS UZQF) CFDPNFT UIF */ NFTTBHF CPEZ. *G B TJOHMF FOUJUZ DBOOPU CF JEFOUJGJFE JO UIF +"9-34 NFUIPE TJHOBUVSF, JU GBMMT CBDL UP UIF PSJHJOBM MessageContentsList. ` #JOBSZ @Multipart CPEZ QBSUT CFDPNF */ NFTTBHF BUUBDINFOUT, TVQQPSUJOH DataHandler, InputStream, DataSource BOE $9''T Attachment DMBTT. ` /PO-CJOBSZ @Multipart CPEZ QBSUT BSF NBQQFE BT */ NFTTBHF IFBEFST. 5IF IFBEFS OBNF NBUDIFT UIF #PEZ 1BSU OBNF. "EEJUJPOBMMZ, UIF GPMMPXJOH SVMFT BQQMZ UP UIF 1BPMLKPB J>MMFKD: ` *G UIF NFTTBHF CPEZ UZQF JT EJGGFSFOU UP javax.ws.rs.core.Response (VTFSCVJMU SFTQPOTF), B OFX Response JT DSFBUFE BOE UIF NFTTBHF CPEZ JT TFU BT UIF FOUJUZ (TP MPOH JU'T OPU OVMM). 5IF SFTQPOTF TUBUVT DPEF JT UBLFO GSPN UIF Exchange.HTTP_RESPONSE_CODE IFBEFS, PS EFGBVMUT UP 200 0, JG OPU QSFTFOU. ` *G UIF NFTTBHF CPEZ UZQF JT FRVBM UP javax.ws.rs.core.Response, JU NFBOT UIBU UIF VTFS IBT CVJMU B DVTUPN SFTQPOTF, BOE UIFSFGPSF JU JT SFTQFDUFE BOE JU CFDPNFT UIF GJOBM SFTQPOTF. ` *O BMM DBTFT, $BNFM IFBEFST QFSNJUUFE CZ DVTUPN PS EFGBVMU HeaderFilterStrategy BSF BEEFE UP UIF )551 SFTQPOTF.

$K>?IFKD QEB 2FJMIB !FKAFKD 2QVIB


5IJT CJOEJOH TUZMF DBO CF BDUJWBUFE CZ TFUUJOH UIF bindingStyle QBSBNFUFS JO UIF DPOTVNFS FOEQPJOU UP WBMVF SimpleConsumer:
from("cxf:bean:rsServer?bindingStyle=SimpleConsumer") .to("log:TEST?showAll=true");

$U>JMIBP LC OBNRBPQ ?FKAFKD TFQE AFCCBOBKQ JBQELA PFDK>QROBP


#FMPX JT B MJTU PG NFUIPE TJHOBUVSFT BMPOH XJUI UIF FYQFDUFE SFTVMU GSPN UIF 4JNQMF CJOEJOH. public Response doAction(BusinessObject request); 3FRVFTU QBZMPBE JT QMBDFE JO */ NFTTBHF CPEZ, SFQMBDJOH UIF PSJHJOBM .FTTBHF$POUFOUT-JTU. public Response doAction(BusinessObject request, @HeaderParam("abcd") String abcd, @QueryParam("defg") String defg); 3FRVFTU QBZMPBE QMBDFE JO */ NFTTBHF CPEZ, SFQMBDJOH UIF PSJHJOBM .FTTBHF$POUFOUT-JTU. #PUI SFRVFTU QBSBNT NBQQFE BT */ NFTTBHF IFBEFST XJUI OBNFT BCDE BOE EFGH.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

601

public Response doAction(@HeaderParam("abcd") String abcd, @QueryParam("defg") String defg); #PUI SFRVFTU QBSBNT NBQQFE BT */ NFTTBHF IFBEFST XJUI OBNFT BCDE BOE EFGH. 5IF PSJHJOBM .FTTBHF$POUFOUT-JTU JT QSFTFSWFE, FWFO UIPVHI JU POMZ DPOUBJOT UIF 2 QBSBNFUFST. public Response doAction(@Multipart(value="body1") BusinessObject request, @Multipart(value="body2") BusinessObject request2); 5IF GJSTU QBSBNFUFS JT USBOTGFSSFE BT B IFBEFS XJUI OBNF CPEZ1, BOE UIF TFDPOE POF JT NBQQFE BT IFBEFS CPEZ2. 5IF PSJHJOBM .FTTBHF$POUFOUT-JTU JT QSFTFSWFE BT UIF */ NFTTBHF CPEZ. public Response doAction(InputStream abcd); 5IF *OQVU4USFBN JT VOXSBQQFE GSPN UIF .FTTBHF$POUFOUT-JTU BOE QSFTFSWFE BT UIF */ NFTTBHF CPEZ. public Response doAction(DataHandler abcd); 5IF %BUB)BOEMFS JT VOXSBQQFE GSPN UIF .FTTBHF$POUFOUT-JTU BOE QSFTFSWFE BT UIF */ NFTTBHF CPEZ.

,LOB BU>JMIBP LC QEB 2FJMIB !FKAFKD 2QVIB


(JWFO B +"9-34 SFTPVSDF DMBTT XJUI UIJT NFUIPE:
@POST @Path("/customers/{type}") public Response newCustomer(Customer customer, @PathParam("type") String type, @QueryParam("active") @DefaultValue("true") boolean active) { return null; }

4FSWJDFE CZ UIF GPMMPXJOH SPVUF:


from("cxf:bean:rsServer?bindingStyle=SimpleConsumer") .recipientList(simple("direct:${header.operationName}")); from("direct:newCustomer") .log("Request: type=${header.type}, active=${header.active}, customerData=${body}");

5IF GPMMPXJOH )551 SFRVFTU XJUI 9.- QBZMPBE (HJWFO UIBU UIF $VTUPNFS %50 JT +"9#BOOPUBUFE):
POST /customers/gold?active=true Payload: <Customer> <fullName>Raul Kripalani</fullName> <country>Spain</country>

602

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<project>Apache Camel</project> </Customer>

8JMM QSJOU UIF NFTTBHF:


Request: type=gold, active=true, customerData=<Customer.toString() representation>

'PS NPSF FYBNQMFT PO IPX UP QSPDFTT SFRVFTUT BOE XSJUF SFTQPOTFT DBO CF GPVOE IFSF. "LKPRJFKD > 1$23 1BNRBPQ - #BC>RIQ !FKAFKD 2QVIB $9' +"934 GSPOU FOE JNQMFNFOUT UIF +"934(+43311) "1*, TP XF DBO FYQPSU UIF SFTPVSDFT DMBTTFT BT B 3&45 TFSWJDF. "OE XF MFWFSBHF UIF $9' *OWPLFS "1* UP UVSO B 3&45 SFRVFTU JOUP B OPSNBM +BWB PCKFDU NFUIPE JOWPDBUJPO. 6OMJLF UIF camel-restlet, ZPV EPO'U OFFE UP TQFDJGZ UIF 63* UFNQMBUF XJUIJO ZPVS SFTUMFU FOEQPJOU, $9' UBLF DBSF PG UIF 3&45 SFRVFTU 63* UP SFTPVSDF DMBTT NFUIPE NBQQJOH BDDPSEJOH UP UIF +43311 TQFDJGJDBUJPO. "MM ZPV OFFE UP EP JO $BNFM JT EFMFHBUF UIJT NFUIPE SFRVFTU UP B SJHIU QSPDFTTPS PS FOEQPJOU. )FSF JT BO FYBNQMF PG B $9'34 SPVUF...
private static final String CXF_RS_ENDPOINT_URI = "cxfrs://http://localhost:" + CXT + "/rest?resourceClasses=org.apache.camel.component.cxf.jaxrs.testbean.CustomerServiceResource"; protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() { errorHandler(new NoErrorHandlerBuilder()); from(CXF_RS_ENDPOINT_URI).process(new Processor() { public void process(Exchange exchange) throws Exception { Message inMessage = exchange.getIn(); // Get the operation name from in message String operationName = inMessage.getHeader(CxfConstants.OPERATION_NAME, String.class); if ("getCustomer".equals(operationName)) { String httpMethod = inMessage.getHeader(Exchange.HTTP_METHOD, String.class); assertEquals("Get a wrong http method", "GET", httpMethod); String path = inMessage.getHeader(Exchange.HTTP_PATH, String.class); // The parameter of the invocation is stored in the body of in message String id = inMessage.getBody(String.class); if ("/customerservice/customers/126".equals(path)) { Customer customer = new Customer(); customer.setId(Long.parseLong(id)); customer.setName("Willem");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

603

// We just put the response Object into the out message body exchange.getOut().setBody(customer); } else { if ("/customerservice/customers/400".equals(path)) { // We return the remote client IP address this time org.apache.cxf.message.Message cxfMessage = inMessage.getHeader(CxfConstants.CAMEL_CXF_MESSAGE, org.apache.cxf.message.Message.class); ServletRequest request = (ServletRequest) cxfMessage.get("HTTP.REQUEST"); String remoteAddress = request.getRemoteAddr(); Response r = Response.status(200).entity("The remoteAddress is " + remoteAddress).build(); exchange.getOut().setBody(r); return; } if ("/customerservice/customers/123".equals(path)) { // send a customer response back Response r = Response.status(200).entity("customer response back!").build(); exchange.getOut().setBody(r); return; } if ("/customerservice/customers/456".equals(path)) { Response r = Response.status(404).entity("Can't found the customer with uri " + path).build(); throw new WebApplicationException(r); } else { throw new RuntimeCamelException("Can't found the customer with uri " + path); } } } if ("updateCustomer".equals(operationName)) { assertEquals("Get a wrong customer message header", "header1;header2", inMessage.getHeader("test")); String httpMethod = inMessage.getHeader(Exchange.HTTP_METHOD, String.class); assertEquals("Get a wrong http method", "PUT", httpMethod); Customer customer = inMessage.getBody(Customer.class); assertNotNull("The customer should not be null.", customer); // Now you can do what you want on the customer object assertEquals("Get a wrong customer name.", "Mary", customer.getName()); // set the response back exchange.getOut().setBody(Response.ok().build()); } } }); }

604

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

}; }

"OE UIF DPSSFTQPOEJOH SFTPVSDF DMBTT VTFE UP DPOGJHVSF UIF FOEQPJOU...


@Path("/customerservice/") public interface CustomerServiceResource { @GET @Path("/customers/{id}/") Customer getCustomer(@PathParam("id") String id); @PUT @Path("/customers/") Response updateCustomer(Customer customer); }

'LT QL FKSLHB QEB 1$23 PBOSF@B QEOLRDE @>JBI-@UCOP MOLAR@BO $9' +"934 GSPOU FOE JNQMFNFOUT B QSPYZ CBTFE DMJFOU "1*, XJUI UIJT "1* ZPV DBO JOWPLF UIF SFNPUF 3&45 TFSWJDF UISPVHI B QSPYZ. camel-cxfrs QSPEVDFS JT CBTFE PO UIJT QSPYZ "1*. 4P, ZPV KVTU OFFE UP TQFDJGZ UIF PQFSBUJPO OBNF JO UIF NFTTBHF IFBEFS BOE QSFQBSF UIF QBSBNFUFS JO UIF NFTTBHF CPEZ, DBNFM-DYGST QSPEVDFS XJMM HFOFSBUF SJHIU 3&45 SFRVFTU GPS ZPV. )FSF JT BO FYBNQMF
Exchange exchange = template.send("direct://proxy", new Processor() { public void process(Exchange exchange) throws Exception { exchange.setPattern(ExchangePattern.InOut); Message inMessage = exchange.getIn(); setupDestinationURL(inMessage); // set the operation name inMessage.setHeader(CxfConstants.OPERATION_NAME, "getCustomer"); // using the proxy client API inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.FALSE); // set a customer header inMessage.setHeader("key", "value"); // set the parameters , if you just have one parameter // camel will put this object into an Object[] itself inMessage.setBody("123"); } }); // get the response message Customer response = (Customer) exchange.getOut().getBody(); assertNotNull("The response should not be null ", response); assertEquals("Get a wrong customer id ", String.valueOf(response.getId()), "123");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

605

KLQB >?LRQ QEB OBPLRO@B @I>PP 5IJT DMBTT JT VTFE UP DPOGJHVSF UIF +"934 QSPQFSUJFT 0/-:. 5IF NFUIPET XJMM /05 CF FYFDVUFE EVSJOH UIF SPVUJOH PG NFTTBHFT UP UIF FOEQPJOU, UIF SPVUF JUTFMG JT SFTQPOTJCMF GPS "-- QSPDFTTJOH JOTUFBE.

assertEquals("Get a wrong customer name", response.getName(), "John"); assertEquals("Get a wrong response code", 200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE)); assertEquals("Get a wrong header value", "value", exchange.getOut().getHeader("key"));

$9' +"934 GSPOU FOE BMTP QSPWJEFT B IUUQ DFOUSJD DMJFOU "1*, :PV DBO BMTP JOWPLF UIJT "1* GSPN camel-cxfrs QSPEVDFS. :PV OFFE UP TQFDJGZ UIF )551@1"5) BOE )UUQ NFUIPE BOE MFU UIF UIF QSPEVDFS LOPX UP VTF UIF IUUQ DFOUSJD DMJFOU CZ VTJOH UIF 63* PQUJPO EQQM"IFBKQ /( PS TFU UIF NFTTBHF IFBEFS XJUI $YG$POTUBOUT.$".&-@$9'@34@64*/(@)551@"1*. :PV DBO UVSO UIF SFTQPOTF PCKFDU UP UIF UZQF DMBTT UIBU ZPV TQFDJGZ XJUI $YG$POTUBOUT.$".&-@$9'@34@3&410/4&@$-"44.
Exchange exchange = template.send("direct://http", new Processor() { public void process(Exchange exchange) throws Exception { exchange.setPattern(ExchangePattern.InOut); Message inMessage = exchange.getIn(); setupDestinationURL(inMessage); // using the http central client API inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.TRUE); // set the Http method inMessage.setHeader(Exchange.HTTP_METHOD, "GET"); // set the relative path inMessage.setHeader(Exchange.HTTP_PATH, "/customerservice/customers/ 123"); // Specify the response class , cxfrs will use InputStream as the response object type inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_RESPONSE_CLASS, Customer.class); // set a customer header inMessage.setHeader("key", "value"); // since we use the Get method, so we don't need to set the message body inMessage.setBody(null); } }); // get the response message Customer response = (Customer) exchange.getOut().getBody(); assertNotNull("The response should assertEquals("Get a wrong customer assertEquals("Get a wrong customer assertEquals("Get a wrong response not be null ", response); id ", String.valueOf(response.getId()), "123"); name", response.getName(), "John"); code", 200,

606

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE)); assertEquals("Get a wrong header value", "value", exchange.getOut().getHeader("key"));

'SPN $BNFM 2.1, XF BMTP TVQQPSU UP TQFDJGZ UIF RVFSZ QBSBNFUFST GSPN DYGST 63* GPS UIF $9'34 IUUQ DFOUSJD DMJFOU.
Exchange exchange = template.send("cxfrs://http://localhost:" + getPort2() + "/" + getClass().getSimpleName() + "/testQuery?httpClientAPI=true&q1=12&q2=13"

5P TVQQPSU UIF %ZOBNJDBM SPVUJOH, ZPV DBO PWFSSJEF UIF 63*'T RVFSZ QBSBNFUFST CZ VTJOH UIF $YG$POTUBOUT.$".&-@$9'@34@26&3:@."1 IFBEFS UP TFU UIF QBSBNFUFS NBQ GPS JU.
Map<String, String> queryMap = new LinkedHashMap<String, String>(); queryMap.put("q1", "new"); queryMap.put("q2", "world"); inMessage.setHeader(CxfConstants.CAMEL_CXF_RS_QUERY_MAP, queryMap);

# 3 2$3 ".,/.-$-3
5FTUJOH PG EJTUSJCVUFE BOE BTZODISPOPVT QSPDFTTJOH JT OPUPSJPVTMZ EJGGJDVMU. 5IF .PDL, 5FTU BOE %BUB4FU FOEQPJOUT XPSL HSFBU XJUI UIF $BNFM 5FTUJOH 'SBNFXPSL UP TJNQMJGZ ZPVS VOJU BOE JOUFHSBUJPO UFTUJOH VTJOH &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT BOE $BNFM'T MBSHF SBOHF PG $PNQPOFOUT UPHFUIFS XJUI UIF QPXFSGVM #FBO *OUFHSBUJPO. 5IF %BUB4FU DPNQPOFOU QSPWJEFT B NFDIBOJTN UP FBTJMZ QFSGPSN MPBE & TPBL UFTUJOH PG ZPVS TZTUFN. *U XPSLT CZ BMMPXJOH ZPV UP DSFBUF %BUB4FU JOTUBODFT CPUI BT B TPVSDF PG NFTTBHFT BOE BT B XBZ UP BTTFSU UIBU UIF EBUB TFU JT SFDFJWFE. $BNFM XJMM VTF UIF UISPVHIQVU MPHHFS XIFO TFOEJOH EBUBTFU'T. 41( CLOJ>Q
dataset:name[?options]

8IFSF K>JB JT VTFE UP GJOE UIF %BUB4FU JOTUBODF JO UIF 3FHJTUSZ $BNFM TIJQT XJUI B TVQQPSU JNQMFNFOUBUJPO PG org.apache.camel.component.dataset.DataSet, UIF org.apache.camel.component.dataset.DataSetSupport DMBTT, UIBU DBO CF VTFE BT B CBTF GPS JNQMFNFOUJOH ZPVS PXO %BUB4FU. $BNFM BMTP TIJQT XJUI B EFGBVMU JNQMFNFOUBUJPO, UIF org.apache.camel.component.dataset.SimpleDataSet UIBU DBO CF VTFE GPS UFTUJOH.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

607

.MQFLKP
.MQFLK
produceDelay consumeDelay preloadSize initialDelay minRate

#BC>RIQ
3 0 0 1000 0

#BP@OFMQFLK
"MMPXT B EFMBZ JO NT UP CF TQFDJGJFE, XIJDI DBVTFT QSPEVDFST UP QBVTF JO PSEFS UP TJNVMBUF TMPX QSPEVDFST. 6TFT B NJOJNVN PG 3 NT EFMBZ VOMFTT ZPV TFU UIJT PQUJPO UP -1 UP GPSDF OP EFMBZ BU BMM. "MMPXT B EFMBZ JO NT UP CF TQFDJGJFE, XIJDI DBVTFT DPOTVNFST UP QBVTF JO PSEFS UP TJNVMBUF TMPX DPOTVNFST. 4FUT IPX NBOZ NFTTBHFT TIPVME CF QSFMPBEFE (TFOU) CFGPSF UIF SPVUF DPNQMFUFT JUT JOJUJBMJ[BUJPO. ">JBI 2.1: 5JNF QFSJPE JO NJMMJT UP XBJU CFGPSF TUBSUJOH TFOEJOH NFTTBHFT. 8BJU VOUJM UIF %BUB4FU DPOUBJOT BU MFBTU UIJT OVNCFS PG NFTTBHFT

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... "LKCFDROFKD #>Q>2BQ $BNFM XJMM MPPLVQ JO UIF 3FHJTUSZ GPS B CFBO JNQMFNFOUJOH UIF %BUB4FU JOUFSGBDF. 4P ZPV DBO SFHJTUFS ZPVS PXO %BUB4FU BT:
<bean id="myDataSet" class="com.mycompany.MyDataSet"> <property name="size" value="100"/> </bean>

$U>JMIB 'PS FYBNQMF, UP UFTU UIBU B TFU PG NFTTBHFT BSF TFOU UP B RVFVF BOE UIFO DPOTVNFE GSPN UIF RVFVF XJUIPVU MPTJOH BOZ NFTTBHFT:
// send the dataset to a queue from("dataset:foo").to("activemq:SomeQueue"); // now lets test that the messages are consumed correctly from("activemq:SomeQueue").to("dataset:foo");

5IF BCPWF XPVME MPPL JO UIF 3FHJTUSZ UP GJOE UIF CLL %BUB4FU JOTUBODF XIJDI JT VTFE UP DSFBUF UIF NFTTBHFT. 5IFO ZPV DSFBUF B %BUB4FU JNQMFNFOUBUJPO, TVDI BT VTJOH UIF SimpleDataSet BT EFTDSJCFE CFMPX, DPOGJHVSJOH UIJOHT MJLF IPX CJH UIF EBUB TFU JT BOE XIBU UIF NFTTBHFT MPPL MJLF FUD. /OLMBOQFBP LK 2FJMIB#>Q>2BQ
/OLMBOQV
defaultBody reportGroup size

3VMB
Object long long

#BP@OFMQFLK
4QFDJGJFT UIF EFGBVMU NFTTBHF CPEZ. 'PS 4JNQMF%BUB4FU JU JT B DPOTUBOU QBZMPBE; UIPVHI JG ZPV XBOU UP DSFBUF DVTUPN QBZMPBET QFS NFTTBHF, DSFBUF ZPVS PXO EFSJWBUJPO PG DataSetSupport. 4QFDJGJFT UIF OVNCFS PG NFTTBHFT UP CF SFDFJWFE CFGPSF SFQPSUJOH QSPHSFTT. 6TFGVM GPS TIPXJOH QSPHSFTT PG B MBSHF MPBE UFTU. 4QFDJGJFT IPX NBOZ NFTTBHFT UP TFOE/DPOTVNF.

608

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2BB

IPL ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4QSJOH 5FTUJOH

#!4. ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.5 5IF A?4L: DPNQPOFOU BMMPXT ZPV UP XPSL XJUI EC4P /P42- EBUBCBTF. 5IF DBNFM-EC4P MJCSBSZ JT QSPWJEFE CZ UIF $BNFM &YUSB QSPKFDU XIJDI IPTUT BMM *(1- SFMBUFE DPNQPOFOUT GPS $BNFM. 2BKAFKD QL QEB BKAMLFKQ 4FOEJOH 10+0 PCKFDU UP UIF EC4P FOEQPJOU BEET BOE TBWFT PCKFDU JOUP UIF EBUBCBTF. 5IF CPEZ PG UIF NFTTBHF JT BTTVNFE UP CF B 10+0 UIBU IBT UP CF TBWFE JOUP UIF EC40 EBUBCBTF TUPSF. "LKPRJFKD COLJ QEB BKAMLFKQ $POTVNJOH NFTTBHFT SFNPWFT (PS VQEBUFT) 10+0 PCKFDUT JO UIF EBUBCBTF. 5IJT BMMPXT ZPV UP VTF B %C4P EBUBTUPSF BT B MPHJDBM RVFVF; DPOTVNFST UBLF NFTTBHFT GSPN UIF RVFVF BOE UIFO EFMFUF UIFN UP MPHJDBMMZ SFNPWF UIFN GSPN UIF RVFVF. *G ZPV EP OPU XJTI UP EFMFUF UIF PCKFDU XIFO JU IBT CFFO QSPDFTTFE, ZPV DBO TQFDJGZ consumeDelete=false PO UIF 63*. 5IJT XJMM SFTVMU JO UIF 10+0 CFJOH QSPDFTTFE FBDI QPMM. 41( CLOJ>Q
db4o:className[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
consumeDelete consumer.delay consumer.initialDelay

#BC>RIQ 5>IRB
true 500 1000

#BP@OFMQFLK
0QUJPO GPS Db4oConsumer POMZ. 4QFDJGJFT XIFUIFS PS OPU UIF FOUJUZ JT EFMFUFE BGUFS JU JT DPOTVNFE. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. %FMBZ JO NJMMJT CFUXFFO FBDI QPMM. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. .JMMJT CFGPSF QPMMJOH TUBSUT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

609

consumer.userFixedDelay

false

0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. 4FU UP true UP VTF GJYFE EFMBZ CFUXFFO QPMMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT.

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

#(1$"3 ".,/.-$-3
5IF AFOB@Q: DPNQPOFOU QSPWJEFT EJSFDU, TZODISPOPVT JOWPDBUJPO PG BOZ DPOTVNFST XIFO B QSPEVDFS TFOET B NFTTBHF FYDIBOHF. 5IJT FOEQPJOU DBO CF VTFE UP DPOOFDU FYJTUJOH SPVUFT JO UIF P>JB DBNFM DPOUFYU. 41( CLOJ>Q
direct:someName[?options]

8IFSF PLJB->JB DBO CF BOZ TUSJOH UP VOJRVFMZ JEFOUJGZ UIF FOEQPJOU .MQFLKP
->JB
allowMultipleConsumers

#BC>RIQ 5>IRB
true

#BP@OFMQFLK
@ABMOB@>QBA *G TFU UP false, UIFO XIFO B TFDPOE DPOTVNFS JT TUBSUFE PO UIF FOEQPJOU, BO IllegalStateException JT UISPXO. 6FII ?B OBJLSBA FK ">JBI 2.1: %JSFDU FOEQPJOU EPFT OPU TVQQPSU NVMUJQMF DPOTVNFST.

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 2>JMIBP *O UIF SPVUF CFMPX XF VTF UIF EJSFDU DPNQPOFOU UP MJOL UIF UXP SPVUFT UPHFUIFS:
from("activemq:queue:order.in") .to("bean:orderServer?method=validate") .to("direct:processOrder"); from("direct:processOrder") .to("bean:orderService?method=process") .to("activemq:queue:order.out");

610

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

PVK@EOLKLRP 5IF 4&%" DPNQPOFOU QSPWJEFT BTZODISPOPVT JOWPDBUJPO PG BOZ DPOTVNFST XIFO B QSPEVDFS TFOET B NFTTBHF FYDIBOHF.

"LKKB@QFLK QL LQEBO @>JBI @LKQBUQP 5IF 7. DPNQPOFOU QSPWJEFT DPOOFDUJPOT CFUXFFO $BNFM DPOUFYUT BT MPOH UIFZ SVO JO UIF TBNF )5,. "OE UIF TBNQMF VTJOH TQSJOH %4-:
<route> <from uri="activemq:queue:order.in"/> <to uri="bean:orderService?method=validate"/> <to uri="direct:processOrder"/> </route> <route> <from uri="direct:processOrder"/> <to uri="bean:orderService?method=process"/> <to uri="activemq:queue:order.out"/> </route>

4FF BMTP TBNQMFT GSPN UIF 4&%" DPNQPOFOU, IPX UIFZ DBO CF VTFE UPHFUIFS. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4&%" 7.

#-2
S>FI>?IB >P LC ">JBI 2.7 5IJT JT BO BEEJUJPOBM DPNQPOFOU GPS $BNFM UP SVO %/4 RVFSJFT, VTJOH %/4+BWB. 5IF DPNQPOFOU JT B UIJO MBZFS PO UPQ PG %/4+BWB. 5IF DPNQPOFOU PGGFST UIF GPMMPXJOH PQFSBUJPOT: JQ, UP SFTPMWF B EPNBJO CZ JUT JQ

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

611

MPPLVQ, UP MPPLVQ JOGPSNBUJPO BCPVU UIF EPNBJO EJH, UP SVO %/4 RVFSJFT .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-dns</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q 5IF 63* TDIFNF GPS B %/4 DPNQPOFOU JT BT GPMMPXT


dns://operation

5IJT DPNQPOFOU POMZ TVQQPSUT QSPEVDFST. .MQFLKP /POF. 'B>ABOP


'B>ABO
EOT.EPNBJO EOT.OBNF EOT.UZQF EOT.DMBTT EOT.RVFSZ EOT.TFSWFS 4USJOH 4USJOH

3VMB
4USJOH 4USJOH

.MBO>QFLKP
JQ MPPLVQ MPPLVQ, EJH MPPLVQ, EJH EJH EJH

#BP@OFMQFLK
5IF EPNBJO OBNF. .BOEBUPSZ. 5IF OBNF UP MPPLVQ. .BOEBUPSZ. 5IF UZQF PG UIF MPPLVQ. 4IPVME NBUDI UIF WBMVFT PG org.xbill.dns.Type. 0QUJPOBM. IF %/4 DMBTT PG UIF MPPLVQ. 4IPVME NBUDI UIF WBMVFT PG org.xbill.dns.DClass. 0QUJPOBM. 5IF RVFSZ JUTFMG. .BOEBUPSZ. 5IF TFSWFS JO QBSUJDVMBS GPS UIF RVFSZ. *G OPOF JT HJWFO, UIF EFGBVMU POF TQFDJGJFE CZ UIF 04 XJMM CF VTFE. 0QUJPOBM.

$U>JMIBP

(/ ILLHRM
<route id="IPCheck"> <from uri="direct:start"/> <to uri="dns:ip"/> </route>

612

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

1BNRFOBP 24- )5, 5IF %/4+BWB MJCSBSZ SFRVJSFT SVOOJOH PO UIF 46/ +7.. *G ZPV VTF "QBDIF 4FSWJDF.JY PS "QBDIF ,BSBG, ZPV'MM OFFE UP BEKVTU UIF etc/ jre.properties GJMF, UP BEE sun.net.spi.nameservice UP UIF MJTU PG +BWB QMBUGPSN QBDLBHFT FYQPSUFE. 5IF TFSWFS XJMM OFFE SFTUBSUJOH CFGPSF UIJT DIBOHF UBLFT FGGFDU. 5IJT MPPLT VQ B EPNBJO'T *1. 'PS FYBNQMF, XXX.FYBNQMF.DPN SFTPMWFT UP 192.0.32.10. 5IF *1 BEESFTT UP MPPLVQ NVTU CF QSPWJEFE JO UIF IFBEFS XJUI LFZ "dns.domain".

#-2 ILLHRM
<route id="IPCheck"> <from uri="direct:start"/> <to uri="dns:lookup"/> </route>

5IJT SFUVSOT B TFU PG %/4 SFDPSET BTTPDJBUFE XJUI B EPNBJO. 5IF OBNF UP MPPLVQ NVTU CF QSPWJEFE JO UIF IFBEFS XJUI LFZ "dns.name".

#-2 #FD
%JH JT B 6OJY DPNNBOE-MJOF VUJMJUZ UP SVO %/4 RVFSJFT.
<route id="IPCheck"> <from uri="direct:start"/> <to uri="dns:dig"/> </route>

5IF RVFSZ NVTU CF QSPWJEFE JO UIF IFBEFS XJUI LFZ "dns.query". 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

613

$)! ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.4 5IF BG?: DPNQPOFOU CJOET &+#T UP $BNFM NFTTBHF FYDIBOHFT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ejb</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
ejb:ejbName[?options]

8IFSF BG?->JB DBO CF BOZ TUSJOH XIJDI JT VTFE UP MPPL VQ UIF &+# JO UIF "QQMJDBUJPO 4FSWFS +/%* 3FHJTUSZ .MQFLKP
->JB
method multiParameterArray

3VMB
String boolean

#BC>RIQ
null false

#BP@OFMQFLK
5IF NFUIPE OBNF UIBU CFBO XJMM CF JOWPLFE. *G OPU QSPWJEFE, $BNFM XJMM USZ UP QJDL UIF NFUIPE JUTFMG. *O DBTF PG BNCJHVJUZ BO FYDFQUJPO JT UISPXO. 4FF #FBO #JOEJOH GPS NPSF EFUBJMT. )PX UP USFBU UIF QBSBNFUFST XIJDI BSF QBTTFE GSPN UIF NFTTBHF CPEZ; JG JU JT true, UIF *O NFTTBHF CPEZ TIPVME CF BO BSSBZ PG QBSBNFUFST.

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 5IF &+# DPNQPOFOU FYUFOET UIF #FBO DPNQPOFOU JO XIJDI NPTU PG UIF EFUBJMT GSPN UIF #FBO DPNQPOFOU BQQMJFT UP UIJT DPNQPOFOU BT XFMM. !B>K !FKAFKD )PX CFBO NFUIPET UP CF JOWPLFE BSF DIPTFO (JG UIFZ BSF OPU TQFDJGJFE FYQMJDJUMZ UISPVHI UIF JBQELA QBSBNFUFS) BOE IPX QBSBNFUFS WBMVFT BSF DPOTUSVDUFE GSPN UIF .FTTBHF BSF BMM EFGJOFE CZ UIF #FBO #JOEJOH NFDIBOJTN XIJDI JT VTFE UISPVHIPVU BMM PG UIF WBSJPVT #FBO *OUFHSBUJPO NFDIBOJTNT JO $BNFM. $U>JMIBP *O UIF GPMMPXJOH FYBNQMFT XF VTF UIF (SFBUFS &+# XIJDI JT EFGJOFE BT GPMMPXT:

614

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

Listing 1. GreaterLocal.java
public interface GreaterLocal { String hello(String name); String bye(String name); }

"OE UIF JNQMFNFOUBUJPO


Listing 1. GreaterImpl.java
@Stateless public class GreaterImpl implements GreaterLocal { public String hello(String name) { return "Hello " + name; } public String bye(String name) { return "Bye " + name; } }

4PFKD )>S> #2+


*O UIJT FYBNQMF XF XBOU UP JOWPLF UIF hello NFUIPE PO UIF &+#. 4JODF UIJT FYBNQMF JT CBTFE PO BO VOJU UFTU VTJOH "QBDIF 0QFO&+# XF IBWF UP TFU B JndiContext PO UIF &+# DPNQPOFOU XJUI UIF 0QFO&+# TFUUJOHT.
@Override protected CamelContext createCamelContext() throws Exception { CamelContext answer = new DefaultCamelContext(); // enlist EJB component using the JndiContext EjbComponent ejb = answer.getComponent("ejb", EjbComponent.class); ejb.setContext(createEjbContext()); return answer; } private static Context createEjbContext() throws NamingException { // here we need to define our context factory to use OpenEJB for our testing Properties properties = new Properties(); properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

615

return new InitialContext(properties); }

5IFO XF BSF SFBEZ UP VTF UIF &+# JO UIF $BNFM SPVUF:


from("direct:start") // invoke the greeter EJB using the local interface and invoke the hello method .to("ejb:GreaterImplLocal?method=hello") .to("mock:result");

4PFKD 2MOFKD 7,+


"OE UIJT JT UIF TBNF FYBNQMF VTJOH 4QSJOH 9.- JOTUFBE: "HBJO TJODF UIJT JT CBTFE PO BO VOJU UFTU XF OFFE UP TFUVQ UIF &+# DPNQPOFOU:
<!-- setup Camel EJB component --> <bean id="ejb" class="org.apache.camel.component.ejb.EjbComponent"> <property name="properties" ref="jndiProperties"/> </bean> <!-- use OpenEJB context factory --> <p:properties id="jndiProperties"> <prop key="java.naming.factory.initial">org.apache.openejb.client.LocalInitialContextFactory</prop> </p:properties>

#FGPSF XF BSF SFBEZ UP VTF &+# JO UIF $BNFM SPVUFT:


<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <to uri="ejb:GreaterImplLocal?method=hello"/> <to uri="mock:result"/> </route> </camelContext>

2BB

IPL ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE #FBO #FBO #JOEJOH

616

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

(K > OB>I >MMIF@>QFLK PBOSBO *O B SFBM BQQMJDBUJPO TFSWFS ZPV NPTU MJLFMZ EP OPU IBWF UP TFUVQ B JndiContext PO UIF &+# DPNQPOFOU BT JU XJMM DSFBUF B EFGBVMU JndiContext PO UIF TBNF +7. BT UIF BQQMJDBUJPO TFSWFS, XIJDI VTVBMMZ BMMPXT JU UP BDDFTT UIF +/%* SFHJTUSZ BOE MPPLVQ UIF &+#T. )PXFWFS JG ZPV OFFE UP BDDFTT B BQQMJDBUJPO TFSWFS PO B SFNPUF +7. PS UIF MJLFT, ZPV IBWF UP QSFQBSF UIF QSPQFSUJFT CFGPSFIBOE. ` #FBO *OUFHSBUJPO

$2/$1
5IF &TQFS DPNQPOFOU TVQQPSUT UIF &TQFS -JCSBSZ GPS &WFOU 4USFBN 1SPDFTTJOH. 5IF @>JBIBPMBO MJCSBSZ JT QSPWJEFE CZ UIF $BNFM &YUSB QSPKFDU XIJDI IPTUT BMM *(1- SFMBUFE DPNQPOFOUT GPS $BNFM. 41( CLOJ>Q
esper:name[?options]

8IFO DPOTVNJOH GSPN BO &TQFS FOEQPJOU ZPV NVTU TQFDJGZ B M>QQBOK PS BNI TUBUFNFOU UP RVFSZ UIF FWFOU TUSFBN. 'PS FYBNQMF
from("esper://cheese?pattern=every event=MyEvent(bar=5)"). to("activemq:Foo");

.MQFLKP
->JB
pattern eql

#BC>RIQ 5>IRB
c c

#BP@OFMQFLK
5IF &TQFS 1BUUFSO FYQSFTTJPO BT B 4USJOH UP GJMUFS FWFOUT 5IF &TQFS &2- FYQSFTTJPO BT B 4USJOH UP GJMUFS FWFOUT

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... #BJL 5IFSF JT B EFNP XIJDI TIPXT IPX UP XPSL XJUI "DUJWF.2, $BNFM BOE &TQFS JO UIF $BNFM &YUSB QSPKFDU

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

617

2BB

IPL ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE &TQFS $BNFM %FNP

$5$-3 ".,/.-$-3
5IF BSBKQ: DPNQPOFOU QSPWJEFT BDDFTT UP UIF 4QSJOH "QQMJDBUJPO&WFOU PCKFDUT. 5IJT BMMPXT ZPV UP QVCMJTI "QQMJDBUJPO&WFOU PCKFDUT UP B 4QSJOH "QQMJDBUJPO$POUFYU PS UP DPOTVNF UIFN. :PV DBO UIFO VTF &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT UP QSPDFTT UIFN TVDI BT .FTTBHF 'JMUFS. 41( CLOJ>Q
spring-event://default

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

%(+$ ".,/.-$-3
5IF 'JMF DPNQPOFOU QSPWJEFT BDDFTT UP GJMF TZTUFNT, BMMPXJOH GJMFT UP CF QSPDFTTFE CZ BOZ PUIFS $BNFM $PNQPOFOUT PS NFTTBHFT GSPN PUIFS DPNQPOFOUT UP CF TBWFE UP EJTL. 41( CLOJ>Q
file:directoryName[?options]

PS
file://directoryName[?options]

8IFSF AFOB@QLOV->JB SFQSFTFOUT UIF VOEFSMZJOH GJMF EJSFDUPSZ.

618

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 41( .MQFLKP

"LJJLK
->JB
autoCreate bufferSize

#BC>RIQ 5>IRB
true 128LC

#BP@OFMQFLK
"VUPNBUJDBMMZ DSFBUF NJTTJOH EJSFDUPSJFT JO UIF GJMF'T QBUIOBNF. 'PS UIF GJMF DPOTVNFS, UIBU NFBOT DSFBUJOH UIF TUBSUJOH EJSFDUPSZ. 'PS UIF GJMF QSPEVDFS, JU NFBOT UIF EJSFDUPSZ UIF GJMFT TIPVME CF XSJUUFO UP. 8SJUF CVGGFS TJ[FE JO CZUFT. 6TF &YQSFTTJPO TVDI BT 'JMF -BOHVBHF UP EZOBNJDBMMZ TFU UIF GJMFOBNF. 'PS DPOTVNFST, JU'T VTFE BT B GJMFOBNF GJMUFS. 'PS QSPEVDFST, JU'T VTFE UP FWBMVBUF UIF GJMFOBNF UP XSJUF. *G BO FYQSFTTJPO JT TFU, JU UBLF QSFDFEFODF PWFS UIF CamelFileName IFBEFS. (-LQB: 5IF IFBEFS JUTFMG DBO BMTP CF BO &YQSFTTJPO). 5IF FYQSFTTJPO PQUJPOT TVQQPSU CPUI String BOE Expression UZQFT. *G UIF FYQSFTTJPO JT B String UZQF, JU JT >IT>VP FWBMVBUFE VTJOH UIF 'JMF -BOHVBHF. *G UIF FYQSFTTJPO JT BO Expression UZQF, UIF TQFDJGJFE Expression UZQF JT VTFE - UIJT BMMPXT ZPV, GPS JOTUBODF, UP VTF 0(/- FYQSFTTJPOT. 'PS UIF DPOTVNFS, ZPV DBO VTF JU UP GJMUFS GJMFOBNFT, TP ZPV DBO GPS JOTUBODF DPOTVNF UPEBZ'T GJMF VTJOH UIF 'JMF -BOHVBHF TZOUBY: mydata-${date:now:yyyyMMdd}.txt. 'SPN ">JBI 2.11 POXBSET UIF QSPEVDFST TVQQPSU UIF CamelOverruleFileName IFBEFS XIJDI UBLFT QSFDFEFODF PWFS BOZ FYJTUJOH CamelFileName IFBEFS; UIF CamelOverruleFileName JT B IFBEFS UIBU JT VTFE POMZ PODF, BOE NBLFT JU FBTJFS BT UIJT BWPJET UP UFNQPSBSZ TUPSF CamelFileName BOE IBWF UP SFTUPSF JU BGUFSXBSET. 'MBUUFO JT VTFE UP GMBUUFO UIF GJMF OBNF QBUI UP TUSJQ BOZ MFBEJOH QBUIT, TP JU'T KVTU UIF GJMF OBNF. 5IJT BMMPXT ZPV UP DPOTVNF SFDVSTJWFMZ JOUP TVC-EJSFDUPSJFT, CVU XIFO ZPV FH XSJUF UIF GJMFT UP BOPUIFS EJSFDUPSZ UIFZ XJMM CF XSJUUFO JO B TJOHMF EJSFDUPSZ. 4FUUJOH UIJT UP true PO UIF QSPEVDFS FOGPSDFT UIBU BOZ GJMF OBNF SFDJWFE JO CamelFileName IFBEFS XJMM CF TUSJQQFE GPS BOZ MFBEJOH QBUIT. ">JBI 2.9.3: UIJT PQUJPO JT VTFE UP TQFDJGZ UIF FODPEJOH PG UIF GJMF, BOE DBNFM XJMM TFU UIF &YDIBOHF QSPQFSUZ XJUI Exchange.CHARSET_NAME XJUI UIF WBMVF PG UIJT PQUJPO. :PV DBO VTF UIJT PO UIF DPOTVNFS, UP TQFDJGZ UIF FODPEJOHT PG UIF GJMFT, XIJDI BMMPX $BNFM UP LOPX UIF DIBSTFU JU TIPVME MPBE UIF GJMF DPOUFOU JO DBTF UIF GJMF DPOUFOU JT CFJOH BDDFTTFE. -JLFXJTF XIFO XSJUJOH B GJMF, ZPV DBO VTF UIJT PQUJPO UP TQFDJGZ XIJDI DIBSTFU UP XSJUF UIF GJMF BT XFMM. 4FF GVSUIFS CFMPX GPS B FYBNQMFT BOE NPSF JNQPSUBOU EFUBJMT. ">JBI 2.9: XIFUIFS UP GBMMCBDL BOE EP B DPQZ BOE EFMFUF GJMF, JO DBTF UIF GJMF DPVME OPU CF SFOBNFE EJSFDUMZ. 5IJT PQUJPO JT OPU BWBJMBCMF GPS UIF '51 DPNQPOFOU.

fileName

null

flatten

false

charset

null

copyAndDeleteOnRenameFail

true

"LKPRJBO
->JB
initialDelay delay useFixedDelay runLoggingLevel recursive delete noop

#BC>RIQ 5>IRB
1000 500 c TRACE false false false

#BP@OFMQFLK
.JMMJTFDPOET CFGPSF QPMMJOH UIF GJMF/EJSFDUPSZ TUBSUT. .JMMJTFDPOET CFGPSF UIF OFYU QPMM PG UIF GJMF/EJSFDUPSZ. $POUSPMT JG GJYFE EFMBZ PS GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT. *O ">JBI 2.7.U PS PMEFS UIF EFGBVMU WBMVF JT false. 'SPN ">JBI 2.8 POXBSET UIF EFGBVMU WBMVF JT true. ">JBI 2.8: 5IF DPOTVNFS MPHT B TUBSU/DPNQMFUF MPH MJOF XIFO JU QPMMT. 5IJT PQUJPO BMMPXT ZPV UP DPOGJHVSF UIF MPHHJOH MFWFM GPS UIBU. *G B EJSFDUPSZ, XJMM MPPL GPS GJMFT JO BMM UIF TVC-EJSFDUPSJFT BT XFMM. *G true, UIF GJMF XJMM CF EFMFUFE >CQBO JU JT QSPDFTTFE *G true, UIF GJMF JT OPU NPWFE PS EFMFUFE JO BOZ XBZ. 5IJT PQUJPO JT HPPE GPS SFBEPOMZ EBUB, PS GPS &5- UZQF SFRVJSFNFOUT. *G noop=true, $BNFM XJMM TFU idempotent=true BT XFMM, UP BWPJE DPOTVNJOH UIF TBNF GJMFT PWFS BOE PWFS BHBJO. &YQSFTTJPO (TVDI BT 'JMF -BOHVBHF) VTFE UP EZOBNJDBMMZ TFU UIF GJMFOBNF XIFO NPWJOH JU ?BCLOB QSPDFTTJOH. 'PS FYBNQMF UP NPWF JO-QSPHSFTT GJMFT JOUP UIF order EJSFDUPSZ TFU UIJT WBMVF UP order. &YQSFTTJPO (TVDI BT 'JMF -BOHVBHF) VTFE UP EZOBNJDBMMZ TFU UIF GJMFOBNF XIFO NPWJOH JU >CQBO QSPDFTTJOH. 5P NPWF GJMFT JOUP B .done TVCEJSFDUPSZ KVTU FOUFS .done.

preMove move

null .camel

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

619

.KIV AFOB@QLOFBP $BNFM TVQQPSUT POMZ FOEQPJOUT DPOGJHVSFE XJUI B TUBSUJOH EJSFDUPSZ. 4P UIF AFOB@QLOV->JB NVTU CF B EJSFDUPSZ. *G ZPV XBOU UP DPOTVNF B TJOHMF GJMF POMZ, ZPV DBO VTF UIF CFIB->JB PQUJPO, F.H. CZ TFUUJOH fileName=thefilename. "MTP, UIF TUBSUJOH EJSFDUPSZ NVTU OPU DPOUBJO EZOBNJD FYQSFTTJPOT XJUI $\ ^ QMBDFIPMEFST. "HBJO VTF UIF fileName PQUJPO UP TQFDJGZ UIF EZOBNJD QBSU PG UIF GJMFOBNF.

SLFA OB>AFKD CFIBP @ROOBKQIV ?BFKD TOFQQBK ?V >KLQEBO >MMIF@>QFLK #FXBSF UIF +%, 'JMF *0 "1* JT B CJU MJNJUFE JO EFUFDUJOH XIFUIFS BOPUIFS BQQMJDBUJPO JT DVSSFOUMZ XSJUJOH/DPQZJOH B GJMF. "OE UIF JNQMFNFOUBUJPO DBO CF EJGGFSFOU EFQFOEJOH PO 04 QMBUGPSN BT XFMM. 5IJT DPVME MFBE UP UIBU $BNFM UIJOLT UIF GJMF JT OPU MPDLFE CZ BOPUIFS QSPDFTT BOE TUBSU DPOTVNJOH JU. 5IFSFGPSF ZPV IBWF UP EP ZPV PXO JOWFTUJHBUJPO XIBU TVJUFT ZPVS FOWJSPONFOU. 5P IFMQ XJUI UIJT $BNFM QSPWJEFT EJGGFSFOU readLock PQUJPOT BOE doneFileName PQUJPO UIBU ZPV DBO VTF. 4FF BMTP UIF TFDUJPO Consuming files from folders where others drop files directly .
&YQSFTTJPO (TVDI BT 'JMF -BOHVBHF) VTFE UP EZOBNJDBMMZ TFU B EJGGFSFOU UBSHFU EJSFDUPSZ XIFO NPWJOH GJMFT BGUFS QSPDFTTJOH (DPOGJHVSFE WJB move EFGJOFE BCPWF) GBJMFE. 'PS FYBNQMF, UP NPWF GJMFT JOUP B .error TVCEJSFDUPSZ VTF: .error. /PUF: 8IFO NPWJOH UIF GJMFT UP UIF eGBJMd MPDBUJPO $BNFM XJMM E>KAIB UIF FSSPS BOE XJMM OPU QJDL VQ UIF GJMF BHBJO. *T VTFE UP JODMVEF GJMFT, JG GJMFOBNF NBUDIFT UIF SFHFY QBUUFSO. *T VTFE UP FYDMVEF GJMFT, JG GJMFOBNF NBUDIFT UIF SFHFY QBUUFSO. ">JBI 2.10: "OU TUZMF GJMUFS JODMVTJPO, GPS FYBNQMF antInclude=*/.txt. .VMUJQMF JODMVTJPOT NBZ CF TQFDJGJFE JO DPNNB-EFMJNJUFE GPSNBU. 4FF CFMPX GPS NPSF EFUBJMT BCPVU BOU QBUI GJMUFST. ">JBI 2.10: "OU TUZMF GJMUFS FYDMVTJPO. *G CPUI antInclude BOE antExclude BSF VTFE, antExclude UBLFT QSFDFEFODF PWFS antInclude. .VMUJQMF FYDMVTJPOT NBZ CF TQFDJGJFE JO DPNNB-EFMJNJUFE GPSNBU. 4FF CFMPX GPS NPSF EFUBJMT BCPVU BOU QBUI GJMUFST. ">JBI 2.11: "OU TUZMF GJMUFS XIJDI JT DBTF TFOTJUJWF PS OPU. 0QUJPO UP VTF UIF *EFNQPUFOU $POTVNFS &*1 QBUUFSO UP MFU $BNFM TLJQ BMSFBEZ QSPDFTTFE GJMFT. 8JMM CZ EFGBVMU VTF B NFNPSZ CBTFE -36$BDIF UIBU IPMET 1000 FOUSJFT. *G noop=true UIFO JEFNQPUFOU XJMM CF FOBCMFE BT XFMM UP BWPJE DPOTVNJOH UIF TBNF GJMFT PWFS BOE PWFS BHBJO. ">JBI 2.11: 5P VTF B DVTUPN JEFNQPUFOU LFZ. #Z EFGBVMU UIF BCTPMVUF QBUI PG UIF GJMF JT VTFE. :PV DBO VTF UIF 'JMF -BOHVBHF, GPS FYBNQMF UP VTF UIF GJMF OBNF BOE GJMF TJ[F, ZPV DBO EP:

moveFailed

null

include exclude antInclude

null null null

antExclude antFilterCaseSensitive idempotent

null true false

idempotentKey

Expression

idempotentKey=${file:name}-${file:size}
.

idempotentRepository

null

" QMVHHBCMF SFQPTJUPSZ PSH.BQBDIF.DBNFM.TQJ.*EFNQPUFOU3FQPTJUPSZ XIJDI CZ EFGBVMU VTF MemoryMessageIdRepository JG OPOF JT TQFDJGJFE BOE idempotent JT true. " QMVHHBCMF JO-QSPHSFTT SFQPTJUPSZ PSH.BQBDIF.DBNFM.TQJ.*EFNQPUFOU3FQPTJUPSZ. 5IF JO-QSPHSFTT SFQPTJUPSZ JT VTFE UP BDDPVOU UIF DVSSFOU JO QSPHSFTT GJMFT CFJOH DPOTVNFE. #Z EFGBVMU B NFNPSZ CBTFE SFQPTJUPSZ JT VTFE. 1MVHHBCMF GJMUFS BT B org.apache.camel.component.file.GenericFileFilter DMBTT. 8JMM TLJQ GJMFT JG GJMUFS SFUVSOT false JO JUT accept() NFUIPE. .PSF EFUBJMT JO TFDUJPO CFMPX. 1MVHHBCMF TPSUFS BT B KBWB.VUJM.$PNQBSBUPS<PSH.BQBDIF.DBNFM.DPNQPOFOU.GJMF.(FOFSJD'JMF> DMBTT.

inProgressRepository

memory

filter sorter

null null

620

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

sortBy

null

#VJMU-JO TPSU VTJOH UIF 'JMF -BOHVBHF. 4VQQPSUT OFTUFE TPSUT, TP ZPV DBO IBWF B TPSU CZ GJMF OBNF BOE BT B 2OE HSPVQ TPSU CZ NPEJGJFE EBUF. 4FF TPSUJOH TFDUJPO CFMPX GPS EFUBJMT. 6TFE CZ DPOTVNFS, UP POMZ QPMM UIF GJMFT JG JU IBT FYDMVTJWF SFBE-MPDL PO UIF GJMF (J.F. UIF GJMF JT OPU JOQSPHSFTT PS CFJOH XSJUUFO). $BNFM XJMM XBJU VOUJM UIF GJMF MPDL JT HSBOUFE. 5IJT PQUJPO QSPWJEFT UIF CVJME JO TUSBUFHJFT: markerFile $BNFM DSFBUFT B NBSLFS GJMF BOE UIFO IPMET B MPDL PO JU. 5IJT PQUJPO JT KLQ BWBJMBCMF GPS UIF '51 DPNQPOFOU. changed JT VTJOH GJMF MFOHUI/NPEJGJDBUJPO UJNFTUBNQ UP EFUFDU XIFUIFS UIF GJMF JT DVSSFOUMZ CFJOH DPQJFE PS OPU. 8JMM BU MFBTU VTF 1 TFD. UP EFUFSNJOF UIJT, TP UIJT PQUJPO DBOOPU DPOTVNF GJMFT BT GBTU BT UIF PUIFST, CVU DBO CF NPSF SFMJBCMF BT UIF +%, *0 "1* DBOOPU BMXBZT EFUFSNJOF XIFUIFS B GJMF JT DVSSFOUMZ CFJOH VTFE CZ BOPUIFS QSPDFTT. 5IF PQUJPO readLockCheckInterval DBO CF VTFE UP TFU UIF DIFDL GSFRVFODZ. 5IJT PQUJPO JT LKIV BWBJM GPS UIF '51 DPNQPOFOU GSPN ">JBI 2.8 POXBSET. /PUJDF UIBU GSPN ">JBI 2.10.1 POXBSET UIF '51 PQUJPO fastExistsCheck DBO CF FOBCMFE UP TQFFEVQ UIJT SFBE-PDL TUSBUFHZ, JG UIF '51 TFSWFS TVQQPSU UIF -*45 PQFSBUJPO XJUI B GVMM GJMF OBNF (TPNF TFSWFST NBZ OPU). fileLock JT GPS VTJOH java.nio.channels.FileLock. 5IJT PQUJPO JT KLQ BWBJM GPS UIF '51 DPNQPOFOU. 5IJT BQQSPBDI TIPVME CF BWPJEFE XIFO BDDFTTJOH B SFNPUF GJMF TZTUFN WJB B NPVOU/TIBSF VOMFTT UIBU GJMF TZTUFN TVQQPSUT EJTUSJCVUFE GJMF MPDLT. rename JT GPS VTJOH B USZ UP SFOBNF UIF GJMF BT B UFTU JG XF DBO HFU FYDMVTJWF SFBE-MPDL. none JT GPS OP SFBE MPDLT BU BMM. /PUJDF GSPN ">JBI 2.10 POXBSET UIF SFBE MPDLT changed, fileLock BOE rename XJMM BMTP VTF B markerFile BT XFMM, UP FOTVSF OPU QJDLJOH VQ GJMFT UIBU NBZ CF JO QSPDFTT CZ BOPUIFS $BNFM DPOTVNFS SVOOJOH PO BOPUIFS OPEF (FH DMVTUFS). 5IJT JT POMZ TVQQPSUFE CZ UIF GJMF DPNQPOFOU (OPU UIF GUQ DPNQPOFOU). 0QUJPOBM UJNFPVU JO NJMMJT GPS UIF SFBE-MPDL, JG TVQQPSUFE CZ UIF SFBE-MPDL. *G UIF SFBE-MPDL DPVME OPU CF HSBOUFE BOE UIF UJNFPVU USJHHFSFE, UIFO $BNFM XJMM TLJQ UIF GJMF. "U OFYU QPMM $BNFM, XJMM USZ UIF GJMF BHBJO, BOE UIJT UJNF NBZCF UIF SFBE-MPDL DPVME CF HSBOUFE. 6TF B WBMVF PG 0 PS MPXFS UP JOEJDBUF GPSFWFS. *O ">JBI 2.0 UIF EFGBVMU WBMVF JT 0. 4UBSUJOH XJUI ">JBI 2.1 UIF EFGBVMU WBMVF JT 10000. $VSSFOUMZ fileLock, changed BOE rename TVQQPSU UIF UJNFPVU. -LQF@B: 'PS '51 UIF EFGBVMU readLockTimeout WBMVF JT 20000 JOTUFBE PG 10000. ">JBI 2.6: *OUFSWBM JO NJMMJT GPS UIF SFBE-MPDL, JG TVQQPSUFE CZ UIF SFBE MPDL. 5IJT JOUFSWBM JT VTFE GPS TMFFQJOH CFUXFFO BUUFNQUT UP BDRVJSF UIF SFBE MPDL. 'PS FYBNQMF XIFO VTJOH UIF changed SFBE MPDL, ZPV DBO TFU B IJHIFS JOUFSWBM QFSJPE UP DBUFS GPS slow writes. 5IF EFGBVMU PG 1 TFD. NBZ CF too fast JG UIF QSPEVDFS JT WFSZ TMPX XSJUJOH UIF GJMF. 'PS '51 UIF EFGBVMU readLockCheckInterval JT 5000. ">JBI 2.10.1: 5IJT PQUJPO BQQMJFE POMZ GPS readLock=changed. 5IJT PQUJPO BMMPXT ZPV UP DPOGJHVSF B NJOJNVN GJMF MFOHUI. #Z EFGBVMU $BNFM FYQFDUT UIF GJMF UP DPOUBJO EBUB, BOE UIVT UIF EFGBVMU WBMVF JT 1. :PV DBO TFU UIJT PQUJPO UP [FSP, UP BMMPX DPOTVNJOH [FSP-MFOHUI GJMFT. ">JBI 2.5: 4JNJMBS UP startingDirectoryMustExist CVU UIJT BQQMJFT EVSJOH QPMMJOH SFDVSTJWF TVC EJSFDUPSJFT. ">JBI 2.6: *G QSPWJEFE, $BNFM XJMM POMZ DPOTVNF GJMFT JG B done GJMF FYJTUT. 5IJT PQUJPO DPOGJHVSFT XIBU GJMF OBNF UP VTF. &JUIFS ZPV DBO TQFDJGZ B GJYFE OBNF. 0S ZPV DBO VTF EZOBNJD QMBDFIPMEFST. 5IF done GJMF JT >IT>VP FYQFDUFE JO UIF TBNF GPMEFS BT UIF PSJHJOBM GJMF. 4FF using done file BOE writing done file TFDUJPOT GPS FYBNQMFT. 1MVHHBCMF SFBE-MPDL BT B org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy JNQMFNFOUBUJPO. "O JOUFHFS UP EFGJOF B NBYJNVN NFTTBHFT UP HBUIFS QFS QPMM. #Z EFGBVMU OP NBYJNVN JT TFU. $BO CF VTFE UP TFU B MJNJU PG F.H. 1000 UP BWPJE XIFO TUBSUJOH VQ UIF TFSWFS UIBU UIFSF BSF UIPVTBOET PG GJMFT. 4FU B WBMVF PG 0 PS OFHBUJWF UP EJTBCMFE JU. 4FF NPSF EFUBJMT BU #BUDI $POTVNFS. -LQF@B: *G UIJT PQUJPO JT JO VTF UIFO UIF 'JMF BOE '51 DPNQPOFOUT XJMM MJNJU ?BCLOB BOZ TPSUJOH. 'PS FYBNQMF JG ZPV IBWF 100000 GJMFT BOE VTF maxMessagesPerPoll=500, UIFO POMZ UIF GJSTU 500 GJMFT XJMM CF QJDLFE VQ, BOE UIFO TPSUFE. :PV DBO VTF UIF eagerMaxMessagesPerPoll PQUJPO BOE TFU UIJT UP false UP BMMPX UP TDBO BMM GJMFT GJSTU BOE UIFO TPSU BGUFSXBSET. ">JBI 2.9.3: "MMPXT GPS DPOUSPMMJOH XIFUIFS UIF MJNJU GSPN maxMessagesPerPoll JT FBHFS PS OPU. *G FBHFS UIFO UIF MJNJU JT EVSJOH UIF TDBOOJOH PG GJMFT. 8IFSF BT false XPVME TDBO BMM GJMFT, BOE UIFO QFSGPSN TPSUJOH. 4FUUJOH UIJT PQUJPO UP false BMMPXT GPS TPSUJOH BMM GJMFT GJSTU, BOE UIFO MJNJU UIF QPMM. .JOE UIBU UIJT SFRVJSFT B IJHIFS NFNPSZ VTBHF BT BMM GJMF EFUBJMT BSF JO NFNPSZ UP QFSGPSN UIF TPSUJOH. ">JBI 2.8: 5IF NJOJNVN EFQUI UP TUBSU QSPDFTTJOH XIFO SFDVSTJWFMZ QSPDFTTJOH B EJSFDUPSZ. 6TJOH minDepth=1 NFBOT UIF CBTF EJSFDUPSZ. 6TJOH minDepth=2 NFBOT UIF GJSTU TVC EJSFDUPSZ. 5IJT PQUJPO JT TVQQPSUFE CZ '51 DPOTVNFS GSPN ">JBI 2.8.2, 2.9 POXBSET. ">JBI 2.8: 5IF NBYJNVN EFQUI UP USBWFSTF XIFO SFDVSTJWFMZ QSPDFTTJOH B EJSFDUPSZ. 5IJT PQUJPO JT TVQQPSUFE CZ '51 DPOTVNFS GSPN ">JBI 2.8.2, 2.9 POXBSET. " QMVHHBCMF org.apache.camel.component.file.GenericFileProcessStrategy BMMPXJOH ZPV UP JNQMFNFOU ZPVS PXO readLock PQUJPO PS TJNJMBS. $BO BMTP CF VTFE XIFO TQFDJBM DPOEJUJPOT NVTU CF NFU CFGPSF B GJMF DBO CF DPOTVNFE, TVDI BT B TQFDJBM ready GJMF FYJTUT. *G UIJT PQUJPO JT TFU UIFO UIF readLock PQUJPO EPFT OPU BQQMZ. ">JBI 2.5: 8IFUIFS UIF TUBSUJOH EJSFDUPSZ NVTU FYJTU. .JOE UIBU UIF autoCreate PQUJPO JT EFGBVMU FOBCMFE, XIJDI NFBOT UIF TUBSUJOH EJSFDUPSZ JT OPSNBMMZ BVUP DSFBUFE JG JU EPFTO'U FYJTU. :PV DBO EJTBCMF autoCreate BOE FOBCMF UIJT UP FOTVSF UIF TUBSUJOH EJSFDUPSZ NVTU FYJTU. 8JMM UISPXO BO FYDFQUJPO JG UIF EJSFDUPSZ EPFTO'U FYJTU.

readLock

markerFile

readLockTimeout

10000

readLockCheckInterval

1000

readLockMinLength

directoryMustExist

false

doneFileName

null

exclusiveReadLockStrategy

null

maxMessagesPerPoll

eagerMaxMessagesPerPoll

true

minDepth

maxDepth

Integer.MAX_VALUE

processStrategy

null

startingDirectoryMustExist

false

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

621

pollStrategy

null

" QMVHHBCMF org.apache.camel.PollingConsumerPollStrategy BMMPXJOH ZPV UP QSPWJEF ZPVS DVTUPN JNQMFNFOUBUJPO UP DPOUSPM FSSPS IBOEMJOH VTVBMMZ PDDVSSFE EVSJOH UIF poll PQFSBUJPO ?BCLOB BO &YDIBOHF IBWF CFFO DSFBUFE BOE CFJOH SPVUFE JO $BNFM. *O PUIFS XPSET UIF FSSPS PDDVSSFE XIJMF UIF QPMMJOH XBT HBUIFSJOH JOGPSNBUJPO, GPS JOTUBODF BDDFTT UP B GJMF OFUXPSL GBJMFE TP $BNFM DBOOPU BDDFTT JU UP TDBO GPS GJMFT. 5IF EFGBVMU JNQMFNFOUBUJPO XJMM MPH UIF DBVTFE FYDFQUJPO BU WARN MFWFM BOE JHOPSF JU. ">JBI 2.9: *G UIF QPMMJOH DPOTVNFS EJE OPU QPMM BOZ GJMFT, ZPV DBO FOBCMF UIJT PQUJPO UP TFOE BO FNQUZ NFTTBHF (OP CPEZ) JOTUFBE. ">JBI 2.10: "MMPXT GPS CSJEHJOH UIF DPOTVNFS UP UIF $BNFM SPVUJOH &SSPS )BOEMFS, XIJDI NFBO BOZ FYDFQUJPOT PDDVSSFE XIJMF USZJOH UP QJDLVQ GJMFT, PS UIF MJLFT, XJMM OPX CF QSPDFTTFE BT B NFTTBHF BOE IBOEMFE CZ UIF SPVUJOH &SSPS )BOEMFS. #Z EFGBVMU UIF DPOTVNFS XJMM VTF UIF org.apache.camel.spi.ExceptionHandler UP EFBM XJUI FYDFQUJPOT, UIBU CZ EFGBVMU XJMM CF MPHHFE BU 8"3//&3303 MFWFM BOE JHOPSFE. 4FF GVSUIFS CFMPX PO UIJT QBHF GPSF NPSF EFUBJMT, BU TFDUJPO How to use the Camel error handler to deal with exceptions triggered outside the routing engine . ">JBI 2.10: "MMPXT GPS DPOGJHVSJOH B DVTUPN/TIBSFE UISFBE QPPM UP VTF GPS UIF DPOTVNFS. #Z EFGBVMU FBDI DPOTVNFS IBT JUT PXO TJOHMF UISFBEFE UISFBE QPPM. 5IJT PQUJPO BMMPXT ZPV UP TIBSF B UISFBE QPPM BNPOH NVMUJQMF GJMF DPOTVNFST.

sendEmptyMessageWhenIdle

false

consumer.bridgeErrorHandler

false

scheduledExecutorService

null

#BC>RIQ ?BE>SFLO CLO CFIB @LKPRJBO


` #Z EFGBVMU UIF GJMF JT MPDLFE GPS UIF EVSBUJPO PG UIF QSPDFTTJOH. ` "GUFS UIF SPVUF IBT DPNQMFUFE, GJMFT BSF NPWFE JOUP UIF .camel TVCEJSFDUPSZ, TP UIBU UIFZ BQQFBS UP CF EFMFUFE. ` 5IF 'JMF $POTVNFS XJMM BMXBZT TLJQ BOZ GJMF XIPTF OBNF TUBSUT XJUI B EPU, TVDI BT ., .camel, .m2 PS .groovy. ` 0OMZ GJMFT (OPU EJSFDUPSJFT) BSF NBUDIFE GPS WBMJE GJMFOBNF, JG PQUJPOT TVDI BT: include PS exclude BSF VTFE.

/OLAR@BO
->JB #BC>RIQ 5>IRB #BP@OFMQFLK
8IBU UP EP JG B GJMF BMSFBEZ FYJTUT XJUI UIF TBNF OBNF. 5IF GPMMPXJOH WBMVFT DBO CF TQFDJGJFE: .SBOOFAB, MMBKA, %>FI, (DKLOB, BOE Move. Override, XIJDI JT UIF EFGBVMU, SFQMBDFT UIF FYJTUJOH GJMF. Append BEET DPOUFOU UP UIF FYJTUJOH GJMF. Fail UISPXT B GenericFileOperationException, JOEJDBUJOH UIBU UIFSF JT BMSFBEZ BO FYJTUJOH GJMF. Ignore TJMFOUMZ JHOPSFT UIF QSPCMFN BOE ALBP KLQ PWFSSJEF UIF FYJTUJOH GJMF, CVU BTTVNFT FWFSZUIJOH JT PLBZ. 5IF Move PQUJPO SFRVJSFT ">JBI 2.10.1 POXBSET, BOE UIF DPSSFTQPOEJOH moveExisting PQUJPO UP CF DPOGJHVSFE BT XFMM. 5IF PQUJPO eagerDeleteTargetFile DBO CF VTFE UP DPOUSPM XIBU UP EP JG BO NPWJOH UIF GJMF, BOE UIFSF FYJTUT BMSFBEZ BO FYJTUJOH GJMF, PUIFSXJTF DBVTJOH UIF NPWF PQFSBUJPO UP GBJM. 5IF Move PQUJPO XJMM NPWF BOZ FYJTUJOH GJMFT, CFGPSF XSJUJOH UIF UBSHFU GJMF. 5IJT PQUJPO JT VTFE UP XSJUF UIF GJMF VTJOH B UFNQPSBSZ OBNF BOE UIFO, BGUFS UIF XSJUF JT DPNQMFUF, SFOBNF JU UP UIF SFBM OBNF. $BO CF VTFE UP JEFOUJGZ GJMFT CFJOH XSJUUFO BOE BMTP BWPJE DPOTVNFST (OPU VTJOH FYDMVTJWF SFBE MPDLT) SFBEJOH JO QSPHSFTT GJMFT. *T PGUFO VTFE CZ '51 XIFO VQMPBEJOH CJH GJMFT. ">JBI 2.1: 5IF P>JB BT tempPrefix PQUJPO CVU PGGFSJOH B NPSF GJOF HSBJOFE DPOUSPM PO UIF OBNJOH PG UIF UFNQPSBSZ GJMFOBNF BT JU VTFT UIF 'JMF -BOHVBHF. ">JBI 2.10.1: &YQSFTTJPO (TVDI BT 'JMF -BOHVBHF) VTFE UP DPNQVUF GJMF OBNF UP VTF XIFO fileExist=Move JT DPOGJHVSFE. 5P NPWF GJMFT JOUP B backup TVCEJSFDUPSZ KVTU FOUFS backup. 5IJT PQUJPO POMZ TVQQPSUT UIF GPMMPXJOH 'JMF -BOHVBHF UPLFOT: "GJMF:OBNF", "GJMF:OBNF.FYU", "GJMF:OBNF.OPFYU", "GJMF:POMZOBNF", "GJMF:POMZOBNF.OPFYU", "GJMF:FYU", BOE "GJMF:QBSFOU". /PUJDF UIF "GJMF:QBSFOU" JT OPU TVQQPSUFE CZ UIF '51 DPNQPOFOU, BT UIF '51 DPNQPOFOU DBO POMZ NPWF BOZ FYJTUJOH GJMFT UP B SFMBUJWF EJSFDUPSZ CBTFE PO DVSSFOU EJS BT CBTF. ">JBI 2.2: 8JMM LFFQ UIF MBTU NPEJGJFE UJNFTUBNQ GSPN UIF TPVSDF GJMF (JG BOZ). 8JMM VTF UIF Exchange.FILE_LAST_MODIFIED IFBEFS UP MPDBUFE UIF UJNFTUBNQ. 5IJT IFBEFS DBO DPOUBJO FJUIFS B java.util.Date PS long XJUI UIF UJNFTUBNQ. *G UIF UJNFTUBNQ FYJTUT BOE UIF PQUJPO JT FOBCMFE JU XJMM TFU UIJT UJNFTUBNQ PO UIF XSJUUFO GJMF. -LQB: 5IJT PQUJPO POMZ BQQMJFT UP UIF CFIB QSPEVDFS. :PV cannot VTF UIJT PQUJPO XJUI BOZ PG UIF GUQ QSPEVDFST.

fileExist

Override

tempPrefix

null

tempFileName

null

moveExisting

null

keepLastModified

false

622

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

eagerDeleteTargetFile

true

">JBI 2.3: 8IFUIFS PS OPU UP FBHFSMZ EFMFUF BOZ FYJTUJOH UBSHFU GJMF. 5IJT PQUJPO POMZ BQQMJFT XIFO ZPV VTF fileExists=Override BOE UIF tempFileName PQUJPO BT XFMM. :PV DBO VTF UIJT UP EJTBCMF (TFU JU UP GBMTF) EFMFUJOH UIF UBSHFU GJMF CFGPSF UIF UFNQ GJMF JT XSJUUFO. 'PS FYBNQMF ZPV NBZ XSJUF CJH GJMFT BOE XBOU UIF UBSHFU GJMF UP FYJTUT EVSJOH UIF UFNQ GJMF JT CFJOH XSJUUFO. 5IJT FOTVSF UIF UBSHFU GJMF JT POMZ EFMFUFE VOUJM UIF WFSZ MBTU NPNFOU, KVTU CFGPSF UIF UFNQ GJMF JT CFJOH SFOBNFE UP UIF UBSHFU GJMFOBNF. 'SPN ">JBI 2.10.1 POXBSET UIJT PQUJPO JT BMTP VTFE UP DPOUSPM XIFUIFS UP EFMFUF BOZ FYJTUJOH GJMFT XIFO fileExist=Move JT FOBCMFE, BOE BO FYJTUJOH GJMF FYJTUT. *G UIJT PQUJPO JT GBMTF, UIFO BO FYDFQUJPO XJMM CF UISPXO JG BO FYJTUJOH GJMF FYJTUFE, JG JUT USVF, UIFO UIF FYJTUJOH GJMF JT EFMFUFE CFGPSF UIF NPWF PQFSBUJPO. ">JBI 2.6: *G QSPWJEFE, UIFO $BNFM XJMM XSJUF B 2OE done GJMF XIFO UIF PSJHJOBM GJMF IBT CFFO XSJUUFO. 5IF done GJMF XJMM CF FNQUZ. 5IJT PQUJPO DPOGJHVSFT XIBU GJMF OBNF UP VTF. &JUIFS ZPV DBO TQFDJGZ B GJYFE OBNF. 0S ZPV DBO VTF EZOBNJD QMBDFIPMEFST. 5IF done GJMF XJMM >IT>VP CF XSJUUFO JO UIF TBNF GPMEFS BT UIF PSJHJOBM GJMF. 4FF writing done file TFDUJPO GPS FYBNQMFT. ">JBI 2.10.1: 6TFE UP TQFDJGZ JG B OVMM CPEZ JT BMMPXFE EVSJOH GJMF XSJUJOH. *G TFU UP USVF UIFO BO FNQUZ GJMF XJMM CF DSFBUFE, XIFO TFU UP GBMTF, BOE BUUFNQUJOH UP TFOE B OVMM CPEZ UP UIF GJMF DPNQPOFOU, B (FOFSJD'JMF8SJUF&YDFQUJPO PG '$BOOPU XSJUF OVMM CPEZ UP GJMF.' XJMM CF UISPXO. *G UIF AGJMF&YJTUA PQUJPO JT TFU UP '0WFSSJEF', UIFO UIF GJMF XJMM CF USVODBUFE, BOE JG TFU UP ABQQFOEA UIF GJMF XJMM SFNBJO VODIBOHFE. ">JBI 2.10.5/2.11: 8IFUIFS UP GPSDF TZODJOH XSJUFT UP UIF GJMF TZTUFN. :PV DBO UVSO UIJT PGG JG ZPV EP OPU XBOU UIJT MFWFM PG HVBSBOUFF, GPS FYBNQMF JG XSJUJOH UP MPHT / BVEJU MPHT FUD; UIJT XPVME ZJFME CFUUFS QFSGPSNBODF.

doneFileName

null

allowNullBody

false

forceWrites

true

#BC>RIQ ?BE>SFLO CLO CFIB MOLAR@BO


` #Z EFGBVMU JU XJMM PWFSSJEF BOZ FYJTUJOH GJMF, JG POF FYJTU XJUI UIF TBNF OBNF. ,LSB >KA #BIBQB LMBO>QFLKP "OZ NPWF PS EFMFUF PQFSBUJPOT JT FYFDVUFE BGUFS (QPTU DPNNBOE) UIF SPVUJOH IBT DPNQMFUFE; TP EVSJOH QSPDFTTJOH PG UIF Exchange UIF GJMF JT TUJMM MPDBUFE JO UIF JOCPY GPMEFS. -FUT JMMVTUSBUF UIJT XJUI BO FYBNQMF:
from("file://inbox?move=.done").to("bean:handleOrder");

8IFO B GJMF JT ESPQQFE JO UIF inbox GPMEFS, UIF GJMF DPOTVNFS OPUJDFT UIJT BOE DSFBUFT B OFX FileExchange UIBU JT SPVUFE UP UIF handleOrder CFBO. 5IF CFBO UIFO QSPDFTTFT UIF File PCKFDU. "U UIJT QPJOU JO UJNF UIF GJMF JT TUJMM MPDBUFE JO UIF inbox GPMEFS. "GUFS UIF CFBO DPNQMFUFT, BOE UIVT UIF SPVUF JT DPNQMFUFE, UIF GJMF DPOTVNFS XJMM QFSGPSN UIF NPWF PQFSBUJPO BOE NPWF UIF GJMF UP UIF .done TVC-GPMEFS. 5IF JLSB BOE MOB,LSB PQUJPOT TIPVME CF B EJSFDUPSZ OBNF, XIJDI DBO CF FJUIFS SFMBUJWF PS BCTPMVUF. *G SFMBUJWF, UIF EJSFDUPSZ JT DSFBUFE BT B TVC-GPMEFS GSPN XJUIJO UIF GPMEFS XIFSF UIF GJMF XBT DPOTVNFE. #Z EFGBVMU, $BNFM XJMM NPWF DPOTVNFE GJMFT UP UIF .camel TVC-GPMEFS SFMBUJWF UP UIF EJSFDUPSZ XIFSF UIF GJMF XBT DPOTVNFE. *G ZPV XBOU UP EFMFUF UIF GJMF BGUFS QSPDFTTJOH, UIF SPVUF TIPVME CF:
from("file://inobox?delete=true").to("bean:handleOrder");

8F IBWF JOUSPEVDFE B MOB NPWF PQFSBUJPO UP NPWF GJMFT ?BCLOB UIFZ BSF QSPDFTTFE. 5IJT BMMPXT ZPV UP NBSL XIJDI GJMFT IBWF CFFO TDBOOFE BT UIFZ BSF NPWFE UP UIJT TVC GPMEFS CFGPSF CFJOH QSPDFTTFE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

623

from("file://inbox?preMove=inprogress").to("bean:handleOrder");

:PV DBO DPNCJOF UIF MOB NPWF BOE UIF SFHVMBS NPWF:
from("file://inbox?preMove=inprogress&move=.done").to("bean:handleOrder");

4P JO UIJT TJUVBUJPO, UIF GJMF JT JO UIF inprogress GPMEFS XIFO CFJOH QSPDFTTFE BOE BGUFS JU'T QSPDFTTFE, JU'T NPWFE UP UIF .done GPMEFS.

%FKB DO>FKBA @LKQOLI LSBO ,LSB >KA /OB,LSB LMQFLK


5IF JLSB BOE MOB,LSB PQUJPO JT &YQSFTTJPO-CBTFE, TP XF IBWF UIF GVMM QPXFS PG UIF 'JMF -BOHVBHF UP EP BEWBODFE DPOGJHVSBUJPO PG UIF EJSFDUPSZ BOE OBNF QBUUFSO. $BNFM XJMM, JO GBDU, JOUFSOBMMZ DPOWFSU UIF EJSFDUPSZ OBNF ZPV FOUFS JOUP B 'JMF -BOHVBHF FYQSFTTJPO. 4P XIFO XF FOUFS move=.done $BNFM XJMM DPOWFSU UIJT JOUP: ${file:parent}/.done/${file:onlyname^. 5IJT JT POMZ EPOF JG $BNFM EFUFDUT UIBU ZPV IBWF OPU QSPWJEFE B $\ ^ JO UIF PQUJPO WBMVF ZPVSTFMG. 4P XIFO ZPV FOUFS B $\ ^ $BNFM XJMM KLQ DPOWFSU JU BOE UIVT ZPV IBWF UIF GVMM QPXFS. 4P JG XF XBOU UP NPWF UIF GJMF JOUP B CBDLVQ GPMEFS XJUI UPEBZ'T EBUF BT UIF QBUUFSO, XF DBO EP:
move=backup/${date:now:yyyyMMdd}/${file:name}

?LRQ JLSB%>FIBA
5IF moveFailed PQUJPO BMMPXT ZPV UP NPWF GJMFT UIBU @LRIA KLQ CF QSPDFTTFE TVDDFTGVMMZ UP BOPUIFS MPDBUJPO TVDI BT B FSSPS GPMEFS PG ZPVS DIPJDF. 'PS FYBNQMF UP NPWF UIF GJMFT JO BO FSSPS GPMEFS XJUI B UJNFTUBNQ ZPV DBO VTF moveFailed=/error/${file:name.noext}${date:now:yyyyMMddHHmmssSSS}.${file:ext^. 4FF NPSF FYBNQMFT BU 'JMF -BOHVBHF ,BPP>DB 'B>ABOP 5IF GPMMPXJOH IFBEFST BSF TVQQPSUFE CZ UIJT DPNQPOFOU:

%FIB MOLAR@BO LKIV


'B>ABO #BP@OFMQFLK

624

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

CamelFileName CamelFileNameProduced

4QFDJGJFT UIF OBNF PG UIF GJMF UP XSJUF (SFMBUJWF UP UIF FOEQPJOU EJSFDUPSZ). 5IF OBNF DBO CF B String; B String XJUI B 'JMF -BOHVBHF PS 4JNQMF FYQSFTTJPO; PS BO &YQSFTTJPO PCKFDU. *G JU'T null UIFO $BNFM XJMM BVUP-HFOFSBUF B GJMFOBNF CBTFE PO UIF NFTTBHF VOJRVF *%. 5IF BDUVBM BCTPMVUF GJMFQBUI (QBUI + OBNF) GPS UIF PVUQVU GJMF UIBU XBT XSJUUFO. 5IJT IFBEFS JT TFU CZ $BNFM BOE JUT QVSQPTF JT QSPWJEJOH FOE-VTFST XJUI UIF OBNF PG UIF GJMF UIBU XBT XSJUUFO. ">JBI 2.11: *T VTFE GPS PWFSSVMJOH CamelFileName IFBEFS BOE VTF UIF WBMVF JOTUFBE (CVU POMZ PODF, BT UIF QSPEVDFS XJMM SFNPWF UIJT IFBEFS BGUFS XSJUJOH UIF GJMF). 5IF WBMVF DBO CF POMZ CF B 4USJOH. /PUJDF UIBU JG UIF PQUJPO fileName IBT CFFO DPOGJHVSFE, UIFO UIJT JT TUJMM CFJOH FWBMVBUFE.

CamelOverruleFileName

%FIB @LKPRJBO LKIV


'B>ABO
CamelFileName CamelFileNameOnly CamelFileAbsolute CamelFileAbsolutePath CamelFilePath CamelFileRelativePath CamelFileParent CamelFileLength CamelFileLastModified

#BP@OFMQFLK
/BNF PG UIF DPOTVNFE GJMF BT B SFMBUJWF GJMF QBUI XJUI PGGTFU GSPN UIF TUBSUJOH EJSFDUPSZ DPOGJHVSFE PO UIF FOEQPJOU. 0OMZ UIF GJMF OBNF (UIF OBNF XJUI OP MFBEJOH QBUIT). " boolean PQUJPO TQFDJGZJOH XIFUIFS UIF DPOTVNFE GJMF EFOPUFT BO BCTPMVUF QBUI PS OPU. 4IPVME OPSNBMMZ CF false GPS SFMBUJWF QBUIT. "CTPMVUF QBUIT TIPVME OPSNBMMZ OPU CF VTFE CVU XF BEEFE UP UIF NPWF PQUJPO UP BMMPX NPWJOH GJMFT UP BCTPMVUF QBUIT. #VU DBO CF VTFE FMTFXIFSF BT XFMM. 5IF BCTPMVUF QBUI UP UIF GJMF. 'PS SFMBUJWF GJMFT UIJT QBUI IPMET UIF SFMBUJWF QBUI JOTUFBE. 5IF GJMF QBUI. 'PS SFMBUJWF GJMFT UIJT JT UIF TUBSUJOH EJSFDUPSZ + UIF SFMBUJWF GJMFOBNF. 'PS BCTPMVUF GJMFT UIJT JT UIF BCTPMVUF QBUI. 5IF SFMBUJWF QBUI. 5IF QBSFOU QBUI. " long WBMVF DPOUBJOJOH UIF GJMF TJ[F. " Date WBMVF DPOUBJOJOH UIF MBTU NPEJGJFE UJNFTUBNQ PG UIF GJMF.

!>Q@E "LKPRJBO 5IJT DPNQPOFOU JNQMFNFOUT UIF #BUDI $POTVNFS.

$U@E>KDB /OLMBOQFBP, CFIB @LKPRJBO LKIV


"T UIF GJMF DPOTVNFS JT BatchConsumer JU TVQQPSUT CBUDIJOH UIF GJMFT JU QPMMT. #Z CBUDIJOH JU NFBOT UIBU $BNFM XJMM BEE TPNF QSPQFSUJFT UP UIF &YDIBOHF TP ZPV LOPX UIF OVNCFS PG GJMFT QPMMFE UIF DVSSFOU JOEFY JO UIBU PSEFS.
/OLMBOQV
CamelBatchSize CamelBatchIndex CamelBatchComplete

#BP@OFMQFLK
5IF UPUBM OVNCFS PG GJMFT UIBU XBT QPMMFE JO UIJT CBUDI. 5IF DVSSFOU JOEFY PG UIF CBUDI. 4UBSUT GSPN 0. " boolean WBMVF JOEJDBUJOH UIF MBTU &YDIBOHF JO UIF CBUDI. *T POMZ true GPS UIF MBTU FOUSZ.

5IJT BMMPXT ZPV GPS JOTUBODF UP LOPX IPX NBOZ GJMFT FYJTUT JO UIJT CBUDI BOE GPS JOTUBODF MFU UIF "HHSFHBUPS2 BHHSFHBUF UIJT OVNCFS PG GJMFT. 4PFKD @E>OPBQ S>FI>?IB >P LC ">JBI 2.9.3 5IF DIBSTFU PQUJPO BMMPXT GPS DPOGJHVSJOH BO FODPEJOH PG UIF GJMFT PO CPUI UIF DPOTVNFS BOE QSPEVDFS FOEQPJOUT. 'PS FYBNQMF JG ZPV SFBE VUG-8 GJMFT, BOE XBOU UP DPOWFSU UIF GJMFT UP JTP-8859-1, ZPV DBO EP:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

625

from("file:inbox?charset=utf-8") .to("file:outbox?charset=iso-8859-1")

:PV DBO BMTP VTF UIF convertBodyTo JO UIF SPVUF. *O UIF FYBNQMF CFMPX XF IBWF TUJMM JOQVU GJMFT JO VUG-8 GPSNBU, CVU XF XBOU UP DPOWFSU UIF GJMF DPOUFOU UP B CZUF BSSBZ JO JTP-8859-1 GPSNBU. "OE UIFO MFU B CFBO QSPDFTT UIF EBUB. #FGPSF XSJUJOH UIF DPOUFOU UP UIF PVUCPY GPMEFS VTJOH UIF DVSSFOU DIBSTFU.
from("file:inbox?charset=utf-8") .convertBodyTo(byte[].class, "iso-8859-1") .to("bean:myBean") .to("file:outbox");

*G ZPV PNJU UIF DIBSTFU PO UIF DPOTVNFS FOEQPJOU, UIFO $BNFM EPFT OPU LOPX UIF DIBSTFU PG UIF GJMF, BOE XPVME CZ EFGBVMU VTF "65'-8". )PXFWFS ZPV DBO DPOGJHVSF B +7. TZTUFN QSPQFSUZ UP PWFSSJEF BOE VTF B EJGGFSFOU EFGBVMU FODPEJOH XJUI UIF LFZ org.apache.camel.default.charset. *O UIF FYBNQMF CFMPX UIJT DPVME CF B QSPCMFN JG UIF GJMFT JT OPU JO 65'-8 FODPEJOH, XIJDI XPVME CF UIF EFGBVMU FODPEJOH GPS SFBE UIF GJMFT. *O UIJT FYBNQMF XIFO XSJUJOH UIF GJMFT, UIF DPOUFOU IBT BMSFBEZ CFFO DPOWFSUFE UP B CZUF BSSBZ, BOE UIVT XPVME XSJUF UIF DPOUFOU EJSFDUMZ BT JT (XJUIPVU BOZ GVSUIFS FODPEJOHT).
from("file:inbox") .convertBodyTo(byte[].class, "iso-8859-1") .to("bean:myBean") .to("file:outbox");

:PV DBO BMTP PWFSSJEF BOE DPOUSPM UIF FODPEJOH EZOBNJD XIFO XSJUJOH GJMFT, CZ TFUUJOH B QSPQFSUZ PO UIF FYDIBOHF XJUI UIF LFZ Exchange.CHARSET_NAME. 'PS FYBNQMF JO UIF SPVUF CFMPX XF TFU UIF QSPQFSUZ XJUI B WBMVF GSPN B NFTTBHF IFBEFS.
from("file:inbox") .convertBodyTo(byte[].class, "iso-8859-1") .to("bean:myBean") .setProperty(Exchange.CHARSET_NAME, header("someCharsetHeader")) .to("file:outbox");

8F TVHHFTU UP LFFQ UIJOHT TJNQMFS, TP JG ZPV QJDLVQ GJMFT XJUI UIF TBNF FODPEJOH, BOE XBOU UP XSJUF UIF GJMFT JO B TQFDJGJD FODPEJOH, UIFO GBWPS UP VTF UIF charset PQUJPO PO UIF FOEQPJOUT. /PUJDF UIBU JG ZPV IBWF FYQMJDJU DPOGJHVSFE B charset PQUJPO PO UIF FOEQPJOU, UIFO UIBU DPOGJHVSBUJPO JT VTFE, SFHBSEMFTT PG UIF Exchange.CHARSET_NAME QSPQFSUZ. *G ZPV IBWF TPNF JTTVFT UIFO ZPV DBO FOBCMF %&#6( MPHHJOH PO org.apache.camel.component.file, BOE $BNFM MPHT XIFO JU SFBET/XSJUF B GJMF VTJOH B

626

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

TQFDJGJD DIBSTFU. 'PS FYBNQMF UIF SPVUF CFMPX XJMM MPH UIF GPMMPXJOH:
from("file:inbox?charset=utf-8") .to("file:outbox?charset=iso-8859-1")

"OE UIF MPHT:


DEBUG GenericFileConverter - Read file /Users/davsclaus/workspace/camel/ camel-core/target/charset/input/input.txt with charset utf-8 DEBUG FileOperations - Using Reader to write file: target/charset/ output.txt with charset: iso-8859-1

"LJJLK DLQ@E>P TFQE CLIABO >KA CFIBK>JBP 8IFO $BNFM JT QSPEVDJOH GJMFT (XSJUJOH GJMFT) UIFSF BSF B GFX HPUDIBT BGGFDUJOH IPX UP TFU B GJMFOBNF PG ZPVS DIPJDF. #Z EFGBVMU, $BNFM XJMM VTF UIF NFTTBHF *% BT UIF GJMFOBNF, BOE TJODF UIF NFTTBHF *% JT OPSNBMMZ B VOJRVF HFOFSBUFE *%, ZPV XJMM FOE VQ XJUI GJMFOBNFT TVDI BT: IDMACHINENAME-2443-1211718892437-1-0. *G TVDI B GJMFOBNF JT OPU EFTJSFE, UIFO ZPV NVTU QSPWJEF B GJMFOBNF JO UIF CamelFileName NFTTBHF IFBEFS. 5IF DPOTUBOU, Exchange.FILE_NAME, DBO BMTP CF VTFE. 5IF TBNQMF DPEF CFMPX QSPEVDFT GJMFT VTJOH UIF NFTTBHF *% BT UIF GJMFOBNF:
from("direct:report").to("file:target/reports");

5P VTF report.txt BT UIF GJMFOBNF ZPV IBWF UP EP:


from("direct:report").setHeader(Exchange.FILE_NAME, constant("report.txt")).to( "file:target/reports");

... UIF TBNF BT BCPWF, CVU XJUI CamelFileName:


from("direct:report").setHeader("CamelFileName", constant("report.txt")).to( "file:target/reports");

"OE B TZOUBY XIFSF XF TFU UIF GJMFOBNF PO UIF FOEQPJOU XJUI UIF CFIB->JB 63* PQUJPO.
from("direct:report").to("file:target/reports/?fileName=report.txt");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

627

%FIBK>JB $UMOBPPFLK 'JMFOBNF DBO CF TFU FJUIFS VTJOH UIF BUMOBPPFLK PQUJPO PS BT B TUSJOH-CBTFE 'JMF -BOHVBHF FYQSFTTJPO JO UIF CamelFileName IFBEFS. 4FF UIF 'JMF -BOHVBHF GPS TZOUBY BOE TBNQMFT. "LKPRJFKD CFIBP COLJ CLIABOP TEBOB LQEBOP AOLM CFIBP AFOB@QIV #FXBSF JG ZPV DPOTVNF GJMFT GSPN B GPMEFS XIFSF PUIFS BQQMJDBUJPOT XSJUF GJMFT EJSFDUMZ. 5BLF B MPPL BU UIF EJGGFSFOU readLock PQUJPOT UP TFF XIBU TVJUT ZPVS VTF DBTFT. 5IF CFTU BQQSPBDI JT IPXFWFS UP XSJUF UP BOPUIFS GPMEFS BOE BGUFS UIF XSJUF NPWF UIF GJMF JO UIF ESPQ GPMEFS. )PXFWFS JG ZPV XSJUF GJMFT EJSFDUMZ UP UIF ESPQ GPMEFS UIFO UIF PQUJPO changed DPVME CFUUFS EFUFDU XIFUIFS B GJMF JT DVSSFOUMZ CFJOH XSJUUFO/DPQJFE BT JU VTFT B GJMF DIBOHFE BMHPSJUIN UP TFF XIFUIFS UIF GJMF TJ[F / NPEJGJDBUJPO DIBOHFT PWFS B QFSJPE PG UJNF. 5IF PUIFS SFBE MPDL PQUJPOT SFMZ PO +BWB 'JMF "1* UIBU TBEMZ JT OPU BMXBZT WFSZ HPPE BU EFUFDUJOH UIJT. :PV NBZ BMTP XBOU UP MPPL BU UIF doneFileName PQUJPO, XIJDI VTFT B NBSLFS GJMF (EPOF) UP TJHOBM XIFO B GJMF JT EPOF BOE SFBEZ UP CF DPOTVNFE. 4PFKD ALKB CFIBP S>FI>?IB >P LC ">JBI 2.6 4FF BMTP TFDUJPO writing done files CFMPX. *G ZPV XBOU POMZ UP DPOTVNF GJMFT XIFO B EPOF GJMF FYJTUT, UIFO ZPV DBO VTF UIF doneFileName PQUJPO PO UIF FOEQPJOU.
from("file:bar?doneFileName=done");

8JMM POMZ DPOTVNF GJMFT GSPN UIF CBS GPMEFS, JG B GJMF OBNF EPOF FYJTUT JO UIF TBNF EJSFDUPSZ BT UIF UBSHFU GJMFT. $BNFM XJMM BVUPNBUJDBMMZ EFMFUF UIF EPOF GJMF XIFO JU'T EPOF DPOTVNJOH UIF GJMFT. 'SPN $BNFM 2.9.3 POXBSET $BNFM XJMM OPU BVUPNBUJD EFMFUF UIF EPOF GJMF JG noop=true JT DPOGJHVSFE. )PXFWFS JUT NPSF DPNNPO UP IBWF POF EPOF GJMF QFS UBSHFU GJMF. 5IJT NFBOT UIFSF JT B 1:1 DPSSFMBUJPO. 5P EP UIJT ZPV NVTU VTF EZOBNJD QMBDFIPMEFST JO UIF doneFileName PQUJPO. $VSSFOUMZ $BNFM TVQQPSUT UIF GPMMPXJOH UXP EZOBNJD UPLFOT: file:name BOE file:name.noext XIJDI NVTU CF FODMPTFE JO $\ ^. 5IF DPOTVNFS POMZ TVQQPSUT UIF TUBUJD QBSU PG UIF EPOF GJMF OBNF BT FJUIFS QSFGJY PS TVGGJY (OPU CPUI).
from("file:bar?doneFileName=${file:name}.done");

*O UIJT FYBNQMF POMZ GJMFT XJMM CF QPMMFE JG UIFSF FYJTUT B EPOF GJMF XJUI UIF OBNF file name.EPOF. 'PS FYBNQMF hello.txt - JT UIF GJMF UP CF DPOTVNFE hello.txt.done - JT UIF BTTPDJBUFE EPOF GJMF :PV DBO BMTP VTF B QSFGJY GPS UIF EPOF GJMF, TVDI BT:
628 $) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("file:bar?doneFileName=ready-${file:name}");

hello.txt - JT UIF GJMF UP CF DPOTVNFE ready-hello.txt - JT UIF BTTPDJBUFE EPOF GJMF 6OFQFKD ALKB CFIBP S>FI>?IB >P LC ">JBI 2.6 "GUFS ZPV IBWF XSJUUFO BG GJMF ZPV NBZ XBOU UP XSJUF BO BEEJUJPOBM done GJMF BT B LJOEB PG NBSLFS, UP JOEJDBUF UP PUIFST UIBU UIF GJMF JT GJOJTIFE BOE IBT CFFO XSJUUFO. 5P EP UIBU ZPV DBO VTF UIF doneFileName PQUJPO PO UIF GJMF QSPEVDFS FOEQPJOU.
.to("file:bar?doneFileName=done");

8JMM TJNQMZ DSFBUF B GJMF OBNFE done JO UIF TBNF EJSFDUPSZ BT UIF UBSHFU GJMF. )PXFWFS JUT NPSF DPNNPO UP IBWF POF EPOF GJMF QFS UBSHFU GJMF. 5IJT NFBOT UIFSF JT B 1:1 DPSSFMBUJPO. 5P EP UIJT ZPV NVTU VTF EZOBNJD QMBDFIPMEFST JO UIF doneFileName PQUJPO. $VSSFOUMZ $BNFM TVQQPSUT UIF GPMMPXJOH UXP EZOBNJD UPLFOT: file:name BOE file:name.noext XIJDI NVTU CF FODMPTFE JO $\ ^.
.to("file:bar?doneFileName=done-${file:name}");

8JMM GPS FYBNQMF DSFBUF B GJMF OBNFE done-foo.txt JG UIF UBSHFU GJMF XBT foo.txt JO UIF TBNF EJSFDUPSZ BT UIF UBSHFU GJMF.
.to("file:bar?doneFileName=${file:name}.done");

8JMM GPS FYBNQMF DSFBUF B GJMF OBNFE foo.txt.done JG UIF UBSHFU GJMF XBT foo.txt JO UIF TBNF EJSFDUPSZ BT UIF UBSHFU GJMF.
.to("file:bar?doneFileName=${file:name.noext}.done");

8JMM GPS FYBNQMF DSFBUF B GJMF OBNFE foo.done JG UIF UBSHFU GJMF XBT foo.txt JO UIF TBNF EJSFDUPSZ BT UIF UBSHFU GJMF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

629

2>JMIBP

1B>A COLJ > AFOB@QLOV >KA TOFQB QL >KLQEBO AFOB@QLOV


from("file://inputdir/?delete=true").to("file://outputdir")

1B>A COLJ > AFOB@QLOV >KA TOFQB QL >KLQEBO AFOB@QLOV RPFKD > LSBOORIB AVK>JF@ K>JB
from("file://inputdir/?delete=true").to("file://outputdir?overruleFile=copy-of-${file:name}")

-JTUFO PO B EJSFDUPSZ BOE DSFBUF B NFTTBHF GPS FBDI GJMF ESPQQFE UIFSF. $PQZ UIF DPOUFOUT UP UIF outputdir BOE EFMFUF UIF GJMF JO UIF inputdir.

1B>AFKD OB@ROPFSBIV COLJ > AFOB@QLOV >KA TOFQFKD QL >KLQEBO


from("file://inputdir/?recursive=true&delete=true").to("file://outputdir")

-JTUFO PO B EJSFDUPSZ BOE DSFBUF B NFTTBHF GPS FBDI GJMF ESPQQFE UIFSF. $PQZ UIF DPOUFOUT UP UIF outputdir BOE EFMFUF UIF GJMF JO UIF inputdir. 8JMM TDBO SFDVSTJWFMZ JOUP TVCEJSFDUPSJFT. 8JMM MBZ PVU UIF GJMFT JO UIF TBNF EJSFDUPSZ TUSVDUVSF JO UIF outputdir BT UIF inputdir, JODMVEJOH BOZ TVC-EJSFDUPSJFT.
inputdir/foo.txt inputdir/sub/bar.txt

8JMM SFTVMU JO UIF GPMMPXJOH PVUQVU MBZPVU:


outputdir/foo.txt outputdir/sub/bar.txt

4PFKD CI>QQBK *G ZPV XBOU UP TUPSF UIF GJMFT JO UIF PVUQVUEJS EJSFDUPSZ JO UIF TBNF EJSFDUPSZ, EJTSFHBSEJOH UIF TPVSDF EJSFDUPSZ MBZPVU (F.H. UP GMBUUFO PVU UIF QBUI), ZPV KVTU BEE UIF flatten=true PQUJPO PO UIF GJMF QSPEVDFS TJEF:

630

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("file://inputdir/?recursive=true&delete=true").to("file://outputdir?flatten=true")

8JMM SFTVMU JO UIF GPMMPXJOH PVUQVU MBZPVU:


outputdir/foo.txt outputdir/bar.txt

1B>AFKD COLJ > AFOB@QLOV >KA QEB ABC>RIQ JLSB LMBO>QFLK


$BNFM XJMM CZ EFGBVMU NPWF BOZ QSPDFTTFE GJMF JOUP B .camel TVCEJSFDUPSZ JO UIF EJSFDUPSZ UIF GJMF XBT DPOTVNFE GSPN.
from("file://inputdir/?recursive=true&delete=true").to("file://outputdir")

"GGFDUT UIF MBZPVU BT GPMMPXT: ?BCLOB


inputdir/foo.txt inputdir/sub/bar.txt

>CQBO
inputdir/.camel/foo.txt inputdir/sub/.camel/bar.txt outputdir/foo.txt outputdir/sub/bar.txt

1B>A COLJ > AFOB@QLOV >KA MOL@BPP QEB JBPP>DB FK G>S>


from("file://inputdir/").process(new Processor() { public void process(Exchange exchange) throws Exception { Object body = exchange.getIn().getBody(); // do some business logic with the input body } });

5IF CPEZ XJMM CF B File PCKFDU UIBU QPJOUT UP UIF GJMF UIBU XBT KVTU ESPQQFE JOUP UIF inputdir EJSFDUPSZ.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

631

6OFQFKD QL CFIBP
$BNFM JT PG DPVSTF BMTP BCMF UP XSJUF GJMFT, J.F. QSPEVDF GJMFT. *O UIF TBNQMF CFMPX XF SFDFJWF TPNF SFQPSUT PO UIF 4&%" RVFVF UIBU XF QSPDFTT CFGPSF UIFZ BSF XSJUUFO UP B EJSFDUPSZ.
public void testToFile() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedMessageCount(1); mock.expectedFileExists("target/test-reports/report.txt"); template.sendBody("direct:reports", "This is a great report"); assertMockEndpointsSatisfied(); } protected JndiRegistry createRegistry() throws Exception { // bind our processor in the registry with the given id JndiRegistry reg = super.createRegistry(); reg.bind("processReport", new ProcessReport()); return reg; } protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // the reports from the seda queue is processed by our processor // before they are written to files in the target/reports directory from("direct:reports").processRef("processReport").to("file://target/ test-reports", "mock:result"); } }; } private static class ProcessReport implements Processor { public void process(Exchange exchange) throws Exception { String body = exchange.getIn().getBody(String.class); // do some business logic here // set the output to the file exchange.getOut().setBody(body); // set the output filename using java code logic, notice that this is done by setting // a special header property of the out exchange exchange.getOut().setHeader(Exchange.FILE_NAME, "report.txt"); } }

632

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

6OFQB QL PR?AFOB@QLOV RPFKD Exchange.FILE_NAME


6TJOH B TJOHMF SPVUF, JU JT QPTTJCMF UP XSJUF B GJMF UP BOZ OVNCFS PG TVCEJSFDUPSJFT. *G ZPV IBWF B SPVUF TFUVQ BT TVDI:
<route> <from uri="bean:myBean"/> <to uri="file:/rootDirectory"/> </route>

:PV DBO IBWF myBean TFU UIF IFBEFS Exchange.FILE_NAME UP WBMVFT TVDI BT:
Exchange.FILE_NAME = hello.txt => /rootDirectory/hello.txt Exchange.FILE_NAME = foo/bye.txt => /rootDirectory/foo/bye.txt

5IJT BMMPXT ZPV UP IBWF B TJOHMF SPVUF UP XSJUF GJMFT UP NVMUJQMF EFTUJOBUJPOT.

4PFKD BUMOBPPFLK CLO CFIBK>JBP


*O UIJT TBNQMF XF XBOU UP NPWF DPOTVNFE GJMFT UP B CBDLVQ GPMEFS VTJOH UPEBZ'T EBUF BT B TVCGPMEFS OBNF:
from("file://inbox?move=backup/${date:now:yyyyMMdd}/${file:name}").to("...");

4FF 'JMF -BOHVBHF GPS NPSF TBNQMFT. SLFAFKD OB>AFKD QEB P>JB CFIB JLOB QE>K LK@B (FABJMLQBKQ @LKPRJBO) $BNFM TVQQPSUT *EFNQPUFOU $POTVNFS EJSFDUMZ XJUIJO UIF DPNQPOFOU TP JU XJMM TLJQ BMSFBEZ QSPDFTTFE GJMFT. 5IJT GFBUVSF DBO CF FOBCMFE CZ TFUUJOH UIF idempotent=true PQUJPO.
from("file://inbox?idempotent=true").to("...");

$BNFM VTFT UIF BCTPMVUF GJMF OBNF BT UIF JEFNQPUFOU LFZ, UP EFUFDU EVQMJDBUF GJMFT. 'SPN ">JBI 2.11 POXBSET ZPV DBO DVTUPNJ[F UIJT LFZ CZ VTJOH BO FYQSFTTJPO JO UIF JEFNQPUFOU,FZ PQUJPO. 'PS FYBNQMF UP VTF CPUI UIF OBNF BOE UIF GJMF TJ[F BT UIF LFZ
<route> <from uri="file://inbox?idempotent=true&amp;idempotentKey=${file:name}-${file-size}"/> <to uri="bean:processInbox"/> </route>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

633

#Z EFGBVMU $BNFM VTFT B JO NFNPSZ CBTFE TUPSF GPS LFFQJOH USBDL PG DPOTVNFE GJMFT, JU VTFT B MFBTU SFDFOUMZ VTFE DBDIF IPMEJOH VQ UP 1000 FOUSJFT. :PV DBO QMVHJO ZPVS PXO JNQMFNFOUBUJPO PG UIJT TUPSF CZ VTJOH UIF idempotentRepository PQUJPO VTJOH UIF # TJHO JO UIF WBMVF UP JOEJDBUF JU'T B SFGFSSJOH UP B CFBO JO UIF 3FHJTUSZ XJUI UIF TQFDJGJFE id.
<!-- define our store as a plain spring bean --> <bean id="myStore" class="com.mycompany.MyIdempotentStore"/> <route> <from uri="file://inbox?idempotent=true&amp;idempotentRepository=#myStore"/> <to uri="bean:processInbox"/> </route>

$BNFM XJMM MPH BU DEBUG MFWFM JG JU TLJQT B GJMF CFDBVTF JU IBT CFFO DPOTVNFE CFGPSF:
DEBUG FileConsumer is idempotent and the file has been consumed before. Will skip this file: target\idempotent\report.txt

4PFKD > CFIB ?>PBA FABJMLQBKQ OBMLPFQLOV


*O UIJT TFDUJPO XF XJMM VTF UIF GJMF CBTFE JEFNQPUFOU SFQPTJUPSZ org.apache.camel.processor.idempotent.FileIdempotentRepository JOTUFBE PG UIF JO-NFNPSZ CBTFE UIBU JT VTFE BT EFGBVMU. 5IJT SFQPTJUPSZ VTFT B 1TU MFWFM DBDIF UP BWPJE SFBEJOH UIF GJMF SFQPTJUPSZ. *U XJMM POMZ VTF UIF GJMF SFQPTJUPSZ UP TUPSF UIF DPOUFOU PG UIF 1TU MFWFM DBDIF. 5IFSFCZ UIF SFQPTJUPSZ DBO TVSWJWF TFSWFS SFTUBSUT. *U XJMM MPBE UIF DPOUFOU PG UIF GJMF JOUP UIF 1TU MFWFM DBDIF VQPO TUBSUVQ. 5IF GJMF TUSVDUVSF JT WFSZ TJNQMF BT JU TUPSFT UIF LFZ JO TFQBSBUF MJOFT JO UIF GJMF. #Z EFGBVMU, UIF GJMF TUPSF IBT B TJ[F MJNJU PG 1NC. 8IFO UIF GJMF HSPXT MBSHFS $BNFM XJMM USVODBUF UIF GJMF TUPSF, SFCVJMEJOH UIF DPOUFOU CZ GMVTIJOH UIF 1TU MFWFM DBDIF JOUP B GSFTI FNQUZ GJMF. 8F DPOGJHVSF PVS SFQPTJUPSZ VTJOH 4QSJOH 9.- DSFBUJOH PVS GJMF JEFNQPUFOU SFQPTJUPSZ BOE EFGJOF PVS GJMF DPOTVNFS UP VTF PVS SFQPTJUPSZ XJUI UIF idempotentRepository VTJOH # TJHO UP JOEJDBUF 3FHJTUSZ MPPLVQ:
<!-- this is our file based idempotent store configured to use the .filestore.dat as file --> <bean id="fileStore" class="org.apache.camel.processor.idempotent.FileIdempotentRepository"> <!-- the filename for the store --> <property name="fileStore" value="target/fileidempotent/.filestore.dat"/> <!-- the max filesize in bytes for the file. Camel will trunk and flush the cache if the file gets bigger --> <property name="maxFileStoreSize" value="512000"/> <!-- the number of elements in our store --> <property name="cacheSize" value="250"/> </bean>

634

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="file://target/ fileidempotent/?idempotent=true&amp;idempotentRepository=#fileStore&amp;move=done/${file:name}"/> <to uri="mock:result"/> </route> </camelContext>

4PFKD > )/

?>PBA FABJMLQBKQ OBMLPFQLOV

*O UIJT TFDUJPO XF XJMM VTF UIF +1" CBTFE JEFNQPUFOU SFQPTJUPSZ JOTUFBE PG UIF JO-NFNPSZ CBTFE UIBU JT VTFE BT EFGBVMU. 'JSTU XF OFFE B QFSTJTUFODF-VOJU JO META-INF/persistence.xml XIFSF XF OFFE UP VTF UIF DMBTT org.apache.camel.processor.idempotent.jpa.MessageProcessed BT NPEFM.
<persistence-unit name="idempotentDb" transaction-type="RESOURCE_LOCAL"> <class>org.apache.camel.processor.idempotent.jpa.MessageProcessed</class> <properties> <property name="openjpa.ConnectionURL" value="jdbc:derby:target/ idempotentTest;create=true"/> <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/> <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/> </properties> </persistence-unit>

5IFO XF OFFE UP TFUVQ B 4QSJOH jpaTemplate JO UIF TQSJOH 9.- GJMF:


<!-- this is standard spring JPA configuration --> <bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> <!-- we use idempotentDB as the persitence unit name defined in the persistence.xml file --> <property name="persistenceUnitName" value="idempotentDb"/> </bean>

"OE GJOBMMZ XF DBO DSFBUF PVS +1" JEFNQPUFOU SFQPTJUPSZ JO UIF TQSJOH 9.- GJMF BT XFMM:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

635

<!-- we define our jpa based idempotent repository we want to use in the file consumer --> <bean id="jpaStore" class="org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository"> <!-- Here we refer to the spring jpaTemplate --> <constructor-arg index="0" ref="jpaTemplate"/> <!-- This 2nd parameter is the name (= a cateogry name). You can have different repositories with different names --> <constructor-arg index="1" value="FileConsumer"/> </bean>

"OE ZFT UIFO XF KVTU OFFE UP SFGFS UP UIF GM>2QLOB CFBO JO UIF GJMF DPOTVNFS FOEQPJOU VTJOH UIF idempotentRepository VTJOH UIF # TZOUBY PQUJPO:
<route> <from uri="file://inbox?idempotent=true&amp;idempotentRepository=#jpaStore"/> <to uri="bean:processInbox"/> </route>

%FIQBO RPFKD LOD.>M>@EB.@>JBI.@LJMLKBKQ.CFIB.&BKBOF@%FIB%FIQBO $BNFM TVQQPSUT QMVHHBCMF GJMUFSJOH TUSBUFHJFT. :PV DBO UIFO DPOGJHVSF UIF FOEQPJOU XJUI TVDI B GJMUFS UP TLJQ DFSUBJO GJMFT CFJOH QSPDFTTFE. *O UIF TBNQMF XF IBWF CVJMU PVS PXO GJMUFS UIBU TLJQT GJMFT TUBSUJOH XJUI skip JO UIF GJMFOBNF:
public class MyFileFilter<T> implements GenericFileFilter<T> { public boolean accept(GenericFile<T> file) { // we want all directories if (file.isDirectory()) { return true; } // we dont accept any files starting with skip in the name return !file.getFileName().startsWith("skip"); } }

"OE UIFO XF DBO DPOGJHVSF PVS SPVUF VTJOH UIF CFIQBO BUUSJCVUF UP SFGFSFODF PVS GJMUFS (VTJOH # OPUBUJPO) UIBU XF IBWF EFGJOFE JO UIF TQSJOH 9.- GJMF:
<!-- define our sorter as a plain spring bean --> <bean id="myFilter" class="com.mycompany.MyFileSorter"/> <route> <from uri="file://inbox?filter=#myFilter"/> <to uri="bean:processInbox"/> </route>

636

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

%FIQBOFKD RPFKD

-3 M>QE J>Q@EBO

5IF "/5 QBUI NBUDIFS JT TIJQQFE PVU-PG-UIF-CPY JO UIF @>JBI-PMOFKD KBS. 4P ZPV OFFE UP EFQFOE PO @>JBI-PMOFKD JG ZPV BSF VTJOH .BWFO. 5IF SFBTPOT JT UIBU XF MFWFSBHF 4QSJOH'T "OU1BUI.BUDIFS UP EP UIF BDUVBM NBUDIJOH. 5IF GJMF QBUIT JT NBUDIFE XJUI UIF GPMMPXJOH SVMFT: ? NBUDIFT POF DIBSBDUFS * NBUDIFT [FSP PS NPSF DIBSBDUFST ** NBUDIFT [FSP PS NPSF EJSFDUPSJFT JO B QBUI 5IF TBNQMF CFMPX EFNPOTUSBUFT IPX UP VTF JU:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <template id="camelTemplate"/> <!-- use myFilter as filter to allow setting ANT paths for which files to scan for --> <endpoint id="myFileEndpoint" uri="file://target/ antpathmatcher?recursive=true&amp;filter=#myAntFilter"/> <route> <from ref="myFileEndpoint"/> <to uri="mock:result"/> </route> </camelContext> <!-- we use the antpath file filter to use ant paths for includes and exlucde --> <bean id="myAntFilter" class="org.apache.camel.component.file.AntPathMatcherGenericFileFilter"> <!-- include and file in the subfolder that has day in the name --> <property name="includes" value="**/subfolder/**/*day*"/> <!-- exclude all files with bad in name or .xml files. Use comma to seperate multiple excludes --> <property name="excludes" value="**/*bad*,**/*.xml"/> </bean>

2LOQFKD RPFKD "LJM>O>QLO $BNFM TVQQPSUT QMVHHBCMF TPSUJOH TUSBUFHJFT. 5IJT TUSBUFHZ JU UP VTF UIF CVJME JO java.util.Comparator JO +BWB. :PV DBO UIFO DPOGJHVSF UIF FOEQPJOU XJUI TVDI B DPNQBSBUPS BOE IBWF $BNFM TPSU UIF GJMFT CFGPSF CFJOH QSPDFTTFE. *O UIF TBNQMF XF IBWF CVJMU PVS PXO DPNQBSBUPS UIBU KVTU TPSUT CZ GJMF OBNF:
public class MyFileSorter<T> implements Comparator<GenericFile<T>> { public int compare(GenericFile<T> o1, GenericFile<T> o2) { return o1.getFileName().compareToIgnoreCase(o2.getFileName()); } }

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

637

-BT LMQFLKP COLJ ">JBI 2.10 LKT>OAP 5IFSF BSF OPX antInclude BOE antExclude PQUJPOT UP NBLF JU FBTZ UP TQFDJGZ "/5 TUZMF JODMVEF/FYDMVEF XJUIPVU IBWJOH UP EFGJOF UIF GJMUFS. 4FF UIF 63* PQUJPOT BCPWF GPS NPSF JOGPSNBUJPO. "OE UIFO XF DBO DPOGJHVSF PVS SPVUF VTJOH UIF PLOQBO PQUJPO UP SFGFSFODF UP PVS TPSUFS (mySorter) XF IBWF EFGJOFE JO UIF TQSJOH 9.- GJMF:
<!-- define our sorter as a plain spring bean --> <bean id="mySorter" class="com.mycompany.MyFileSorter"/> <route> <from uri="file://inbox?sorter=#mySorter"/> <to uri="bean:processInbox"/> </route>

2LOQFKD RPFKD PLOQ!V $BNFM TVQQPSUT QMVHHBCMF TPSUJOH TUSBUFHJFT. 5IJT TUSBUFHZ JU UP VTF UIF 'JMF -BOHVBHF UP DPOGJHVSF UIF TPSUJOH. 5IF sortBy PQUJPO JT DPOGJHVSFE BT GPMMPXT:
sortBy=group 1;group 2;group 3;...

8IFSF FBDI HSPVQ JT TFQBSBUFE XJUI TFNJ DPMPO. *O UIF TJNQMF TJUVBUJPOT ZPV KVTU VTF POF HSPVQ, TP B TJNQMF FYBNQMF DPVME CF:
sortBy=file:name

5IJT XJMM TPSU CZ GJMF OBNF, ZPV DBO SFWFSTF UIF PSEFS CZ QSFGJYJOH reverse: UP UIF HSPVQ, TP UIF TPSUJOH JT OPX ;..":
sortBy=reverse:file:name

"T XF IBWF UIF GVMM QPXFS PG 'JMF -BOHVBHF XF DBO VTF TPNF PG UIF PUIFS QBSBNFUFST, TP JG XF XBOU UP TPSU CZ GJMF TJ[F XF EP:
sortBy=file:length

:PV DBO DPOGJHVSF UP JHOPSF UIF DBTF, VTJOH ignoreCase: GPS TUSJOH DPNQBSJTPO, TP JG ZPV XBOU UP VTF GJMF OBNF TPSUJOH CVU UP JHOPSF UIF DBTF UIFO XF EP:

638

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( LMQFLKP @>K OBCBOBK@B ?B>KP RPFKD QEB # PVKQ>U *O UIF 4QSJOH %4- SPVUF BCPVU OPUJDF UIBU XF DBO SFGFS UP CFBOT JO UIF 3FHJTUSZ CZ QSFGJYJOH UIF JE XJUI #. 4P XSJUJOH sorter=#mySorter, XJMM JOTUSVDU $BNFM UP HP MPPL JO UIF 3FHJTUSZ GPS B CFBO XJUI UIF *%, mySorter.

sortBy=ignoreCase:file:name

:PV DBO DPNCJOF JHOPSF DBTF BOE SFWFSTF, IPXFWFS SFWFSTF NVTU CF TQFDJGJFE GJSTU:
sortBy=reverse:ignoreCase:file:name

*O UIF TBNQMF CFMPX XF XBOU UP TPSU CZ MBTU NPEJGJFE GJMF, TP XF EP:


sortBy=file:modifed

"OE UIFO XF XBOU UP HSPVQ CZ OBNF BT B 2OE PQUJPO TP GJMFT XJUI TBNF NPEJGDBUJPO JT TPSUFE CZ OBNF:
sortBy=file:modifed;file:name

/PX UIFSF JT BO JTTVF IFSF, DBO ZPV TQPU JU 8FMM UIF NPEJGJFE UJNFTUBNQ PG UIF GJMF JT UPP GJOF BT JU XJMM CF JO NJMMJTFDPOET, CVU XIBU JG XF XBOU UP TPSU CZ EBUF POMZ BOE UIFO TVCHSPVQ CZ OBNF 8FMM BT XF IBWF UIF USVF QPXFS PG 'JMF -BOHVBHF XF DBO VTF UIF JUT EBUF DPNNBOE UIBU TVQQPSUT QBUUFSOT. 4P UIJT DBO CF TPMWFE BT:
sortBy=date:file:yyyyMMdd;file:name

:FBI, UIBU JT QSFUUZ QPXFSGVM, PI CZ UIF XBZ ZPV DBO BMTP VTF SFWFSTF QFS HSPVQ, TP XF DPVME SFWFSTF UIF GJMF OBNFT:
sortBy=date:file:yyyyMMdd;reverse:file:name

4PFKD &BKBOF@%FIB/OL@BPP2QO>QBDV 5IF PQUJPO processStrategy DBO CF VTFE UP VTF B DVTUPN GenericFileProcessStrategy UIBU BMMPXT ZPV UP JNQMFNFOU ZPVS PXO begin, commit BOE rollback MPHJD.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

639

'PS JOTUBODF MFUT BTTVNF B TZTUFN XSJUFT B GJMF JO B GPMEFS ZPV TIPVME DPOTVNF. #VU ZPV TIPVME OPU TUBSU DPOTVNJOH UIF GJMF CFGPSF BOPUIFS ready GJMF IBT CFFO XSJUUFO BT XFMM. 4P CZ JNQMFNFOUJOH PVS PXO GenericFileProcessStrategy XF DBO JNQMFNFOU UIJT BT: *O UIF begin() NFUIPE XF DBO UFTU XIFUIFS UIF TQFDJBM ready GJMF FYJTUT. 5IF CFHJO NFUIPE SFUVSOT B boolean UP JOEJDBUF JG XF DBO DPOTVNF UIF GJMF PS OPU. *O UIF abort() NFUIPE ($BNFM 2.10) TQFDJBM MPHJD DBO CF FYFDVUFE JO DBTF UIF begin PQFSBUJPO SFUVSOFE false, GPS FYBNQMF UP DMFBOVQ SFTPVSDFT FUD. JO UIF commit() NFUIPE XF DBO NPWF UIF BDUVBM GJMF BOE BMTP EFMFUF UIF ready GJMF. 4PFKD CFIQBO 5IF filter PQUJPO BMMPXT ZPV UP JNQMFNFOU B DVTUPN GJMUFS JO +BWB DPEF CZ JNQMFNFOUJOH UIF org.apache.camel.component.file.GenericFileFilter JOUFSGBDF. 5IJT JOUFSGBDF IBT BO accept NFUIPE UIBU SFUVSOT B CPPMFBO. 3FUVSO true UP JODMVEF UIF GJMF, BOE false UP TLJQ UIF GJMF. 'SPN $BNFM 2.10 POXBSET, UIFSF JT B isDirectory NFUIPE PO GenericFile XIFUIFS UIF GJMF JT B EJSFDUPSZ. 5IJT BMMPXT ZPV UP GJMUFS VOXBOUFE EJSFDUPSJFT, UP BWPJE USBWFSTJOH EPXO VOXBOUFE EJSFDUPSJFT. 'PS FYBNQMF UP TLJQ BOZ EJSFDUPSJFT XIJDI TUBSUT XJUI "skip" JO UIF OBNF, DBO CF JNQMFNFOUFE BT GPMMPXT:
public class MyDirectoryFilter<T> implements GenericFileFilter<T> { public boolean accept(GenericFile<T> file) { // remember the name due unit testing (should not be needed in regular use-cases) names.add(file.getFileName()); // we dont accept any files within directory starting with skip in the name if (file.isDirectory() && file.getFileName().startsWith("skip")) { return false; } return true; } }

'LT QL RPB QEB ">JBI BOOLO E>KAIBO QL AB>I TFQE BU@BMQFLKP QOFDDBOBA LRQPFAB QEB OLRQFKD BKDFKB 5IF GJMF BOE GUQ DPOTVNFST, XJMM CZ EFGBVMU USZ UP QJDLVQ GJMFT. 0OMZ JG UIBU JT TVDDFTTGVM UIFO B $BNFM &YDIBOHF DBO CF DSFBUFE BOE QBTTFE JO UIF $BNFM SPVUJOH FOHJOF. 8IFO UIF &YDIBOHF JT QSPDFTTFE CZ UIF SPVUJOH FOHJOF, UIFO UIF $BNFM &SSPS )BOEMJOH UBLFT PWFS (FH UIF PO&YDFQUJPO / FSSPS)BOEMFS JO UIF SPVUFT).

640

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)PXFWFS PVUTJEF UIF TDPQF PG UIF SPVUJOH FOHJOF, BOZ FYDFQUJPOT IBOEMJOH JT DPNQPOFOU TQFDJGJD. $BNFM PGGFST B org.apache.camel.spi.ExceptionHandler UIBU BMMPXT DPNQPOFOUT UP VTF UIBU BT B QMVHHBCMF IPPL GPS FOE VTFST UP VTF UIFJS PXO JNQMFNFOUBUJPO. $BNFM PGGFST B EFGBVMU LoggingExceptionHandler UIBU XJMM MPH UIF FYDFQUJPO BU &3303/8"3/ MFWFM. 'PS UIF GJMF BOE GUQ DPNQPOFOUT UIJT XPVME CF UIF DBTF. )PXFWFS JG ZPV XBOU UP CSJEHF UIF ExceptionHandler TP JU VTFT UIF $BNFM &SSPS )BOEMJOH, UIFO ZPV OFFE UP JNQMFNFOU B DVTUPN ExceptionHandler UIBU XJMM IBOEMF UIF FYDFQUJPO CZ DSFBUJOH B $BNFM &YDIBOHF BOE TFOE JU UP UIF SPVUJOH FOHJOF; UIFO UIF FSSPS IBOEMJOH PG UIF SPVUJOH FOHJOF DBO HFU USJHHFSFE. )FSF JT TVDI BO FYBNQMF CBTFE VQPO BO VOJU UFTU. 'JSTU XF IBWF B DVTUPN ExceptionHandler XIFSF ZPV DBO TFF XF EFBM XJUI UIF FYDFQUJPO CZ TFOEJOH JU UP B $BNFM &OEQPJOU OBNFE "EJSFDU:GJMF-FSSPS":
Listing 1. MyExceptionHandler
/** * Custom {@link ExceptionHandler} to be used on the file consumer, to send * exceptions to a Camel route, to let Camel deal with the error. */ private static class MyExceptionHandler implements ExceptionHandler { private ProducerTemplate template; /** * We use a producer template to send a message to the Camel route */ public void setTemplate(ProducerTemplate template) { this.template = template; } @Override public void handleException(Throwable exception) { handleException(exception.getMessage(), exception); } @Override public void handleException(String message, Throwable exception) { handleException(exception.getMessage(), null, exception); } @Override public void handleException(final String message, final Exchange originalExchange, final Throwable exception) { // send the message to the special direct:file-error endpoint, which will trigger exception handling // template.send("direct:file-error", new Processor() { @Override public void process(Exchange exchange) throws Exception { // set an exception on the message from the start so the error

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

641

$>PFBO TFQE ">JBI 2.10 5IF OFX PQUJPO DPOTVNFS.CSJEHF&SSPS)BOEMFS DBO CF TFU UP USVF, UP NBLF UIJT FWFO FBTJFS. 4FF GVSUIFS CFMPX

handling is triggered exchange.setException(exception); exchange.getIn().setBody(message); } }); } }

5IFO XF IBWF B $BNFM SPVUF UIBU VTFT UIF $BNFM SPVUJOH FSSPS IBOEMFS, XIJDI JT UIF onException XIFSF XF IBOEMF BOZ *0&YDFQUJPO CFJOH UISPXO. 8F UIFO TFOE UIF NFTTBHF UP UIF TBNF "EJSFDU:GJMF-FSSPS" FOEQPJOU, XIFSF XF IBOEMF JU CZ USBOTGPSNJOH JU UP B NFTTBHF, BOE UIFO CFJOH TFOU UP B .PDL FOEQPJOU. 5IJT JT KVTU GPS UFTUJOH QVSQPTF. :PV DBO IBOEMF UIF FYDFQUJPO JO BOZ DVTUPN XBZ ZPV XBOU, TVDI BT VTJOH B #FBO PS TFOEJOH BO FNBJM FUD. /PUJDF IPX XF DPOGJHVSF PVS DVTUPN MyExceptionHandler CZ VTJOH UIF consumer.exceptionHandler PQUJPO UP SFGFS UP #myExceptionHandler XIJDI JT B JE PG UIF CFBO SFHJTUFSFE JO UIF 3FHJTUSZ. *G VTJOH 4QSJOH 9.- PS 04(J #MVFQSJOU, UIFO UIBU XPVME CF B <CFBO JE="NZ&YDFQUJPO)BOEMFS" DMBTT="DPN.GPP..Z&YDFQUJPO)BOEMFS"/>:
Listing 1. Camel route with routing engine error handling
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { // to handle any IOException being thrown onException(IOException.class) .handled(true) .log("IOException occurred due: ${exception.message}") // as we handle the exception we can send it to direct:file-error, // where we could send out alerts or whatever we want .to("direct:file-error"); // special route that handles file errors from("direct:file-error") .log("File error route triggered to deal with exception ${exception?.class}") // as this is based on unit test just transform a message and send it to a mock .transform().simple("Error ${exception.message}") .to("mock:error");

642

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

// this is the file route that pickup files, notice how we use our custom exception handler on the consumer // the exclusiveReadLockStrategy is only configured because this is from an unit test, so we use that to simulate exceptions from("file:target/ nospace?exclusiveReadLockStrategy=#myReadLockStrategy&consumer.exceptionHandler=#myExceptionHandler") .convertBodyTo(String.class) .to("mock:result"); } }; }

5IF TPVSDF DPEF GPS UIJT FYBNQMF DBO CF TFFO IFSF

4PFKD @LKPRJBO.?OFADB$OOLO'>KAIBO
S>FI>?IB >P LC ">JBI 2.10 *G ZPV XBOU UP VTF UIF $BNFM &SSPS )BOEMFS UP EFBM XJUI BOZ FYDFQUJPO PDDVSSJOH JO UIF GJMF DPOTVNFS, UIFO ZPV DBO FOBCMF UIF consumer.bridgeErrorHandler PQUJPO BT TIPXO CFMPX:
Listing 1. Using consumer.bridgeErrorHandler
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { // to handle any IOException being thrown onException(IOException.class) .handled(true) .log("IOException occurred due: ${exception.message}") .transform().simple("Error ${exception.message}") .to("mock:error"); // this is the file route that pickup files, notice how we bridge the consumer to use the Camel routing error handler // the exclusiveReadLockStrategy is only configured because this is from an unit test, so we use that to simulate exceptions from("file:target/ nospace?exclusiveReadLockStrategy=#myReadLockStrategy&consumer.bridgeErrorHandler=true") .convertBodyTo(String.class) .to("mock:result"); } }; }

4P BMM ZPV IBWF UP EP JT UP FOBCMF UIJT PQUJPO, BOE UIF FSSPS IBOEMFS JO UIF SPVUF XJMM UBLF JU GSPN UIFSF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

643

#B?RD ILDDFKD 5IJT DPNQPOFOU IBT MPH MFWFM 31 "$ UIBU DBO CF IFMQGVM JG ZPV IBWF QSPCMFNT. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 'JMF -BOHVBHF '51 1PMMJOH $POTVNFS

%+ 3/ "* ".,/.-$-3
5IF 'MBUQBDL DPNQPOFOU TVQQPSUT GJYFE XJEUI BOE EFMJNJUFE GJMF QBSTJOH WJB UIF 'MBU1BDL MJCSBSZ. -LQF@B: 5IJT DPNQPOFOU POMZ TVQQPSUT DPOTVNJOH GSPN GMBUQBDL GJMFT UP 0CKFDU NPEFM. :PV DBO OPU (ZFU) XSJUF GSPN 0CKFDU NPEFM UP GMBUQBDL GPSNBU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-flatpack</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
flatpack:[delim|fixed]:flatPackConfig.pzmap.xml[?options]

0S GPS B EFMJNJUFE GJMF IBOEMFS XJUI OP DPOGJHVSBUJPO GJMF KVTU VTF


flatpack:someName[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

644

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( .MQFLKP
->JB
delimiter textQualifier ignoreFirstRecord splitRows allowShortLines ignoreExtraColumns

#BC>RIQ 5>IRB
, " true true false false

#BP@OFMQFLK
5IF EFGBVMU DIBSBDUFS EFMJNJUFS GPS EFMJNJUFE GJMFT. 5IF UFYU RVBMJGJFS GPS EFMJNJUFE GJMFT. 8IFUIFS UIF GJSTU MJOF JT JHOPSFE GPS EFMJNJUFE GJMFT (GPS UIF DPMVNO IFBEFST). 5IF DPNQPOFOU DBO FJUIFS QSPDFTT FBDI SPX POF CZ POF PS UIF FOUJSF DPOUFOU BU PODF. ">JBI 2.9.7 >KA 2.10.5 LKT>OAP: "MMPXT GPS MJOFT UP CF TIPSUFS UIBO FYQFDUFE BOE JHOPSFT UIF FYUSB DIBSBDUFST. ">JBI 2.9.7 >KA 2.10.5 LKT>OAP: "MMPXT GPS MJOFT UP CF MPOHFS UIBO FYQFDUFE BOE JHOPSFT UIF FYUSB DIBSBDUFST.

$U>JMIBP ` flatpack:fixed:foo.pzmap.xml DSFBUFT B GJYFE-XJEUI FOEQPJOU VTJOH UIF foo.pzmap.xml GJMF DPOGJHVSBUJPO. ` flatpack:delim:bar.pzmap.xml DSFBUFT B EFMJNJUFE FOEQPJOU VTJOH UIF bar.pzmap.xml GJMF DPOGJHVSBUJPO. ` flatpack:foo DSFBUFT B EFMJNJUFE FOEQPJOU DBMMFE foo XJUI OP GJMF DPOGJHVSBUJPO. ,BPP>DB 'B>ABOP $BNFM XJMM TUPSF UIF GPMMPXJOH IFBEFST PO UIF */ NFTTBHF:
'B>ABO
camelFlatpackCounter

#BP@OFMQFLK
5IF DVSSFOU SPX JOEFY. 'PS splitRows=false UIF DPVOUFS JT UIF UPUBM OVNCFS PG SPXT.

,BPP>DB !LAV 5IF DPNQPOFOU EFMJWFST UIF EBUB JO UIF */ NFTTBHF BT B org.apache.camel.component.flatpack.DataSetList PCKFDU UIBU IBT DPOWFSUFST GPS java.util.Map PS java.util.List. 6TVBMMZ ZPV XBOU UIF Map JG ZPV QSPDFTT POF SPX BU B UJNF (splitRows=true). 6TF List GPS UIF FOUJSF DPOUFOU (splitRows=false), XIFSF FBDI FMFNFOU JO UIF MJTU JT B Map. &BDI Map DPOUBJOT UIF LFZ GPS UIF DPMVNO OBNF BOE JUT DPSSFTQPOEJOH WBMVF. 'PS FYBNQMF UP HFU UIF GJSTUOBNF GSPN UIF TBNQMF CFMPX:
Map row = exchange.getIn().getBody(Map.class); String firstName = row.get("FIRSTNAME");

)PXFWFS, ZPV DBO BMTP BMXBZT HFU JU BT B List (FWFO GPS splitRows=true). 5IF TBNF FYBNQMF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

645

List data = exchange.getIn().getBody(List.class); Map row = (Map)data.get(0); String firstName = row.get("FIRSTNAME");

'B>ABO >KA 3O>FIBO OB@LOAP 5IF IFBEFS BOE USBJMFS OPUJPOT JO 'MBUQBDL BSF TVQQPSUFE. )PXFWFS, ZPV JRPQ VTF GJYFE SFDPSE *%T: ` header GPS UIF IFBEFS SFDPSE (NVTU CF MPXFSDBTF) ` trailer GPS UIF USBJMFS SFDPSE (NVTU CF MPXFSDBTF) 5IF FYBNQMF CFMPX JMMVTUSBUFT UIJT GBDU UIBU XF IBWF B IFBEFS BOE B USBJMFS. :PV DBO PNJU POF PS CPUI PG UIFN JG OPU OFFEFE.
<RECORD id="header" startPosition="1" endPosition="3" indicator="HBT"> <COLUMN name="INDICATOR" length="3"/> <COLUMN name="DATE" length="8"/> </RECORD> <COLUMN <COLUMN <COLUMN <COLUMN <COLUMN <COLUMN name="FIRSTNAME" length="35" /> name="LASTNAME" length="35" /> name="ADDRESS" length="100" /> name="CITY" length="100" /> name="STATE" length="2" /> name="ZIP" length="5" />

<RECORD id="trailer" startPosition="1" endPosition="3" indicator="FBT"> <COLUMN name="INDICATOR" length="3"/> <COLUMN name="STATUS" length="7"/> </RECORD>

4PFKD QEB BKAMLFKQ " DPNNPO VTF DBTF JT TFOEJOH B GJMF UP UIJT FOEQPJOU GPS GVSUIFS QSPDFTTJOH JO B TFQBSBUF SPVUF. 'PS FYBNQMF:
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="file://someDirectory"/> <to uri="flatpack:foo"/> </route> <route> <from uri="flatpack:foo"/> ... </route> </camelContext>

646

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV DBO BMTP DPOWFSU UIF QBZMPBE PG FBDI NFTTBHF DSFBUFE UP B Map GPS FBTZ #FBO *OUFHSBUJPO

%+ 3/ "* # 3 %.1, 3
5IF 'MBUQBDL DPNQPOFOU TIJQT XJUI UIF 'MBUQBDL EBUB GPSNBU UIBU DBO CF VTFE UP GPSNBU CFUXFFO GJYFE XJEUI PS EFMJNJUFE UFYU NFTTBHFT UP B List PG SPXT BT Map. NBSTIBM = GSPN List<Map<String, Object>> UP OutputStream (DBO CF DPOWFSUFE UP String) VONBSTIBM = GSPN java.io.InputStream (TVDI BT B File PS String) UP B java.util.List BT BO org.apache.camel.component.flatpack.DataSetList JOTUBODF. 5IF SFTVMU PG UIF PQFSBUJPO XJMM DPOUBJO BMM UIF EBUB. *G ZPV OFFE UP QSPDFTT FBDI SPX POF CZ POF ZPV DBO TQMJU UIF FYDIBOHF, VTJOH 4QMJUUFS. -LQF@B: 5IF 'MBUQBDL MJCSBSZ EPFT DVSSFOUMZ OPU TVQQPSU IFBEFS BOE USBJMFST GPS UIF NBSTIBM PQFSBUJPO. .MQFLKP 5IF EBUB GPSNBU IBT UIF GPMMPXJOH PQUJPOT: .MQFLK definition fixed ignoreFirstRecord textQualifier delimiter parserFactory allowShortLines #BC>RIQ null false true " , null false #BP@OFMQFLK 5IF GMBUQBDL Q[NBQ DPOGJHVSBUJPO GJMF. $BO CF PNJUUFE JO TJNQMFS TJUVBUJPOT, CVU JUT QSFGFSSFE UP VTF UIF Q[NBQ. %FMJNJUFE PS GJYFE. 8IFUIFS UIF GJSTU MJOF JT JHOPSFE GPS EFMJNJUFE GJMFT (GPS UIF DPMVNO IFBEFST). *G UIF UFYU JT RVBMJGJFE XJUI B DIBS TVDI BT ". 5IF EFMJNJUFS DIBS (DPVME CF ; , PS TJNJMBS) 6TFT UIF EFGBVMU 'MBUQBDL QBSTFS GBDUPSZ. ">JBI 2.9.7 >KA 2.10.5 LKT>OAP: "MMPXT GPS MJOFT UP CF TIPSUFS UIBO FYQFDUFE BOE JHOPSFT UIF FYUSB DIBSBDUFST. ">JBI 2.9.7 >KA 2.10.5 LKT>OAP: "MMPXT GPS MJOFT UP CF MPOHFS UIBO FYQFDUFE BOE JHOPSFT UIF FYUSB DIBSBDUFST.

ignoreExtraColumns

false

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

647

4P>DB 5P VTF UIF EBUB GPSNBU, TJNQMZ JOTUBOUJBUF BO JOTUBODF BOE JOWPLF UIF NBSTIBM PS VONBSTIBM PQFSBUJPO JO UIF SPVUF CVJMEFS:
FlatpackDataFormat fp = new FlatpackDataFormat(); fp.setDefinition(new ClassPathResource("INVENTORY-Delimited.pzmap.xml")); ... from("file:order/in").unmarshal(df).to("seda:queue:neworder");

5IF TBNQMF BCPWF XJMM SFBE GJMFT GSPN UIF order/in GPMEFS BOE VONBSTIBM UIF JOQVU VTJOH UIF 'MBUQBDL DPOGJHVSBUJPO GJMF INVENTORY-Delimited.pzmap.xml UIBU DPOGJHVSFT UIF TUSVDUVSF PG UIF GJMFT. 5IF SFTVMU JT B DataSetList PCKFDU XF TUPSF PO UIF 4&%" RVFVF.
FlatpackDataFormat df = new FlatpackDataFormat(); df.setDefinition(new ClassPathResource("PEOPLE-FixedLength.pzmap.xml")); df.setFixed(true); df.setIgnoreFirstRecord(false); from("seda:people").marshal(df).convertBodyTo(String.class).to("jms:queue:people");

*O UIF DPEF BCPWF XF NBSTIBM UIF EBUB GSPN B 0CKFDU SFQSFTFOUBUJPO BT B List PG SPXT BT Maps. 5IF SPXT BT Map DPOUBJOT UIF DPMVNO OBNF BT UIF LFZ, BOE UIF UIF DPSSFTQPOEJOH WBMVF. 5IJT TUSVDUVSF DBO CF DSFBUFE JO +BWB DPEF GSPN F.H. B QSPDFTTPS. 8F NBSTIBM UIF EBUB BDDPSEJOH UP UIF 'MBUQBDL GPSNBU BOE DPOWFSU UIF SFTVMU BT B String PCKFDU BOE TUPSF JU PO B +.4 RVFVF. #BMBKABK@FBP 5P VTF 'MBUQBDL JO ZPVS DBNFM SPVUFT ZPV OFFE UP BEE UIF B EFQFOEFODZ PO @>JBI-CI>QM>@H XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. *G ZPV VTF NBWFO ZPV DPVME KVTU BEE UIF GPMMPXJOH UP ZPVS QPN.YNM, TVCTUJUVUJOH UIF WFSTJPO OVNCFS GPS UIF MBUFTU & HSFBUFTU SFMFBTF (TFF UIF EPXOMPBE QBHF GPS UIF MBUFTU WFSTJPOT).
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-flatpack</artifactId> <version>x.x.x</version> </dependency>

2BB

IPL ` $POGJHVSJOH $BNFM ` $PNQPOFOU ` &OEQPJOU

648

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

` (FUUJOH 4UBSUFE

%1$$, 1*$1
5IF COBBJ>OHBO: DPNQPOFOU BMMPXT GPS QSPDFTTJOH B NFTTBHF VTJOH B 'SFF.BSLFS UFNQMBUF. 5IJT DBO CF JEFBM XIFO VTJOH 5FNQMBUJOH UP HFOFSBUF SFTQPOTFT GPS SFRVFTUT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-freemarker</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
freemarker:templateName[?options]

8IFSF QBJMI>QB->JB JT UIF DMBTTQBUI-MPDBM 63* PG UIF UFNQMBUF UP JOWPLF; PS UIF DPNQMFUF 63- PG UIF SFNPUF UFNQMBUF (FH: GJMF://GPMEFS/NZGJMF.GUM). :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
contentCache encoding templateUpdateDelay

#BC>RIQ
true null 5

#BP@OFMQFLK
$BDIF GPS UIF SFTPVSDF DPOUFOU XIFO JU'T MPBEFE. /PUF: BT PG ">JBI 2.9 DBDIFE SFTPVSDF DPOUFOU DBO CF DMFBSFE WJB +.9 VTJOH UIF FOEQPJOU'T clearContentCache PQFSBUJPO. $IBSBDUFS FODPEJOH PG UIF SFTPVSDF DPOUFOU. ">JBI 2.9: /VNCFS PG TFDPOET UIF MPBEFE UFNQMBUF SFTPVSDF XJMM SFNBJO JO UIF DBDIF.

'B>ABOP )FBEFST TFU EVSJOH UIF 'SFF.BSLFS FWBMVBUJPO BSF SFUVSOFE UP UIF NFTTBHF BOE BEEFE BT IFBEFST. 5IJT QSPWJEFT B NFDIBOJTN GPS UIF 'SFF.BSLFS DPNQPOFOU UP SFUVSO WBMVFT UP UIF .FTTBHF. "O FYBNQMF: 4FU UIF IFBEFS WBMVF PG fruit JO UIF 'SFF.BSLFS UFNQMBUF:
${request.setHeader('fruit', 'Apple')}

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

649

5IF IFBEFS, fruit, JT OPX BDDFTTJCMF GSPN UIF message.out.headers. %OBB,>OHBO "LKQBUQ $BNFM XJMM QSPWJEF FYDIBOHF JOGPSNBUJPO JO UIF 'SFF.BSLFS DPOUFYU (KVTU B Map). 5IF Exchange JT USBOTGFSSFE BT:
HBV
exchange exchange.properties headers camelContext request body response

S>IRB
5IF Exchange JUTFMG. 5IF Exchange QSPQFSUJFT. 5IF IFBEFST PG UIF *O NFTTBHF. 5IF $BNFM $POUFYU. 5IF *O NFTTBHF. 5IF *O NFTTBHF CPEZ. 5IF 0VU NFTTBHF (POMZ GPS *O0VU NFTTBHF FYDIBOHF QBUUFSO).

'LQ OBIL>AFKD 5IF 'SFF.BSLFS UFNQMBUF SFTPVSDF JT CZ EFGBVMU KLQ IPU SFMPBEBCMF GPS CPUI GJMF BOE DMBTTQBUI SFTPVSDFT (FYQBOEFE KBS). *G ZPV TFU contentCache=false, UIFO $BNFM XJMM OPU DBDIF UIF SFTPVSDF BOE IPU SFMPBEJOH JT UIVT FOBCMFE. 5IJT TDFOBSJP DBO CF VTFE JO EFWFMPQNFOU. #VK>JF@ QBJMI>QBP $BNFM QSPWJEFT UXP IFBEFST CZ XIJDI ZPV DBO EFGJOF B EJGGFSFOU SFTPVSDF MPDBUJPO GPS B UFNQMBUF PS UIF UFNQMBUF DPOUFOU JUTFMG. *G BOZ PG UIFTF IFBEFST JT TFU UIFO $BNFM VTFT UIJT PWFS UIF FOEQPJOU DPOGJHVSFE SFTPVSDF. 5IJT BMMPXT ZPV UP QSPWJEF B EZOBNJD UFNQMBUF BU SVOUJNF.
'B>ABO
'SFFNBSLFS$POTUBOUT.'3&&."3,&3@3&4063$& 'SFFNBSLFS$POTUBOUT.'3&&."3,&3@3&4063$&@63* 'SFFNBSLFS$POTUBOUT.'3&&."3,&3@5&.1-"5&

3VMB
PSH.TQSJOHGSBNFXPSL.DPSF.JP.3FTPVSDF 4USJOH 4USJOH

#BP@OFMQFLK
5IF UFNQMBUF SFTPVSDF " 63* GPS UIF UFNQMBUF SFTPVSDF UP VTF JOTUFBE PG UIF FOEQPJOU DPOGJHVSFE. 5IF UFNQMBUF UP VTF JOTUFBE PG UIF FOEQPJOU DPOGJHVSFE.

2RMMLOQ 5BOPFLK
<= 2.1 >= 2.1 >= 2.1

2>JMIBP 'PS FYBNQMF ZPV DPVME VTF TPNFUIJOH MJLF:


from("activemq:My.Queue"). to("freemarker:com/acme/MyResponse.ftl");

5P VTF B 'SFF.BSLFS UFNQMBUF UP GPSNVMBUF B SFTQPOTF GPS B NFTTBHF GPS *O0VU NFTTBHF FYDIBOHFT (XIFSF UIFSF JT B JMSReplyTo IFBEFS). *G ZPV XBOU UP VTF *O0OMZ BOE DPOTVNF UIF NFTTBHF BOE TFOE JU UP BOPUIFS EFTUJOBUJPO ZPV DPVME VTF:
650 $) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("activemq:My.Queue"). to("freemarker:com/acme/MyResponse.ftl"). to("activemq:Another.Queue");

"OE UP EJTBCMF UIF DPOUFOU DBDIF, F.H. GPS EFWFMPQNFOU VTBHF XIFSF UIF .ftl UFNQMBUF TIPVME CF IPU SFMPBEFE:
from("activemq:My.Queue"). to("freemarker:com/acme/MyResponse.ftl?contentCache=false"). to("activemq:Another.Queue");

"OE B GJMF-CBTFE SFTPVSDF:


from("activemq:My.Queue"). to("freemarker:file://myfolder/MyResponse.ftl?contentCache=false"). to("activemq:Another.Queue");

*O ">JBI 2.1 JU'T QPTTJCMF UP TQFDJGZ XIBU UFNQMBUF UIF DPNQPOFOU TIPVME VTF EZOBNJDBMMZ WJB B IFBEFS, TP GPS FYBNQMF:
from("direct:in"). setHeader(FreemarkerConstants.FREEMARKER_RESOURCE_URI).constant("path/to/my/ template.ftl"). to("freemarker:dummy");

3EB $J>FI 2>JMIB *O UIJT TBNQMF XF XBOU UP VTF 'SFF.BSLFS UFNQMBUJOH GPS BO PSEFS DPOGJSNBUJPO FNBJM. 5IF FNBJM UFNQMBUF JT MBJE PVU JO 'SFF.BSLFS BT:
Dear ${headers.lastName}, ${headers.firstName} Thanks for the order of ${headers.item}. Regards Camel Riders Bookstore ${body}

"OE UIF KBWB DPEF:


private Exchange createLetter() { Exchange exchange = context.getEndpoint("direct:a").createExchange(); Message msg = exchange.getIn(); msg.setHeader("firstName", "Claus"); msg.setHeader("lastName", "Ibsen");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

651

msg.setHeader("item", "Camel in Action"); msg.setBody("PS: Next beer is on me, James"); return exchange; } @Test public void testFreemarkerLetter() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedMessageCount(1); mock.expectedBodiesReceived("Dear Ibsen, Claus\n\nThanks for the order of Camel in Action." + "\n\nRegards Camel Riders Bookstore\nPS: Next beer is on me, James"); template.send("direct:a", createLetter()); mock.assertIsSatisfied(); } protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { from("direct:a") .to("freemarker:org/apache/camel/component/freemarker/letter.ftl") .to("mock:result"); } }; }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

%3//2%3//%3/2 ".,/.-$-3
5IJT DPNQPOFOU QSPWJEFT BDDFTT UP SFNPUF GJMF TZTUFNT PWFS UIF '51 BOE 4'51 QSPUPDPMT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ftp</artifactId> <version>x.x.x</version>

652

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
ftp://[username@]hostname[:port]/directoryname[?options] sftp://[username@]hostname[:port]/directoryname[?options] ftps://[username@]hostname[:port]/directoryname[?options]

8IFSF AFOB@QLOVK>JB SFQSFTFOUT UIF VOEFSMZJOH EJSFDUPSZ. $BO DPOUBJO OFTUFE GPMEFST. *G OP RPBOK>JB JT QSPWJEFE, UIFO anonymous MPHJO JT BUUFNQUFE VTJOH OP QBTTXPSE. *G OP MLOQ OVNCFS JT QSPWJEFE, $BNFM XJMM QSPWJEF EFGBVMU WBMVFT BDDPSEJOH UP UIF QSPUPDPM (GUQ = 21, TGUQ = 22, GUQT = 2222). :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 5IJT DPNQPOFOU VTFT UXP EJGGFSFOU MJCSBSJFT GPS UIF BDUVBM '51 XPSL. '51 BOE '514 VTFT "QBDIF $PNNPOT /FU XIJMF 4'51 VTFT +$SBGU +4$). 5IF '514 DPNQPOFOU JT POMZ BWBJMBCMF JO $BNFM 2.2 PS OFXFS. '514 (BMTP LOPXO BT '51 4FDVSF) JT BO FYUFOTJPO UP '51 UIBU BEET TVQQPSU GPS UIF 5SBOTQPSU -BZFS 4FDVSJUZ (5-4) BOE UIF 4FDVSF 4PDLFUT -BZFS (44-) DSZQUPHSBQIJD QSPUPDPMT. 41( .MQFLKP 5IF PQUJPOT CFMPX BSF FYDMVTJWF GPS UIF '51 DPNQPOFOU.
->JB
username password binary disconnect

#BC>RIQ 5>IRB
null null false false

#BP@OFMQFLK
4QFDJGJFT UIF VTFSOBNF UP VTF UP MPH JO UP UIF SFNPUF GJMF TZTUFO. 4QFDJGJFT UIF QBTTXPSE UP VTF UP MPH JO UP UIF SFNPUF GJMF TZTUFN. 4QFDJGJFT UIF GJMF USBOTGFS NPEF, #*/"3: PS "4$**. %FGBVMU JT "4$** (false). ">JBI 2.2: 8IFUIFS PS OPU UP EJTDPOOFDU GSPN SFNPUF '51 TFSWFS SJHIU BGUFS VTF. $BO CF VTFE GPS CPUI DPOTVNFS BOE QSPEVDFS. %JTDPOOFDU XJMM POMZ EJTDPOOFDU UIF DVSSFOU DPOOFDUJPO UP UIF '51 TFSWFS. *G ZPV IBWF B DPOTVNFS XIJDI ZPV XBOU UP TUPQ, UIFO ZPV OFFE UP TUPQ UIF DPOTVNFS/SPVUF JOTUFBE. 8IFO DPOTVNJOH, B MPDBM XPSL EJSFDUPSZ DBO CF VTFE UP TUPSF UIF SFNPUF GJMF DPOUFOU EJSFDUMZ JO MPDBM GJMFT, UP BWPJE MPBEJOH UIF DPOUFOU JOUP NFNPSZ. 5IJT JT CFOFGJDJBM, JG ZPV DPOTVNF B WFSZ CJH SFNPUF GJMF BOE UIVT DBO DPOTFSWF NFNPSZ. 4FF CFMPX GPS NPSF EFUBJMT. %3/ >KA %3/2 LKIV: 4QFDJGJFT XIFUIFS UP VTF QBTTJWF NPEF DPOOFDUJPOT. %FGBVMU JT BDUJWF NPEF (false). %3/2 LKIV: 4FUT UIF VOEFSMZJOH TFDVSJUZ QSPUPDPM. 5IF GPMMPXJOH WBMVFT BSF EFGJOFE: TLS: 5SBOTQPSU -BZFS 4FDVSJUZ SSL: 4FDVSF 4PDLFUT -BZFS ">JBI 2.4: %3/2 LKIV: 8IFUIFS PS OPU UP EJTBCMF VTJOH EFGBVMU WBMVFT GPS execPbsz BOE execProt XIFO VTJOH TFDVSF EBUB USBOTGFS. :PV DBO TFU UIJT PQUJPO UP true JG ZPV XBOU UP CF JO BCTPMVUF GVMM DPOUSPM XIBU UIF PQUJPOT execPbsz BOE execProt TIPVME CF VTFE. ">JBI 2.11: 8IFUIFS UIF '51 DPOTVNFS TIPVME EPXOMPBE UIF GJMF. *G UIJT PQUJPO JT TFU UP false, UIFO UIF NFTTBHF CPEZ XJMM CF null, CVU UIF DPOTVNFS XJMM TUJMM USJHHFS B $BNFM &YDIBOHF UIBU IBT EFUBJMT BCPVU UIF GJMF TVDI BT GJMF OBNF, GJMF TJ[F, FUD. *U'T KVTU UIBU UIF GJMF XJMM OPU CF EPXOMPBEFE.

localWorkDirectory

null

passiveMode

false

securityProtocol

TLS

disableSecureDataChannelDefaults

false

download

true

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

653

,LOB LMQFLKP 4FF 'JMF GPS NPSF PQUJPOT BT BMM UIF PQUJPOT GSPN 'JMF JT JOIFSJUFE.

"LKPRJFKD COLJ OBJLQB %3/ PBOSBO .BLF TVSF ZPV SFBE UIF TFDUJPO UJUMFE Default when consuming files GVSUIFS CFMPX GPS EFUBJMT SFMBUFE UP DPOTVNJOH GJMFT.

,LOB LMQFLKP 4FF 'JMF GPS NPSF PQUJPOT BT BMM UIF PQUJPOT GSPN 'JMF JT JOIFSJUFE.
">JBI 2.11:c8IFUIFS UIF DPOTVNFS TIPVME EPXOMPBE UIF FOUJSF GJMF VQ GSPOU, UIF EFGBVMU CFIBWJPS, PS JG JU TIPVME QBTT BO *OQVU4USFBNcSFBE GSPN UIF SFNPUF SFTPVSDF SBUIFS UIBO BO JO-NFNPSZ BSSBZ BT UIF JO CPEZ PG UIFc$BNFMc&YDIBOHF. c5IJT PQUJPO JT JHOPSFE JG EPXOMPBEcJT GBMTFcPS JT MPDBM8PSL%JSFDUPSZ JT QSPWJEFE. c5IJT PQUJPO JT VTFGVM GPS XPSLJOH XJUI MBSHF SFNPUF GJMFT. ">JBI 2.4: %3/2 LKIV: 8JMM CZ EFGBVMU VTF PQUJPO P JG TFDVSF EBUB DIBOOFM EFGBVMUT IBTO'U CFFO EJTBCMFE. 1PTTJCMF WBMVFT BSF: C: $MFBS S: 4BGF (44- QSPUPDPM POMZ) E: $POGJEFOUJBM (44- QSPUPDPM POMZ) P: 1SJWBUF ">JBI 2.4: %3/2 LKIV: 5IJT PQUJPO TQFDJGJFT UIF CVGGFS TJ[F PG UIF TFDVSF EBUB DIBOOFM. *G PQUJPO useSecureDataChannel IBT CFFO FOBCMFE BOE UIJT PQUJPO IBT OPU CFFO FYQMJDJU TFU, UIFO WBMVF 0 JT VTFE. %3/2 LKIV: 4FUT UIF TFDVSJUZ NPEF(JNQMJDJU/FYQMJDJU). %FGBVMU JT FYQMJDJU (false). 2%3/ LKIV: 4FUT UIF known_hosts GJMF, TP UIBU UIF 4'51 FOEQPJOU DBO EP IPTU LFZ WFSJGJDBUJPO. 2%3/ LKIV: 4FU UIF QSJWBUF LFZ GJMF UP UIBU UIF 4'51 FOEQPJOU DBO EP QSJWBUF LFZ WFSJGJDBUJPO. 2%3/ LKIV: 4FU UIF QSJWBUF LFZ GJMF QBTTQISBTF UP UIBU UIF 4'51 FOEQPJOU DBO EP QSJWBUF LFZ WFSJGJDBUJPO. ">JBI 2.8.2, 2.9: 2%3/ LKIV 4FU B DPNNB TFQBSBUFE MJTU PG DJQIFST UIBU XJMM CF VTFE JO PSEFS PG QSFGFSFODF. 1PTTJCMF DJQIFS OBNFT BSF EFGJOFE CZ +$SBGU +4$). 4PNF FYBNQMFT JODMVEF: BFT128-DUS,BFT128-DCD,3EFT-DUS,3EFT-DCD,CMPXGJTI-DCD,BFT192-DCD,BFT256-DCD. *G OPU TQFDJGJFE UIF EFGBVMU MJTU GSPN +4$) XJMM CF VTFE. ">JBI 2.8.2, 2.9: *G TFU UIJT PQUJPO UP CF USVF, DBNFM-GUQ XJMM VTF UIF MJTU GJMF EJSFDUMZ UP DIFDL JG UIF GJMF FYJTUT. 4JODF TPNF '51 TFSWFS NBZ OPU TVQQPSU UP MJTU UIF GJMF EJSFDUMZ, JG UIF PQUJPO JT GBMTF, DBNFM-GUQ XJMM VTF UIF PME XBZ UP MJTU UIF EJSFDUPSZ BOE DIFDL JG UIF GJMF FYJTUT. /PUF GSPN ">JBI 2.10.1 POXBSET UIJT PQUJPO BMTP JOGMVFODFT readLock=changed UP DPOUSPM XIFUIFS JU QFSGPSNT B GBTU DIFDL UP VQEBUF GJMF JOGPSNBUJPO PS OPU. 5IJT DBO CF VTFE UP TQFFE VQ UIF QSPDFTT JG UIF '51 TFSWFS IBT B MPU PG GJMFT. 2%3/ LKIV: ">JBI 2.2: 4FUT XIFUIFS UP VTF TUSJDU IPTU LFZ DIFDLJOH. 1PTTJCMF WBMVFT BSF: no, yes BOE ask. ask EPFT OPU NBLF TFOTF UP VTF BT $BNFM DBOOPU BOTXFS UIF RVFTUJPO GPS ZPV BT JUT NFBOU GPS IVNBO JOUFSWFOUJPO. -LQB: 5IF EFGBVMU JO $BNFM 2.1 BOE CFMPX XBT ask. 4QFDJGJFT UIF NBYJNVN SFDPOOFDU BUUFNQUT $BNFM QFSGPSNT XIFO JU USJFT UP DPOOFDU UP UIF SFNPUF '51 TFSWFS. 6TF 0 UP EJTBCMF UIJT CFIBWJPS. %FMBZ JO NJMMJT $BNFM XJMM XBJU CFGPSF QFSGPSNJOH B SFDPOOFDU BUUFNQU. ">JBI 2.4: *T UIF DPOOFDU UJNFPVU JO NJMMJT. 5IJT DPSSFTQPOET UP VTJOH ftpClient.connectTimeout GPS UIF '51/'514. 'PS 4'51 UIJT PQUJPO JT BMTP VTFE XIFO BUUFNQUJOH UP DPOOFDU. %3/ >KA %3/2 .KIV: ">JBI 2.4: *T UIF SocketOptions.SO_TIMEOUT WBMVF JO NJMMJT. /PUF 4'51 XJMM BVUPNBUJD VTF UIF connectTimeout BT UIF soTimeout. %3/ >KA %3/2 .KIV: ">JBI 2.4: *T UIF EBUB UJNFPVU JO NJMMJT. 5IJT DPSSFTQPOET UP VTJOH ftpClient.dataTimeout GPS UIF '51/'514. 'PS 4'51 UIFSF JT OP EBUB UJNFPVU. ">JBI 2.5: 8IFUIFS PS OPU UP UISPXO BO FYDFQUJPO JG B TVDDFTTGVM DPOOFDUJPO BOE MPHJO DPVME OPU CF FTUBCMJTI. 5IJT BMMPXT B DVTUPN pollStrategy UP EFBM XJUI UIF FYDFQUJPO, GPS FYBNQMF UP TUPQ UIF DPOTVNFS PS UIF MJLFT.

TUSFBN%PXOMPBE

GBMTF

execProt

null

execPbsz isImplicit knownHostsFile privateKeyFile privateKeyFilePassphrase

null false null null null

ciphers

null

fastExistsCheck

false

strictHostKeyChecking

no

maximumReconnectAttempts reconnectDelay connectTimeout soTimeout timeout

3 1000 10000 null 30000

throwExceptionOnConnectFailed

false

654

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

siteCommand

null

%3/ >KA %3/2 .KIV: ">JBI 2.5: 5P FYFDVUF TJUF DPNNBOET BGUFS TVDDFTTGVM MPHJO. .VMUJQMF TJUF DPNNBOET DBO CF TFQBSBUFE VTJOH B OFX MJOF DIBSBDUFS (=O). 6TF help site UP TFF XIJDI TJUF DPNNBOET ZPVS '51 TFSWFS TVQQPSUT. ">JBI 2.6: 8IFUIFS PS OPU TUFQXJTF USBWFSTJOH EJSFDUPSJFT TIPVME CF VTFE PS OPU. 4UFQXJTF NFBOT UIBU JU XJMM $% POF EJSFDUPSZ BU B UJNF. 4FF NPSF EFUBJMT CFMPX. :PV DBO EJTBCMF UIJT JO DBTF ZPV DBO'U VTF UIJT BQQSPBDI. ">JBI 2.6: %JDUBUFT XIBU QBUI TFQBSBUPS DIBS UP VTF XIFO VQMPBEJOH GJMFT. Auto = 6TF UIF QBUI QSPWJEFE XJUIPVU BMUFSJOH JU. UNIX = 6TF VOJY TUZMF QBUI TFQBSBUPST. Windows = 6TF 8JOEPXT TUZMF QBUI TFQBSBUPST. 2%3/ /OLAR@BO .KIV: ">JBI 2.9: "MMPXT ZPV UP TFU DINPE PO UIF TUPSFE GJMF. 'PS FYBNQMF chmod=640. 2%3/ .KIV: ">JBI 2.8.3/2.9: 5P VTF DPNQSFTTJPO. 4QFDJGZ B MFWFM GSPN 1 UP 10. (JMLOQ>KQ: :PV NVTU NBOVBMMZ BEE UIF OFFEFE +4$) [MJC +"3 UP UIF DMBTTQBUI GPS DPNQSFTTJPO TVQQPSU. %3/ >KA %3/2 .KIV: ">JBI 2.1: "MMPXT ZPV UP VTF B DVTUPN org.apache.commons.net.ftp.FTPClient JOTUBODF. %3/ >KA %3/2 .KIV: ">JBI 2.1: "MMPXT ZPV UP VTF B DVTUPN org.apache.commons.net.ftp.FTPClientConfig JOTUBODF. 2%3/ .KIV: ">JBI 2.8 "MMPXT ZPV UP TFU UIF TFSWFS"MJWF*OUFSWBM PG UIF TGUQ TFTTJPO 2%3/ .KIV: ">JBI 2.8 "MMPXT ZPV UP TFU UIF TFSWFS"MJWF$PVOU.BY PG UIF TGUQ TFTTJPO %3/2 .KIV: 4FUT UIF USVTU TUPSF GJMF, TP UIBU UIF '514 DMJFOU DBO MPPL VQ GPS USVTUFE DFSUJGJDBUFT. %3/2 .KIV: 4FUT UIF USVTU TUPSF UZQF. %3/2 .KIV: 4FUT UIF USVTU TUPSF BMHPSJUIN. %3/2 .KIV: 4FUT UIF USVTU TUPSF QBTTXPSE. %3/2 .KIV: 4FUT UIF LFZ TUPSF GJMF, TP UIBU UIF '514 DMJFOU DBO MPPL VQ GPS UIF QSJWBUF DFSUJGJDBUF. %3/2 .KIV: 4FUT UIF LFZ TUPSF UZQF. %3/2 .KIV: 4FUT UIF LFZ TUPSF BMHPSJUIN. %3/2 .KIV: 4FUT UIF LFZ TUPSF QBTTXPSE. %3/2 .KIV: 4FUT UIF QSJWBUF LFZ QBTTXPSE. %3/2 .KIV: ">JBI 2.9: 3FGFSFODF UP B org.apache.camel.util.jsse.SSLContextParameters JO UIF 3FHJTUSZ.c 5IJT SFGFSFODF PWFSSJEFT BOZ DPOGJHVSFE 44- SFMBUFE PQUJPOT PO GUQ$MJFOU BT XFMM BT UIF TFDVSJUZ1SPUPDPM (44-, 5-4, FUD.) TFU PO 'UQT$POGJHVSBUJPO.c 4FF 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ.

stepwise

true

separator chmod compression ftpClient ftpClientConfig serverAliveInterval serverAliveCountMax ftpClient.trustStore.file ftpClient.trustStore.type ftpClient.trustStore.algorithm ftpClient.trustStore.password ftpClient.keyStore.file ftpClient.keyStore.type ftpClient.keyStore.algorithm ftpClient.keyStore.password ftpClient.keyStore.keyPassword

Auto null 0 null null 0 1 null JKS SunX509 null null JKS SunX509 null null

sslContextParameters

null

:PV DBO DPOGJHVSF BEEJUJPOBM PQUJPOT PO UIF ftpClient BOE ftpClientConfig GSPN UIF 63* EJSFDUMZ CZ VTJOH UIF ftpClient. PS ftpClientConfig. QSFGJY. 'PS FYBNQMF UP TFU UIF setDataTimeout PO UIF FTPClient UP 30 TFDPOET ZPV DBO EP:
from("ftp://foo@myserver?password=secret&ftpClient.dataTimeout=30000").to("bean:foo");

:PV DBO NJY BOE NBUDI BOE IBWF VTF CPUI QSFGJYFT, GPS FYBNQMF UP DPOGJHVSF EBUF GPSNBU PS UJNF[POFT.

from("ftp://foo@myserver?password=secret&ftpClient.dataTimeout=30000&ftpClientConfig.serverLanguageCod

:PV DBO IBWF BT NBOZ PG UIFTF PQUJPOT BT ZPV MJLF. 4FF UIF EPDVNFOUBUJPO PG UIF "QBDIF $PNNPOT '51 '51$MJFOU$POGJH GPS QPTTJCMF PQUJPOT BOE NPSF EFUBJMT. "OE BT XFMM GPS "QBDIF $PNNPOT '51 '51$MJFOU. *G ZPV EP OPU MJLF IBWJOH NBOZ BOE MPOH DPOGJHVSBUJPO JO UIF VSM ZPV DBO SFGFS UP UIF ftpClient PS ftpClientConfig UP VTF CZ MFUUJOH $BNFM MPPLVQ JO UIF 3FHJTUSZ GPS JU. 'PS FYBNQMF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

655

%3/2 @LJMLKBKQ ABC>RIQ QORPQ PQLOB 8IFO VTJOH UIF ftpClient. QSPQFSUJFT SFMBUFE UP 44- XJUI UIF '514 DPNQPOFOU, UIF USVTU TUPSF BDDFQU BMM DFSUJGJDBUFT. *G ZPV POMZ XBOU USVTU TFMFDUJWF DFSUJGJDBUFT, ZPV IBWF UP DPOGJHVSF UIF USVTU TUPSF XJUI UIF ftpClient.trustStore.xxx PQUJPOT PS CZ DPOGJHVSJOH B DVTUPN ftpClient.
8IFO VTJOH sslContextParameters, UIF USVTU TUPSF JT NBOBHFE CZ UIF DPOGJHVSBUJPO PG UIF QSPWJEFE 44-$POUFYU1BSBNFUFST JOTUBODF.

<bean id="myConfig" class="org.apache.commons.net.ftp.FTPClientConfig"> <property name="lenientFutureDates" value="true"/> <property name="serverLanguageCode" value="fr"/> </bean>

"OE UIFO MFU $BNFM MPPLVQ UIJT CFBO XIFO ZPV VTF UIF # OPUBUJPO JO UIF VSM.
from("ftp://foo@myserver?password=secret&ftpClientConfig=#myConfig").to("bean:foo");

,LOB 41( LMQFLKP $U>JMIBP ftp://someone@someftpserver.com/public/upload/images/ holiday2008?password=secret&binary=true ftp://someoneelse@someotherftpserver.co.uk:12049/reports/2008/ password=secret&binary=false ftp://publicftpserver.com/download #BC>RIQ TEBK @LKPRJFKD CFIBP 5IF '51 DPOTVNFS XJMM CZ EFGBVMU MFBWF UIF DPOTVNFE GJMFT VOUPVDIFE PO UIF SFNPUF '51 TFSWFS. :PV IBWF UP DPOGJHVSF JU FYQMJDJUMZ JG ZPV XBOU JU UP EFMFUF UIF GJMFT PS NPWF UIFN UP BOPUIFS MPDBUJPO. 'PS FYBNQMF ZPV DBO VTF delete=true UP EFMFUF UIF GJMFT, PS VTF move=.done UP NPWF UIF GJMFT JOUP B IJEEFO EPOF TVC EJSFDUPSZ. 5IF SFHVMBS 'JMF DPOTVNFS JT EJGGFSFOU BT JU XJMM CZ EFGBVMU NPWF GJMFT UP B .camel TVC EJSFDUPSZ. 5IF SFBTPO $BNFM EPFT KLQ EP UIJT CZ EFGBVMU GPS UIF '51 DPOTVNFS JT UIBU JU NBZ MBDL QFSNJTTJPOT CZ EFGBVMU UP CF BCMF UP NPWF PS EFMFUF GJMFT.

656

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4FF 'JMF2 BT BMM UIF PQUJPOT UIFSF BMTP BQQMJFT GPS UIJT DPNQPOFOU.

%3/ "LKPRJBO ALBP KLQ PRMMLOQ @LK@ROOBK@V 5IF '51 DPOTVNFS (XJUI UIF TBNF FOEQPJOU) EPFT OPU TVQQPSU DPODVSSFODZ (UIF CBDLJOH '51 DMJFOU JT OPU UISFBE TBGF). :PV DBO VTF NVMUJQMF '51 DPOTVNFST UP QPMM GSPN EJGGFSFOU FOEQPJOUT. *U JT POMZ B TJOHMF FOEQPJOU UIBU EPFT OPU TVQQPSU DPODVSSFOU DPOTVNFST.
5IF '51 QSPEVDFS EPFT KLQ IBWF UIJT JTTVF, JU TVQQPSUT DPODVSSFODZ.

,LOB FKCLOJ>QFLK 5IJT DPNQPOFOU JT BO FYUFOTJPO PG UIF 'JMF DPNQPOFOU. 4P UIFSF BSF NPSF TBNQMFT BOE EFUBJMT PO UIF 'JMF DPNQPOFOU QBHF.

IFJFQ>QFLKP
5IF PQUJPO OB>A+L@H DBO CF VTFE UP GPSDF $BNFM KLQ UP DPOTVNF GJMFT UIBU JT DVSSFOUMZ JO UIF QSPHSFTT PG CFJOH XSJUUFO. )PXFWFS, UIJT PQUJPO JT UVSOFE PGG CZ EFGBVMU, BT JU SFRVJSFT UIBU UIF VTFS IBT XSJUF BDDFTT. 4FF UIF PQUJPOT UBCMF BU 'JMF2 GPS NPSF EFUBJMT BCPVU SFBE MPDLT. 5IFSF BSF PUIFS TPMVUJPOT UP BWPJE DPOTVNJOH GJMFT UIBU BSF DVSSFOUMZ CFJOH XSJUUFO PWFS '51; GPS JOTUBODF, ZPV DBO XSJUF UP B UFNQPSBSZ EFTUJOBUJPO BOE NPWF UIF GJMF BGUFS JU IBT CFFO XSJUUFO. 8IFO NPWJOH GJMFT VTJOH move PS preMove PQUJPO UIF GJMFT BSF SFTUSJDUFE UP UIF '51@3005 GPMEFS. 5IBU QSFWFOUT ZPV GSPN NPWJOH GJMFT PVUTJEF UIF '51 BSFB. *G ZPV XBOU UP NPWF GJMFT UP BOPUIFS BSFB ZPV DBO VTF TPGU MJOLT BOE NPWF GJMFT JOUP B TPGU MJOLFE GPMEFS. ,BPP>DB 'B>ABOP 5IF GPMMPXJOH NFTTBHF IFBEFST DBO CF VTFE UP BGGFDU UIF CFIBWJPS PG UIF DPNQPOFOU
'B>ABO
CamelFileName CamelFileNameProduced CamelFileBatchIndex CamelFileBatchSize CamelFileHost CamelFileLocalWorkPath

#BP@OFMQFLK
4QFDJGJFT UIF PVUQVU GJMF OBNF (SFMBUJWF UP UIF FOEQPJOU EJSFDUPSZ) UP CF VTFE GPS UIF PVUQVU NFTTBHF XIFO TFOEJOH UP UIF FOEQPJOU. *G UIJT JT OPU QSFTFOU BOE OP FYQSFTTJPO FJUIFS, UIFO B HFOFSBUFE NFTTBHF *% JT VTFE BT UIF GJMFOBNF JOTUFBE. 5IF BDUVBM BCTPMVUF GJMFQBUI (QBUI + OBNF) GPS UIF PVUQVU GJMF UIBU XBT XSJUUFO. 5IJT IFBEFS JT TFU CZ $BNFM BOE JUT QVSQPTF JT QSPWJEJOH FOEVTFST UIF OBNF PG UIF GJMF UIBU XBT XSJUUFO. $VSSFOU JOEFY PVU PG UPUBM OVNCFS PG GJMFT CFJOH DPOTVNFE JO UIJT CBUDI. 5PUBM OVNCFS PG GJMFT CFJOH DPOTVNFE JO UIJT CBUDI. 5IF SFNPUF IPTUOBNF. 1BUI UP UIF MPDBM XPSL GJMF, JG MPDBM XPSL EJSFDUPSZ JT VTFE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

657

?LRQ QFJBLRQP 5IF UXP TFU PG MJCSBSJFT (TFF UPQ) IBT EJGGFSFOU "1* GPS TFUUJOH UJNFPVU. :PV DBO VTF UIF connectTimeout PQUJPO GPS CPUI PG UIFN UP TFU B UJNFPVU JO NJMMJT UP FTUBCMJTI B OFUXPSL DPOOFDUJPO. "O JOEJWJEVBM soTimeout DBO BMTP CF TFU PO UIF '51/'514, XIJDI DPSSFTQPOET UP VTJOH ftpClient.soTimeout. /PUJDF 4'51 XJMM BVUPNBUJDBMMZ VTF connectTimeout BT JUT soTimeout. 5IF timeout PQUJPO POMZ BQQMJFT GPS '51/'541 BT UIF EBUB UJNFPVU, XIJDI DPSSFTQPOET UP UIF ftpClient.dataTimeout WBMVF. "MM UJNFPVU WBMVFT BSF JO NJMMJT. 4PFKD +L@>I 6LOH #FOB@QLOV $BNFM TVQQPSUT DPOTVNJOH GSPN SFNPUF '51 TFSWFST BOE EPXOMPBEJOH UIF GJMFT EJSFDUMZ JOUP B MPDBM XPSL EJSFDUPSZ. 5IJT BWPJET SFBEJOH UIF FOUJSF SFNPUF GJMF DPOUFOU JOUP NFNPSZ BT JU JT TUSFBNFE EJSFDUMZ JOUP UIF MPDBM GJMF VTJOH FileOutputStream. $BNFM XJMM TUPSF UP B MPDBM GJMF XJUI UIF TBNF OBNF BT UIF SFNPUF GJMF, UIPVHI XJUI .inprogress BT FYUFOTJPO XIJMF UIF GJMF JT CFJOH EPXOMPBEFE. "GUFSXBSET, UIF GJMF JT SFOBNFE UP SFNPWF UIF .inprogress TVGGJY. "OE GJOBMMZ, XIFO UIF &YDIBOHF JT DPNQMFUF UIF MPDBM GJMF JT EFMFUFE. 4P JG ZPV XBOU UP EPXOMPBE GJMFT GSPN B SFNPUF '51 TFSWFS BOE TUPSF JU BT GJMFT UIFO ZPV OFFE UP SPVUF UP B GJMF FOEQPJOU TVDI BT:
from("ftp://someone@someserver.com?password=secret&localWorkDirectory=/tmp").to("file://inbox");

2QBMTFPB @E>KDFKD AFOB@QLOFBP $BNFM '51 DBO PQFSBUF JO UXP NPEFT JO UFSNT PG USBWFSTJOH EJSFDUPSJFT XIFO DPOTVNJOH GJMFT (FH EPXOMPBEJOH) PS QSPEVDJOH GJMFT (FH VQMPBEJOH) TUFQXJTF OPU TUFQXJTF :PV NBZ XBOU UP QJDL FJUIFS POF EFQFOEJOH PO ZPVS TJUVBUJPO BOE TFDVSJUZ JTTVFT. 4PNF $BNFM FOE VTFST DBO POMZ EPXOMPBE GJMFT JG UIFZ VTF TUFQXJTF, XIJMF PUIFST DBO POMZ EPXOMPBE JG UIFZ EP OPU. "U MFBTU ZPV IBWF UIF DIPJDF UP QJDL (GSPN $BNFM 2.6 POXBSET). *O $BNFM 2.0 - 2.5 UIFSF JT POMZ POF NPEF BOE JU JT: CFGPSF 2.5 OPU TUFQXJTF 2.5 TUFQXJTF 'SPN $BNFM 2.6 POXBSET UIFSF JT OPX BO PQUJPO stepwise ZPV DBO VTF UP DPOUSPM UIF CFIBWJPS. /PUF UIBU TUFQXJTF DIBOHJOH PG EJSFDUPSZ XJMM JO NPTU DBTFT POMZ XPSL XIFO UIF VTFS JT DPOGJOFE UP JU'T IPNF EJSFDUPSZ BOE XIFO UIF IPNF EJSFDUPSZ JT SFQPSUFE BT "/". 5IF EJGGFSFODF CFUXFFO UIF UXP PG UIFN JT CFTU JMMVTUSBUFE XJUI BO FYBNQMF. 4VQQPTF XF IBWF UIF GPMMPXJOH EJSFDUPSZ TUSVDUVSF PO UIF SFNPUF '51 TFSWFS XF OFFE UP USBWFSTF BOE EPXOMPBE GJMFT:

658

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.MQFJFW>QFLK ?V OBK>JFKD TLOH CFIB 5IF SPVUF BCPWF JT VMUSB FGGJDJFOU BT JU BWPJET SFBEJOH UIF FOUJSF GJMF DPOUFOU JOUP NFNPSZ. *U XJMM EPXOMPBE UIF SFNPUF GJMF EJSFDUMZ UP B MPDBM GJMF TUSFBN. 5IF java.io.File IBOEMF JT UIFO VTFE BT UIF &YDIBOHF CPEZ. 5IF GJMF QSPEVDFS MFWFSBHFT UIJT GBDU BOE DBO XPSL EJSFDUMZ PO UIF XPSL GJMF java.io.File IBOEMF BOE QFSGPSN B java.io.File.rename UP UIF UBSHFU GJMFOBNF. "T $BNFM LOPXT JU'T B MPDBM XPSL GJMF, JU DBO PQUJNJ[F BOE VTF B SFOBNF JOTUFBE PG B GJMF DPQZ, BT UIF XPSL GJMF JT NFBOU UP CF EFMFUFE BOZXBZ.

/ /one /one/two /one/two/sub-a /one/two/sub-b

"OE UIBU XF IBWF B GJMF JO FBDI PG TVC-B (B.UYU) BOE TVC-C (C.UYU) GPMEFS.

4PFKD PQBMTFPB=QORB (ABC>RIQ JLAB)


TYPE A 200 Type set to A PWD 257 "/" is current directory. CWD one 250 CWD successful. "/one" is current directory. CWD two 250 CWD successful. "/one/two" is current directory. SYST 215 UNIX emulated by FileZilla PORT 127,0,0,1,17,94 200 Port command successful LIST 150 Opening data channel for directory list. 226 Transfer OK CWD sub-a 250 CWD successful. "/one/two/sub-a" is current directory. PORT 127,0,0,1,17,95 200 Port command successful LIST 150 Opening data channel for directory list. 226 Transfer OK CDUP 200 CDUP successful. "/one/two" is current directory. CWD sub-b 250 CWD successful. "/one/two/sub-b" is current directory.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

659

PORT 127,0,0,1,17,96 200 Port command successful LIST 150 Opening data channel for directory list. 226 Transfer OK CDUP 200 CDUP successful. "/one/two" is current directory. CWD / 250 CWD successful. "/" is current directory. PWD 257 "/" is current directory. CWD one 250 CWD successful. "/one" is current directory. CWD two 250 CWD successful. "/one/two" is current directory. PORT 127,0,0,1,17,97 200 Port command successful RETR foo.txt 150 Opening data channel for file transfer. 226 Transfer OK CWD / 250 CWD successful. "/" is current directory. PWD 257 "/" is current directory. CWD one 250 CWD successful. "/one" is current directory. CWD two 250 CWD successful. "/one/two" is current directory. CWD sub-a 250 CWD successful. "/one/two/sub-a" is current directory. PORT 127,0,0,1,17,98 200 Port command successful RETR a.txt 150 Opening data channel for file transfer. 226 Transfer OK CWD / 250 CWD successful. "/" is current directory. PWD 257 "/" is current directory. CWD one 250 CWD successful. "/one" is current directory. CWD two 250 CWD successful. "/one/two" is current directory. CWD sub-b 250 CWD successful. "/one/two/sub-b" is current directory. PORT 127,0,0,1,17,99 200 Port command successful RETR b.txt 150 Opening data channel for file transfer. 226 Transfer OK CWD / 250 CWD successful. "/" is current directory. QUIT

660

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

221 Goodbye disconnected.

"T ZPV DBO TFF XIFO TUFQXJTF JT FOBCMFE, JU XJMM USBWFSTF UIF EJSFDUPSZ TUSVDUVSF VTJOH $% YYY.

4PFKD PQBMTFPB=C>IPB
230 Logged on TYPE A 200 Type set to A SYST 215 UNIX emulated by FileZilla PORT 127,0,0,1,4,122 200 Port command successful LIST one/two 150 Opening data channel for directory list 226 Transfer OK PORT 127,0,0,1,4,123 200 Port command successful LIST one/two/sub-a 150 Opening data channel for directory list 226 Transfer OK PORT 127,0,0,1,4,124 200 Port command successful LIST one/two/sub-b 150 Opening data channel for directory list 226 Transfer OK PORT 127,0,0,1,4,125 200 Port command successful RETR one/two/foo.txt 150 Opening data channel for file transfer. 226 Transfer OK PORT 127,0,0,1,4,126 200 Port command successful RETR one/two/sub-a/a.txt 150 Opening data channel for file transfer. 226 Transfer OK PORT 127,0,0,1,4,127 200 Port command successful RETR one/two/sub-b/b.txt 150 Opening data channel for file transfer. 226 Transfer OK QUIT 221 Goodbye disconnected.

"T ZPV DBO TFF XIFO OPU VTJOH TUFQXJTF, UIFSF BSF OP $% PQFSBUJPO JOWPLFE BU BMM.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

661

2>JMIBP *O UIF TBNQMF CFMPX XF TFU VQ $BNFM UP EPXOMPBE BMM UIF SFQPSUT GSPN UIF '51 TFSWFS PODF FWFSZ IPVS (60 NJO) BT #*/"3: DPOUFOU BOE TUPSF JU BT GJMFT PO UIF MPDBM GJMF TZTUFN.
protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { // we use a delay of 60 minutes (eg. once pr. hour we poll the FTP server long delay = 60 * 60 * 1000L; // from the given FTP server we poll (= download) all the files // from the public/reports folder as BINARY types and store this as files // in a local directory. Camel will use the filenames from the FTPServer // "consumer." in // consumer.delay // Component. notice that the FTPConsumer properties must be prefixed with the URL the delay parameter is from the FileConsumer component so we should use as the URI parameter name. The FTP Component is an extension of the File

from("ftp://tiger:scott@localhost/public/reports?binary=true&consumer.delay=" + delay). to("file://target/test-reports"); } }; }

"OE UIF SPVUF VTJOH 4QSJOH %4-:


<route> <from uri="ftp://scott@localhost/public/ reports?password=tiger&amp;binary=true&amp;delay=60000"/> <to uri="file://target/test-reports"/> </route>

"LKPRJFKD > OBJLQB %3/2 PBOSBO (FJMIF@FQ 22+) >KA @IFBKQ >RQEBKQF@>QFLK
from("ftps://admin@localhost:2222/public/camel?password=admin&securityProtocol=SSL&isImplicit=true &ftpClient.keyStore.file=./src/test/resources/server.jks &ftpClient.keyStore.password=password&ftpClient.keyStore.keyPassword=password") .to("bean:foo");

662

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"LKPRJFKD > OBJLQB %3/2 PBOSBO (BUMIF@FQ 3+2) >KA > @RPQLJ QORPQ PQLOB @LKCFDRO>QFLK
from("ftps://admin@localhost:2222/public/camel?password=admin&ftpClient.trustStore.file=./src/ test/resources/server.jks&ftpClient.trustStore.password=password") .to("bean:foo");

%FIQBO RPFKD org.apache.camel.component.file.GenericFileFilter $BNFM TVQQPSUT QMVHHBCMF GJMUFSJOH TUSBUFHJFT. 5IJT TUSBUFHZ JU UP VTF UIF CVJME JO org.apache.camel.component.file.GenericFileFilter JO +BWB. :PV DBO UIFO DPOGJHVSF UIF FOEQPJOU XJUI TVDI B GJMUFS UP TLJQ DFSUBJO GJMUFST CFGPSF CFJOH QSPDFTTFE. *O UIF TBNQMF XF IBWF CVJMU PVS PXO GJMUFS UIBU POMZ BDDFQUT GJMFT TUBSUJOH XJUI SFQPSU JO UIF GJMFOBNF.
public class MyFileFilter<T> implements GenericFileFilter<T> { public boolean accept(GenericFile<T> file) { // we only want report files return file.getFileName().startsWith("report"); } }

"OE UIFO XF DBO DPOGJHVSF PVS SPVUF VTJOH UIF CFIQBO BUUSJCVUF UP SFGFSFODF PVS GJMUFS (VTJOH # OPUBUJPO) UIBU XF IBWF EFGJOFE JO UIF TQSJOH 9.- GJMF:
<!-- define our sorter as a plain spring bean --> <bean id="myFilter" class="com.mycompany.MyFileFilter"/> <route> <from uri="ftp://someuser@someftpserver.com?password=secret&amp;filter=#myFilter"/> <to uri="bean:processInbox"/> </route>

%FIQBOFKD RPFKD

-3 M>QE J>Q@EBO

5IF "/5 QBUI NBUDIFS JT B GJMUFS UIBU JT TIJQQFE PVU-PG-UIF-CPY JO UIF @>JBI-PMOFKD KBS. 4P ZPV OFFE UP EFQFOE PO @>JBI-PMOFKD JG ZPV BSF VTJOH .BWFO. 5IF SFBTPO JT UIBU XF MFWFSBHF 4QSJOH'T "OU1BUI.BUDIFS UP EP UIF BDUVBM NBUDIJOH. 5IF GJMF QBUIT BSF NBUDIFE XJUI UIF GPMMPXJOH SVMFT: ? NBUDIFT POF DIBSBDUFS * NBUDIFT [FSP PS NPSF DIBSBDUFST ** NBUDIFT [FSP PS NPSF EJSFDUPSJFT JO B QBUI 5IF TBNQMF CFMPX EFNPOTUSBUFT IPX UP VTF JU:
$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9 663

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <template id="camelTemplate"/> <!-- use myFilter as filter to allow setting ANT paths for which files to scan for -->

<endpoint id="myFTPEndpoint" uri="ftp://admin@localhost:${SpringFileAntPathMatcherRemoteFileFilterTest.ftpPort}/antpath?password=ad <route> <from ref="myFTPEndpoint"/> <to uri="mock:result"/> </route> </camelContext> <!-- we use the AntPathMatcherRemoteFileFilter to use ant paths for includes and exclude --> <bean id="myAntFilter" class="org.apache.camel.component.file.AntPathMatcherGenericFileFilter"> <!-- include any files in the sub folder that has day in the name --> <property name="includes" value="**/subfolder/**/*day*"/> <!-- exclude all files with bad in name or .xml files. Use comma to separate multiple excludes --> <property name="excludes" value="**/*bad*,**/*.xml"/> </bean>

#B?RD ILDDFKD 5IJT DPNQPOFOU IBT MPH MFWFM 31 "$ UIBU DBO CF IFMQGVM JG ZPV IBWF QSPCMFNT. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 'JMF2

" ,$+ ".,/.-$-32 %.1 &..&+$

// $-&(-$

5IF $BNFM DPNQPOFOUT GPS (PPHMF "QQ &OHJOF (("&) BSF QBSU PG UIF camel-gae QSPKFDU BOE QSPWJEF DPOOFDUJWJUZ UP ("&'T DMPVE DPNQVUJOH TFSWJDFT. 5IFZ NBLF UIF ("& DMPVE DPNQVUJOH FOWJSPONFOU BDDFTTJCMF UP BQQMJDBUJPOT WJB $BNFM JOUFSGBDFT. 'PMMPXJOH UIJT QBUUFSO GPS PUIFS DMPVE DPNQVUJOH FOWJSPONFOUT DPVME NBLF JU FBTJFS UP QPSU $BNFM BQQMJDBUJPOT GSPN POF DMPVE DPNQVUJOH QSPWJEFS UP BOPUIFS. 5IF GPMMPXJOH UBCMF MJTUT UIF DMPVE DPNQVUJOH TFSWJDFT QSPWJEFE CZ (PPHMF BOE UIF TVQQPSUJOH $BNFM DPNQPOFOUT. 5IF EPDVNFOUBUJPO PG FBDI DPNQPOFOU DBO CF GPVOE CZ GPMMPXJOH UIF MJOL JO UIF Camel Component DPMVNO.

664

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

3RQLOF>IP ` " HPPE TUBSUJOH QPJOU GPS VTJOH $BNFM PO ("& JT UIF 5VUPSJBM GPS $BNFM PO (PPHMF "QQ &OHJOF ` 5IF 0"VUI UVUPSJBM EFNPOTUSBUFT IPX UP JNQMFNFOU 0"VUI JO XFC BQQMJDBUJPOT.

& $ PBOSF@B
63- GFUDI TFSWJDF 5BTL RVFVFJOH TFSWJDF .BJM TFSWJDF .FNDBDIF TFSWJDF 9.11 TFSWJDF *NBHFT TFSWJDF %BUBTUPSF TFSWJDF

">JBI @LJMLKBKQ
HIUUQ HUBTL HNBJM c c c c

"LJMLKBKQ ABP@OFMQFLK
1SPWJEFT DPOOFDUJWJUZ UP UIF ("& 63- GFUDI TFSWJDF CVU DBO BMTP CF VTFE UP SFDFJWF NFTTBHFT GSPN TFSWMFUT. 4VQQPSUT BTZODISPOPVT NFTTBHF QSPDFTTJOH PO ("& CZ VTJOH UIF UBTL RVFVFJOH TFSWJDF BT NFTTBHF RVFVF. 4VQQPSUT TFOEJOH PG FNBJMT WJB UIF ("& NBJM TFSWJDF. 3FDFJWJOH NBJMT JT OPU TVQQPSUFE ZFU CVU XJMM CF BEEFE MBUFS. /PU TVQQPSUFE ZFU. /PU TVQQPSUFE ZFU. /PU TVQQPSUFE ZFU. /PU TVQQPSUFE ZFU. 5IFTF DPNQPOFOUT JOUFSBDU XJUI UIF (PPHMF "DDPVOUT "1* GPS BVUIFOUJDBUJPO BOE BVUIPSJ[BUJPO. (PPHMF "DDPVOUT JT OPU TQFDJGJD UP (PPHMF "QQ &OHJOF CVU JT PGUFO VTFE CZ ("& BQQMJDBUJPOT GPS JNQMFNFOUJOH TFDVSJUZ. 5IF HBVUI DPNQPOFOU JT VTFE CZ XFC BQQMJDBUJPOT UP JNQMFNFOU B (PPHMF-TQFDJGJD 0"VUI DPOTVNFS. 5IJT DPNQPOFOU DBO BMTP CF VTFE UP 0"VUI-FOBCMF OPO-("& XFC BQQMJDBUJPOT. 5IF HMPHJO DPNQPOFOU JT VTFE CZ +BWB DMJFOUT (PVUTJEF ("&) GPS QSPHSBNNBUJD MPHJO UP ("& BQQMJDBUJPOT. 'PS JOTUSVDUJPOT IPX UP QSPUFDU ("& BQQMJDBUJPOT BHBJOTU VOBVUIPSJ[FE BDDFTT SFGFS UP UIF 4FDVSJUZ GPS $BNFM ("& BQQMJDBUJPOT QBHF.

"DDPVOUT TFSWJDF

HBVUI HMPHJO

">JBI @LKQBUQ 4FUUJOH VQ B SpringCamelContext PO (PPHMF "QQ &OHJOF EJGGFST CFUXFFO $BNFM 2.1 BOE IJHIFS WFSTJPOT. 5IF QSPCMFN JT UIBU VTBHF PG UIF $BNFM-TQFDJGJD 4QSJOH DPOGJHVSBUJPO 9.TDIFNB GSPN UIF http://camel.apache.org/schema/spring OBNFTQBDF SFRVJSFT +"9# BOE $BNFM 2.1 EFQFOET PO B (PPHMF "QQ &OHJOF 4%, WFSTJPO UIBU EPFTO'U TVQQPSU +"9# ZFU. 5IJT MJNJUBUJPO IBT CFFO SFNPWFE TJODF $BNFM 2.2. +.9 NVTU CF EJTBCMFE JO BOZ DBTF CFDBVTF UIF javax.management QBDLBHF JTO'U PO UIF "QQ &OHJOF +3& XIJUFMJTU.

">JBI 2.1
camel-gae 2.1 DPNFT XJUI UIF GPMMPXJOH CamelContext JNQMFNFOUBUJPOT. ` org.apache.camel.component.gae.context.GaeDefaultCamelContext (FYUFOET org.apache.camel.impl.DefaultCamelContext) ` org.apache.camel.component.gae.context.GaeSpringCamelContext (FYUFOET org.apache.camel.spring.SpringCamelContext) #PUI EJTBCMF +.9 CFGPSF TUBSUVQ. 5IF GaeSpringCamelContext BEEJUJPOBMMZ QSPWJEFT TFUUFS NFUIPET BEEJOH SPVUF CVJMEFST BT TIPXO JO UIF OFYU FYBNQMF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

665

Listing 1. appctx.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="camelContext" class="org.apache.camel.component.gae.context.GaeSpringCamelContext"> <property name="routeBuilder" ref="myRouteBuilder" /> </bean> <bean id="myRouteBuilder" class="org.example.MyRouteBuilder"> </bean> </beans>

"MUFSOBUJWFMZ, VTF UIF routeBuilders QSPQFSUZ PG UIF GaeSpringCamelContext GPS TFUUJOH B MJTU PG SPVUF CVJMEFST. 6TJOH UIJT BQQSPBDI, B SpringCamelContext DBO CF DPOGJHVSFE PO ("& XJUIPVU UIF OFFE GPS +"9#.

">JBI 2.2 LO EFDEBO


8JUI $BNFM 2.2 PS IJHIFS, BQQMJDBUJPOT DBO VTF UIF http://camel.apache.org/ schema/spring OBNFTQBDF GPS DPOGJHVSJOH B SpringCamelContext CVU TUJMM OFFE UP EJTBCMF +.9. )FSF'T BO FYBNQMF.
Listing 1. appctx.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camel:camelContext id="camelContext"> <camel:jmxAgent id="agent" disabled="true" /> <camel:routeBuilder ref="myRouteBuilder"/> </camel:camelContext> <bean id="myRouteBuilder" class="org.example.MyRouteBuilder"> </bean> </beans>

666

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

3EB TB?.UJI 3VOOJOH $BNFM PO ("& SFRVJSFT VTBHF PG UIF CamelHttpTransportServlet GSPN camel-servlet. 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DPOGJHVSF UIJT TFSWMFU UPHFUIFS XJUI B 4QSJOH BQQMJDBUJPO DPOUFYU 9.- GJMF.
Listing 1. web.xml
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <servlet> <servlet-name>CamelServlet</servlet-name> <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>appctx.xml</param-value> </init-param> </servlet> <!-Mapping used for external requests --> <servlet-mapping> <servlet-name>CamelServlet</servlet-name> <url-pattern>/camel/*</url-pattern> </servlet-mapping> <!-Mapping used for web hooks accessed by task queueing service. --> <servlet-mapping> <servlet-name>CamelServlet</servlet-name> <url-pattern>/worker/*</url-pattern> </servlet-mapping> </web-app>

5IF MPDBUJPO PG UIF 4QSJOH BQQMJDBUJPO DPOUFYU 9.- GJMF JT HJWFO CZ UIF contextConfigLocation JOJU QBSBNFUFS. 5IF appctx.xml GJMF NVTU CF PO UIF DMBTTQBUI. 5IF TFSWMFU NBQQJOH NBLFT UIF $BNFM BQQMJDBUJPO BDDFTTJCMF VOEFS http://<appname>.appspot.com/camel/... XIFO EFQMPZFE UP (PPHMF "QQ &OHJOF XIFSF <appname> NVTU CF SFQMBDFE CZ B SFBM ("& BQQMJDBUJPO OBNF. 5IF TFDPOE TFSWMFU NBQQJOH JT VTFE JOUFSOBMMZ CZ UIF UBTL RVFVFJOH TFSWJDF GPS CBDLHSPVOE QSPDFTTJOH WJB XFC IPPLT. 5IJT NBQQJOH JT SFMFWBOU GPS UIF HUBTL DPNQPOFOU BOE JT FYQMBJOFE UIFSF JO NPSF EFUBJM.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

667

' 9$+" 23 ".,/.-$-3


S>FI>?IB >P LC ">JBI 2.7 5IF E>WBI@>PQ: DPNQPOFOU BMMPXT ZPV UP XPSL XJUI UIF )B[FMDBTU EJTUSJCVUFE EBUB HSJE / DBDIF. )B[FMDBTU JT B JO NFNPSZ EBUB HSJE, FOUJSFMZ XSJUUFO JO +BWB (TJOHMF KBS). *U PGGFST B HSFBU QBMFUUF PG EJGGFSFOU EBUB TUPSFT MJLF NBQ, NVMUJ NBQ (TBNF LFZ, O WBMVFT), RVFVF, MJTU BOE BUPNJD OVNCFS. 5IF NBJO SFBTPO UP VTF )B[FMDBTU JT JUT TJNQMF DMVTUFS TVQQPSU. *G ZPV IBWF FOBCMFE NVMUJDBTU PO ZPVS OFUXPSL ZPV DBO SVO B DMVTUFS XJUI IVOESFE OPEFT XJUI OP FYUSB DPOGJHVSBUJPO. )B[FMDBTU DBO TJNQMZ DPOGJHVSFE UP BEE BEEJUJPOBM GFBUVSFT MJLF O DPQJFT CFUXFFO OPEFT (EFGBVMU JT 1), DBDIF QFSTJTUFODF, OFUXPSL DPOGJHVSBUJPO (JG OFFEFE), OFBS DBDIF, FOWJDUJPO BOE TP PO. 'PS NPSF JOGPSNBUJPO DPOTVMU UIF )B[FMDBTU EPDVNFOUBUJPO PO IUUQ://XXX.IB[FMDBTU.DPN/EPDT.KTQ. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-hazelcast</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
hazelcast:[ map | multimap | queue | seda | set | atomicvalue | instance]:cachename[?options]

2B@QFLKP 1. 2. 3. 4. 5. 6. 7. 6TBHF PG NBQ 6TBHF PG NVMUJNBQ 6TBHF PG RVFVF 6TBHF PG MJTU 6TBHF PG TFEB 6TBHF PG BUPNJD OVNCFS 6TBHF PG DMVTUFS TVQQPSU (JOTUBODF)

668

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV IBWF UP VTF UIF TFDPOE QSFGJY UP EFGJOF XIJDI UZQF PG EBUB TUPSF ZPV XBOU UP VTF. 4P>DB LC ,>M

J>M @>@EB MOLAR@BO - QL("E>WBI@>PQ:J>M:CLL")


*G ZPV XBOU UP TUPSF B WBMVF JO B NBQ ZPV DBO VTF UIF NBQ DBDIF QSPEVDFS. 5IF NBQ DBDIF QSPEVDFS QSPWJEFT 5 PQFSBUJPOT (QVU, HFU, VQEBUF, EFMFUF, RVFSZ). 'PS UIF GJSTU 4 ZPV IBWF UP QSPWJEF UIF PQFSBUJPO JOTJEF UIF "IB[FMDBTU.PQFSBUJPO.UZQF" IFBEFS WBSJBCMF. *O +BWB %4- ZPV DBO VTF UIF DPOTUBOUT GSPN org.apache.camel.component.hazelcast.HazelcastConstants. )FBEFS 7BSJBCMFT GPS UIF SFRVFTU NFTTBHF: ->JB hazelcast.operation.type 3VMB String #BP@OFMQFLK WBMJE WBMVFT BSF: QVU, EFMFUF, HFU, VQEBUF, RVFSZ UIF PCKFDU JE UP TUPSF / GJOE ZPVS PCKFDU JOTJEF UIF DBDIF (OPU OFFEFE GPS UIF RVFSZ PQFSBUJPO) #BP@OFMQFLK WBMJE WBMVFT BSF: QVU, EFMFUF, HFU, VQEBUF, RVFSZ :5BOPFLK 2.8< UIF PCKFDU JE UP TUPSF / GJOE ZPVS PCKFDU JOTJEF UIF DBDIF (OPU OFFEFE GPS UIF RVFSZ PQFSBUJPO) :5BOPFLK 2.8<

hazelcast.objectId ->JB

String 3VMB

CamelHazelcastOperationType

String

CamelHazelcastObjectId :PV DBO DBMM UIF TBNQMFT XJUI:

String

template.sendBodyAndHeader("direct:[put|get|update|delete|query]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");

2>JMIB CLO MRQ: +BWB %4-:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

669

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

from("direct:put") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:put" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>put</constant> </setHeader> <to uri="hazelcast:map:foo" /> </route>

2>JMIB CLO DBQ: +BWB %4-:


from("direct:get") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX) .to("seda:out");

4QSJOH %4-:
<route> <from uri="direct:get" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>get</constant> </setHeader> <to uri="hazelcast:map:foo" /> <to uri="seda:out" /> </route>

2>JMIB CLO RMA>QB: +BWB %4-:

670

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("direct:update") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.UPDATE_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:update" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>update</constant> </setHeader> <to uri="hazelcast:map:foo" /> </route>

2>JMIB CLO ABIBQB: +BWB %4-:


from("direct:delete") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DELETE_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:delete" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>delete</constant> </setHeader> <to uri="hazelcast:map:foo" /> </route>

2>JMIB CLO NRBOV +BWB %4-:


from("direct:query") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.QUERY_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX) .to("seda:out");

4QSJOH %4-:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

671

<route> <from uri="direct:query" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>query</constant> </setHeader> <to uri="hazelcast:map:foo" /> <to uri="seda:out" /> </route>

'PS UIF RVFSZ PQFSBUJPO )B[FMDBTU PGGFST B 42- MJLF TZOUBY UP RVFSZ ZPVS EJTUSJCVUFE NBQ.
String q1 = "bar > 1000"; template.sendBodyAndHeader("direct:query", null, HazelcastConstants.QUERY, q1);

J>M @>@EB @LKPRJBO - COLJ("E>WBI@>PQ:J>M:CLL") )B[FMDBTU QSPWJEFT FWFOU MJTUFOFST PO UIFJS EBUB HSJE. *G ZPV XBOU UP CF OPUJGJFE JG B DBDIF XJMM CF NBOJQVMBUFE, ZPV DBO VTF UIF NBQ DPOTVNFS. 5IFSF'SF 4 FWFOUT: MRQ, RMA>QB, ABIBQB BOE BKSF@Q. 5IF FWFOU UZQF XJMM CF TUPSFE JO UIF "E>WBI@>PQ.IFPQBKBO.>@QFLK" IFBEFS WBSJBCMF. 5IF NBQ DPOTVNFS QSPWJEFT TPNF BEEJUJPOBM JOGPSNBUJPO JOTJEF UIFTF WBSJBCMFT: )FBEFS 7BSJBCMFT JOTJEF UIF SFTQPOTF NFTTBHF: ->JB hazelcast.listener.time hazelcast.listener.type hazelcast.listener.action hazelcast.objectId hazelcast.cache.name hazelcast.cache.type ->JB CamelHazelcastListenerTime CamelHazelcastListenerType 3VMB Long String String String String String 3VMB Long String #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT UIF NBQ DPOTVNFS TFUT IFSF "DBDIFMJTUFOFS" UZQF PG FWFOU - IFSF >AABA, RMA>QBA, BKSF@QBA BOE OBJLSBA UIF PJE PG UIF PCKFDU UIF OBNF PG UIF DBDIF - F.H. "GPP" UIF UZQF PG UIF DBDIF - IFSF NBQ #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT :5BOPFLK 2.8< UIF NBQ DPOTVNFS TFUT IFSF "DBDIFMJTUFOFS" :5BOPFLK 2.8<

672

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

CamelHazelcastListenerAction

String

UZQF PG FWFOU - IFSF >AABA, RMA>QBA, BKSF@QBA BOE OBJLSBA. :5BOPFLK 2.8< UIF PJE PG UIF PCKFDU :5BOPFLK 2.8< UIF OBNF PG UIF DBDIF - F.H. "GPP" :5BOPFLK 2.8< UIF UZQF PG UIF DBDIF - IFSF NBQ :5BOPFLK 2.8<

CamelHazelcastObjectId CamelHazelcastCacheName CamelHazelcastCacheType

String String String

5IF PCKFDU WBMVF XJMM CF TUPSFE XJUIJO MRQ BOE RMA>QB BDUJPOT JOTJEF UIF NFTTBHF CPEZ. )FSF'T B TBNQMF:
fromF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX) .log("object...") .choice() .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED)) .log("...added") .to("mock:added") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ENVICTED)) .log("...envicted") .to("mock:envicted") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.UPDATED)) .log("...updated") .to("mock:updated") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED)) .log("...removed") .to("mock:removed") .otherwise() .log("fail!");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

673

4P>DB LC ,RIQF ,>M

JRIQFJ>M @>@EB MOLAR@BO - QL("E>WBI@>PQ:JRIQFJ>M:CLL")


" NVMUJNBQ JT B DBDIF XIFSF ZPV DBO TUPSF O WBMVFT UP POF LFZ. 5IF NVMUJNBQ QSPEVDFS QSPWJEFT 4 PQFSBUJPOT (QVU, HFU, SFNPWFWBMVF, EFMFUF). )FBEFS 7BSJBCMFT GPS UIF SFRVFTU NFTTBHF: ->JB hazelcast.operation.type hazelcast.objectId 3VMB String String #BP@OFMQFLK WBMJE WBMVFT BSF: QVU, HFU, SFNPWFWBMVF, EFMFUF UIF PCKFDU JE UP TUPSF / GJOE ZPVS PCKFDU JOTJEF UIF DBDIF

->JB CamelHazelcastOperationType

3VMB String

#BP@OFMQFLK WBMJE WBMVFT BSF: QVU, EFMFUF, HFU, VQEBUF, RVFSZ S>FI>?IB >P LC ">JBI 2.8 UIF PCKFDU JE UP TUPSF / GJOE ZPVS PCKFDU JOTJEF UIF DBDIF (OPU OFFEFE GPS UIF RVFSZ PQFSBUJPO) :5BOPFLK 2.8<

CamelHazelcastObjectId :PV DBO DBMM UIF TBNQMFT XJUI:

String

template.sendBodyAndHeader("direct:[put|get|update|delete|query]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");

2>JMIB CLO MRQ: +BWB %4-:


from("direct:put") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:put" />

674

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

<!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>put</constant> </setHeader> <to uri="hazelcast:map:foo" /> </route>

2>JMIB CLO DBQ: +BWB %4-:


from("direct:get") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX) .to("seda:out");

4QSJOH %4-:
<route> <from uri="direct:get" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>get</constant> </setHeader> <to uri="hazelcast:map:foo" /> <to uri="seda:out" /> </route>

2>JMIB CLO RMA>QB: +BWB %4-:


from("direct:update") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.UPDATE_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX);

4QSJOH %4-:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

675

<route> <from uri="direct:update" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>update</constant> </setHeader> <to uri="hazelcast:map:foo" /> </route>

2>JMIB CLO ABIBQB: +BWB %4-:


from("direct:delete") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DELETE_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:delete" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>delete</constant> </setHeader> <to uri="hazelcast:map:foo" /> </route>

2>JMIB CLO NRBOV +BWB %4-:


from("direct:query") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.QUERY_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX) .to("seda:out");

4QSJOH %4-:
<route> <from uri="direct:query" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type">

676

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<constant>query</constant> </setHeader> <to uri="hazelcast:map:foo" /> <to uri="seda:out" /> </route>

'PS UIF RVFSZ PQFSBUJPO )B[FMDBTU PGGFST B 42- MJLF TZOUBY UP RVFSZ ZPVS EJTUSJCVUFE NBQ.
String q1 = "bar > 1000"; template.sendBodyAndHeader("direct:query", null, HazelcastConstants.QUERY, q1);

J>M @>@EB @LKPRJBO - COLJ("E>WBI@>PQ:J>M:CLL") )B[FMDBTU QSPWJEFT FWFOU MJTUFOFST PO UIFJS EBUB HSJE. *G ZPV XBOU UP CF OPUJGJFE JG B DBDIF XJMM CF NBOJQVMBUFE, ZPV DBO VTF UIF NBQ DPOTVNFS. 5IFSF'SF 4 FWFOUT: MRQ, RMA>QB, ABIBQB BOE BKSF@Q. 5IF FWFOU UZQF XJMM CF TUPSFE JO UIF "E>WBI@>PQ.IFPQBKBO.>@QFLK" IFBEFS WBSJBCMF. 5IF NBQ DPOTVNFS QSPWJEFT TPNF BEEJUJPOBM JOGPSNBUJPO JOTJEF UIFTF WBSJBCMFT: )FBEFS 7BSJBCMFT JOTJEF UIF SFTQPOTF NFTTBHF: ->JB hazelcast.listener.time hazelcast.listener.type hazelcast.listener.action hazelcast.objectId hazelcast.cache.name hazelcast.cache.type ->JB CamelHazelcastListenerTime CamelHazelcastListenerType 3VMB Long String String String String String 3VMB Long String #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT UIF NBQ DPOTVNFS TFUT IFSF "DBDIFMJTUFOFS" UZQF PG FWFOU - IFSF >AABA, RMA>QBA, BKSF@QBA BOE OBJLSBA UIF PJE PG UIF PCKFDU UIF OBNF PG UIF DBDIF - F.H. "GPP" UIF UZQF PG UIF DBDIF - IFSF NBQ #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT :5BOPFLK 2.8< UIF NBQ DPOTVNFS TFUT IFSF "DBDIFMJTUFOFS" :5BOPFLK 2.8< UZQF PG FWFOU - IFSF >AABA, RMA>QBA, BKSF@QBA BOE OBJLSBA. :5BOPFLK 2.8<

CamelHazelcastListenerAction

String

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

677

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

CamelHazelcastObjectId CamelHazelcastCacheName CamelHazelcastCacheType

String String String

UIF PJE PG UIF PCKFDU :5BOPFLK 2.8< UIF OBNF PG UIF DBDIF - F.H. "GPP" :5BOPFLK 2.8< UIF UZQF PG UIF DBDIF - IFSF NBQ :5BOPFLK 2.8<

5IF PCKFDU WBMVF XJMM CF TUPSFE XJUIJO MRQ BOE RMA>QB BDUJPOT JOTJEF UIF NFTTBHF CPEZ. )FSF'T B TBNQMF:
fromF("hazelcast:%sfoo", HazelcastConstants.MAP_PREFIX) .log("object...") .choice() .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED)) .log("...added") .to("mock:added") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ENVICTED)) .log("...envicted") .to("mock:envicted") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.UPDATED)) .log("...updated") .to("mock:updated") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED)) .log("...removed") .to("mock:removed") .otherwise() .log("fail!");

4P>DB LC ,RIQF ,>M

JRIQFJ>M @>@EB MOLAR@BO - QL("E>WBI@>PQ:JRIQFJ>M:CLL")


" NVMUJNBQ JT B DBDIF XIFSF ZPV DBO TUPSF O WBMVFT UP POF LFZ. 5IF NVMUJNBQ QSPEVDFS QSPWJEFT 4 PQFSBUJPOT (QVU, HFU, SFNPWFWBMVF, EFMFUF). )FBEFS 7BSJBCMFT GPS UIF SFRVFTU NFTTBHF: ->JB 3VMB #BP@OFMQFLK

678

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

hazelcast.operation.type hazelcast.objectId ->JB

String String 3VMB

WBMJE WBMVFT BSF: QVU, HFU, SFNPWFWBMVF, EFMFUF UIF PCKFDU JE UP TUPSF / GJOE ZPVS PCKFDU JOTJEF UIF DBDIF #BP@OFMQFLK WBMJE WBMVFT BSF: QVU, HFU, SFNPWFWBMVF, EFMFUF :5BOPFLK 2.8< UIF PCKFDU JE UP TUPSF / GJOE ZPVS PCKFDU JOTJEF UIF DBDIF :5BOPFLK 2.8<

CamelHazelcastOperationType

String

CamelHazelcastObjectId

String

2>JMIB CLO MRQ: +BWB %4-:


from("direct:put") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION)) .to(String.format("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX));

4QSJOH %4-:
<route> <from uri="direct:put" /> <log message="put.."/> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>put</constant> </setHeader> <to uri="hazelcast:multimap:foo" /> </route>

2>JMIB CLO OBJLSBS>IRB: +BWB %4-:


from("direct:removevalue") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.REMOVEVALUE_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX);

4QSJOH %4-:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

679

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

<route> <from uri="direct:removevalue" /> <log message="removevalue..."/> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>removevalue</constant> </setHeader> <to uri="hazelcast:multimap:foo" /> </route>

5P SFNPWF B WBMVF ZPV IBWF UP QSPWJEF UIF WBMVF ZPV XBOU UP SFNPWF JOTJEF UIF NFTTBHF CPEZ. *G ZPV IBWF B NVMUJNBQ PCKFDU \key: "4711" values: { "my-foo", "my-bar"^^ ZPV IBWF UP QVU "NZ-GPP" JOTJEF UIF NFTTBHF CPEZ UP SFNPWF UIF "NZ-GPP" WBMVF. 2>JMIB CLO DBQ: +BWB %4-:
from("direct:get") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX) .to("seda:out");

4QSJOH %4-:
<route> <from uri="direct:get" /> <log message="get.."/> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>get</constant> </setHeader> <to uri="hazelcast:multimap:foo" /> <to uri="seda:out" /> </route>

2>JMIB CLO ABIBQB: +BWB %4-:

680

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("direct:delete") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DELETE_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:delete" /> <log message="delete.."/> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>delete</constant> </setHeader> <to uri="hazelcast:multimap:foo" /> </route>

ZPV DBO DBMM UIFN JO ZPVS UFTU DMBTT XJUI:


template.sendBodyAndHeader("direct:[put|get|removevalue|delete]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");

JRIQFJ>M @>@EB @LKPRJBO - COLJ("E>WBI@>PQ:JRIQFJ>M:CLL")


'PS UIF NVMUJNBQ DBDIF UIJT DPNQPOFOU QSPWJEFT UIF TBNF MJTUFOFST / WBSJBCMFT BT GPS UIF NBQ DBDIF DPOTVNFS (FYDFQU UIF VQEBUF BOE FOWJDUJPO MJTUFOFS). 5IF POMZ EJGGFSFODF JT UIF JRIQFJ>M QSFGJY JOTJEF UIF 63*. )FSF JT B TBNQMF:
fromF("hazelcast:%sbar", HazelcastConstants.MULTIMAP_PREFIX) .log("object...") .choice() .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED)) .log("...added") .to("mock:added") //.when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ENVICTED)) // .log("...envicted") // .to("mock:envicted") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED)) .log("...removed") .to("mock:removed") .otherwise() .log("fail!");

)FBEFS 7BSJBCMFT JOTJEF UIF SFTQPOTF NFTTBHF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

681

->JB hazelcast.listener.time hazelcast.listener.type hazelcast.listener.action hazelcast.objectId hazelcast.cache.name hazelcast.cache.type ->JB CamelHazelcastListenerTime CamelHazelcastListenerType

3VMB Long String String String String String 3VMB Long

#BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT UIF NBQ DPOTVNFS TFUT IFSF "DBDIFMJTUFOFS" UZQF PG FWFOU - IFSF >AABA BOE OBJLSBA (BOE TPPO BKSF@QBA) UIF PJE PG UIF PCKFDU UIF OBNF PG UIF DBDIF - F.H. "GPP" UIF UZQF PG UIF DBDIF - IFSF NVMUJNBQ #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT :5BOPFLK 2.8< UIF NBQ DPOTVNFS TFUT IFSF "DBDIFMJTUFOFS" :5BOPFLK 2.8< UZQF PG FWFOU - IFSF >AABA BOE OBJLSBA (BOE TPPO BKSF@QBA) :5BOPFLK 2.8< UIF PJE PG UIF PCKFDU :5BOPFLK 2.8< UIF OBNF PG UIF DBDIF - F.H. "GPP" :5BOPFLK 2.8< UIF UZQF PG UIF DBDIF - IFSF NVMUJNBQ :5BOPFLK 2.8<

&WJDUJPO XJMM CF BEEFE BT GFBUVSF, TPPO (UIJT JT B )B[FMDBTU JTTVF).

String

CamelHazelcastListenerAction

String

CamelHazelcastObjectId CamelHazelcastCacheName CamelHazelcastCacheType

String String String

4P>DB LC 0RBRB

0RBRB MOLAR@BO ] QL(\E>WBI@>PQ:NRBRB:CLL[)


5IF RVFVF QSPEVDFS QSPWJEFT 6 PQFSBUJPOT (BEE, QVU, QPMM, QFFL, PGGFS, SFNPWFWBMVF).

682

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8 2>JMIB CLO >AA:


from("direct:add") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.ADD_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX);

2>JMIB CLO MRQ:


from("direct:put") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PUT_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX);

2>JMIB CLO MLII:


from("direct:poll") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.POLL_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX);

2>JMIB CLO MBBH:


from("direct:peek") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.PEEK_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX);

2>JMIB CLO LCCBO:


from("direct:offer") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.OFFER_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX);

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

683

2>JMIB CLO OBJLSBS>IRB:


from("direct:removevalue") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.REMOVEVALUE_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.QUEUE_PREFIX);

0RBRB @LKPRJBO ] COLJ(\E>WBI@>PQ:NRBRB:CLL[)


5IF RVFVF DPOTVNFS QSPWJEFT 2 PQFSBUJPOT (BEE, SFNPWF).
fromF("hazelcast:%smm", HazelcastConstants.QUEUE_PREFIX) .log("object...") .choice() .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED)) .log("...added") .to("mock:added") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED)) .log("...removed") .to("mock:removed") .otherwise() .log("fail!");

4P>DB LC +FPQ

+FPQ MOLAR@BO ] QL(\E>WBI@>PQ:IFPQ:CLL[)


5IF MJTU QSPEVDFS QSPWJEFT 4 PQFSBUJPOT (BEE, TFU, HFU, SFNPWFWBMVF). 2>JMIB CLO >AA:
from("direct:add") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.ADD_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX);

2>JMIB CLO DBQ:


from("direct:get") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION))

684

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.toF("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX) .to("seda:out");

2>JMIB CLO PBQS>IRB:


from("direct:set") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.SETVALUE_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX);

2>JMIB CLO OBJLSBS>IRB:


from("direct:removevalue") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.REMOVEVALUE_OPERATION)) .toF("hazelcast:%sbar", HazelcastConstants.LIST_PREFIX);

+FPQ @LKPRJBO ] COLJ(\E>WBI@>PQ:IFPQ:CLL[)


5IF MJTU DPOTVNFS QSPWJEFT 2 PQFSBUJPOT (BEE, SFNPWF).
fromF("hazelcast:%smm", HazelcastConstants.LIST_PREFIX) .log("object...") .choice() .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED)) .log("...added") .to("mock:added") .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.REMOVED)) .log("...removed") .to("mock:removed") .otherwise() .log("fail!");

4P>DB LC 2$# 4&%" DPNQPOFOU EJGGFST GSPN UIF SFTU DPNQPOFOUT QSPWJEFE. *U JNQMFNFOUT B XPSL-RVFVF JO PSEFS UP TVQQPSU BTZODISPOPVT 4&%" BSDIJUFDUVSFT, TJNJMBS UP UIF DPSF "4&%"" DPNQPOFOU.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

685

1MFBTF OPUF UIBU TFU,HFU BOE SFNPWFWBMVF BOE OPU ZFU TVQQPSUFE CZ IB[FMDBTU, XJMM CF BEEFE JO UIF GVUVSF..

2$#

MOLAR@BO ] QL(\E>WBI@>PQ:PBA>:CLL[)
ABC>RIQ S>IRB false

5IF 4&%" QSPEVDFS QSPWJEFT OP PQFSBUJPOT. :PV POMZ TFOE EBUB UP UIF TQFDJGJFE RVFVF. ->JB #BP@OFMQFLK ">JBI 2.8.0: JG TFU UP USVF UIF XIPMF &YDIBOHF XJMM CF USBOTGFSFE. *G IFBEFS PS CPEZ DPOUBJOT OPU TFSJBMJ[BCMF PCKFDUT, UIFZ XJMM CF TLJQQFE.

transferExchange +BWB %4- :

from("direct:foo") .to("hazelcast:seda:foo");

4QSJOH %4- :
<route> <from uri="direct:start" /> <to uri="hazelcast:seda:foo" /> </route>

2$#

@LKPRJBO ] COLJ(\E>WBI@>PQ:PBA>:CLL[)
ABC>RIQ S>IRB 1000 1

5IF 4&%" DPOTVNFS QSPWJEFT OP PQFSBUJPOT. :PV POMZ SFUSJFWF EBUB GSPN UIF TQFDJGJFE RVFVF. ->JB pollInterval concurrentConsumers #BP@OFMQFLK )PX GSFRVFOU UP QPMM GSPN UIF 4&%" RVFVF 5P VTF DPODVSSFOU DPOTVNFST QPMMJOH GSPN UIF 4&%" RVFVF. ">JBI 2.8.0: JG TFU UP USVF UIF XIPMF &YDIBOHF XJMM CF USBOTGFSFE. *G IFBEFS PS CPEZ DPOUBJOT OPU TFSJBMJ[BCMF PCKFDUT, UIFZ XJMM CF TLJQQFE.

transferExchange

false

686

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

transacted

false

">JBI 2.10.4: JG TFU UP USVF UIFO UIF DPOTVNFS SVOT JO USBOTBDUJPO NPEF, XIFSF UIF NFTTBHFT JO UIF TFEB RVFVF XJMM POMZ CF SFNPWFE JG UIF USBOTBDUJPO DPNNJUT, XIJDI IBQQFOT XIFO UIF QSPDFTTJOH JT DPNQMFUF.

+BWB %4- :
from("hazelcast:seda:foo") .to("mock:result");

4QSJOH %4-:
<route> <from uri="hazelcast:seda:foo" /> <to uri="mock:result" /> </route>

4P>DB LC

QLJF@ -RJ?BO

>QLJF@ KRJ?BO MOLAR@BO - QL("E>WBI@>PQ:>QLJF@KRJ?BO:CLL")


"O BUPNJD OVNCFS JT BO PCKFDU UIBU TJNQMZ QSPWJEFT B HSJE XJEF OVNCFS (MPOH). 5IF PQFSBUJPOT GPS UIJT QSPEVDFS BSF TFUWBMVF (TFU UIF OVNCFS XJUI B HJWFO WBMVF), HFU, JODSFBTF (+1), EFDSFBTF (-1) BOE EFTUSPZ. )FBEFS 7BSJBCMFT GPS UIF SFRVFTU NFTTBHF: ->JB hazelcast.operation.type ->JB CamelHazelcastOperationType 3VMB String 3VMB String #BP@OFMQFLK WBMJE WBMVFT BSF: TFUWBMVF, HFU, JODSFBTF, EFDSFBTF, EFTUSPZ #BP@OFMQFLK WBMJE WBMVFT BSF: TFUWBMVF, HFU, JODSFBTF, EFDSFBTF, EFTUSPZ S>FI>?IB >P LC ">JBI SBOPFLK 2.8

2>JMIB CLO PBQ: +BWB %4-:


from("direct:set") .setHeader(HazelcastConstants.OPERATION,

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

687

5IFSF JT OP DPOTVNFS GPS UIJT FOEQPJOU!

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

constant(HazelcastConstants.SETVALUE_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:set" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>setvalue</constant> </setHeader> <to uri="hazelcast:atomicvalue:foo" /> </route>

1SPWJEF UIF WBMVF UP TFU JOTJEF UIF NFTTBHF CPEZ (IFSF UIF WBMVF JT 10): template.sendBody("direct:set", 10); 2>JMIB CLO DBQ: +BWB %4-:
from("direct:get") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.GET_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:get" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>get</constant> </setHeader> <to uri="hazelcast:atomicvalue:foo" /> </route>

688

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV DBO HFU UIF OVNCFS XJUI long body = template.requestBody("direct:get", null, Long.class);. 2>JMIB CLO FK@OBJBKQ: +BWB %4-:
from("direct:increment") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.INCREMENT_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:increment" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>increment</constant> </setHeader> <to uri="hazelcast:atomicvalue:foo" /> </route>

5IF BDUVBM WBMVF (BGUFS JODSFNFOU) XJMM CF QSPWJEFE JOTJEF UIF NFTTBHF CPEZ. 2>JMIB CLO AB@OBJBKQ: +BWB %4-:
from("direct:decrement") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DECREMENT_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:decrement" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>decrement</constant> </setHeader> <to uri="hazelcast:atomicvalue:foo" /> </route>

5IF BDUVBM WBMVF (BGUFS EFDSFNFOU) XJMM CF QSPWJEFE JOTJEF UIF NFTTBHF CPEZ.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

689

2>JMIB CLO ABPQOLV +BWB %4-:


from("direct:destroy") .setHeader(HazelcastConstants.OPERATION, constant(HazelcastConstants.DESTROY_OPERATION)) .toF("hazelcast:%sfoo", HazelcastConstants.ATOMICNUMBER_PREFIX);

4QSJOH %4-:
<route> <from uri="direct:destroy" /> <!-- If using version 2.8 and above set headerName to "CamelHazelcastOperationType" --> <setHeader headerName="hazelcast.operation.type"> <constant>destroy</constant> </setHeader> <to uri="hazelcast:atomicvalue:foo" /> </route>

@IRPQBO PRMMLOQ FKPQ>K@B @LKPRJBO - COLJ("E>WBI@>PQ:FKPQ>K@B:CLL") )B[FMDBTU NBLFT TFOTF JO POF TJOHMF "TFSWFS OPEF", CVU JU'T FYUSFNMZ QPXFSGVM JO B DMVTUFSFE FOWJSPONFOU. 5IF JOTUBODF DPOTVNFS GJSFT JG B OFX DBDIF JOTUBODF XJMM KPJO PS MFBWF UIF DMVTUFS. )FSF'T B TBNQMF:
fromF("hazelcast:%sfoo", HazelcastConstants.INSTANCE_PREFIX) .log("instance...") .choice() .when(header(HazelcastConstants.LISTENER_ACTION).isEqualTo(HazelcastConstants.ADDED)) .log("...added") .to("mock:added") .otherwise() .log("...removed") .to("mock:removed");

&BDI FWFOU QSPWJEFT UIF GPMMPXJOH JOGPSNBUJPO JOTJEF UIF NFTTBHF IFBEFS: )FBEFS 7BSJBCMFT JOTJEF UIF SFTQPOTF NFTTBHF: ->JB hazelcast.listener.time 3VMB Long #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT

690

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

5IFSF'T B CVH JOTJEF )B[FMDBTU. 4P UIJT GFBUVSF NBZ OPU XPSL QSPQFSMZ. 8JMM CF GJYFE JO 1.9.3.

5IJT FOEQPJOU QSPWJEFT OP QSPEVDFS!

hazelcast.listener.type hazelcast.listener.action hazelcast.instance.host hazelcast.instance.port ->JB CamelHazelcastListenerTime CamelHazelcastListenerType

String String String Integer 3VMB Long

UIF NBQ DPOTVNFS TFUT IFSF "JOTUBODFMJTUFOFS" UZQF PG FWFOU - IFSF >AABA PS OBJLSBA IPTU OBNF PG UIF JOTUBODF QPSU OVNCFS PG UIF JOTUBODF #BP@OFMQFLK UJNF PG UIF FWFOU JO NJMMJT :5BOPFLK 2.8< UIF NBQ DPOTVNFS TFUT IFSF "JOTUBODFMJTUFOFS" :5BOPFLK 2.8< UZQF PG FWFOU - IFSF >AABA PS OBJLSBA. :5BOPFLK 2.8< IPTU OBNF PG UIF JOTUBODF :5BOPFLK 2.8< QPSU OVNCFS PG UIF JOTUBODF :5BOPFLK 2.8<

String String String Integer

CamelHazelcastListenerActionn CamelHazelcastInstanceHost CamelHazelcastInstancePort

'#%2 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.8 5IF EACP DPNQPOFOU FOBCMFT ZPV UP SFBE BOE XSJUF NFTTBHFT GSPN/UP BO )%'4 GJMF TZTUFN. )%'4 JT UIF EJTUSJCVUFE GJMF TZTUFN BU UIF IFBSU PG )BEPPQ. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

691

)FBEFS WBSJBCMFT IBWF DIBOHFE JO $BNFM 2.8

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-hdfs</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
hdfs://hostname[:port][/path][?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 5IF QBUI JT USFBUFE JO UIF GPMMPXJOH XBZ: 1. BT B DPOTVNFS, JG JU'T B GJMF, JU KVTU SFBET UIF GJMF, PUIFSXJTF JG JU SFQSFTFOUT B EJSFDUPSZ JU TDBOT BMM UIF GJMF VOEFS UIF QBUI TBUJTGZJOH UIF DPOGJHVSFE QBUUFSO. "MM UIF GJMFT VOEFS UIBU EJSFDUPSZ NVTU CF PG UIF TBNF UZQF. 2. BT B QSPEVDFS, JG BU MFBTU POF TQMJU TUSBUFHZ JT EFGJOFE, UIF QBUI JT DPOTJEFSFE B EJSFDUPSZ BOE VOEFS UIBU EJSFDUPSZ UIF QSPEVDFS DSFBUFT B EJGGFSFOU GJMF QFS TQMJU OBNFE TFH0, TFH1, TFH2, FUD. .MQFLKP
->JB
overwrite append bufferSize replication blockSize fileType fileSystemType keyType valueType splitStrategy openedSuffix readSuffix initialDelay delay

#BC>RIQ 5>IRB
true false 4096 3 67108864 NORMAL_FILE HDFS NULL TEXT c opened read 0 0

#BP@OFMQFLK
5IF GJMF DBO CF PWFSXSJUUFO "QQFOE UP FYJTUJOH GJMF. /PUJDF UIBU OPU BMM )%'4 GJMF TZTUFNT TVQQPSU UIF BQQFOE PQUJPO. 5IF CVGGFS TJ[F VTFE CZ )%'4 5IF )%'4 SFQMJDBUJPO GBDUPS 5IF TJ[F PG UIF )%'4 CMPDLT *U DBO CF 4&26&/$&@'*-&, ."1@'*-&, "33":@'*-&, PS #-00.."1@'*-&, TFF )BEPPQ *U DBO CF -0$"- GPS MPDBM GJMFTZTUFN 5IF UZQF GPS UIF LFZ JO DBTF PG TFRVFODF PS NBQ GJMFT. 4FF CFMPX. 5IF UZQF GPS UIF LFZ JO DBTF PG TFRVFODF PS NBQ GJMFT. 4FF CFMPX. " TUSJOH EFTDSJCJOH UIF TUSBUFHZ PO IPX UP TQMJU UIF GJMF CBTFE PO EJGGFSFOU DSJUFSJB. 4FF CFMPX. 8IFO B GJMF JT PQFOFE GPS SFBEJOH/XSJUJOH UIF GJMF JT SFOBNFE XJUI UIJT TVGGJY UP BWPJE UP SFBE JU EVSJOH UIF XSJUJOH QIBTF. 0ODF UIF GJMF IBT CFFO SFBE JT SFOBNFE XJUI UIJT TVGGJY UP BWPJE UP SFBE JU BHBJO. 'PS UIF DPOTVNFS, IPX NVDI UP XBJU (NJMMJTFDPOET) CFGPSF UP TUBSU TDBOOJOH UIF EJSFDUPSZ. 5IF JOUFSWBM (NJMMJTFDPOET) CFUXFFO UIF EJSFDUPSZ TDBOT.

692

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

pattern chunkSize connectOnStartup

* 4096 true

5IF QBUUFSO VTFE GPS TDBOOJOH UIF EJSFDUPSZ 8IFO SFBEJOH B OPSNBM GJMF, UIJT JT TQMJU JOUP DIVOLT QSPEVDJOH B NFTTBHF QFS DIVOL. ">JBI 2.9.3/2.10.1: 8IFUIFS UP DPOOFDU UP UIF )%'4 GJMF TZTUFN PO TUBSUJOH UIF QSPEVDFS/DPOTVNFS. *G false UIFO UIF DPOOFDUJPO JT DSFBUFE PO-EFNBOE. /PUJDF UIBU )%'4 NBZ UBLF VQ UJMM 15 NJOVUFT UP FTUBCMJTI B DPOOFDUJPO, BT JU IBT IBSEDPEFE 45 Y 20 TFD SFEFMJWFSZ. #Z TFUUJOH UIJT PQUJPO UP false BMMPXT ZPVS BQQMJDBUJPO UP TUBSUVQ, BOE OPU CMPDL GPS VQ UJMM 15 NJOVUFT.

*BV3VMB >KA 5>IRB3VMB


` /6-- JU NFBOT UIBU UIF LFZ PS UIF WBMVF JT BCTFOU ` #:5& GPS XSJUJOH B CZUF, UIF KBWB #ZUF DMBTT JT NBQQFE JOUP B #:5& ` #:5&4 GPS XSJUJOH B TFRVFODF PG CZUFT. *U NBQT UIF KBWB #ZUF#VGGFS DMBTT ` */5 GPS XSJUJOH KBWB JOUFHFS ` '-0"5 GPS XSJUJOH KBWB GMPBU ` -0/( GPS XSJUJOH KBWB MPOH ` %06#-& GPS XSJUJOH KBWB EPVCMF ` 5&95 GPS XSJUJOH KBWB TUSJOHT #:5&4 JT BMTP VTFE XJUI FWFSZUIJOH FMTF, GPS FYBNQMF, JO $BNFM B GJMF JT TFOU BSPVOE BT BO *OQVU4USFBN, JOU UIJT DBTF JT XSJUUFO JO B TFRVFODF GJMF PS B NBQ GJMF BT B TFRVFODF PG CZUFT. 2MIFQQFKD 2QO>QBDV *O UIF DVSSFOU WFSTJPO PG )BEPPQ PQFOJOH B GJMF JO BQQFOE NPEF JT EJTBCMFE TJODF JU'T OPU FOPVHI SFMJBCMF. 4P, GPS UIF NPNFOU, JU'T POMZ QPTTJCMF UP DSFBUF OFX GJMFT. 5IF $BNFM )%'4 FOEQPJOU USJFT UP TPMWF UIJT QSPCMFN JO UIJT XBZ: ` *G UIF TQMJU TUSBUFHZ PQUJPO IBT CFFO EFGJOFE, UIF BDUVBM GJMF OBNF XJMM CFDPNF B EJSFDUPSZ OBNF BOE B <GJMF OBNF>/TFH0 XJMM CF JOJUJBMMZ DSFBUFE. ` &WFSZ UJNF B TQMJUUJOH DPOEJUJPO JT NFU B OFX GJMF JT DSFBUFE XJUI OBNF <PSJHJOBM GJMF OBNF>/TFH/ XIFSF / JT 1, 2, 3, FUD. 5IF TQMJU4USBUFHZ PQUJPO JT EFGJOFE BT B TUSJOH XJUI UIF GPMMPXJOH TZOUBY: TQMJU4USBUFHZ=<45>:<WBMVF>,<45>:<WBMVF>,* XIFSF <45> DBO CF: ` #:5&4 B OFX GJMF JT DSFBUFE, BOE UIF PME JT DMPTFE XIFO UIF OVNCFS PG XSJUUFO CZUFT JT NPSF UIBO <WBMVF> ` .&44"(&4 B OFX GJMF JT DSFBUFE, BOE UIF PME JT DMPTFE XIFO UIF OVNCFS PG XSJUUFO NFTTBHFT JT NPSF UIBO <WBMVF> ` *%-& B OFX GJMF JT DSFBUFE, BOE UIF PME JT DMPTFE XIFO OP XSJUJOH IBQQFOFE JO UIF MBTU <WBMVF> NJMMJTFDPOET GPS FYBNQMF:
hdfs://localhost/tmp/simple-file?splitStrategy=IDLE:1000,BYTES:5

JU NFBOT: B OFX GJMF JT DSFBUFE FJUIFS XIFO JU IBT CFFO JEMF GPS NPSF UIBO 1 TFDPOE PS JG NPSF UIBO 5 CZUFT IBWF CFFO XSJUUFO. 4P, SVOOJOH hadoop fs -ls /tmp/simple-file ZPV'MM GJOE UIF GPMMPXJOH GJMFT TFH0, TFH1, TFH2, FUD

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

693

"LKQOLIIFKD QL @ILPB CFIB PQOB>J S>FI>?IB >P LC ">JBI 2.10.4 8IFO VTJOH UIF )%'4 QSPEVDFS TFQELRQ B TQMJU TUSBUFHZ, UIFO UIF GJMF PVUQVU TUSFBN JT CZ EFGBVMU DMPTFE BGUFS UIF XSJUF. )PXFWFS ZPV NBZ XBOU UP LFFQ UIF TUSFBN PQFO, BOE POMZ FYQMJDJU DMPTF UIF TUSFBN MBUFS. 'PS UIBU ZPV DBO VTF UIF IFBEFS HdfsConstants.HDFS_CLOSE (WBMVF = "CamelHdfsClose") UP DPOUSPM UIJT. 4FUUJOH UIJT WBMVF UP B CPPMFBO BMMPXT ZPV UP FYQMJDJU DPOUSPM XIFUIFS UIF TUSFBN TIPVME CF DMPTFE PS OPU. /PUJDF UIJT EPFT OPU BQQMZ JG ZPV VTF B TQMJU TUSBUFHZ, BT UIFSF JT WBSJPT TUSBUFHZ UIBU DPOUSPM XIFO UIF TUSFBN JT DMPTFE. 4PFKD QEFP @LJMLKBKQ FK .2&F 5IJT DPNQPOFOU JT GVMMZ GVODUJPOBM JO BO 04(J FOWJSPONFOU IPXFWFS, JU SFRVJSFT TPNF BDUJPOT GSPN UIF VTFS. )BEPPQ VTFT UIF UISFBE DPOUFYU DMBTT MPBEFS JO PSEFS UP MPBE SFTPVSDFT. 6TVBMMZ, UIF UISFBE DPOUFYU DMBTTMPBEFS XJMM CF UIF CVOEMF DMBTT MPBEFS PG UIF CVOEMF UIBU DPOUBJOT UIF SPVUFT. 4P, UIF EFGBVMU DPOGJHVSBUJPO GJMFT OFFE UP CF WJTJCMF GSPN UIF CVOEMF DMBTT MPBEFS. " UZQJDBM XBZ UP EFBM XJUI JU JT UP LFFQ B DPQZ PG DPSF-EFGBVMU.YNM JO ZPVS CVOEMF SPPU. 5IBU GJMF DBO CF GPVOE JO UIF IBEPPQ-DPNNPO.KBS.

'(!$1- 3$ ".,/.-$-3
5IF EF?BOK>QB: DPNQPOFOU BMMPXT ZPV UP XPSL XJUI EBUBCBTFT VTJOH )JCFSOBUF BT UIF PCKFDU SFMBUJPOBM NBQQJOH UFDIOPMPHZ UP NBQ 10+0T UP EBUBCBTF UBCMFT. 5IF @>JBI-EF?BOK>QB MJCSBSZ JT QSPWJEFE CZ UIF $BNFM &YUSB QSPKFDU XIJDI IPTUT BMM *(1- SFMBUFE DPNQPOFOUT GPS $BNFM. 2BKAFKD QL QEB BKAMLFKQ 4FOEJOH 10+0T UP UIF IJCFSOBUF FOEQPJOU JOTFSUT FOUJUJFT JOUP UIF EBUBCBTF. 5IF CPEZ PG UIF NFTTBHF JT BTTVNFE UP CF BO FOUJUZ CFBO UIBU ZPV IBWF NBQQFE UP B SFMBUJPOBM UBCMF VTJOH UIF IJCFSOBUF .hbm.xml GJMFT. *G UIF CPEZ EPFT OPU DPOUBJO BO FOUJUZ CFBO, VTF B .FTTBHF 5SBOTMBUPS JO GSPOU PG UIF FOEQPJOU UP QFSGPSN UIF OFDFTTBSZ DPOWFSTJPO GJSTU. "LKPRJFKD COLJ QEB BKAMLFKQ $POTVNJOH NFTTBHFT SFNPWFT (PS VQEBUFT) FOUJUJFT JO UIF EBUBCBTF. 5IJT BMMPXT ZPV UP VTF B EBUBCBTF UBCMF BT B MPHJDBM RVFVF; DPOTVNFST UBLF NFTTBHFT GSPN UIF RVFVF BOE UIFO EFMFUF/ VQEBUF UIFN UP MPHJDBMMZ SFNPWF UIFN GSPN UIF RVFVF. *G ZPV EP OPU XJTI UP EFMFUF UIF FOUJUZ XIFO JU IBT CFFO QSPDFTTFE, ZPV DBO TQFDJGZ consumeDelete=false PO UIF 63*. 5IJT XJMM SFTVMU JO UIF FOUJUZ CFJOH QSPDFTTFE FBDI QPMM.

694

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

/PUF UIBU $BNFM BMTP TIJQT XJUI B +1" DPNQPOFOU. 5IF +1" DPNQPOFOU BCTUSBDUT GSPN UIF VOEFSMZJOH QFSTJTUFODF QSPWJEFS BOE BMMPXT ZPV UP XPSL XJUI )JCFSOBUF, 0QFO+1" PS &DMJQTF-JOL. *G ZPV XPVME SBUIFS QFSGPSN TPNF VQEBUF PO UIF FOUJUZ UP NBSL JU BT QSPDFTTFE (TVDI BT UP FYDMVEF JU GSPN B GVUVSF RVFSZ) UIFO ZPV DBO BOOPUBUF B NFUIPE XJUI !$POTVNFE XIJDI XJMM CF JOWPLFE PO ZPVS FOUJUZ CFBO XIFO UIF FOUJUZ CFBO JT DPOTVNFE. 41( CLOJ>Q
hibernate:[entityClassName][?options]

'PS TFOEJOH UP UIF FOEQPJOU, UIF BKQFQV"I>PP->JB JT PQUJPOBM. *G TQFDJGJFE JU JT VTFE UP IFMQ VTF UIF UZQF DPOWFSTJPO UP FOTVSF UIF CPEZ JT PG UIF DPSSFDU UZQF. 'PS DPOTVNJOH UIF BKQFQV"I>PP->JB JT NBOEBUPSZ. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
entityType consumeDelete consumeLockEntity flushOnSend maximumResults consumer.delay consumer.initialDelay consumer.userFixedDelay

#BC>RIQ 5>IRB
entityClassName true true true -1 500 1000 false

#BP@OFMQFLK
*T UIF QSPWJEFE entityClassName GSPN UIF 63*. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. 4QFDJGJFT XIFUIFS PS OPU UIF FOUJUZ JT EFMFUFE BGUFS JU JT DPOTVNFE. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. 4QFDJGJFT XIFUIFS PS OPU UP VTF FYDMVTJWF MPDLJOH PG FBDI FOUJUZ XIJMF QSPDFTTJOH UIF SFTVMUT GSPN UIF QPPMJOH. 0QUJPO GPS )JCFSOBUF1SPEVDFS POMZ. 'MVTIFT UIF &OUJUZ.BOBHFS BGUFS UIF FOUJUZ CFBO IBT CFFO QFSTJTUFE. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. 4FU UIF NBYJNVN OVNCFS PG SFTVMUT UP SFUSJFWF PO UIF 2VFSZ. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. %FMBZ JO NJMMJT CFUXFFO FBDI QPMM. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. .JMMJT CFGPSF QPMMJOH TUBSUT. 0QUJPO GPS )JCFSOBUF$POTVNFS POMZ. 4FU UP true UP VTF GJYFE EFMBZ CFUXFFO QPMMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT.

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE )JCFSOBUF &YBNQMF

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

695

'+7 ".,/.-$-3
5IF EI7 DPNQPOFOU JT VTFE GPS XPSLJOH XJUI UIF )-7 .--1 QSPUPDPM BOE )-7 W2 NFTTBHFT VTJOH UIF )"1* MJCSBSZ. 5IJT DPNQPOFOU TVQQPSUT UIF GPMMPXJOH: )-7 .--1 DPEFD GPS .JOB "HOPTUJD EBUB GPSNBU VTJOH FJUIFS QMBJO 4USJOH PCKFDUT PS )"1* )-7 NPEFM PCKFDUT. 5ZQF $POWFSUFS GSPN/UP )"1* BOE 4USJOH )-7 %BUB'PSNBU VTJOH )"1* MJCSBSZ &WFO NPSF FBTF-PG-VTF BT JU'T JOUFHSBUFE XFMM XJUI UIF DBNFM-NJOB (">JBI 2.11: <DBNFM-NJOB2> ) DPNQPOFOU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-hl7</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

'+7 ,++/ MOLQL@LI )-7 JT PGUFO VTFE XJUI UIF )-7 .--1 QSPUPDPM UIBU JT B UFYU CBTFE 5$1 TPDLFU CBTFE QSPUPDPM. 5IJT DPNQPOFOU TIJQT XJUI B .JOB $PEFD UIBU DPOGPSNT UP UIF .--1 QSPUPDPM TP ZPV DBO FBTJMZ FYQPTF B )-7 MJTUFOFS UIBU BDDFQUT )-7 SFRVFTUT PWFS UIF 5$1 USBOTQPSU. 5P FYQPTF B )-7 MJTUFOFS TFSWJDF XF SFVTF UIF FYJTUJOH NJOB/NJOB2 DPNQPOFOU XIFSF XF KVTU VTF UIF HL7MLLPCodec BT DPEFD. 5IF )-7 .--1 DPEFD IBT UIF GPMMPXJOH PQUJPOT:
->JB
startByte endByte1 endByte2 charset convertLFtoCR validate parser

#BC>RIQ 5>IRB
0x0b 0x1c 0x0d +7. %FGBVMU true (">JBI 2.11:false) true ca.uhn.hl7v2.parser.PipeParser

#BP@OFMQFLK
5IF TUBSU CZUF TQBOOJOH UIF )-7 QBZMPBE. 5IF GJSTU FOE CZUF TQBOOJOH UIF )-7 QBZMPBE. 5IF 2OE FOE CZUF TQBOOJOH UIF )-7 QBZMPBE. 5IF FODPEJOH (JT B DIBSTFU OBNF) UP VTF GPS UIF DPEFD. *G OPU QSPWJEFE, $BNFM XJMM VTF UIF +7. EFGBVMU $IBSTFU. 8JMM DPOWFSU \n UP \r (0x0d, 13 EFDJNBM) BT )-7 TUJQVMBUFT \r BT TFHNFOU UFSNJOBUPST. 5IF )"1* MJCSBSZ SFRVJSFT UIF VTF PG \r. 8IFUIFS )"1* 1BSTFS TIPVME WBMJEBUF PS OPU. ">JBI 2.11: 5P VTF B DVTUPN QBSTFS. .VTU CF PG UZQF ca.uhn.hl7v2.parser.Parser.

$UMLPFKD > '+7 IFPQBKBO


*O PVS 4QSJOH 9.- GJMF, XF DPOGJHVSF BO FOEQPJOU UP MJTUFO GPS )-7 SFRVFTUT VTJOH 5$1:

696

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<endpoint id="hl7listener" uri="mina:tcp://localhost:8888?sync=true&amp;codec=#hl7codec"/> <!-- Camel 2.11: uri="mina2:tcp... -->

/PUJDF UIBU XF VTF 5$1 PO localhost PO QPSU 8888. 8F VTF PVK@=QORB UP JOEJDBUF UIBU UIJT MJTUFOFS JT TZODISPOPVT BOE UIFSFGPSF XJMM SFUVSO B )-7 SFTQPOTF UP UIF DBMMFS. 5IFO XF TFUVQ NJOB UP VTF PVS )-7 DPEFD XJUI @LAB@=#EI7@LAB@. /PUJDF UIBU hl7codec JT KVTU B 4QSJOH CFBO *%, TP XF DPVME IBWF OBNFE JU mygreatcodecforhl7 PS XIBUFWFS. 5IF DPEFD JT BMTP TFU VQ JO UIF 4QSJOH 9.- GJMF:
<bean id="hl7codec" class="org.apache.camel.component.hl7.HL7MLLPCodec"> <property name="charset" value="iso-8859-1"/> </bean>

"CPWF XF BMTP DPOGJHVSF UIF DIBSTFU FODPEJOH UP VTF (iso-8859-1). 5IF FOEQPJOU EI7IFPQBKBO DBO UIFO CF VTFE JO B SPVUF BT B DPOTVNFS, BT UIJT +BWB %4FYBNQMF JMMVTUSBUFT:
from("hl7listener").to("patientLookupService");

5IJT JT B WFSZ TJNQMF SPVUF UIBU XJMM MJTUFO GPS )-7 BOE SPVUF JU UP B TFSWJDF OBNFE M>QFBKQ+LLHRM2BOSF@B UIBU JT BMTP B 4QSJOH CFBO *% XF IBWF DPOGJHVSFE JO UIF 4QSJOH 9.BT:
<bean id="patientLookupService" class="com.mycompany.healthcare.service.PatientLookupService"/>

"OPUIFS QPXFSGVM GFBUVSF PG $BNFM JT UIBU XF DBO IBWF PVS CVTJOFTT MPHJD JO 10+0 DMBTTFT UIBU JT OPU UJFE UP $BNFM BT TIPXO IFSF:

import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v24.segment.QRD; public class PatientLookupService { public Message lookupPatient(Message input) throws HL7Exception { QRD qrd = (QRD)input.get("QRD"); String patientId = qrd.getWhoSubjectFilter(0).getIDNumber().getValue(); // find patient data based on the patient id and create a HL7 model object with the response Message response = ... create and set response data return response }

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

697

/PUJDF UIBU UIJT DMBTT VTFT KVTU JNQPSUT GSPN UIF )"1* MJCSBSZ BOE KLQ GSPN $BNFM. '+7 ,LABI RPFKD G>S>.I>KD.2QOFKD 5IF )-7.--1 DPEFD VTFT QMBJO String BT JUT EBUB GPSNBU. $BNFM VTFT JUT 5ZQF $POWFSUFS UP DPOWFSU UP/GSPN TUSJOHT UP UIF )"1* )-7 NPEFM PCKFDUT. )PXFWFS, ZPV DBO VTF QMBJO String PCKFDUT JG ZPV QSFGFS, GPS JOTUBODF JG ZPV XJTI UP QBSTF UIF EBUB ZPVSTFMG. 4FF TBNQMFT GPS TVDI BO FYBNQMF. '+7S2 ,LABI RPFKD ' /( 5IF )-7W2 NPEFM VTFT +BWB PCKFDUT GSPN UIF )"1* MJCSBSZ. 6TJOH UIJT MJCSBSZ, XF DBO FODPEF BOE EFDPEF GSPN UIF &%* GPSNBU (&37) UIBU JT NPTUMZ VTFE XJUI )-7W2. 8JUI UIJT NPEFM ZPV DBO DPEF XJUI +BWB PCKFDUT JOTUFBE PG UIF &%* CBTFE )-7 GPSNBU UIBU DBO CF IBSE GPS IVNBOT UP SFBE BOE VOEFSTUBOE. 5IF TBNQMF CFMPX JT B SFRVFTU UP MPPLVQ B QBUJFOU XJUI UIF QBUJFOU *% 0101701234.
MSH|^~\\&|MYSENDER|MYRECEIVER|MYAPPLICATION||200612211200||QRY^A19|1234|P|2.4 QRD|200612211200|R|I|GetPatient|||1^RD|0101701234|DEM||

6TJOH UIF )-7 NPEFM XF DBO XPSL XJUI UIF EBUB BT B ca.uhn.hl7v2.model.Message PCKFDU. 5P SFUSJFWF UIF QBUJFOU *% JO UIF NFTTBHF BCPWF, ZPV DBO EP UIJT JO +BWB DPEF:
Message msg = exchange.getIn().getBody(Message.class); QRD qrd = (QRD)msg.get("QRD"); String patientId = qrd.getWhoSubjectFilter(0).getIDNumber().getValue();

*G ZPV LOPX UIF NFTTBHF UZQF JO BEWBODF, ZPV DBO CF NPSF UZQF-TBGF:
QRY_A19 msg = exchange.getIn().getBody(QRY_A19.class); String patientId = msg.getQRD().getWhoSubjectFilter(0).getIDNumber().getValue();

$BNFM IBT CVJMU-JO UZQF DPOWFSUFST, TP XIFO UIJT PQFSBUJPO JT JOWPLFE:


Message msg = exchange.getIn().getBody(Message.class);

$BNFM XJMM DPOWFSU UIF SFDFJWFE )-7 EBUB GSPN String UP Message. 5IJT JT QPXFSGVM XIFO DPNCJOFE XJUI UIF )-7 MJTUFOFS, UIFO ZPV BT UIF FOE-VTFS EPO'U IBWF UP XPSL XJUI byte[], String PS BOZ PUIFS TJNQMF PCKFDU GPSNBUT. :PV DBO KVTU VTF UIF )"1* )-7W2 NPEFM PCKFDUT.

698

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

'+7 #>Q>%LOJ>Q 5IF )-7 DPNQPOFOU TIJQT XJUI B )-7 EBUB GPSNBU UIBU DBO CF VTFE UP GPSNBU CFUXFFO String BOE )-7 NPEFM PCKFDUT. marshal = GSPN .FTTBHF UP CZUF TUSFBN (DBO CF VTFE XIFO SFUVSOJOH BT SFTQPOTF VTJOH UIF )-7 .--1 DPEFD) unmarshal = GSPN CZUF TUSFBN UP .FTTBHF (DBO CF VTFE XIFO SFDFJWJOH TUSFBNFE EBUB GSPN UIF )-7 .--1 5P VTF UIF EBUB GPSNBU, TJNQMZ JOTUBOUJBUF BO JOTUBODF BOE JOWPLF UIF NBSTIBM PS VONBSTIBM PQFSBUJPO JO UIF SPVUF CVJMEFS:
DataFormat hl7 = new HL7DataFormat(); ... from("direct:hl7in").marshal(hl7).to("jms:queue:hl7out");

*O UIF TBNQMF BCPWF, UIF )-7 JT NBSTIBMMFE GSPN B )"1* .FTTBHF PCKFDU UP B CZUF TUSFBN BOE QVU PO B +.4 RVFVF. 5IF OFYU FYBNQMF JT UIF PQQPTJUF:
DataFormat hl7 = new HL7DataFormat(); ... from("jms:queue:hl7out").unmarshal(hl7).to("patientLookupService");

)FSF XF VONBSTIBM UIF CZUF TUSFBN JOUP B )"1* .FTTBHF PCKFDU UIBU JT QBTTFE UP PVS QBUJFOU MPPLVQ TFSWJDF. /PUJDF UIFSF JT B TIPSUIBOE TZOUBY JO $BNFM GPS XFMM-LOPXO EBUB GPSNBUT UIBU JT DPNNPOMZ VTFE. 5IFO ZPV EPO'U OFFE UP DSFBUF BO JOTUBODF PG UIF HL7DataFormat PCKFDU:
from("direct:hl7in").marshal().hl7().to("jms:queue:hl7out"); from("jms:queue:hl7out").unmarshal().hl7().to("patientLookupService");

,BPP>DB 'B>ABOP 5IF RKJ>OPE>I PQFSBUJPO BEET UIFTF .4) GJFMET BT IFBEFST PO UIF $BNFM NFTTBHF:
*BV
CamelHL7SendingApplication CamelHL7SendingFacility CamelHL7ReceivingApplication CamelHL7ReceivingFacility CamelHL7Timestamp CamelHL7Security CamelHL7MessageType CamelHL7TriggerEvent

,2' CFBIA
MSH-3 MSH-4 MSH-5 MSH-6 MSH-7 MSH-8 MSH-9-1 MSH-9-2

$U>JMIB
MYSERVER MYSERVERAPP MYCLIENT MYCLIENTAPP 20071231235900 null ADT A01

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

699

2BDJBKQ PBM>O>QLOP "T PG ">JBI 2.11, unmarshal EPFT OPU BVUPNBUJDBMMZ GJY TFHNFOU TFQBSBUPST BOZNPSF CZ DPOWFSUJOH \n UP \r. *G ZPV OFFE UIJT DPOWFSTJPO, org.apache.camel.component.hl7.HL7#convertLFToCR QSPWJEFT B IBOEZ Expression GPS UIJT QVSQPTF.

2BOF>IFW>?IB JBPP>DBP "T PG )"1* 2.0 (VTFE CZ ">JBI 2.11), UIF )-7W2 NPEFM DMBTTFT BSF GVMMZ TFSJBMJ[BCMF. 4P ZPV DBO QVU )-7W2 NFTTBHFT EJSFDUMZ JOUP B +.4 RVFVF (J.F. XJUIPVU DBMMJOH marshal() BOE SFBE UIFN BHBJO EJSFDUMZ GSPN UIF RVFVF (J.F. XJUIPVU DBMMJOH unmarshal().
CamelHL7MessageControl CamelHL7ProcessingId CamelHL7VersionId MSH-10 MSH-11 MSH-12 1234 P 2.4

"MM IFBEFST BSF String UZQFT. *G B IFBEFS WBMVF JT NJTTJOH, JUT WBMVF JT null. .MQFLKP 5IF )-7 %BUB 'PSNBU TVQQPSUT UIF GPMMPXJOH PQUJPOT:
.MQFLK
validate parser

#BC>RIQ
USVF ca.uhn.hl7v2.parser.GenericParser

#BP@OFMQFLK
8IFUIFS UIF )"1* 1BSTFS TIPVME WBMJEBUF VTJOH UIF EFGBVMU WBMJEBUJPO SVMFT. ">JBI 2.11: CFUUFS VTF UIF parser PQUJPO BOE JOJUJBMJ[F UIF QBSTFS XJUI UIF EFTJSFE )"1* ValidationContext ">JBI 2.11: 5P VTF B DVTUPN QBSTFS. .VTU CF PG UZQF ca.uhn.hl7v2.parser.Parser. /PUF UIBU GenericParser BMTP BMMPXT UP QBSTF 9.--FODPEFE )-7W2 NFTTBHFT.

#BMBKABK@FBP 5P VTF )-7 JO ZPVS $BNFM SPVUFT ZPV'MM OFFE UP BEE B EFQFOEFODZ PO @>JBI-EI7 MJTUFE BCPWF, XIJDI JNQMFNFOUT UIJT EBUB GPSNBU. 5IF )"1* MJCSBSZ TJODF 7FSTJPO 0.6 IBT CFFO TQMJU JOUP B CBTF MJCSBSZ BOE TFWFSBM TUSVDUVSF MJCSBSJFT, POF GPS FBDI )-7W2 NFTTBHF WFSTJPO: ` W2.1 TUSVDUVSFT MJCSBSZ ` W2.2 TUSVDUVSFT MJCSBSZ ` W2.3 TUSVDUVSFT MJCSBSZ ` W2.3.1 TUSVDUVSFT MJCSBSZ ` W2.4 TUSVDUVSFT MJCSBSZ ` W2.5 TUSVDUVSFT MJCSBSZ

700

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

` W2.5.1 TUSVDUVSFT MJCSBSZ ` W2.6 TUSVDUVSFT MJCSBSZ #Z EFGBVMU camel-hl7 POMZ SFGFSFODFT UIF )"1* CBTF MJCSBSZ. "QQMJDBUJPOT BSF SFTQPOTJCMF GPS JODMVEJOH TUSVDUVSF MJCSBSJFT UIFNTFMWFT. 'PS FYBNQMF, JG B BQQMJDBUJPO XPSLT XJUI )-7W2 NFTTBHF WFSTJPOT 2.4 BOE 2.5 UIFO UIF GPMMPXJOH EFQFOEFODJFT NVTU CF BEEFE:
<dependency> <groupId>ca.uhn.hapi</groupId> <artifactId>hapi-structures-v24</artifactId> <version>1.2</version> <!-- use the same version as your hapi-base version --> </dependency> <dependency> <groupId>ca.uhn.hapi</groupId> <artifactId>hapi-structures-v25</artifactId> <version>1.2</version> <!-- use the same version as your hapi-base version --> </dependency>

"MUFSOBUJWFMZ, BO 04(J CVOEMF DPOUBJOJOH UIF CBTF MJCSBSZ, BMM TUSVDUVSFT MJCSBSJFT BOE SFRVJSFE EFQFOEFODJFT (PO UIF CVOEMF DMBTTQBUI) DBO CF EPXOMPBEFE GSPN UIF DFOUSBM .BWFO SFQPTJUPSZ.
<dependency> <groupId>ca.uhn.hapi</groupId> <artifactId>hapi-osgi-base</artifactId> <version>1.2</version> </dependency>

3BOPBO I>KDR>DB (">JBI 2.11) )"1* QSPWJEFT B 5FSTFS DMBTT UIBU QSPWJEFT BDDFTT UP GJFMET VTJOH B DPNNPOMZ VTFE UFSTF MPDBUJPO TQFDJGJDBUJPO TZOUBY. 5IF 5FSTFS MBOHVBHF BMMPXT UP VTF UIJT TZOUBY UP FYUSBDU WBMVFT GSPN NFTTBHFT BOE UP VTF UIFN BT FYQSFTTJPOT BOE QSFEJDBUFT GPS GJMUFSJOH, DPOUFOU-CBTFE SPVUJOH FUD. 4BNQMF:
import static org.apache.camel.component.hl7.HL7.terser; ... // extract patient ID from field QRD-8 in the QRY_A19 message above and put into message header from("direct:test1") .setHeader("PATIENT_ID",terser("QRD-8(0)-1")) .to("mock:test1"); // continue processing if extracted field equals a message header from("direct:test2") .filter(terser("QRD-8(0)-1")

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

701

.isEqualTo(header("PATIENT_ID")) .to("mock:test2");

'+7 5>IFA>QFLK MOBAF@>QB (">JBI 2.11) 0GUFO JU JT QSFGFSBCMF UP QBSTF B )-7W2 NFTTBHF BOE WBMJEBUF JU BHBJOTU B )"1* 7BMJEBUJPO$POUFYU JO B TFQBSBUF TUFQ BGUFSXBSET. 4BNQMF:

import static org.apache.camel.component.hl7.HL7.messageConformsTo; import ca.uhn.hl7v2.validation.impl.DefaultValidation; ... // Use standard or define your own validation rules ValidationContext defaultContext = new DefaultValidation(); // Throws PredicateValidationException if message does not validate from("direct:test1").validate(messageConformsTo(defaultContext)).to("mock:test1");

'+7

@HKLTIBADBJBKQ BUMOBPPFLK (">JBI 2.11)

" DPNNPO UBTL JO )-7W2 QSPDFTTJOH JT UP HFOFSBUF BO BDLOPXMFEHFNFOU NFTTBHF BT SFTQPOTF UP BO JODPNJOH )-7W2 NFTTBHF, F.H. CBTFE PO B WBMJEBUJPO SFTVMU. 5IF ack FYQSFTTJPO MFUT VT BDDPNQMJTI UIJT WFSZ FMFHBOUMZ:

import static org.apache.camel.component.hl7.HL7.messageConformsTo; import static org.apache.camel.component.hl7.HL7.ack; import ca.uhn.hl7v2.validation.impl.DefaultValidation; ... // Use standard or define your own validation rules ValidationContext defaultContext = new DefaultValidation(); from("direct:test1") .onException(Exception.class) .handled(true) .transform(ack()) // auto-generates negative ack because of exception in Exchange .end() .validate(messageConformsTo(defaultContext)) // do something meaningful here ... // acknowledgement .transform(ack())

702

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

,LOB 2>JMIBP *O UIF GPMMPXJOH FYBNQMF XF TFOE B )-7 SFRVFTU UP B )-7 MJTUFOFS BOE SFUSJFWFT B SFTQPOTF. 8F VTF QMBJO String UZQFT JO UIJT FYBNQMF:
String line1 = "MSH|^~\\&|MYSENDER|MYRECEIVER|MYAPPLICATION||200612211200||QRY^A19|1234|P|2.4"; String line2 = "QRD|200612211200|R|I|GetPatient|||1^RD|0101701234|DEM||"; StringBuilder in = new StringBuilder(); in.append(line1); in.append("\n"); in.append(line2); String out = (String)template.requestBody("mina2:tcp://127.0.0.1:8888?sync=true&codec=#hl7codec", in.toString());

*O UIF OFYU TBNQMF, XF XBOU UP SPVUF )-7 SFRVFTUT GSPN PVS )-7 MJTUFOFS UP PVS CVTJOFTT MPHJD. 8F IBWF PVS CVTJOFTT MPHJD JO B QMBJO 10+0 UIBU XF IBWF SFHJTUFSFE JO UIF SFHJTUSZ BT hl7service = GPS JOTUBODF VTJOH 4QSJOH BOE MFUUJOH UIF CFBO JE = hl7service. 0VS CVTJOFTT MPHJD JT B QMBJO 10+0 POMZ VTJOH UIF )"1* MJCSBSZ TP XF IBWF UIFTF PQFSBUJPOT EFGJOFE:
public class MyHL7BusinessLogic { // This is a plain POJO that has NO imports whatsoever on Apache Camel. // its a plain POJO only importing the HAPI library so we can much easier work with the HL7 format. public Message handleA19(Message msg) throws Exception { // here you can have your business logic for A19 messages assertTrue(msg instanceof QRY_A19); // just return the same dummy response return createADR19Message(); } public Message handleA01(Message msg) throws Exception { // here you can have your business logic for A01 messages assertTrue(msg instanceof ADT_A01); // just return the same dummy response return createADT01Message(); } }

5IFO XF TFU VQ UIF $BNFM SPVUFT VTJOH UIF RouteBuilder BT GPMMPXT:


DataFormat hl7 = new HL7DataFormat(); // we setup or HL7 listener on port 8888 (using the hl7codec) and in sync mode so we can return a response

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

703

from("mina2:tcp://127.0.0.1:8888?sync=true&codec=#hl7codec") // we use the HL7 data format to unmarshal from HL7 stream to the HAPI Message model // this ensures that the camel message has been enriched with hl7 specific headers to // make the routing much easier (see below) .unmarshal(hl7) // using choice as the content base router .choice() // where we choose that A19 queries invoke the handleA19 method on our hl7service bean .when(header("CamelHL7TriggerEvent").isEqualTo("A19")) .beanRef("hl7service", "handleA19") .to("mock:a19") // and A01 should invoke the handleA01 method on our hl7service bean .when(header("CamelHL7TriggerEvent").isEqualTo("A01")).to("mock:a01") .beanRef("hl7service", "handleA01") .to("mock:a19") // other types should go to mock:unknown .otherwise() .to("mock:unknown") // end choice block .end() // marshal response back .marshal(hl7);

/PUJDF UIBU XF VTF UIF )-7 %BUB'PSNBU UP FOSJDI PVS $BNFM .FTTBHF XJUI UIF .4) GJFMET QSFDPOGJHVSFE PO UIF $BNFM .FTTBHF. 5IJT MFUT VT NVDI NPSF FBTJMZ EFGJOF PVS SPVUFT VTJOH UIF GMVFOU CVJMEFST. *G XF EP OPU VTF UIF )-7 %BUB'PSNBU, UIFO XF EP OPU HBJOT UIFTF IFBEFST BOE XF NVTU SFTPSU UP B EJGGFSFOU UFDIOJRVF GPS DPNQVUJOH UIF .4) USJHHFS FWFOU (= XIBU LJOE PG )-7 NFTTBHF JU JT). 5IJT JT B CJH BEWBOUBHF PG UIF )-7 %BUB'PSNBU PWFS UIF QMBJO )-7 UZQF DPOWFSUFST.

2>JMIB RPFKD MI>FK 2QOFKD L?GB@QP


*O UIJT TBNQMF XF VTF QMBJO String PCKFDUT BT UIF EBUB GPSNBU, UIBU XF TFOE, QSPDFTT BOE SFDFJWF. "T UIF TBNQMF JT QBSU PG B VOJU UFTU, UIFSF JT TPNF DPEF GPS BTTFSUJPOT, CVU ZPV TIPVME CF BCMF UP VOEFSTUBOE XIBU IBQQFOT. 'JSTU XF TFOE UIF QMBJO TUSJOH, Hello World, UP UIF HL7MLLPCodec BOE SFDFJWF UIF SFTQPOTF BT B QMBJO TUSJOH, Bye World.
MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedBodiesReceived("Bye World"); // send plain hello world as String Object out = template.requestBody("mina2:tcp://127.0.0.1:8888?sync=true&codec=#hl7codec", "Hello World");

704

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

assertMockEndpointsSatisfied(); // and the response is also just plain String assertEquals("Bye World", out);

)FSF XF QSPDFTT UIF JODPNJOH EBUB BT QMBJO 4USJOH BOE TFOE UIF SFTQPOTF BMTP BT QMBJO 4USJOH:
from("mina2:tcp://127.0.0.1:8888?sync=true&codec=#hl7codec") .process(new Processor() { public void process(Exchange exchange) throws Exception { // use plain String as message format String body = exchange.getIn().getBody(String.class); assertEquals("Hello World", body); // return the response as plain string exchange.getOut().setBody("Bye World"); } }) .to("mock:result");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

'33/ ".,/.-$-3
5IF EQQM: DPNQPOFOU QSPWJEFT )551 CBTFE FOEQPJOUT GPS DPOTVNJOH FYUFSOBM )551 SFTPVSDFT (BT B DMJFOU UP DBMM FYUFSOBM TFSWFST VTJOH )551). .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-http</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

705

41( CLOJ>Q
http:hostname[:port][/resourceUri][?param1=value1][&param2=value2]

8JMM CZ EFGBVMU VTF QPSU 80 GPS )551 BOE 443 GPS )5514. $U>JMIBP $BMM UIF VSM XJUI UIF CPEZ VTJOH 1045 BOE SFUVSO SFTQPOTF BT PVU NFTTBHF. *G CPEZ JT OVMM DBMM 63- VTJOH (&5 BOE SFUVSO SFTQPOTF BT PVU NFTTBHF )>S> #2+
from("direct:start") .to("http://myhost/mypath");

2MOFKD #2+
<from uri="direct:start"/> <to uri="http://oldhost"/>

:PV DBO PWFSSJEF UIF )551 FOEQPJOU 63* CZ BEEJOH B IFBEFS. $BNFM XJMM DBMM UIF IUUQ://OFXIPTU. 5IJT JT WFSZ IBOEZ GPS F.H. 3&45 VSMT. )>S> #2+
from("direct:start") .setHeader(Exchange.HTTP_URI, simple("http://myserver/orders/${header.orderId}")) .to("http://dummyhost");

63* QBSBNFUFST DBO FJUIFS CF TFU EJSFDUMZ PO UIF FOEQPJOU 63* PS BT B IFBEFS )>S> #2+
from("direct:start") .to("http://oldhost?order=123&detail=short"); from("direct:start") .setHeader(Exchange.HTTP_QUERY, constant("order=123&detail=short")) .to("http://oldhost");

4FU UIF )551 SFRVFTU NFUIPE UP 1045 )>S> #2+ 2MOFKD #2+

706

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

@>JBI-EQQM SP @>JBI-GBQQV :PV DBO POMZ QSPEVDF UP FOEQPJOUT HFOFSBUFE CZ UIF )551 DPNQPOFOU. 5IFSFGPSF JU TIPVME OFWFS CF VTFE BT JOQVU JOUP ZPVS DBNFM 3PVUFT. 5P CJOE/FYQPTF BO )551 FOEQPJOU WJB B )551 TFSWFS BT JOQVU UP B DBNFM SPVUF, ZPV DBO VTF UIF +FUUZ $PNQPOFOU PS UIF 4FSWMFU $PNQPOFOU

from("direct:start") .setHeader(Exchange.HTTP_METHOD, constant("POST")) .to("http://www.google.com");

<from uri="direct:start"/> <setHeader headerName="CamelHttpMethod"> <constant>POST</constant> </setHeader> <to uri="http://www.google.com"/> <to uri="mock:results"/>

'QQM$KAMLFKQ .MQFLKP
->JB
throwExceptionOnFailure

#BC>RIQ 5>IRB
true

#BP@OFMQFLK
0QUJPO UP EJTBCMF UISPXJOH UIF HttpOperationFailedException JO DBTF PG GBJMFE SFTQPOTFT GSPN UIF SFNPUF TFSWFS. 5IJT BMMPXT ZPV UP HFU BMM SFTQPOTFT SFHBSEMFT PG UIF )551 TUBUVT DPEF. *G UIF PQUJPO JT USVF , )UUQ1SPEVDFS XJMM JHOPSF UIF &YDIBOHF.)551@63* IFBEFS, BOE VTF UIF FOEQPJOU'T 63* GPS SFRVFTU. :PV NBZ BMTP TFU UIF QEOLT$U@MBQFLK.K%>FIROB UP CF GBMTF UP MFU UIF )UUQ1SPEVDFS TFOE BMM UIF GBVMU SFTQPOTF CBDL. ">JBI 2.3: *G UIF PQUJPO JT USVF, )UUQ1SPEVDFS BOE $BNFM4FSWMFU XJMM TLJQ UIF H[JQ QSPDFTTJOH JG UIF DPOUFOU-FODPEJOH JT "H[JQ". %FGBVMU)UUQ#JOEJOH XJMM DPQZ UIF SFRVFTU JOQVU TUSFBN JOUP B TUSFBN DBDIF BOE QVU JU JOUP NFTTBHF CPEZ JG UIJT PQUJPO JT GBMTF UP TVQQPSU SFBE JU UXJDF, PUIFSXJTF %FGBVMU)UUQ#JOEJOH XJMM TFU UIF SFRVFTU JOQVU TUSFBN EJSFDU JOUP UIF NFTTBHF CPEZ. 3FGFSFODF UP B org.apache.camel.component.http.HttpBinding JO UIF 3FHJTUSZ. 'SPN $BNFM 2.3 POXBSET QSFGFS UP VTF UIF httpBinding PQUJPO. 3FGFSFODF UP B org.apache.camel.component.http.HttpBinding JO UIF 3FHJTUSZ. 3FGFSFODF UP B org.apache.camel.component.http.HttpClientConfigurer JO UIF 3FHJTUSZ. 'SPN $BNFM 2.3 POXBSET QSFGFS UP VTF UIF httpClientConfigurer PQUJPO. 3FGFSFODF UP B org.apache.camel.component.http.HttpClientConfigurer JO UIF 3FHJTUSZ. 4FUUJOH PQUJPOT PO UIF )UUQ$MJFOU1BSBNT. 'PS JOTUBODF httpClient.soTimeout=5000 XJMM TFU UIF SO_TIMEOUT UP 5 TFDPOET. 5P VTF B DVTUPN org.apache.http.conn.ClientConnectionManager. ">JBI 2.6: *G FOBCMFE BOE BO &YDIBOHF GBJMFE QSPDFTTJOH PO UIF DPOTVNFS TJEF, BOE JG UIF DBVTFE Exception XBT TFOE CBDL TFSJBMJ[FE JO UIF SFTQPOTF BT B application/x-java-serialized-object DPOUFOU UZQF (GPS FYBNQMF VTJOH +FUUZ PS 4&37-&5 $BNFM DPNQPOFOUT). 0O UIF QSPEVDFS TJEF UIF FYDFQUJPO XJMM CF EFTFSJBMJ[FE BOE UISPXO BT JT, JOTUFBE PG UIF HttpOperationFailedException. 5IF DBVTFE FYDFQUJPO JT SFRVJSFE UP CF TFSJBMJ[FE. ">JBI 2.11: 3FGFSFODF UP B JOTUBODF PG org.apache.camel.spi.HeaderFilterStrategy JO UIF 3FHJTUSZ. *U XJMM CF VTFE UP BQQMZ UIF DVTUPN IFBEFS'JMUFS4USBUFHZ PO UIF OFX DSFBUF )UUQ&OEQPJOU. ">JBI 2.11: /OLAR@BO LKIV 3FGFST UP B DVTUPN org.apache.camel.component.http.UrlRewrite XIJDI BMMPXT ZPV UP SFXSJUF VSMT XIFO ZPV CSJEHF/QSPYZ FOEQPJOUT. 4FF NPSF EFUBJMT BU 6SM3FXSJUF BOE )PX UP VTF $BNFM BT B )551 QSPYZ CFUXFFO B DMJFOU BOE TFSWFS.

bridgeEndpoint

false

disableStreamCache

false

httpBindingRef httpBinding httpClientConfigurerRef httpClientConfigurer httpClient.XXX clientConnectionManager

null null null null null null

transferException

false

headerFilterStrategy

null

urlRewrite

null

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

707

RQEBKQF@>QFLK >KA /OLUV 5IF GPMMPXJOH BVUIFOUJDBUJPO PQUJPOT DBO BMTP CF TFU PO UIF )UUQ&OEQPJOU:
->JB
authMethod authMethodPriority authUsername authPassword authDomain authHost proxyHost proxyPort proxyAuthMethod proxyAuthUsername proxyAuthPassword proxyAuthDomain proxyAuthHost

#BC>RIQ 5>IRB
null null null null null null null null null null null null null

#BP@OFMQFLK
"VUIFOUJDBUJPO NFUIPE, FJUIFS BT Basic, Digest PS NTLM. 1SJPSJUZ PG BVUIFOUJDBUJPO NFUIPET. *T B MJTU TFQBSBUFE XJUI DPNNB. 'PS FYBNQMF: Basic,Digest UP FYDMVEF NTLM. 6TFSOBNF GPS BVUIFOUJDBUJPO 1BTTXPSE GPS BVUIFOUJDBUJPO %PNBJO GPS /5.- BVUIFOUJDBUJPO 0QUJPOBM IPTU GPS /5.- BVUIFOUJDBUJPO 5IF QSPYZ IPTU OBNF 5IF QSPYZ QPSU OVNCFS "VUIFOUJDBUJPO NFUIPE GPS QSPYZ, FJUIFS BT Basic, Digest PS NTLM. 6TFSOBNF GPS QSPYZ BVUIFOUJDBUJPO 1BTTXPSE GPS QSPYZ BVUIFOUJDBUJPO %PNBJO GPS QSPYZ /5.- BVUIFOUJDBUJPO 0QUJPOBM IPTU GPS QSPYZ /5.- BVUIFOUJDBUJPO

8IFO VTJOH BVUIFOUJDBUJPO ZPV JRPQ QSPWJEF UIF DIPJDF PG NFUIPE GPS UIF authMethod PS authProxyMethod PQUJPOT. :PV DBO DPOGJHVSF UIF QSPYZ BOE BVUIFOUJDBUJPO EFUBJMT PO FJUIFS UIF HttpComponent PS UIF HttpEndoint. 7BMVFT QSPWJEFE PO UIF HttpEndpoint XJMM UBLF QSFDFEFODF PWFS HttpComponent. *UT NPTU MJLFMZ CFTU UP DPOGJHVSF UIJT PO UIF HttpComponent XIJDI BMMPXT ZPV UP EP UIJT PODF. 5IF )551 DPNQPOFOU VTFT DPOWFOUJPO PWFS DPOGJHVSBUJPO XIJDI NFBOT UIBU JG ZPV IBWF OPU FYQMJDJU TFU B authMethodPriority UIFO JU XJMM GBMMCBDL BOE VTF UIF TFMFDU(FE) authMethod BT QSJPSJUZ BT XFMM. 4P JG ZPV VTF authMethod.Basic UIFO UIF auhtMethodPriority XJMM CF Basic POMZ. 'QQM"LJMLKBKQ .MQFLKP
->JB
httpBinding httpClientConfigurer httpConnectionManager httpConfiguration

#BC>RIQ 5>IRB
null null null null

#BP@OFMQFLK
5P VTF B DVTUPN org.apache.camel.component.http.HttpBinding. 5P VTF B DVTUPN org.apache.camel.component.http.HttpClientConfigurer. 5P VTF B DVTUPN org.apache.commons.httpclient.HttpConnectionManager. 5P VTF B DVTUPN org.apache.camel.component.http.HttpConfiguration

HttpConfiguration DPOUBJOT BMM UIF PQUJPOT MJTUFE JO UIF UBCMF BCPWF VOEFS UIF TFDUJPO HttpConfiguration - Setting Authentication and Proxy. ,BPP>DB 'B>ABOP
->JB
Exchange.HTTP_URI Exchange.HTTP_METHOD

3VMB
String String

#BP@OFMQFLK
63* UP DBMM. 8JMM PWFSSJEF FYJTUJOH 63* TFU EJSFDUMZ PO UIF FOEQPJOU. )551 .FUIPE / 7FSC UP VTF ((&5/1045/165/%&-&5&/)&"%/015*0/4/53"$&)

708

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

Exchange.HTTP_PATH Exchange.HTTP_QUERY Exchange.HTTP_RESPONSE_CODE Exchange.HTTP_CHARACTER_ENCODING Exchange.CONTENT_TYPE Exchange.CONTENT_ENCODING Exchange.HTTP_SERVLET_REQUEST Exchange.HTTP_SERVLET_RESPONSE Exchange.HTTP_PROTOCOL_VERSION

String String int String String String HttpServletRequest HttpServletResponse String

3FRVFTU 63*'T QBUI, UIF IFBEFS XJMM CF VTFE UP CVJME UIF SFRVFTU 63* XJUI UIF )551@63*. ">JBI 2.3.0: *G UIF QBUI JT TUBSU XJUI "/", IUUQ QSPEVDFS XJMM USZ UP GJOE UIF SFMBUJWF QBUI CBTFE PO UIF &YDIBOHF.)551@#"4&@63* IFBEFS PS UIF FYDIBOHF.HFU'SPN&OEQPJOU().HFU&OEQPJOU6SJ(); 63* QBSBNFUFST. 8JMM PWFSSJEF FYJTUJOH 63* QBSBNFUFST TFU EJSFDUMZ PO UIF FOEQPJOU. 5IF )551 SFTQPOTF DPEF GSPN UIF FYUFSOBM TFSWFS. *T 200 GPS 0,. $IBSBDUFS FODPEJOH. 5IF )551 DPOUFOU UZQF. *T TFU PO CPUI UIF */ BOE 065 NFTTBHF UP QSPWJEF B DPOUFOU UZQF, TVDI BT text/html. 5IF )551 DPOUFOU FODPEJOH. *T TFU PO CPUI UIF */ BOE 065 NFTTBHF UP QSPWJEF B DPOUFOU FODPEJOH, TVDI BT gzip. 5IF HttpServletRequest PCKFDU. 5IF HttpServletResponse PCKFDU. ">JBI 2.5: :PV DBO TFU UIF IUUQ QSPUPDPM WFSTJPO XJUI UIJT IFBEFS, FH. ")551/1.0". *G ZPV EJEO'U TQFDJGZ UIF IFBEFS, )UUQ1SPEVDFS XJMM VTF UIF EFGBVMU WBMVF ")551/1.1"

5IF IFBEFS OBNF BCPWF BSF DPOTUBOUT. 'PS UIF TQSJOH %4- ZPV IBWF UP VTF UIF WBMVF PG UIF DPOTUBOU JOTUFBE PG UIF OBNF. ,BPP>DB !LAV $BNFM XJMM TUPSF UIF )551 SFTQPOTF GSPN UIF FYUFSOBM TFSWFS PO UIF 065 CPEZ. "MM IFBEFST GSPN UIF */ NFTTBHF XJMM CF DPQJFE UP UIF 065 NFTTBHF, TP IFBEFST BSF QSFTFSWFE EVSJOH SPVUJOH. "EEJUJPOBMMZ $BNFM XJMM BEE UIF )551 SFTQPOTF IFBEFST BT XFMM UP UIF 065 NFTTBHF IFBEFST. 1BPMLKPB @LAB $BNFM XJMM IBOEMF BDDPSEJOH UP UIF )551 SFTQPOTF DPEF: 3FTQPOTF DPEF JT JO UIF SBOHF 100..299, $BNFM SFHBSET JU BT B TVDDFTT SFTQPOTF. 3FTQPOTF DPEF JT JO UIF SBOHF 300..399, $BNFM SFHBSET JU BT B SFEJSFDUJPO SFTQPOTF BOE XJMM UISPX B HttpOperationFailedException XJUI UIF JOGPSNBUJPO. 3FTQPOTF DPEF JT 400+, $BNFM SFHBSET JU BT BO FYUFSOBM TFSWFS GBJMVSF BOE XJMM UISPX B HttpOperationFailedException XJUI UIF JOGPSNBUJPO. 'QQM.MBO>QFLK%>FIBA$U@BMQFLK 5IJT FYDFQUJPO DPOUBJOT UIF GPMMPXJOH JOGPSNBUJPO: 5IF )551 TUBUVT DPEF 5IF )551 TUBUVT MJOF (UFYU PG UIF TUBUVT DPEF) 3FEJSFDU MPDBUJPO, JG TFSWFS SFUVSOFE B SFEJSFDU 3FTQPOTF CPEZ BT B java.lang.String, JG TFSWFS QSPWJEFE B CPEZ BT SFTQPOTF ">IIFKD RPFKD &$3 LO /.23 5IF GPMMPXJOH BMHPSJUIN JT VTFE UP EFUFSNJOF JG FJUIFS GET PS POST )551 NFUIPE TIPVME CF VTFE: 1. 6TF NFUIPE QSPWJEFE JO IFBEFS.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

709

QEOLT$U@BMQFLK.K%>FIROB 5IF PQUJPO, throwExceptionOnFailure, DBO CF TFU UP false UP QSFWFOU UIF HttpOperationFailedException GSPN CFJOH UISPXO GPS GBJMFE SFTQPOTF DPEFT. 5IJT BMMPXT ZPV UP HFU BOZ SFTQPOTF GSPN UIF SFNPUF TFSWFS. 5IFSF JT B TBNQMF CFMPX EFNPOTUSBUJOH UIJT. 2. GET JG RVFSZ TUSJOH JT QSPWJEFE JO IFBEFS. 3. GET JG FOEQPJOU JT DPOGJHVSFE XJUI B RVFSZ TUSJOH. 4. POST JG UIFSF JT EBUB UP TFOE (CPEZ JT OPU OVMM). 5. GET PUIFSXJTF. 'LT QL DBQ >@@BPP QL 'QQM2BOSIBQ1BNRBPQ >KA 'QQM2BOSIBQ1BPMLKPB :PV DBO HFU BDDFTT UP UIFTF UXP VTJOH UIF $BNFM UZQF DPOWFSUFS TZTUFN VTJOH
HttpServletRequest request = exchange.getIn().getBody(HttpServletRequest.class); HttpServletRequest response = exchange.getIn().getBody(HttpServletResponse.class);

4PFKD @IFBKQ QFJBLRQ - 2.=3(,$.43 4FF UIF VOJU UFTU JO UIJT MJOL

,.1$ $7 ,/+$2
"LKCFDROFKD > /OLUV )>S> #2+
from("direct:start") .to("http://oldhost?proxyHost=www.myproxy.com&proxyPort=80");

5IFSF JT BMTP TVQQPSU GPS QSPYZ BVUIFOUJDBUJPO WJB UIF proxyUsername BOE proxyPassword PQUJPOT.

4PFKD MOLUV PBQQFKDP LRQPFAB LC 41(


)>S> #2+ 2MOFKD #2+

710

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

context.getProperties().put("http.proxyHost", "172.168.18.9"); context.getProperties().put("http.proxyPort" "8080");

<camelContext> <properties> <property key="http.proxyHost" value="172.168.18.9"/> <property key="http.proxyPort" value="8080"/> </properties> </camelContext>

0QUJPOT PO &OEQPJOU XJMM PWFSSJEF PQUJPOT PO UIF DPOUFYU. "LKCFDROFKD @E>OPBQ *G ZPV BSF VTJOH POST UP TFOE EBUB ZPV DBO DPOGJHVSF UIF charset
setProperty(Exchange.CHARSET_NAME, "iso-8859-1");

2>JMIB TFQE P@EBARIBA MLII 5IF TBNQMF QPMMT UIF (PPHMF IPNFQBHF FWFSZ 10 TFDPOET BOE XSJUF UIF QBHF UP UIF GJMF message.html:
from("timer://foo?fixedRate=true&delay=0&period=10000") .to("http://www.google.com") .setHeader(FileComponent.HEADER_FILE_NAME, "message.html").to("file:target/ google");

&BQQFKD QEB 1BPMLKPB "LAB :PV DBO HFU UIF )551 SFTQPOTF DPEF GSPN UIF )551 DPNQPOFOU CZ HFUUJOH UIF WBMVF GSPN UIF 0VU NFTTBHF IFBEFS XJUI HttpProducer.HTTP_RESPONSE_CODE.
Exchange exchange = template.send("http://www.google.com/search", new Processor() { public void process(Exchange exchange) throws Exception { exchange.getIn().setHeader(Exchange.HTTP_QUERY, constant("hl=en&q=activemq")); } }); Message out = exchange.getOut(); int responseCode = out.getHeader(HttpProducer.HTTP_RESPONSE_CODE, Integer.class);

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

711

4PFKD throwExceptionOnFailure=false QL DBQ >KV OBPMLKPB ?>@H *O UIF SPVUF CFMPX XF XBOU UP SPVUF B NFTTBHF UIBU XF FOSJDI XJUI EBUB SFUVSOFE GSPN B SFNPUF )551 DBMM. "T XF XBOU BOZ SFTQPOTF GSPN UIF SFNPUF TFSWFS, XF TFU UIF throwExceptionOnFailure PQUJPO UP false TP XF HFU BOZ SFTQPOTF JO UIF AggregationStrategy. "T UIF DPEF JT CBTFE PO B VOJU UFTU UIBU TJNVMBUFT B )551 TUBUVT DPEF 404, UIFSF JT TPNF BTTFSUJPO DPEF FUD.

// We set throwExceptionOnFailure to false to let Camel return any response from the remove HTTP server without thrown // HttpOperationFailedException in case of failures. // This allows us to handle all responses in the aggregation strategy where we can check the HTTP response code // and decide what to do. As this is based on an unit test we assert the code is 404 from("direct:start").enrich("http://localhost:{{port}}/myserver?throwExceptionOnFailure=false&user=Cam new AggregationStrategy() { public Exchange aggregate(Exchange original, Exchange resource) { // get the response code Integer code = resource.getIn().getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class); assertEquals(404, code.intValue()); return resource; } }).to("mock:result"); // this is our jetty server where we simulate the 404 from("jetty://http://localhost:{{port}}/myserver") .process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setBody("Page not found"); exchange.getOut().setHeader(Exchange.HTTP_RESPONSE_CODE, 404); } });

#FP>?IFKD "LLHFBP 5P EJTBCMF DPPLJFT ZPV DBO TFU UIF )551 $MJFOU UP JHOPSF DPPLJFT CZ BEEJOH UIJT 63* PQUJPO: httpClient.cookiePolicy=ignoreCookies AS>K@BA 4P>DB *G ZPV OFFE NPSF DPOUSPM PWFS UIF )551 QSPEVDFS ZPV TIPVME VTF UIF HttpComponent XIFSF ZPV DBO TFU WBSJPVT DMBTTFT UP HJWF ZPV DVTUPN CFIBWJPS.

2BQQFKD ,>U"LKKB@QFLKP/BO'LPQ
5IF )551 $PNQPOFOU IBT B org.apache.commons.httpclient.HttpConnectionManager XIFSF ZPV DBO

712

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

DPOGJHVSF WBSJPVT HMPCBM DPOGJHVSBUJPO GPS UIF HJWFO DPNQPOFOU. #Z HMPCBM, XF NFBO UIBU BOZ FOEQPJOU UIF DPNQPOFOU DSFBUFT IBT UIF TBNF TIBSFE HttpConnectionManager. 4P, JG XF XBOU UP TFU B EJGGFSFOU WBMVF GPS UIF NBY DPOOFDUJPO QFS IPTU, XF OFFE UP EFGJOF JU PO UIF )551 DPNQPOFOU BOE KLQ PO UIF FOEQPJOU 63* UIBU XF VTVBMMZ VTF. 4P IFSF DPNFT: 'JSTU, XF EFGJOF UIF http DPNQPOFOU JO 4QSJOH 9.-. :FT, XF VTF UIF TBNF TDIFNF OBNF, http, CFDBVTF PUIFSXJTF $BNFM XJMM BVUP-EJTDPWFS BOE DSFBUF UIF DPNQPOFOU XJUI EFGBVMU TFUUJOHT. 8IBU XF OFFE JT UP PWFSSVMF UIJT TP XF DBO TFU PVS PQUJPOT. *O UIF TBNQMF CFMPX XF TFU UIF NBY DPOOFDUJPO UP 5 JOTUFBE PG UIF EFGBVMU PG 2.
<bean id="http" class="org.apache.camel.component.http.HttpComponent"> <property name="camelContext" ref="camel"/> <property name="httpConnectionManager" ref="myHttpConnectionManager"/> </bean> <bean id="myHttpConnectionManager" class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager"> <property name="params" ref="myHttpConnectionManagerParams"/> </bean> <bean id="myHttpConnectionManagerParams" class="org.apache.commons.httpclient.params.HttpConnectionManagerParams"> <property name="defaultMaxConnectionsPerHost" value="5"/> </bean>

"OE UIFO XF DBO KVTU VTF JU BT XF OPSNBMMZ EP JO PVS SPVUFT:


<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring" trace="true"> <route> <from uri="direct:start"/> <to uri="http://www.google.com"/> <to uri="mock:result"/> </route> </camelContext>

4PFKD MOBBJMQFSB >RQEBKQF@>QFLK


"O FOE VTFS SFQPSUFE UIBU IF IBE QSPCMFN XJUI BVUIFOUJDBUJOH XJUI )5514. 5IF QSPCMFN XBT FWFOUVBMMZ SFTPMWFE XIFO IF EJTDPWFSFE UIF )5514 TFSWFS EJE OPU SFUVSO B )551 DPEF 401 "VUIPSJ[BUJPO 3FRVJSFE. 5IF TPMVUJPO XBT UP TFU UIF GPMMPXJOH 63* PQUJPO: httpClient.authenticationPreemptive=true

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

713

@@BMQFKD PBIC PFDKBA @BOQFCF@>QBP COLJ OBJLQB PBOSBO


4FF UIJT MJOL GSPN B NBJMJOH MJTU EJTDVTTJPO XJUI TPNF DPEF UP PVUMJOF IPX UP EP UIJT XJUI UIF "QBDIF $PNNPOT )551 "1*.

2BQQFKD RM 22+ CLO '33/ "IFBKQ


4PFKD QEB )22$ "LKCFDRO>QFLK 4QFIFQV

"T PG $BNFM 2.8, UIF )5514 DPNQPOFOU TVQQPSUT 44-/5-4 DPOGJHVSBUJPO UISPVHI UIF $BNFM +44& $POGJHVSBUJPO 6UJMJUZ.c 5IJT VUJMJUZ HSFBUMZ EFDSFBTFT UIF BNPVOU PG DPNQPOFOU TQFDJGJD DPEF ZPV OFFE UP XSJUF BOE JT DPOGJHVSBCMF BU UIF FOEQPJOU BOE DPNQPOFOU MFWFMT.c 5IF GPMMPXJOH FYBNQMFT EFNPOTUSBUF IPX UP VTF UIF VUJMJUZ XJUI UIF )5514 DPNQPOFOU. 5IF WFSTJPO PG UIF "QBDIF )551 DMJFOU VTFE JO UIJT DPNQPOFOU SFTPMWFT 44-/5-4 JOGPSNBUJPO GSPN B HMPCBM "QSPUPDPM" SFHJTUSZ.c 5IJT DPNQPOFOU QSPWJEFT BO JNQMFNFOUBUJPO, org.apache.camel.component.http.SSLContextParametersSecureProtocolSocketFac PG UIF )551 DMJFOU'T QSPUPDPM TPDLFU GBDUPSZ JO PSEFS UP TVQQPSU UIF VTF PG UIF $BNFM +44& $POGJHVSBUJPO VUJMJUZ.c 5IF GPMMPXJOH FYBNQMF EFNPOTUSBUFT IPX UP DPOGJHVSF UIF QSPUPDPM SFHJTUSZ BOE VTF UIF SFHJTUFSFE QSPUPDPM JOGPSNBUJPO JO B SPVUF.
KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/keystore.jks"); ksp.setPassword("keystorePassword"); KeyManagersParameters kmp = new KeyManagersParameters(); kmp.setKeyStore(ksp); kmp.setKeyPassword("keyPassword"); SSLContextParameters scp = new SSLContextParameters(); scp.setKeyManagers(kmp); ProtocolSocketFactory factory = new SSLContextParametersSecureProtocolSocketFactory(scp); Protocol.registerProtocol("https", new Protocol( "https", factory, 443)); from("direct:start") .to("https://mail.google.com/mail/").to("mock:results");

714

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"LKCFDROFKD

M>@EB '33/ "IFBKQ #FOB@QIV

#BTJDBMMZ DBNFM-IUUQ DPNQPOFOU JT CVJMU PO UIF UPQ PG "QBDIF )551 DMJFOU, BOE ZPV DBO JNQMFNFOU B DVTUPN org.apache.camel.component.http.HttpClientConfigurer UP EP TPNF DPOGJHVSBUJPO PO UIF IUUQ DMJFOU JG ZPV OFFE GVMM DPOUSPM PG JU. )PXFWFS JG ZPV just XBOU UP TQFDJGZ UIF LFZTUPSF BOE USVTUTUPSF ZPV DBO EP UIJT XJUI "QBDIF )551 HttpClientConfigurer, GPS FYBNQMF:
Protocol authhttps = new Protocol("https", new AuthSSLProtocolSocketFactory( new URL("file:my.keystore"), "mypassword", new URL("file:my.truststore"), "mypassword"), 443); Protocol.registerProtocol("https", authhttps);

"OE UIFO ZPV OFFE UP DSFBUF B DMBTT UIBU JNQMFNFOUT HttpClientConfigurer, BOE SFHJTUFST IUUQT QSPUPDPM QSPWJEJOH B LFZTUPSF PS USVTUTUPSF QFS FYBNQMF BCPWF. 5IFO, GSPN ZPVS DBNFM SPVUF CVJMEFS DMBTT ZPV DBO IPPL JU VQ MJLF TP:
HttpComponent httpComponent = getContext().getComponent("http", HttpComponent.class); httpComponent.setHttpClientConfigurer(new MyHttpClientConfigurer());

*G ZPV BSF EPJOH UIJT VTJOH UIF 4QSJOH %4-, ZPV DBO TQFDJGZ ZPVS HttpClientConfigurer VTJOH UIF 63*. 'PS FYBNQMF:
<bean id="myHttpClientConfigurer" class="my.https.HttpClientConfigurer"> </bean> <to uri="https://myhostname.com:443/ myURL?httpClientConfigurerRef=myHttpClientConfigurer"/>

"T MPOH BT ZPV JNQMFNFOU UIF )UUQ$MJFOU$POGJHVSFS BOE DPOGJHVSF ZPVS LFZTUPSF BOE USVTUTUPSF BT EFTDSJCFE BCPWF, JU XJMM XPSL GJOF. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE +FUUZ

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

715

(! 3(2
5IF F?>QFP: DPNQPOFOU BMMPXT ZPV UP RVFSZ, QPMM, JOTFSU, VQEBUF BOE EFMFUF EBUB JO B SFMBUJPOBM EBUBCBTF VTJOH "QBDIF J#"5*4. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ibatis</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
ibatis:statementName[?options]

8IFSF PQ>QBJBKQ->JB JT UIF OBNF JO UIF J#"5*4 9.- DPOGJHVSBUJPO GJMF XIJDI NBQT UP UIF RVFSZ, JOTFSU, VQEBUF PS EFMFUF PQFSBUJPO ZPV XJTI UP FWBMVBUF. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 5IJT DPNQPOFOU XJMM CZ EFGBVMU MPBE UIF J#BUJT 4RM.BQ$POGJH GJMF GSPN UIF SPPU PG UIF DMBTTQBUI BOE FYQFDUFE OBNFE BT SqlMapConfig.xml. *U VTFT 4QSJOH SFTPVSDF MPBEJOH TP ZPV DBO EFGJOF JU VTJOH classpath, file PS http BT QSFGJY UP MPBE SFTPVSDFT XJUI UIPTF TDIFNFT. *O $BNFM 2.2 ZPV DBO DPOGJHVSF UIJT PO UIF J#BUJT$PNQPOFOU XJUI UIF setSqlMapConfig(String) NFUIPE. .MQFLKP
.MQFLK
consumer.onConsume

3VMB
String

#BC>RIQ
null

#BP@OFMQFLK
4UBUFNFOUT UP SVO BGUFS DPOTVNJOH. $BO CF VTFE, GPS FYBNQMF, UP VQEBUF SPXT BGUFS UIFZ IBWF CFFO DPOTVNFE BOE QSPDFTTFE JO $BNFM. 4FF TBNQMF MBUFS. .VMUJQMF TUBUFNFOUT DBO CF TFQBSBUFE XJUI DPNNB. *G true FBDI SPX SFUVSOFE XIFO QPMMJOH XJMM CF QSPDFTTFE JOEJWJEVBMMZ. *G false UIF FOUJSF List PG EBUB JT TFU BT UIF */ CPEZ. 4FUT XIFUIFS FNQUZ SFTVMU TFU TIPVME CF SPVUFE PS OPU. #Z EFGBVMU, FNQUZ SFTVMU TFUT BSF OPU SPVUFE. .BOEBUPSZ UP TQFDJGZ GPS *CBUJT1SPEVDFS UP DPOUSPM XIJDI J#BUJT SqlMapClient NFUIPE UP JOWPLF. 5IF FOVN WBMVFT BSF: QueryForObject, QueryForList, Insert, Update, Delete. "O JOUFHFS UP EFGJOF B NBYJNVN NFTTBHFT UP HBUIFS QFS QPMM. #Z EFGBVMU, OP NBYJNVN JT TFU. $BO CF VTFE UP TFU B MJNJU PG F.H. 1000 UP BWPJE XIFO TUBSUJOH VQ UIF TFSWFS UIBU UIFSF BSF UIPVTBOET PG GJMFT. 4FU B WBMVF PG 0 PS OFHBUJWF UP EJTBCMFE JU.

consumer.useIterator consumer.routeEmptyResultSet

boolean boolean

true false

statementType

StatementType

null

maxMessagesPerPoll

int

716

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

/OBCBO ,V!>QFP 5IF "QBDIF J#BUJT QSPKFDU JT OP MPOHFS BDUJWF. 5IF QSPKFDU JT NPWFE PVUTJEF "QBDIF BOE JT OPX LOPX BT UIF .Z#BUJT QSPKFDU. 5IFSFGPSF XF FODPVSBHF VTFST UP VTF .Z#BUJT JOTUFBE. 5IJT DBNFM-JCBUJT DPNQPOFOU XJMM CF SFNPWFE JO $BNFM 3.0.
">JBI 2.9: " 4USJOH UIF EFGJOFT UIF USBOTBDUJPO JTPMBUJPO MFWFM PG UIF XJMM CF VTFE. "MMPXFE WBMVFT BSF 53"/4"$5*0/@/0/&, 53"/4"$5*0/@3&"%@6/$0..*55&%, 53"/4"$5*0/@3&"%@$0..*55&%, 53"/4"$5*0/@3&1&"5"#-&@3&"%, 53"/4"$5*0/@4&3*"-*;"#-&

isolation

String

TRANSACTION_REPEATABLE_READ

isolation

String

TRANSACTION_REPEATABLE_READ

">JBI 2.9: " 4USJOH UIF EFGJOFT UIF USBOTBDUJPO JTPMBUJPO MFWFM PG UIF XJMM CF VTFE. "MMPXFE WBMVFT BSF 53"/4"$5*0/@/0/&, 53"/4"$5*0/@3&"%@6/$0..*55&%, 53"/4"$5*0/@3&"%@$0..*55&%, 53"/4"$5*0/@3&1&"5"#-&@3&"%, 53"/4"$5*0/@4&3*"-*;"#-&

,BPP>DB 'B>ABOP $BNFM XJMM QPQVMBUF UIF SFTVMU NFTTBHF, FJUIFS */ PS 065 XJUI B IFBEFS XJUI UIF PQFSBUJPO/BNF VTFE:
'B>ABO
CamelIBatisStatementName CamelIBatisResult

3VMB
String Object

#BP@OFMQFLK
5IF PQ>QBJBKQ->JB VTFE (GPS FYBNQMF: JOTFSU"DDPVOU). 5IF OBPMLKPB SFUVSOFE GSPN J#BUJT JO BOZ PG UIF PQFSBUJPOT. 'PS JOTUBODF BO INSERT DPVME SFUVSO UIF BVUP-HFOFSBUFE LFZ, PS OVNCFS PG SPXT FUD.

,BPP>DB !LAV 5IF SFTQPOTF GSPN J#BUJT XJMM POMZ CF TFU BT CPEZ JG JU'T B SELECT TUBUFNFOU. 5IBU NFBOT, GPS FYBNQMF, GPS INSERT TUBUFNFOUT $BNFM XJMM OPU SFQMBDF UIF CPEZ. 5IJT BMMPXT ZPV UP DPOUJOVF SPVUJOH BOE LFFQ UIF PSJHJOBM CPEZ. 5IF SFTQPOTF GSPN J#BUJT JT BMXBZT TUPSFE JO UIF IFBEFS XJUI UIF LFZ CamelIBatisResult. 2>JMIBP 'PS FYBNQMF JG ZPV XJTI UP DPOTVNF CFBOT GSPN B +.4 RVFVF BOE JOTFSU UIFN JOUP B EBUBCBTF ZPV DPVME EP UIF GPMMPXJOH:
from("activemq:queue:newAccount"). to("ibatis:insertAccount?statementType=Insert");

/PUJDF XF IBWF UP TQFDJGZ UIF statementType, BT XF OFFE UP JOTUSVDU $BNFM XIJDI SqlMapClient PQFSBUJPO UP JOWPLF. 8IFSF FKPBOQ @@LRKQ JT UIF J#BUJT *% JO UIF 42- NBQ GJMF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

717

<!-- Insert example, using the Account parameter class --> <insert id="insertAccount" parameterClass="Account"> insert into ACCOUNT ( ACC_ID, ACC_FIRST_NAME, ACC_LAST_NAME, ACC_EMAIL ) values ( #id#, #firstName#, #lastName#, #emailAddress# ) </insert>

4PFKD 2Q>QBJBKQ3VMB CLO ?BQQBO @LKQOLI LC (!>QFP 8IFO SPVUJOH UP BO J#BUJT FOEQPJOU ZPV XBOU NPSF GJOF HSBJOFE DPOUSPM TP ZPV DBO DPOUSPM XIFUIFS UIF 42- TUBUFNFOU UP CF FYFDVUFE JT B SELEECT, UPDATE, DELETE PS INSERT FUD. 4P GPS JOTUBODF JG XF XBOU UP SPVUF UP BO J#BUJT FOEQPJOU JO XIJDI UIF */ CPEZ DPOUBJOT QBSBNFUFST UP B SELECT TUBUFNFOU XF DBO EP:
from("direct:start") .to("ibatis:selectAccountById?statementType=QueryForObject") .to("mock:result");

*O UIF DPEF BCPWF XF DBO JOWPLF UIF J#BUJT TUBUFNFOU selectAccountById BOE UIF */ CPEZ TIPVME DPOUBJO UIF BDDPVOU JE XF XBOU UP SFUSJFWF, TVDI BT BO Integer UZQF. 8F DBO EP UIF TBNF GPS TPNF PG UIF PUIFS PQFSBUJPOT, TVDI BT QueryForList:
from("direct:start") .to("ibatis:selectAllAccounts?statementType=QueryForList") .to("mock:result");

"OE UIF TBNF GPS UPDATE, XIFSF XF DBO TFOE BO Account PCKFDU BT */ CPEZ UP J#BUJT:
from("direct:start") .to("ibatis:updateAccount?statementType=Update") .to("mock:result");

2@EBARIBA MLIIFKD BU>JMIB


4JODF UIJT DPNQPOFOU EPFT OPU TVQQPSU TDIFEVMFE QPMMJOH, ZPV OFFE UP VTF BOPUIFS NFDIBOJTN GPS USJHHFSJOH UIF TDIFEVMFE QPMMT, TVDI BT UIF 5JNFS PS 2VBSU[ DPNQPOFOUT.

718

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*O UIF TBNQMF CFMPX XF QPMM UIF EBUBCBTF, FWFSZ 30 TFDPOET VTJOH UIF 5JNFS DPNQPOFOU BOE TFOE UIF EBUB UP UIF +.4 RVFVF:

from("timer://pollTheDatabase?delay=30000").to("ibatis:selectAllAccounts?statementType=QueryForList").

"OE UIF J#BUJT 42- NBQ GJMF VTFE:


<!-- Select with no parameters using the result map for Account class. --> <select id="selectAllAccounts" resultMap="AccountResult"> select * from ACCOUNT </select>

4PFKD LK"LKPRJB
5IJT DPNQPOFOU TVQQPSUT FYFDVUJOH TUBUFNFOUT >CQBO EBUB IBWF CFFO DPOTVNFE BOE QSPDFTTFE CZ $BNFM. 5IJT BMMPXT ZPV UP EP QPTU VQEBUFT JO UIF EBUBCBTF. /PUJDF BMM TUBUFNFOUT NVTU CF UPDATE TUBUFNFOUT. $BNFM TVQQPSUT FYFDVUJOH NVMUJQMF TUBUFNFOUT XIPTF OBNF TIPVME CF TFQBSBUFE CZ DPNNB. 5IF SPVUF CFMPX JMMVTUSBUFT XF FYFDVUF UIF @LKPRJB @@LRKQ TUBUFNFOU EBUB JT QSPDFTTFE. 5IJT BMMPXT VT UP DIBOHF UIF TUBUVT PG UIF SPX JO UIF EBUBCBTF UP QSPDFTTFE, TP XF BWPJE DPOTVNJOH JU UXJDF PS NPSF.
from("ibatis:selectUnprocessedAccounts?consumer.onConsume=consumeAccount").to("mock:results");

"OE UIF TUBUFNFOUT JO UIF TRMNBQ GJMF:


<select id="selectUnprocessedAccounts" resultMap="AccountResult"> select * from ACCOUNT where PROCESSED = false </select>

<update id="consumeAccount" parameterClass="Account"> update ACCOUNT set PROCESSED = true where ACC_ID = #id# </update>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE .Z#BUJT

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

719

(1" ".,/.-$-3
5IF FO@ DPNQPOFOU JNQMFNFOUT BO *3$ (*OUFSOFU 3FMBZ $IBU) USBOTQPSU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-irc</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
irc:nick@host[:port]/#room[?options] irc:nick@host[:port]?channels=#channel1,#channel2,#channel3[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
channels nickname username password realname colors onReply onNick onQuit onJoin onKick onMode onPart onTopic onPrivmsg

#BP@OFMQFLK
$PNNB TFQBSBUFE MJTU PG *3$ DIBOOFMT UP KPJO. 5IF OJDLOBNF VTFE JO DIBU. 5IF *3$ TFSWFS VTFS OBNF. 5IF *3$ TFSWFS QBTTXPSE. 5IF *3$ VTFS'T BDUVBM OBNF. 8IFUIFS PS OPU UIF TFSWFS TVQQPSUT DPMPS DPEFT. 8IFUIFS PS OPU UP IBOEMF HFOFSBM SFTQPOTFT UP DPNNBOET PS JOGPSNBUJPOBM NFTTBHFT. )BOEMF OJDLOBNF DIBOHF FWFOUT. )BOEMF VTFS RVJU FWFOUT. )BOEMF VTFS KPJO FWFOUT. )BOEMF LJDL FWFOUT. )BOEMF NPEF DIBOHF FWFOUT. )BOEMF VTFS QBSU FWFOUT. )BOEMF UPQJD DIBOHF FWFOUT. )BOEMF NFTTBHF FWFOUT.

$U>JMIB
channels=#channel1,#channel2 irc:MyNick@irc.server.org#channel PS irc:irc.server.org#channel?nickname=MyUser irc:MyUser@irc.server.org#channel PS irc:irc.server.org#channel?username=MyUser password=somepass realname=MyName true, false true, false true, false true, false true, false true, false true, false true, false true, false true, false

#BC>RIQ 5>IRB
null null 4BNF BT OJDLOBNF. None None true false true true true true true true true true 5IF EFGBVMU USVTU NBOBHFS, XIJDI BDDFQUT all DFSUJGJDBUFT, XJMM CF VTFE.

trustManager

5IF USVTU NBOBHFS VTFE UP WFSJGZ UIF 44- TFSWFS'T DFSUJGJDBUF.

trustManager=#referenceToTrustManagerBean

720

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

keys

">JBI 2.2: $PNNB TFQBSBUFE MJTU PG *3$ DIBOOFM LFZT. *NQPSUBOU UP CF MJTUFE JO TBNF PSEFS BT DIBOOFMT. 8IFO KPJOJOH NVMUJQMF DIBOOFMT XJUI POMZ TPNF OFFEJOH LFZT KVTU JOTFSU BO FNQUZ WBMVF GPS UIBU DIBOOFM. ">JBI 2.9: 3FGFSFODF UP B org.apache.camel.util.jsse.SSLContextParameters JO UIF 3FHJTUSZ.c 5IJT SFGFSFODF PWFSSJEFT BOZ DPOGJHVSFE 44-$POUFYU1BSBNFUFST BU UIF DPNQPOFOU MFWFM.c 4FF 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ.c /PUF UIBU UIJT TFUUJOH PWFSSJEFT UIF USVTU.BOBHFS PQUJPO.

irc:MyNick@irc.server.org/#channel?keys=chankey

null

TTM$POUFYU1BSBNFUFST

#NZ4TM$POUFYU1BSBNFUFST

null

22+ 2RMMLOQ

4PFKD QEB )22$ "LKCFDRO>QFLK 4QFIFQV


"T PG $BNFM 2.9, UIF *3$ DPNQPOFOU TVQQPSUT 44-/5-4 DPOGJHVSBUJPO UISPVHI UIF $BNFM +44& $POGJHVSBUJPO 6UJMJUZ.c 5IJT VUJMJUZ HSFBUMZ EFDSFBTFT UIF BNPVOU PG DPNQPOFOU TQFDJGJD DPEF ZPV OFFE UP XSJUF BOE JT DPOGJHVSBCMF BU UIF FOEQPJOU BOE DPNQPOFOU MFWFMT.c 5IF GPMMPXJOH FYBNQMFT EFNPOTUSBUF IPX UP VTF UIF VUJMJUZ XJUI UIF *3$ DPNQPOFOU. /OLDO>JJ>QF@ @LKCFDRO>QFLK LC QEB BKAMLFKQ
KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/truststore.jks"); ksp.setPassword("keystorePassword"); TrustManagersParameters tmp = new TrustManagersParameters(); tmp.setKeyStore(ksp); SSLContextParameters scp = new SSLContextParameters(); scp.setTrustManagers(tmp); Registry registry = ... registry.bind("sslContextParameters", scp); ... from(...)

.to("ircs://camel-prd-user@server:6669/#camel-test?nickname=camel-prd&password=password&sslContextPara

2MOFKD #2+ ?>PBA @LKCFDRO>QFLK LC BKAMLFKQ


... <camel:sslContextParameters id="sslContextParameters"> <camel:trustManagers>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

721

<camel:keyStore resource="/users/home/server/truststore.jks" password="keystorePassword"/> </camel:keyManagers> </camel:sslContextParameters>... ... <to uri="ircs://camel-prd-user@server:6669/#camel-test?nickname=camel-prd&password=password&sslContextPara

4PFKD QEB IBD>@V ?>PF@ @LKCFDRO>QFLK LMQFLKP


:PV DBO BMTP DPOOFDU UP BO 44- FOBCMFE *3$ TFSWFS, BT GPMMPXT:
ircs:host[:port]/#room?username=user&password=pass

#Z EFGBVMU, UIF *3$ USBOTQPSU VTFT 44-%FGBVMU5SVTU.BOBHFS. *G ZPV OFFE UP QSPWJEF ZPVS PXO DVTUPN USVTU NBOBHFS, VTF UIF trustManager QBSBNFUFS BT GPMMPXT:
ircs:host[:port]/#room?username=user&password=pass&trustManager=#referenceToMyTrustManagerBean

4PFKD HBVP S>FI>?IB >P LC ">JBI 2.2 4PNF JSD SPPNT SFRVJSFT ZPV UP QSPWJEF B LFZ UP CF BCMF UP KPJO UIBU DIBOOFM. 5IF LFZ JT KVTU B TFDSFU XPSE. 'PS FYBNQMF XF KPJO 3 DIBOOFMT XIFSF BT POMZ DIBOOFM 1 BOE 3 VTFT B LFZ.
irc:nick@irc.server.org?channels=#chan1,#chan2,#chan3&keys=chan1Key,,chan3key

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

) 28/3 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.5

722

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

+BTZQU JT B TJNQMJGJFE FODSZQUJPO MJCSBSZ XIJDI NBLFT FODSZQUJPO BOE EFDSZQUJPO FBTZ. $BNFM JOUFHSBUFT XJUI +BTZQU UP BMMPX TFOTJUJWF JOGPSNBUJPO JO 1SPQFSUJFT GJMFT UP CF FODSZQUFE. #Z ESPQQJOH camel-jasypt PO UIF DMBTTQBUI UIPTF FODSZQUFE WBMVFT XJMM BVUPNBUJD CF EFDSZQUFE PO-UIF-GMZ CZ $BNFM. 5IJT FOTVSFT UIBU IVNBO FZFT DBO'U FBTJMZ TQPU TFOTJUJWF JOGPSNBUJPO TVDI BT VTFSOBNFT BOE QBTTXPSET. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jasypt</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

3LLIFKD 5IF +BTZQU DPNQPOFOU QSPWJEFT B MJUUMF DPNNBOE MJOF UPPMJOH UP FODSZQU PS EFDSZQU WBMVFT. 5IF DPOTPMF PVUQVU UIF TZOUBY BOE XIJDI PQUJPOT JU QSPWJEFT:
Apache Camel Jasypt takes the following options -h -c -p -i -a or or or or or -help = Displays the help screen -command <command> = Command either encrypt or decrypt -password <password> = Password to use -input <input> = Text to encrypt or decrypt -algorithm <algorithm> = Optional algorithm to use

'PS FYBNQMF UP FODSZQU UIF WBMVF tiger ZPV SVO XJUI UIF GPMMPXJOH QBSBNFUFST. *O UIF BQBDIF DBNFM LJU, ZPV DE JOUP UIF MJC GPMEFS BOE SVO UIF GPMMPXJOH KBWB DNE, XIFSF <CAMEL_HOME> JT XIFSF ZPV IBWF EPXOMPBEFE BOE FYUSBDU UIF $BNFM EJTUSJCVUJPO.
$ cd <CAMEL_HOME>/lib $ java -jar camel-jasypt-2.5.0.jar -c encrypt -p secret -i tiger

8IJDI PVUQVUT UIF GPMMPXJOH SFTVMU


Encrypted text: qaEEacuW7BUti8LcMgyjKw==

5IJT NFBOT UIF FODSZQUFE SFQSFTFOUBUJPO qaEEacuW7BUti8LcMgyjKw== DBO CF EFDSZQUFE CBDL UP tiger JG ZPV LOPX UIF NBTUFS QBTTXPSE XIJDI XBT secret. *G ZPV SVO UIF UPPM BHBJO UIFO UIF FODSZQUFE WBMVF XJMM SFUVSO B EJGGFSFOU SFTVMU. #VU EFDSZQUJOH UIF WBMVF XJMM BMXBZT SFUVSO UIF DPSSFDU PSJHJOBM WBMVF. 4P ZPV DBO UFTU JU CZ SVOOJOH UIF UPPMJOH VTJOH UIF GPMMPXJOH QBSBNFUFST:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

723

$ cd <CAMEL_HOME>/lib $ java -jar camel-jasypt-2.5.0.jar -c decrypt -p secret -i qaEEacuW7BUti8LcMgyjKw==

8IJDI PVUQVUT UIF GPMMPXJOH SFTVMU:


Decrypted text: tiger

5IF JEFB JT UIFO UP VTF UIPTF FODSZQUFE WBMVFT JO ZPVS 1SPQFSUJFT GJMFT. /PUJDF IPX UIF QBTTXPSE WBMVF JT FODSZQUFE BOE UIF WBMVF IBT UIF UPLFOT TVSSPVOEJOH ENC(value here)
# refer to a mock endpoint name by that encrypted password cool.result=mock:{{cool.password}} # here is a password which is encrypted cool.password=ENC(bsW9uV37gQ0QHFu7KO03Ww==)

3LLIFKD ABMBKABK@FBP CLO ">JBI 2.5 >KA 2.6


5IF UPPMJOH SFRVJSFT UIF GPMMPXJOH +"3T JO UIF DMBTTQBUI, XIJDI IBT CFFO FOMJTUFE JO UIF MANIFEST.MF GJMF PG camel-jasypt XJUI optional/ BT QSFGJY. )FODF XIZ UIF KBWB DNE BCPWF DBO QJDLVQ UIF OFFEFE +"3T GSPN UIF "QBDIF %JTUSJCVUJPO JO UIF optional EJSFDUPSZ.
jasypt-1.6.jar commons-lang-2.4.jar commons-codec-1.4.jar icu4j-4.0.1.jar

3LLIFKD ABMBKABK@FBP CLO ">JBI 2.7 LO ?BQQBO


+BTZQU 1.7 POXBSET JT OPX GVMMZ TUBOEBMPOF TP OP BEEJUJPOBM +"3T JT OFFEFE. 41( .MQFLKP 5IF PQUJPOT CFMPX BSF FYDMVTJWF GPS UIF +BTZQU DPNQPOFOU.
->JB
password algorithm

#BC>RIQ 5>IRB
null null

3VMB
String String

#BP@OFMQFLK
4QFDJGJFT UIF NBTUFS QBTTXPSE UP VTF GPS EFDSZQUJOH. 5IJT PQUJPO JT NBOEBUPSZ. 4FF CFMPX GPS NPSF EFUBJMT. /BNF PG BO PQUJPOBM BMHPSJUIN UP VTF.

/OLQB@QFKD QEB J>PQBO M>PPTLOA 5IF NBTUFS QBTTXPSE VTFE CZ +BTZQU NVTU CF QSPWJEFE, TP JUT DBQBCMF PG EFDSZQUJOH UIF WBMVFT. )PXFWFS IBWJOH UIJT NBTUFS QBTTXPSE PVU JO UIF PQFOJOH NBZ OPU CF BO JEFBM TPMVUJPO. 5IFSFGPSF ZPV DPVME GPS FYBNQMF QSPWJEFE JU BT B +7. TZTUFN QSPQFSUZ PS BT B 04 FOWJSPONFOU

724

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)>S> 1.5 RPBOP 5IF icu4j-4.0.1.jar JT POMZ OFFEFE XIFO SVOOJOH PO +%, 1.5.
5IJT +"3 JT OPU EJTUSJCVUFE CZ "QBDIF $BNFM BOE ZPV IBWF UP EPXOMPBE JU NBOVBMMZ BOE DPQZ JU UP UIF lib/optional EJSFDUPSZ PG UIF $BNFM EJTUSJCVUJPO. :PV DBO EPXOMPBE JU GSPN "QBDIF $FOUSBM .BWFO SFQP.

TFUUJOH. *G ZPV EFDJEF UP EP TP UIFO UIF password PQUJPO TVQQPSUT QSFGJYFT XIJDI EJDUBUFT UIJT. sysenv: NFBOT UP MPPLVQ UIF 04 TZTUFN FOWJSPONFOU XJUI UIF HJWFO LFZ. sys: NFBOT UP MPPLVQ B +7. TZTUFN QSPQFSUZ. 'PS FYBNQMF ZPV DPVME QSPWJEFE UIF QBTTXPSE CFGPSF ZPV TUBSU UIF BQQMJDBUJPO
$ export CAMEL_ENCRYPTION_PASSWORD=secret

5IFO TUBSU UIF BQQMJDBUJPO, TVDI BT SVOOJOH UIF TUBSU TDSJQU. 8IFO UIF BQQMJDBUJPO JT VQ BOE SVOOJOH ZPV DBO VOTFU UIF FOWJSPONFOU
$ unset CAMEL_ENCRYPTION_PASSWORD

5IF password PQUJPO JT UIFO B NBUUFS PG EFGJOJOH BT GPMMPXT: password=sysenv:CAMEL_ENCRYPTION_PASSWORD. $U>JMIB TFQE )>S> #2+ *O +BWB %4- ZPV OFFE UP DPOGJHVSF +BTZQU BT B JasyptPropertiesParser JOTUBODF BOE TFU JU PO UIF 1SPQFSUJFT DPNQPOFOU BT TIPX CFMPX:
// create the jasypt properties parser JasyptPropertiesParser jasypt = new JasyptPropertiesParser(); // and set the master password jasypt.setPassword("secret"); // create the properties component PropertiesComponent pc = new PropertiesComponent(); pc.setLocation("classpath:org/apache/camel/component/jasypt/myproperties.properties"); // and use the jasypt properties parser so we can decrypt values pc.setPropertiesParser(jasypt); // add properties component to camel context context.addComponent("properties", pc);

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

725

5IF QSPQFSUJFT GJMF myproperties.properties UIFO DPOUBJO UIF FODSZQUFE WBMVF, TVDI BT TIPXO CFMPX. /PUJDF IPX UIF QBTTXPSE WBMVF JT FODSZQUFE BOE UIF WBMVF IBT UIF UPLFOT TVSSPVOEJOH ENC(value here)
# refer to a mock endpoint name by that encrypted password cool.result=mock:{{cool.password}} # here is a password which is encrypted cool.password=ENC(bsW9uV37gQ0QHFu7KO03Ww==)

$U>JMIB TFQE 2MOFKD 7,+ *O 4QSJOH 9.- ZPV OFFE UP DPOGJHVSF UIF JasyptPropertiesParser XIJDI JT TIPXO CFMPX. 5IFO UIF $BNFM 1SPQFSUJFT DPNQPOFOU JT UPME UP VTF jasypt BT UIF QSPQFSUJFT QBSTFS, XIJDI NFBOT +BTZQU IBWF JUT DIBODF UP EFDSZQU WBMVFT MPPLFE VQ JO UIF QSPQFSUJFT.
<!-- define the jasypt properties parser with the given password to be used --> <bean id="jasypt" class="org.apache.camel.component.jasypt.JasyptPropertiesParser"> <property name="password" value="secret"/> </bean> <!-- define the camel properties component --> <bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent"> <!-- the properties file is in the classpath --> <property name="location" value="classpath:org/apache/camel/component/jasypt/ myproperties.properties"/> <!-- and let it leverage the jasypt parser --> <property name="propertiesParser" ref="jasypt"/> </bean>

5IF 1SPQFSUJFT DPNQPOFOU DBO BMTP CF JOMJOFE JOTJEF UIF <camelContext> UBH XIJDI JT TIPXO CFMPX. /PUJDF IPX XF VTF UIF propertiesParserRef BUUSJCVUF UP SFGFS UP +BTZQU.
<!-- define the jasypt properties parser with the given password to be used --> <bean id="jasypt" class="org.apache.camel.component.jasypt.JasyptPropertiesParser"> <!-- password is mandatory, you can prefix it with sysenv: or sys: to indicate it should use an OS environment or JVM system property value, so you dont have the master password defined here --> <property name="password" value="secret"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- define the camel properties placeholder, and let it leverage jasypt --> <propertyPlaceholder id="properties" location="classpath:org/apache/camel/component/jasypt/ myproperties.properties"

726

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

propertiesParserRef="jasypt"/> <route> <from uri="direct:start"/> <to uri="{{cool.result}}"/> </route> </camelContext>

2BB

IPL 4FDVSJUZ 1SPQFSUJFT &ODSZQUFE QBTTXPSET JO "DUJWF.2 - "DUJWF.2 IBT B TJNJMBS GFBUVSF BT UIJT cameljasypt DPNQPOFOU

) 5 2/ "$ ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.1 5IF G>S>PM>@B DPNQPOFOU JT B USBOTQPSU GPS XPSLJOH XJUI BOZ +BWB4QBDF DPNQMJBOU JNQMFNFOUBUJPO BOE UIJT DPNQPOFOU IBT CFFO UFTUFE XJUI CPUI UIF #MJU[ JNQMFNFOUBUJPO BOE UIF (JHB4QBDF JNQMFNFOUBUJPO . 5IJT DPNQPOFOU DBO CF VTFE GPS TFOEJOH BOE SFDFJWJOH BOZ PCKFDU JOIFSJUJOH GSPN UIF +JOJ net.jini.core.entry.Entry DMBTT. *U JT BMTP QPTTJCMF UP QBTT UIF CFBO *% PG B UFNQMBUF UIBU DBO CF VTFE GPS SFBEJOH/UBLJOH UIF FOUSJFT GSPN UIF TQBDF. 5IJT DPNQPOFOU DBO CF VTFE GPS TFOEJOH/SFDFJWJOH BOZ TFSJBMJ[BCMF PCKFDU BDUJOH BT B TPSU PG HFOFSJD USBOTQPSU. 5IF +BWB4QBDF DPNQPOFOU DPOUBJOT B TQFDJBM PQUJNJ[BUJPO GPS EFBMJOH XJUI UIF BeanExchange. *U DBO CF VTFE UP JOWPLF B 10+0 SFNPUFMZ, VTJOH B +BWB4QBDF BT B USBOTQPSU. 5IJT MBUUFS GFBUVSF DBO QSPWJEF B TJNQMF JNQMFNFOUBUJPO PG UIF NBTUFS/XPSLFS QBUUFSO, XIFSF B 10+0 QSPWJEFT UIF CVTJOFTT MPHJD GPS UIF XPSLFS. -PPL BU UIF UFTU DBTFT GPS FYBNQMFT PG WBSJPVT VTF DBTFT GPS UIJT DPNQPOFOU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-javaspace</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

727

41( CLOJ>Q
javaspace:jini://host[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
spaceName verb transactional transactionalTimeout concurrentConsumers templateId

#BC>RIQ 5>IRB
null take false Long.MAX_VALUE 1 null

#BP@OFMQFLK
4QFDJGJFT UIF +BWB4QBDF OBNF. 4QFDJGJFT UIF WFSC GPS HFUUJOH +BWB4QBDF FOUSJFT. 5IF WBMVFT DBO CF: take PS read. *G true, TFOEJOH BOE SFDFJWJOH FOUSJFT JT QFSGPSNFE XJUIJO B USBOTBDUJPO. 4QFDJGJFT UIF USBOTBDUJPO UJNFPVU. 4QFDJGJFT UIF OVNCFS PG DPODVSSFOU DPOTVNFST HFUUJOH FOUSJFT GSPN UIF +BWB4QBDF. *G QSFTFOU, UIJT PQUJPO TQFDJGJFT UIF 4QSJOH CFBO *% PG UIF UFNQMBUF UP VTF GPS SFBEJOH/UBLJOH FOUSJFT.

$U>JMIBP

2BKAFKD >KA 1B@BFSFKD $KQOFBP


// sending route from("direct:input") .to("javaspace:jini://localhost?spaceName=mySpace");

// receiving Route from("javaspace:jini://localhost?spaceName=mySpace&templateId=template&verb=take&concurrentConsumers=1 .to("mock:foo");

*O UIJT DBTF UIF QBZMPBE DBO CF BOZ PCKFDU UIBU JOIFSJUT GSPN UIF +JOJ Entry UZQF.

2BKAFKD >KA OB@BFSFKD PBOF>IFW>?IB L?GB@QP


6TJOH UIF QSFDFEJOH SPVUFT, JU JT BMTP QPTTJCMF UP TFOE BOE SFDFJWF BOZ TFSJBMJ[BCMF PCKFDU. 5IF +BWB4QBDF DPNQPOFOU EFUFDUT UIBU UIF QBZMPBE JT OPU B +JOJ Entry BOE UIFO JU BVUPNBUJDBMMZ XSBQT UIF QBZMPBE XJUI B $BNFM +JOJ Entry. *O UIJT XBZ, B +BWB4QBDF DBO CF VTFE BT B HFOFSJD USBOTQPSU NFDIBOJTN.

728

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD )>S>2M>@B >P > OBJLQB FKSL@>QFLK QO>KPMLOQ


5IF +BWB4QBDF DPNQPOFOU IBT CFFO UBJMPSFE UP XPSL JO DPNCJOBUJPO XJUI UIF $BNFM CFBO DPNQPOFOU. *U JT UIFSFGPSF QPTTJCMF UP DBMM B SFNPUF 10+0 VTJOH +BWB4QBDF BT UIF USBOTQPSU:
// client side from("direct:input") .to("javaspace:jini://localhost?spaceName=mySpace"); // server side from("javaspace:jini://localhost?concurrentConsumers=10&spaceName=mySpace") .to("mock:foo");

*O UIF DPEF UIFSF BSF UXP UFTU DBTFT TIPXJOH IPX UP VTF B 10+0 UP SFBMJ[F UIF NBTUFS/XPSLFS QBUUFSO. 5IF JEFB JT UP VTF UIF 10+0 UP QSPWJEF UIF CVTJOFTT MPHJD BOE SFMZ PO $BNFM GPS TFOEJOH/SFDFJWJOH SFRVFTUT/SFQMJFT XJUI UIF QSPQFS DPSSFMBUJPO. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

)!( ".,/.-$-3
5IF G?F DPNQPOFOU JT JNQMFNFOUFE CZ UIF 4FSWJDF.JY $BNFM NPEVMF BOE QSPWJEFT JOUFHSBUJPO XJUI B +#* /PSNBMJ[FE .FTTBHF 3PVUFS, TVDI BT UIF POF QSPWJEFE CZ "QBDIF 4FSWJDF.JY. 5IF GPMMPXJOH DPEF:
from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")

"VUPNBUJDBMMZ FYQPTFT B OFX FOEQPJOU UP UIF CVT, XIFSF UIF TFSWJDF 2/BNF JT \http://foo.bar.org}MyService BOE UIF FOEQPJOU OBNF JT MyEndpoint (TFF 63*GPSNBU). 8IFO B +#* FOEQPJOU BQQFBST BU UIF FOE PG B SPVUF, GPS FYBNQMF:
to("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")

5IF NFTTBHFT TFOU CZ UIJT QSPEVDFS FOEQPJOU BSF TFOU UP UIF BMSFBEZ EFQMPZFE +#* FOEQPJOU.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

729

4FF CFMPX GPS JOGPSNBUJPO BCPVU IPX UP VTF StreamSource UZQFT GSPN 4FSWJDF.JY JO $BNFM. 41( CLOJ>Q
jbi:service:serviceNamespace[sep]serviceName[?options] jbi:endpoint:serviceNamespace[sep]serviceName[sep]endpointName[?options] jbi:name:endpointName[?options]

5IF TFQBSBUPS UIBU TIPVME CF VTFE JO UIF FOEQPJOU 63- JT: ` / (GPSXBSE TMBTI), JG serviceNamespace TUBSUT XJUI http://, PS ` : (DPMPO), JG serviceNamespace TUBSUT XJUI urn:foo:bar. 'PS NPSF EFUBJMT PG WBMJE +#* 63*T TFF UIF 4FSWJDF.JY 63* (VJEF. 6TJOH UIF jbi:service: PS jbi:endpoint: 63* GPSNBUT TFUT UIF TFSWJDF 2/BNF PO UIF +#* FOEQPJOU UP UIF POF TQFDJGJFE. 0UIFSXJTF, UIF EFGBVMU $BNFM +#* 4FSWJDF 2/BNF JT VTFE, XIJDI JT:
{http://activemq.apache.org/camel/schema/jbi}endpoint

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

$U>JMIBP
jbi:service:http://foo.bar.org/MyService jbi:endpoint:urn:foo:bar:MyService:MyEndpoint jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint jbi:name:cheese

41( LMQFLKP ->JB #BC>RIQ S>IRB .&1 PG UIF $BNFM &YDIBOHF #BP@OFMQFLK "MMPXT VTFST UP PWFSSJEF UIF .&1 TFU PO UIF &YDIBOHF PCKFDU. 7BMJE WBMVFT GPS UIJT PQUJPO BSF in-only, in-out, robustin-out BOE in-optional-out.

mep

730

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

operation

7BMVF PG UIF jbi.operation IFBEFS QSPQFSUZ

4QFDJGJFT UIF +#* PQFSBUJPO GPS UIF MessageExchange. *G OP WBMVF JT TVQQMJFE, UIF +#* CJOEJOH XJMM VTF UIF WBMVF PG UIF jbi.operation IFBEFS QSPQFSUZ. %FGBVMU WBMVF (basic) XJMM DIFDL JG IFBEFST BSF TFSJBMJ[BCMF CZ MPPLJOH BU UIF UZQF, TFUUJOH UIJT PQUJPO UP strict XJMM EFUFDU PCKFDUT UIBU DBO OPU CF TFSJBMJ[FE BMUIPVHI UIFZ JNQMFNFOU UIF Serializable JOUFSGBDF. 4FU UP nocheck UP EJTBCMF UIJT DIFDL BMUPHFUIFS, OPUF UIBU UIJT TIPVME POMZ CF VTFE GPS JO-NFNPSZ USBOTQPSUT MJLF 4&%"'MPX, PUIFSXJTF ZPV DBO FYQFDU UP HFU NotSerializableException UISPXO BU SVOUJNF. false: TFOE BOZ FYDFQUJPOT UISPXO GSPN UIF $BNFM SPVUF CBDL VONPEJGJFE true: DPOWFSU BMM FYDFQUJPOT UP B +#* 'BVMU&YDFQUJPO (DBO CF VTFE UP BWPJE OPOTFSJBMJ[BCMF FYDFQUJPOT PS UP JNQMFNFOU HFOFSJD FSSPS IBOEMJOH

serialization

basic

convertException

false

$U>JMIBP
jbi:service:http://foo.bar.org/MyService?mep=in-out (override the MEP, use InOut JBI MessageExchanges) jbi:endpoint:urn:foo:bar:MyService:MyEndpoint?mep=in (override the MEP, use InOnly JBI MessageExchanges) jbi:endpoint:urn:foo:bar:MyService:MyEndpoint?operation={http://www.mycompany.org}AddNumbers (overide the operation for the JBI Exchange to {http://www.mycompany.org}AddNumbers)

4PFKD 2QOB>J ?LAFBP *G ZPV BSF VTJOH B TUSFBN UZQF BT UIF NFTTBHF CPEZ, ZPV TIPVME CF BXBSF UIBU B TUSFBN JT POMZ DBQBCMF PG CFJOH SFBE PODF. 4P JG ZPV FOBCMF DEBUG MPHHJOH, UIF CPEZ JT VTVBMMZ MPHHFE BOE UIVT SFBE. 5P EFBM XJUI UIJT, $BNFM IBT B streamCaching PQUJPO UIBU DBO DBDIF UIF TUSFBN, FOBCMJOH ZPV UP SFBE JU NVMUJQMF UJNFT.
from("jbi:endpoint:http://foo.bar.org/MyService/ MyEndpoint").streamCaching().to("xslt:transform.xsl", "bean:doSomething");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

731

5IF TUSFBN DBDIJOH JT EFGBVMU FOBCMFE, TP JU JT OPU OFDFTTBSZ UP TFU UIF streamCaching() PQUJPO. 8F TUPSF CJH JOQVU TUSFBNT (CZ EFGBVMU, PWFS 64,) JO B temp GJMF VTJOH CachedOutputStream. 8IFO ZPV DMPTF UIF JOQVU TUSFBN, UIF UFNQ GJMF XJMM CF EFMFUFE. "OB>QFKD > )!( 2BOSF@B 4KFQ *G ZPV IBWF TPNF $BNFM SPVUFT UIBU ZPV XBOU UP EFQMPZ JOTJEF +#* BT B 4FSWJDF 6OJU, ZPV DBO VTF UIF +#* 4FSWJDF 6OJU "SDIFUZQF UP DSFBUF B OFX .BWFO QSPKFDU GPS UIF 4FSWJDF 6OJU. *G ZPV IBWF BO FYJTUJOH .BWFO QSPKFDU UIBU ZPV OFFE UP DPOWFSU JOUP B +#* 4FSWJDF 6OJU, ZPV NBZ XBOU UP DPOTVMU 4FSWJDF.JY .BWFO +#* 1MVHJOT GPS GVSUIFS IFMQ. 5IF LFZ TUFQT BSF BT GPMMPXT: ` $SFBUF B 4QSJOH 9.- GJMF BU src/main/resources/camel-context.xml UP CPPUTUSBQ ZPVS SPVUFT JOTJEF UIF +#* 4FSWJDF 6OJU. ` $IBOHF UIF 10. GJMF'T QBDLBHJOH UP jbi-service-unit. :PVS pom.xml TIPVME MPPL TPNFUIJOH MJLF UIJT UP FOBCMF UIF jbi-service-unit QBDLBHJOH:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/ maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>myGroupId</groupId> <artifactId>myArtifactId</artifactId> <packaging>jbi-service-unit</packaging> <version>1.0-SNAPSHOT</version> <name>A Camel based JBI Service Unit</name> <url>http://www.myorganization.org</url> <properties> <camel-version>x.x.x</camel-version> <servicemix-version>3.3</servicemix-version> </properties> <dependencies> <dependency> <groupId>org.apache.servicemix</groupId> <artifactId>servicemix-camel</artifactId> <version>${servicemix-version}</version> </dependency> <dependency> <groupId>org.apache.servicemix</groupId> <artifactId>servicemix-core</artifactId> <version>${servicemix-version}</version>

732

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<scope>provided</scope> </dependency> </dependencies> <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.5</source> <target>1.5</target> </configuration> </plugin> <!-- creates the JBI deployment unit --> <plugin> <groupId>org.apache.servicemix.tooling</groupId> <artifactId>jbi-maven-plugin</artifactId> <version>${servicemix-version}</version> <extensions>true</extensions> </plugin> </plugins> </build> </project>

2BB

IPL ` ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4FSWJDF.JY $BNFM NPEVMF 6TJOH $BNFM XJUI 4FSWJDF.JY $PPLCPPL PO VTJOH $BNFM XJUI 4FSWJDF.JY

)"1 ".,/.-$-3
5IF jcr DPNQPOFOU BMMPXT ZPV UP BEE/SFBE OPEFT UP/GSPN B +$3 DPNQMJBOU DPOUFOU SFQPTJUPSZ (GPS FYBNQMF, "QBDIF +BDLSBCCJU) XJUI JUT QSPEVDFS, PS SFHJTUFS BO &WFOU-JTUFOFS XJUI UIF DPOTVNFS. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

733

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jcr</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
jcr://user:password@repository/path/to/node

4P>DB 5IF repository FMFNFOU PG UIF 63* JT VTFE UP MPPL VQ UIF +$3 Repository PCKFDU JO UIF $BNFM DPOUFYU SFHJTUSZ.

/OLAR@BO
->JB
CamelJcrOperation CamelJcrNodeName

#BC>RIQ 5>IRB
CamelJcrInsert null

#BP@OFMQFLK
$BNFM+DS*OTFSU PS $BNFM+DS(FU#Z*E PQFSBUJPO UP VTF 6TFE UP EFUFSNJOF UIF OPEF OBNF UP VTF.

8IFO B NFTTBHF JT TFOU UP B +$3 QSPEVDFS FOEQPJOU: ` *G UIF PQFSBUJPO JT $BNFM+DS*OTFSU: " OFX OPEF JT DSFBUFE JO UIF DPOUFOU SFQPTJUPSZ, BMM UIF NFTTBHF QSPQFSUJFT PG UIF */ NFTTBHF BSF USBOTGPSNFE UP +$3 Value JOTUBODFT BOE BEEFE UP UIF OFX OPEF BOE UIF OPEF'T 66*% JT SFUVSOFE JO UIF 065 NFTTBHF. ` *G UIF PQFSBUJPO JT $BNFM+DS(FU#Z*E: " OFX OPEF JT SFUSJFWFE GSPN UIF SFQPTJUPSZ VTJOH UIF NFTTBHF CPEZ BT OPEF JEFOUJGJFS.

"LKPRJBO
5IF DPOTVNFS XJMM DPOOFDU UP +$3 QFSJPEJDBMMZ BOE SFUVSO B -JTU<KBWBY.KDS.PCTFSWBUJPO.&WFOU> JO UIF NFTTBHF CPEZ.
->JB
eventTypes deep uuids nodeTypeNames

#BC>RIQ 5>IRB
0 false null null

#BP@OFMQFLK
" DPNCJOBUJPO PG POF PS NPSF FWFOU UZQFT FODPEFE BT B CJU NBTL WBMVF TVDI BT KBWBY.KDS.PCTFSWBUJPO.&WFOU./0%&@"%%&%, KBWBY.KDS.PCTFSWBUJPO.&WFOU./0%&@3&.07&%, FUD. 8IFO JU JT USVF, FWFOUT XIPTF BTTPDJBUFE QBSFOU OPEF JT BU DVSSFOU QBUI PS XJUIJO JUT TVCHSBQI BSF SFDFJWFE. 0OMZ FWFOUT XIPTF BTTPDJBUFE QBSFOU OPEF IBT POF PG UIF JEFOUJGJFST JO UIF DPNNB TFQBSBUFE VVJE MJTU XJMM CF SFDFJWFE. 0OMZ FWFOUT XIPTF BTTPDJBUFE QBSFOU OPEF IBT POF PG UIF OPEF UZQFT (PS B TVCUZQF PG POF PG UIF OPEF UZQFT) JO UIJT MJTU XJMM CF SFDFJWFE.

734

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"LKPRJBO >AABA 'SPN ">JBI 2.10 POXBSET ZPV DBO VTF DPOTVNFS BT BO &WFOU-JTUFOFS JO +$3 PS B QSPEVDFS UP SFBE B OPEF CZ JEFOUJGJFS.
*G noLocal JT true, UIFO FWFOUT HFOFSBUFE CZ UIF TFTTJPO UISPVHI XIJDI UIF MJTUFOFS XBT SFHJTUFSFE BSF JHOPSFE. 0UIFSXJTF, UIFZ BSF OPU JHOPSFE. *OUFSWBM JO NJMMJTFDPOET UP XBJU CFGPSF FBDI TFTTJPO MJWF DIFDLJOH. *OUFSWBM JO NJMMJTFDPOET UP XBJU CFGPSF UIF GJSTU TFTTJPO MJWF DIFDLJOH.

noLocal sessionLiveCheckInterval sessionLiveCheckIntervalOnStart

false 60000 3000

$U>JMIB 5IF TOJQQFU CFMPX DSFBUFT B OPEF OBNFE node VOEFS UIF /home/test OPEF JO UIF DPOUFOU SFQPTJUPSZ. 0OF BEEJUJPOBM BUUSJCVUF JT BEEFE UP UIF OPEF BT XFMM: my.contents.property XIJDI XJMM DPOUBJO UIF CPEZ PG UIF NFTTBHF CFJOH TFOU.
from("direct:a").setProperty(JcrConstants.JCR_NODE_NAME, constant("node")) .setProperty("my.contents.property", body()) .to("jcr://user:pass@repository/home/test");

5IF GPMMPXJOH DPEF XJMM SFHJTUFS BO &WFOU-JTUFOFS VOEFS UIF QBUI JNQPSU-BQQMJDBUJPO/JOCPY GPS &WFOU./0%&@"%%&% BOE &WFOU./0%&@3&.07&% FWFOUT (FWFOU UZQFT 1 BOE 2, CPUI NBTLFE BT 3) BOE MJTUFOJOH EFFQ GPS BMM UIF DIJMESFO.
<route> <from uri="jcr://user:pass@repository/import-application/ inbox?eventTypes=3&deep=true" /> <to uri="direct:execute-import-application" /> </route>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

)#!" ".,/.-$-3
5IF GA?@ DPNQPOFOU FOBCMFT ZPV UP BDDFTT EBUBCBTFT UISPVHI +%#$, XIFSF 42- RVFSJFT BOE PQFSBUJPOT BSF TFOU JO UIF NFTTBHF CPEZ. 5IJT DPNQPOFOU VTFT UIF TUBOEBSE +%#$ "1*, VOMJLF UIF 42- $PNQPOFOU DPNQPOFOU, XIJDI VTFT TQSJOH-KECD.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

735

.BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jdbc</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
jdbc:dataSourceName[?options]

5IJT DPNQPOFOU POMZ TVQQPSUT QSPEVDFS FOEQPJOUT. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP ->JB #BC>RIQ 5>IRB #BP@OFMQFLK 5IF EFGBVMU NBYJNVN OVNCFS PG SPXT UIBU DBO CF SFBE CZ B QPMMJOH RVFSZ. 5IF EFGBVMU WBMVF JT 0. ">JBI 2.1: 4FUT BEEJUJPOBM PQUJPOT PO UIF java.sql.Statement UIBU JT VTFE CFIJOE UIF TDFOFT UP FYFDVUF UIF RVFSJFT. 'PS JOTUBODF, statement.maxRows=10. 'PS EFUBJMFE EPDVNFOUBUJPO, TFF UIF java.sql.Statement KBWBEPD EPDVNFOUBUJPO.

readSize

statement.<xxx>

null

736

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

5IJT DPNQPOFOU DBO POMZ CF VTFE UP EFGJOF QSPEVDFS FOEQPJOUT, XIJDI NFBOT UIBU ZPV DBOOPU VTF UIF +%#$ DPNQPOFOU JO B from() TUBUFNFOU.

5IJT DPNQPOFOU DBO OPU CF VTFE BT B 5SBOTBDUJPOBM $MJFOU. *G ZPV OFFE USBOTBDUJPO TVQQPSU JO ZPVS SPVUF, ZPV TIPVME VTF UIF 42- DPNQPOFOU JOTUFBE.

useJDBC4ColumnNameAndLabelSemantics

true

">JBI 2.2: 4FUT XIFUIFS UP VTF +%#$ 4/3 DPMVNO MBCFM/ OBNF TFNBOUJDT. :PV DBO VTF UIJT PQUJPO UP UVSO JU false JO DBTF ZPV IBWF JTTVFT XJUI ZPVS +%#$ ESJWFS UP TFMFDU EBUB. 5IJT POMZ BQQMJFT XIFO VTJOH SQL SELECT VTJOH BMJBTFT (F.H. SQL SELECT id as identifier, name as given_name from persons). ">JBI 2.9: $BNFM XJMM TFU UIF BVUP$PNNJU PO UIF +%#$ DPOOFDUJPO UP CF GBMTF, DPNNJU UIF DIBOHF BGUFS FYFDVUFE UIF TUBUFNFOU BOE SFTFU UIF BVUP$PNNJU GMBH PG UIF DPOOFDUJPO BU UIF FOE, JG UIF SFTFU"VUP$PNNJU JT USVF. *G UIF +%#$ DPOOFDUJPO EPFTO'U TVQQPSU UP SFTFU UIF BVUP$PNNJU GMBH, ZPV DBO TFU UIF SFTFU"VUP$PNNJU GMBH UP CF GBMTF, BOE $BNFM XJMM OPU USZ UP SFTFU UIF BVUP$PNNJU GMBH.

resetAutoCommit

true

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

737

1BPRIQ 5IF SFTVMU JT SFUVSOFE JO UIF 065 CPEZ BT BO ArrayList<HashMap<String, Object>>. 5IF List PCKFDU DPOUBJOT UIF MJTU PG SPXT BOE UIF Map PCKFDUT DPOUBJO FBDI SPX XJUI UIF String LFZ BT UIF DPMVNO OBNF. -LQB: 5IJT DPNQPOFOU GFUDIFT ResultSetMetaData UP CF BCMF UP SFUVSO UIF DPMVNO OBNF BT UIF LFZ JO UIF Map.

,BPP>DB 'B>ABOP
'B>ABO CamelJdbcRowCount CamelJdbcUpdateCount CamelGeneratedKeysRows CamelGeneratedKeysRowCount #BP@OFMQFLK *G UIF RVFSZ JT B SELECT, RVFSZ UIF SPX DPVOU JT SFUVSOFE JO UIJT 065 IFBEFS. *G UIF RVFSZ JT BO UPDATE, RVFSZ UIF VQEBUF DPVOU JT SFUVSOFE JO UIJT 065 IFBEFS. ">JBI 2.10: 3PXT UIBU DPOUBJOT UIF HFOFSBUFE LFUT. ">JBI 2.10: 5IF OVNCFS PG SPXT JO UIF IFBEFS UIBU DPOUBJOT HFOFSBUFE LFZT.

&BKBO>QBA HBVP S>FI>?IB >P LC ">JBI 2.10 *G ZPV JOTFSU EBUB VTJOH 42- */4&35, UIFO UIF 3%#.4 NBZ TVQQPSU BVUP HFOFSBUFE LFZT. :PV DBO JOTUSVDU UIF +%#$ QSPEVDFS UP SFUVSO UIF HFOFSBUFE LFZT JO IFBEFST. 5P EP UIBU TFU UIF IFBEFS CamelRetrieveGeneratedKeys=true. 5IFO UIF HFOFSBUFE LFZT XJMM CF QSPWJEFE BT IFBEFST XJUI UIF LFZT MJTUFE JO UIF UBCMF BCPWF. :PV DBO TFF NPSF EFUBJMT JO UIJT VOJU UFTU. 2>JMIBP *O UIF GPMMPXJOH FYBNQMF, XF GFUDI UIF SPXT GSPN UIF DVTUPNFS UBCMF. 'JSTU XF SFHJTUFS PVS EBUBTPVSDF JO UIF $BNFM SFHJTUSZ BT testdb:
JndiRegistry reg = super.createRegistry(); reg.bind("testdb", db); return reg;

5IFO XF DPOGJHVSF B SPVUF UIBU SPVUFT UP UIF +%#$ DPNQPOFOU, TP UIF 42- XJMM CF FYFDVUFE. /PUF IPX XF SFGFS UP UIF testdb EBUBTPVSDF UIBU XBT CPVOE JO UIF QSFWJPVT TUFQ:

738

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

// lets add simple route public void configure() throws Exception { from("direct:hello").to("jdbc:testdb?readSize=100"); }

0S ZPV DBO DSFBUF B DataSource JO 4QSJOH MJLF UIJT:


<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <!-- trigger every second --> <from uri="timer://kickoff?period=1s"/> <setBody> <constant>select * from customer</constant> </setBody> <to uri="jdbc:testdb"/> <to uri="mock:result"/> </route> </camelContext> <!-- Just add a demo to show how to bind a date source for camel in Spring--> <jdbc:embedded-database id="testdb" type="DERBY"> <jdbc:script location="classpath:sql/init.sql"/> </jdbc:embedded-database>

8F DSFBUF BO FOEQPJOU, BEE UIF 42- RVFSZ UP UIF CPEZ PG UIF */ NFTTBHF, BOE UIFO TFOE UIF FYDIBOHF. 5IF SFTVMU PG UIF RVFSZ JT SFUVSOFE JO UIF 065 CPEZ:
// first we create our exchange using the endpoint Endpoint endpoint = context.getEndpoint("direct:hello"); Exchange exchange = endpoint.createExchange(); // then we set the SQL on the in body exchange.getIn().setBody("select * from customer order by ID"); // now we send the exchange to the endpoint, and receives the response from Camel Exchange out = template.send(endpoint, exchange); // assertions of the response assertNotNull(out); assertNotNull(out.getOut()); List<Map<String, Object>> data = out.getOut().getBody(List.class); assertNotNull(data); assertEquals(3, data.size()); Map<String, Object> row = data.get(0); assertEquals("cust1", row.get("ID")); assertEquals("jstrachan", row.get("NAME")); row = data.get(1); assertEquals("cust2", row.get("ID")); assertEquals("nsandhu", row.get("NAME"));

*G ZPV XBOU UP XPSL PO UIF SPXT POF CZ POF JOTUFBE PG UIF FOUJSF 3FTVMU4FU BU PODF ZPV OFFE UP VTF UIF 4QMJUUFS &*1 TVDI BT:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

739

from("direct:hello") // here we split the data from the testdb into new messages one by one // so the mock endpoint will receive a message per row in the table .to("jdbc:testdb").split(body()).to("mock:result");

2>JMIB - /LIIFKD QEB A>Q>?>PB BSBOV JFKRQB *G XF XBOU UP QPMM B EBUBCBTF VTJOH UIF +%#$ DPNQPOFOU, XF OFFE UP DPNCJOF JU XJUI B QPMMJOH TDIFEVMFS TVDI BT UIF 5JNFS PS 2VBSU[ FUD. *O UIF GPMMPXJOH FYBNQMF, XF SFUSJFWF EBUB GSPN UIF EBUBCBTF FWFSZ 60 TFDPOET:
from("timer://foo?period=60000").setBody(constant("select * from customer")).to("jdbc:testdb").to("activemq:queue:customers");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 42-

)$338 ".,/.-$-3
5IF GBQQV DPNQPOFOU QSPWJEFT )551-CBTFE FOEQPJOUT GPS DPOTVNJOH BOE QSPEVDJOH )551 SFRVFTUT. 5IBU JT, UIF +FUUZ DPNQPOFOU CFIBWFT BT B TJNQMF 8FC TFSWFS. +FUUZ DBO BMTP CF VTFE BT B IUUQ DMJFOU XIJDI NFBO ZPV DBO BMTP VTF JU XJUI $BNFM BT B QSPEVDFS. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jetty</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
jetty:http://hostname[:port][/resourceUri][?options]

740

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2QOB>J +FUUZ JT TUSFBN CBTFE, XIJDI NFBOT UIF JOQVU JU SFDFJWFT JT TVCNJUUFE UP $BNFM BT B TUSFBN. 5IBU NFBOT ZPV XJMM POMZ CF BCMF UP SFBE UIF DPOUFOU PG UIF TUSFBN LK@B. *G ZPV GJOE B TJUVBUJPO XIFSF UIF NFTTBHF CPEZ BQQFBST UP CF FNQUZ PS ZPV OFFE UP BDDFTT UIF EBUB NVMUJQMF UJNFT (FH: EPJOH NVMUJDBTUJOH, PS SFEFMJWFSZ FSSPS IBOEMJOH) ZPV TIPVME VTF 4USFBN DBDIJOH PS DPOWFSU UIF NFTTBHF CPEZ UP B String XIJDI JT TBGF UP CF SF-SFBE NVMUJQMF UJNFT. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
sessionSupport httpClient.XXX httpClient httpClientMinThreads httpClientMaxThreads httpBindingRef jettyHttpBindingRef matchOnUriPrefix handlers chunked enableJmx

#BC>RIQ 5>IRB
false null null null null null null false null true false

#BP@OFMQFLK
4QFDJGJFT XIFUIFS UP FOBCMF UIF TFTTJPO NBOBHFS PO UIF TFSWFS TJEF PG +FUUZ. $POGJHVSBUJPO PG +FUUZ'T )UUQ$MJFOU. 'PS FYBNQMF, TFUUJOH httpClient.idleTimeout=30000 TFUT UIF JEMF UJNFPVU UP 30 TFDPOET. 5P VTF B TIBSFE org.eclipse.jetty.client.HttpClient GPS BMM QSPEVDFST DSFBUFE CZ UIJT FOEQPJOU. 5IJT PQUJPO TIPVME POMZ CF VTFE JO TQFDJBM DJSDVNTUBODFT. ">JBI 2.11: /OLAR@BO LKIV: 5P TFU B WBMVF GPS NJOJNVN OVNCFS PG UISFBET JO HttpClient UISFBE QPPM. 5IJT TFUUJOH PWFSSJEF BOZ TFUUJOH DPOGJHVSFE PO DPNQPOFOU MFWFM. /PUJDF UIBU CPUI B NJO BOE NBY TJ[F NVTU CF DPOGJHVSFE. ">JBI 2.11: /OLAR@BO LKIV: 5P TFU B WBMVF GPS NBYJNVN OVNCFS PG UISFBET JO HttpClient UISFBE QPPM. 5IJT TFUUJOH PWFSSJEF BOZ TFUUJOH DPOGJHVSFE PO DPNQPOFOU MFWFM. /PUJDF UIBU CPUI B NJO BOE NBY TJ[F NVTU CF DPOGJHVSFE. 3FGFSFODF UP BO org.apache.camel.component.http.HttpBinding JO UIF 3FHJTUSZ. HttpBinding DBO CF VTFE UP DVTUPNJ[F IPX B SFTQPOTF TIPVME CF XSJUUFO GPS UIF DPOTVNFS. ">JBI 2.6.0+: 3FGFSFODF UP BO org.apache.camel.component.jetty.JettyHttpBinding JO UIF 3FHJTUSZ. JettyHttpBinding DBO CF VTFE UP DVTUPNJ[F IPX B SFTQPOTF TIPVME CF XSJUUFO GPS UIF QSPEVDFS. 8IFUIFS PS OPU UIF CamelServlet TIPVME USZ UP GJOE B UBSHFU DPOTVNFS CZ NBUDIJOH UIF 63* QSFGJY JG OP FYBDU NBUDI JT GPVOE. 4FF IFSF )PX EP * MFU +FUUZ NBUDI XJMEDBSET. 4QFDJGJFT B DPNNB-EFMJNJUFE TFU PG org.mortbay.jetty.Handler JOTUBODFT JO ZPVS 3FHJTUSZ (TVDI BT ZPVS 4QSJOH ApplicationContext). 5IFTF IBOEMFST BSF BEEFE UP UIF +FUUZ TFSWMFU DPOUFYU (GPS FYBNQMF, UP BEE TFDVSJUZ). ">JBI 2.2: *G UIJT PQUJPO JT GBMTF +FUUZ TFSWMFU XJMM EJTBCMF UIF )551 TUSFBNJOH BOE TFU UIF DPOUFOU-MFOHUI IFBEFS PO UIF SFTQPOTF ">JBI 2.3: *G UIJT PQUJPO JT USVF, +FUUZ +.9 TVQQPSU XJMM CF FOBCMFE GPS UIJT FOEQPJOU. 4FF +FUUZ +.9 TVQQPSU GPS NPSF EFUBJMT. ">JBI 2.3: %FUFSNJOFT XIFUIFS PS OPU UIF SBX JOQVU TUSFBN GSPN +FUUZ JT DBDIFE PS OPU ($BNFM XJMM SFBE UIF TUSFBN JOUP B JO NFNPSZ/PWFSGMPX UP GJMF, 4USFBN DBDIJOH) DBDIF. #Z EFGBVMU $BNFM XJMM DBDIF UIF +FUUZ JOQVU TUSFBN UP TVQQPSU SFBEJOH JU NVMUJQMF UJNFT UP FOTVSF JU $BNFM DBO SFUSJFWF BMM EBUB GSPN UIF TUSFBN. )PXFWFS ZPV DBO TFU UIJT PQUJPO UP true XIFO ZPV GPS FYBNQMF OFFE UP BDDFTT UIF SBX TUSFBN, TVDI BT TUSFBNJOH JU EJSFDUMZ UP B GJMF PS PUIFS QFSTJTUFOU TUPSF. %FGBVMU)UUQ#JOEJOH XJMM DPQZ UIF SFRVFTU JOQVU TUSFBN JOUP B TUSFBN DBDIF BOE QVU JU JOUP NFTTBHF CPEZ JG UIJT PQUJPO JT false UP TVQQPSU SFBEJOH UIF TUSFBN NVMUJQMF UJNFT. *G ZPV VTF +FUUZ UP CSJEHF/QSPYZ BO FOEQPJOU UIFO DPOTJEFS FOBCMJOH UIJT PQUJPO UP JNQSPWF QFSGPSNBODF, JO DBTF ZPV EP OPU OFFE UP SFBE UIF NFTTBHF QBZMPBE NVMUJQMF UJNFT. ">JBI 2.1: *G UIF PQUJPO JT USVF , )UUQ1SPEVDFS XJMM JHOPSF UIF &YDIBOHF.)551@63* IFBEFS, BOE VTF UIF FOEQPJOU'T 63* GPS SFRVFTU. :PV NBZ BMTP TFU UIF QEOLT$U@BMQFLK.K%>FIROB UP CF GBMTF UP MFU UIF )UUQ1SPEVDFS TFOE BMM UIF GBVMU SFTQPOTF CBDL. ">JBI 2.3: *G UIF PQUJPO JT USVF, )UUQ1SPEVDFS BOE $BNFM4FSWMFU XJMM TLJQ UIF H[JQ QSPDFTTJOH JG UIF DPOUFOU-FODPEJOH JT "H[JQ". "MTP DPOTJEFS TFUUJOH AFP>?IB2QOB>J">@EB UP USVF UP PQUJNJ[F XIFO CSJEHJOH. ">JBI 2.5: 8IFUIFS +FUUZ org.eclipse.jetty.servlets.MultiPartFilter JT FOBCMFE PS OPU. :PV TIPVME TFU UIJT WBMVF UP false XIFO CSJEHJOH FOEQPJOUT, UP FOTVSF NVMUJQBSU SFRVFTUT JT QSPYJFE/CSJEHFE BT XFMM. ">JBI 2.6: "MMPXT VTJOH B DVTUPN NVMUJQBSU GJMUFS. /PUF: TFUUJOH multipartFilterRef GPSDFT UIF WBMVF PG enableMultipartFilter UP true. ">JBI 2.9: "MMPXT VTJOH B DVTUPN GJMUFST XIJDI JT QVUUFE JOUP B MJTU BOE DBO CF GJOE JO UIF 3FHJTUSZ

disableStreamCache

false

bridgeEndpoint

false

enableMultipartFilter multipartFilterRef filtersRef

true null null

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

741

continuationTimeout useContinuation sslContextParametersRef traceEnabled headerFilterStrategy

null true null false null

">JBI 2.6: "MMPXT UP TFU B UJNFPVU JO NJMMJT XIFO VTJOH +FUUZ BT DPOTVNFS (TFSWFS). #Z EFGBVMU +FUUZ VTFT 30000. :PV DBO VTF B WBMVF PG <= 0 UP OFWFS FYQJSF. *G B UJNFPVU PDDVST UIFO UIF SFRVFTU XJMM CF FYQJSFE BOE +FUUZ XJMM SFUVSO CBDL B IUUQ FSSPS 503 UP UIF DMJFOU. 5IJT PQUJPO JT POMZ JO VTF XIFO VTJOH +FUUZ XJUI UIF "TZODISPOPVT 3PVUJOH &OHJOF. ">JBI 2.6: 8IFUIFS PS OPU UP VTF +FUUZ DPOUJOVBUJPOT GPS UIF +FUUZ 4FSWFS. ">JBI 2.8: 3FGFSFODF UP B org.apache.camel.util.jsse.SSLContextParameters JO UIF 3FHJTUSZ.c 5IJT SFGFSFODF PWFSSJEFT BOZ DPOGJHVSFE 44-$POUFYU1BSBNFUFST BU UIF DPNQPOFOU MFWFM.c 4FF 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ. 4QFDJGJFT XIFUIFS UP FOBCMF )551 53"$& GPS UIJT +FUUZ DPOTVNFS. #Z EFGBVMU 53"$& JT UVSOFE PGG. ">JBI 2.11: 3FGFSFODF UP B JOTUBODF PG org.apache.camel.spi.HeaderFilterStrategy JO UIF 3FHJTUSZ. *U XJMM CF VTFE UP BQQMZ UIF DVTUPN IFBEFS'JMUFS4USBUFHZ PO UIF OFX DSFBUF )UUQ+FUUZ&OEQPJOU. ">JBI 2.11: /OLAR@BO LKIV 3FGFST UP B DVTUPN org.apache.camel.component.http.UrlRewrite XIJDI BMMPXT ZPV UP SFXSJUF VSMT XIFO ZPV CSJEHF/QSPYZ FOEQPJOUT. 4FF NPSF EFUBJMT BU 6SM3FXSJUF BOE )PX UP VTF $BNFM BT B )551 QSPYZ CFUXFFO B DMJFOU BOE TFSWFS.

urlRewrite

null

,BPP>DB 'B>ABOP $BNFM VTFT UIF TBNF NFTTBHF IFBEFST BT UIF )551 DPNQPOFOU. 'SPN $BNFM 2.2, JU BMTP VTFT (&YDIBOHF.)551@$)6/,&%,$BNFM)UUQ$IVOLFE) IFBEFS UP UVSO PO PS UVSO PGG UIF DIVDIFE FODPEJOH PO UIF DBNFM-KFUUZ DPOTVNFS. $BNFM BMTP QPQVMBUFT >II SFRVFTU.QBSBNFUFS BOE SFRVFTU.IFBEFST. 'PS FYBNQMF, HJWFO B DMJFOU SFRVFTU XJUI UIF 63-, http://myserver/myserver?orderid=123, UIF FYDIBOHF XJMM DPOUBJO B IFBEFS OBNFE orderid XJUI UIF WBMVF 123. 4UBSUJOH XJUI $BNFM 2.2.0, ZPV DBO HFU UIF SFRVFTU.QBSBNFUFS GSPN UIF NFTTBHF IFBEFS OPU POMZ GSPN (FU .FUIPE, CVU BMTP PUIFS )551 NFUIPE. 4P>DB 5IF +FUUZ DPNQPOFOU TVQQPSUT CPUI DPOTVNFS BOE QSPEVDFS FOEQPJOUT. "OPUIFS PQUJPO GPS QSPEVDJOH UP PUIFS )551 FOEQPJOUT, JT UP VTF UIF )551 $PNQPOFOU "LJMLKBKQ .MQFLKP 5IF JettyHttpComponent QSPWJEFT UIF GPMMPXJOH PQUJPOT:
->JB
enableJmx sslKeyPassword sslPassword sslKeystore minThreads maxThreads threadPool sslSocketConnectors socketConnectors

#BC>RIQ 5>IRB
false null null null null null null null null

#BP@OFMQFLK
">JBI 2.3: *G UIJT PQUJPO JT USVF, +FUUZ +.9 TVQQPSU XJMM CF FOBCMFE GPS UIJT FOEQPJOU. 4FF +FUUZ +.9 TVQQPSU GPS NPSF EFUBJMT. "LKPRJBO LKIV: 5IF QBTTXPSE GPS UIF LFZTUPSF XIFO VTJOH 44-. "LKPRJBO LKIV: 5IF QBTTXPSE XIFO VTJOH 44-. "LKPRJBO LKIV: 5IF QBUI UP UIF LFZTUPSF. ">JBI 2.5 "LKPRJBO LKIV: 5P TFU B WBMVF GPS NJOJNVN OVNCFS PG UISFBET JO TFSWFS UISFBE QPPM. /PUJDF UIBU CPUI B NJO BOE NBY TJ[F NVTU CF DPOGJHVSFE. ">JBI 2.5 "LKPRJBO LKIV: 5P TFU B WBMVF GPS NBYJNVN OVNCFS PG UISFBET JO TFSWFS UISFBE QPPM. /PUJDF UIBU CPUI B NJO BOE NBY TJ[F NVTU CF DPOGJHVSFE. ">JBI 2.5 "LKPRJBO LKIV: 5P VTF B DVTUPN UISFBE QPPM GPS UIF TFSWFS. 5IJT PQUJPO TIPVME POMZ CF VTFE JO TQFDJBM DJSDVNTUBODFT. ">JBI 2.3 "LKPRJBO LKIV: " NBQ XIJDI DPOUBJOT QFS QPSU OVNCFS TQFDJGJD 44- DPOOFDUPST. 4FF TFDUJPO SSL support GPS NPSF EFUBJMT. ">JBI 2.5 "LKPRJBO LKIV: " NBQ XIJDI DPOUBJOT QFS QPSU OVNCFS TQFDJGJD )551 DPOOFDUPST. 6TFT UIF TBNF QSJODJQMF BT sslSocketConnectors BOE UIFSFGPSF TFF TFDUJPO SSL support GPS NPSF EFUBJMT.

742

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

sslSocketConnectorProperties socketConnectorProperties httpClient httpClientMinThreads httpClientMaxThreads httpClientThreadPool sslContextParameters

null null null null null null null

">JBI 2.5 "LKPRJBO LKIV. " NBQ XIJDI DPOUBJOT HFOFSBM 44- DPOOFDUPS QSPQFSUJFT. 4FF TFDUJPO SSL support GPS NPSF EFUBJMT. ">JBI 2.5 "LKPRJBO LKIV. " NBQ XIJDI DPOUBJOT HFOFSBM )551 DPOOFDUPS QSPQFSUJFT. 6TFT UIF TBNF QSJODJQMF BT sslSocketConnectorProperties BOE UIFSFGPSF TFF TFDUJPO SSL support GPS NPSF EFUBJMT. #BMOB@>QBA: /OLAR@BO LKIV: 5P VTF B DVTUPN HttpClient XJUI UIF KFUUZ QSPEVDFS. 5IJT PQUJPO JT SFNPWFE GSPN $BNFM 2.11 POXBSET, JOTUFBE ZPV DBO TFU UIF PQUJPO PO UIF FOEQPJOU JOTUFBE. /OLAR@BO LKIV: 5P TFU B WBMVF GPS NJOJNVN OVNCFS PG UISFBET JO HttpClient UISFBE QPPM. /PUJDF UIBU CPUI B NJO BOE NBY TJ[F NVTU CF DPOGJHVSFE. /OLAR@BO LKIV: 5P TFU B WBMVF GPS NBYJNVN OVNCFS PG UISFBET JO HttpClient UISFBE QPPM. /PUJDF UIBU CPUI B NJO BOE NBY TJ[F NVTU CF DPOGJHVSFE. #BMOB@>QBA: /OLAR@BO LKIV: 5P VTF B DVTUPN UISFBE QPPM GPS UIF DMJFOU. 5IJT PQUJPO JT SFNPWFE GSPN $BNFM 2.11 POXBSET. ">JBI 2.8: 5P DPOGJHVSF B DVTUPN 44-/5-4 DPOGJHVSBUJPO PQUJPOT BU UIF DPNQPOFOU MFWFM.c 4FFc 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ GPS NPSF EFUBJMT.

/OLAR@BO $U>JMIB 5IF GPMMPXJOH JT B CBTJD FYBNQMF PG IPX UP TFOE BO )551 SFRVFTU UP BO FYJTUJOH )551 FOEQPJOU. JO +BWB %4from("direct:start").to("jetty://http://www.google.com");

PS JO 4QSJOH 9.<route> <from uri="direct:start"/> <to uri="jetty://http://www.google.com"/> <route>

"LKPRJBO $U>JMIB *O UIJT TBNQMF XF EFGJOF B SPVUF UIBU FYQPTFT B )551 TFSWJDF BU http://localhost:8080/myapp/myservice:
from("jetty:http://localhost:{{port}}/myapp/myservice").process(new MyBookService());

0VS CVTJOFTT MPHJD JT JNQMFNFOUFE JO UIF MyBookService DMBTT, XIJDI BDDFTTFT UIF )551 SFRVFTU DPOUFOUT BOE UIFO SFUVSOT B SFTQPOTF. -LQB: 5IF assert DBMM BQQFBST JO UIJT FYBNQMF, CFDBVTF UIF DPEF JT QBSU PG BO VOJU UFTU.
public class MyBookService implements Processor { public void process(Exchange exchange) throws Exception { // just get the body as a string String body = exchange.getIn().getBody(String.class); // we have access to the HttpServletRequest here and we can grab it if we need

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

743

4P>DB LC IL@>IELPQ 8IFO ZPV TQFDJGZ localhost JO B 63-, $BNFM FYQPTFT UIF FOEQPJOU POMZ PO UIF MPDBM 5$1/*1 OFUXPSL JOUFSGBDF, TP JU DBOOPU CF BDDFTTFE GSPN PVUTJEF UIF NBDIJOF JU PQFSBUFT PO.
*G ZPV OFFE UP FYQPTF B +FUUZ FOEQPJOU PO B TQFDJGJD OFUXPSL JOUFSGBDF, UIF OVNFSJDBM *1 BEESFTT PG UIJT JOUFSGBDF TIPVME CF VTFE BT UIF IPTU. *G ZPV OFFE UP FYQPTF B +FUUZ FOEQPJOU PO BMM OFUXPSL JOUFSGBDFT, UIF 0.0.0.0 BEESFTT TIPVME CF VTFE.

it HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class); assertNotNull(req); // for unit testing assertEquals("bookid=123", body); // send a html response exchange.getOut().setBody("<html><body>Book 123 is Camel in Action</body></html>"); } }

5IF GPMMPXJOH TBNQMF TIPXT B DPOUFOU-CBTFE SPVUF UIBU SPVUFT BMM SFRVFTUT DPOUBJOJOH UIF 63* QBSBNFUFS, one, UP UIF FOEQPJOU, mock:one, BOE BMM PUIFST UP mock:other.
from("jetty:" + serverUri) .choice() .when().simple("${header.one}").to("mock:one") .otherwise() .to("mock:other");

4P JG B DMJFOU TFOET UIF )551 SFRVFTU, http://serverUri?one=hello, UIF +FUUZ DPNQPOFOU XJMM DPQZ UIF )551 SFRVFTU QBSBNFUFS, one UP UIF FYDIBOHF'T in.header. 8F DBO UIFO VTF UIF simple MBOHVBHF UP SPVUF FYDIBOHFT UIBU DPOUBJO UIJT IFBEFS UP B TQFDJGJD FOEQPJOU BOE BMM PUIFST UP BOPUIFS. *G XF VTFE B MBOHVBHF NPSF QPXFSGVM UIBO 4JNQMF--TVDI BT &- PS 0(/---XF DPVME BMTP UFTU GPS UIF QBSBNFUFS WBMVF BOE EP SPVUJOH CBTFE PO UIF IFBEFS WBMVF BT XFMM. 2BPPFLK 2RMMLOQ 5IF TFTTJPO TVQQPSU PQUJPO, sessionSupport, DBO CF VTFE UP FOBCMF B HttpSession PCKFDU BOE BDDFTT UIF TFTTJPO PCKFDU XIJMF QSPDFTTJOH UIF FYDIBOHF. 'PS FYBNQMF, UIF GPMMPXJOH SPVUF FOBCMFT TFTTJPOT:

744

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<route> <from uri="jetty:http://0.0.0.0/myapp/myservice/?sessionSupport=true"/> <processRef ref="myCode"/> <route>

5IF myCode 1SPDFTTPS DBO CF JOTUBOUJBUFE CZ B 4QSJOH bean FMFNFOU:


<bean id="myCode"class="com.mycompany.MyCodeProcessor"/>

8IFSF UIF QSPDFTTPS JNQMFNFOUBUJPO DBO BDDFTT UIF HttpSession BT GPMMPXT:


public void process(Exchange exchange) throws Exception { HttpSession session = exchange.getIn(HttpMessage.class).getRequest().getSession(); ... }

22+ 2RMMLOQ ('33/2) 4PFKD QEB )22$ "LKCFDRO>QFLK 4QFIFQV "T PG $BNFM 2.8, UIF +FUUZ DPNQPOFOU TVQQPSUT 44-/5-4 DPOGJHVSBUJPO UISPVHI UIF $BNFM +44& $POGJHVSBUJPO 6UJMJUZ.c 5IJT VUJMJUZ HSFBUMZ EFDSFBTFT UIF BNPVOU PG DPNQPOFOU TQFDJGJD DPEF ZPV OFFE UP XSJUF BOE JT DPOGJHVSBCMF BU UIF FOEQPJOU BOE DPNQPOFOU MFWFMT.c 5IF GPMMPXJOH FYBNQMFT EFNPOTUSBUF IPX UP VTF UIF VUJMJUZ XJUI UIF +FUUZ DPNQPOFOU.
/OLDO>JJ>QF@ @LKCFDRO>QFLK LC QEB @LJMLKBKQ
KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/keystore.jks"); ksp.setPassword("keystorePassword"); KeyManagersParameters kmp = new KeyManagersParameters(); kmp.setKeyStore(ksp); kmp.setKeyPassword("keyPassword"); SSLContextParameters scp = new SSLContextParameters(); scp.setKeyManagers(kmp); JettyComponent jettyComponent = getContext().getComponent("jetty", JettyComponent.class); jettyComponent.setSslContextParameters(scp);

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

745

2MOFKD #2+ ?>PBA @LKCFDRO>QFLK LC BKAMLFKQ


... <camel:sslContextParameters id="sslContextParameters"> <camel:keyManagers keyPassword="keyPassword"> <camel:keyStore resource="/users/home/server/keystore.jks" password="keystorePassword"/> </camel:keyManagers> </camel:sslContextParameters>... ... <to uri="jetty:https://127.0.0.1/ mail/?sslContextParametersRef=sslContextParameters"/> ...

"LKCFDROFKD )BQQV #FOB@QIV +FUUZ QSPWJEFT 44- TVQQPSU PVU PG UIF CPY. 5P FOBCMF +FUUZ UP SVO JO 44- NPEF, TJNQMZ GPSNBU UIF 63* XJUI UIF https:// QSFGJY---GPS FYBNQMF:
<from uri="jetty:https://0.0.0.0/myapp/myservice/"/>

+FUUZ BMTP OFFET UP LOPX XIFSF UP MPBE ZPVS LFZTUPSF GSPN BOE XIBU QBTTXPSET UP VTF JO PSEFS UP MPBE UIF DPSSFDU 44- DFSUJGJDBUF. 4FU UIF GPMMPXJOH +7. 4ZTUFN 1SPQFSUJFT: RKQFI ">JBI 2.2 ` jetty.ssl.keystore TQFDJGJFT UIF MPDBUJPO PG UIF +BWB LFZTUPSF GJMF, XIJDI DPOUBJOT UIF +FUUZ TFSWFS'T PXO 9.509 DFSUJGJDBUF JO B key entry. " LFZ FOUSZ TUPSFT UIF 9.509 DFSUJGJDBUF (FGGFDUJWFMZ, UIF public key) BOE BMTP JUT BTTPDJBUFE QSJWBUF LFZ. ` jetty.ssl.password UIF TUPSF QBTTXPSE, XIJDI JT SFRVJSFE UP BDDFTT UIF LFZTUPSF GJMF (UIJT JT UIF TBNF QBTTXPSE UIBU JT TVQQMJFE UP UIF keystore DPNNBOE'T -storepass PQUJPO). ` jetty.ssl.keypassword UIF LFZ QBTTXPSE, XIJDI JT VTFE UP BDDFTT UIF DFSUJGJDBUF'T LFZ FOUSZ JO UIF LFZTUPSF (UIJT JT UIF TBNF QBTTXPSE UIBU JT TVQQMJFE UP UIF keystore DPNNBOE'T -keypass PQUJPO). COLJ ">JBI 2.3 LKT>OAP ` org.eclipse.jetty.ssl.keystore TQFDJGJFT UIF MPDBUJPO PG UIF +BWB LFZTUPSF GJMF, XIJDI DPOUBJOT UIF +FUUZ TFSWFS'T PXO 9.509 DFSUJGJDBUF JO B key entry. " LFZ FOUSZ TUPSFT UIF 9.509 DFSUJGJDBUF (FGGFDUJWFMZ, UIF public key) BOE BMTP JUT BTTPDJBUFE QSJWBUF LFZ. ` org.eclipse.jetty.ssl.password UIF TUPSF QBTTXPSE, XIJDI JT SFRVJSFE UP BDDFTT UIF LFZTUPSF GJMF (UIJT JT UIF TBNF QBTTXPSE UIBU JT TVQQMJFE UP UIF keystore DPNNBOE'T -storepass PQUJPO).

746

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

` org.eclipse.jetty.ssl.keypassword UIF LFZ QBTTXPSE, XIJDI JT VTFE UP BDDFTT UIF DFSUJGJDBUF'T LFZ FOUSZ JO UIF LFZTUPSF (UIJT JT UIF TBNF QBTTXPSE UIBU JT TVQQMJFE UP UIF keystore DPNNBOE'T -keypass PQUJPO). 'PS EFUBJMT PG IPX UP DPOGJHVSF 44- PO B +FUUZ FOEQPJOU, SFBE UIF GPMMPXJOH EPDVNFOUBUJPO BU UIF +FUUZ 4JUF: IUUQ://EPDT.DPEFIBVT.PSH/EJTQMBZ/+&55:/)PX+UP+DPOGJHVSF+444PNF 44- QSPQFSUJFT BSFO'U FYQPTFE EJSFDUMZ CZ $BNFM, IPXFWFS $BNFM EPFT FYQPTF UIF VOEFSMZJOH 4TM4PDLFU$POOFDUPS, XIJDI XJMM BMMPX ZPV UP TFU QSPQFSUJFT MJLF OFFE$MJFOU"VUI GPS NVUVBM BVUIFOUJDBUJPO SFRVJSJOH B DMJFOU DFSUJGJDBUF PS XBOU$MJFOU"VUI GPS NVUVBM BVUIFOUJDBUJPO XIFSF B DMJFOU EPFTO'U OFFE B DFSUJGJDBUF CVU DBO IBWF POF. 5IFSF'T B TMJHIU EJGGFSFODF CFUXFFO UIF WBSJPVT $BNFM WFSTJPOT: 4M QL ">JBI 2.2
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent"> <property name="sslSocketConnectors"> <map> <entry key="8043"> <bean class="org.mortbay.jetty.security.SslSocketConnector"> <property name="password"value="..."/> <property name="keyPassword"value="..."/> <property name="keystore"value="..."/> <property name="needClientAuth"value="..."/> <property name="truststore"value="..."/> </bean> </entry> </map> </property> </bean>

">JBI 2.3, 2.4


<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent"> <property name="sslSocketConnectors"> <map> <entry key="8043"> <bean class="org.eclipse.jetty.server.ssl.SslSocketConnector"> <property name="password"value="..."/> <property name="keyPassword"value="..."/> <property name="keystore"value="..."/> <property name="needClientAuth"value="..."/> <property name="truststore"value="..."/> </bean> </entry> </map> </property> </bean>

*'SPN $BNFM 2.5 XF TXJUDI UP VTF 4TM4FMFDU$IBOOFM$POOFDUPS *

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

747

<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent"> <property name="sslSocketConnectors"> <map> <entry key="8043"> <bean class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector"> <property name="password"value="..."/> <property name="keyPassword"value="..."/> <property name="keystore"value="..."/> <property name="needClientAuth"value="..."/> <property name="truststore"value="..."/> </bean> </entry> </map> </property> </bean>

5IF WBMVF ZPV VTF BT LFZT JO UIF BCPWF NBQ JT UIF QPSU ZPV DPOGJHVSF +FUUZ UP MJTUFO PO.

"LKCFDROFKD DBKBO>I 22+ MOLMBOQFBP


S>FI>?IB >P LC ">JBI 2.5 *OTUFBE PG B QFS QPSU OVNCFS TQFDJGJD 44- TPDLFU DPOOFDUPS (BT TIPXO BCPWF) ZPV DBO OPX DPOGJHVSF HFOFSBM QSPQFSUJFT XIJDI BQQMJFT GPS BMM 44- TPDLFU DPOOFDUPST (XIJDI JT OPU FYQMJDJU DPOGJHVSFE BT BCPWF XJUI UIF QPSU OVNCFS BT FOUSZ).
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent"> <property name="sslSocketConnectorProperties"> <map> <entry key="password"value="..."/> <entry key="keyPassword"value="..."/> <entry key="keystore"value="..."/> <entry key="needClientAuth"value="..."/> <entry key="truststore"value="..."/> </map> </property> </bean>

'LT QL L?Q>FK OBCBOBK@B QL QEB 7509"BOQFCF@>QB


+FUUZ TUPSFT B SFGFSFODF UP UIF DFSUJGJDBUF JO UIF )UUQ4FSWMFU3FRVFTU XIJDI ZPV DBO BDDFTT GSPN DPEF BT GPMMPXT:
HttpServletRequest req = exchange.getIn().getBody(HttpServletRequest.class); X509Certificate cert = (X509Certificate) req.getAttribute("javax.servlet.request.X509Certificate")

748

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"LKCFDROFKD DBKBO>I '33/ MOLMBOQFBP


S>FI>?IB >P LC ">JBI 2.5 *OTUFBE PG B QFS QPSU OVNCFS TQFDJGJD )551 TPDLFU DPOOFDUPS (BT TIPXO BCPWF) ZPV DBO OPX DPOGJHVSF HFOFSBM QSPQFSUJFT XIJDI BQQMJFT GPS BMM )551 TPDLFU DPOOFDUPST (XIJDI JT OPU FYQMJDJU DPOGJHVSFE BT BCPWF XJUI UIF QPSU OVNCFS BT FOUSZ).
<bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent"> <property name="socketConnectorProperties"> <map> <entry key="acceptors" value="4"/> <entry key="maxIdleTime" value="300000"/> </map> </property> </bean>

#BC>RIQ ?BE>SFLO CLO OBQROKFKD '33/ PQ>QRP @LABP 5IF EFGBVMU CFIBWJPS PG )551 TUBUVT DPEFT JT EFGJOFE CZ UIF org.apache.camel.component.http.DefaultHttpBinding DMBTT, XIJDI IBOEMFT IPX B SFTQPOTF JT XSJUUFO BOE BMTP TFUT UIF )551 TUBUVT DPEF. *G UIF FYDIBOHF XBT QSPDFTTFE TVDDFTTGVMMZ, UIF 200 )551 TUBUVT DPEF JT SFUVSOFE. *G UIF FYDIBOHF GBJMFE XJUI BO FYDFQUJPO, UIF 500 )551 TUBUVT DPEF JT SFUVSOFE, BOE UIF TUBDLUSBDF JT SFUVSOFE JO UIF CPEZ. *G ZPV XBOU UP TQFDJGZ XIJDI )551 TUBUVT DPEF UP SFUVSO, TFU UIF DPEF JO UIF HttpProducer.HTTP_RESPONSE_CODE IFBEFS PG UIF 065 NFTTBHF. "RPQLJFWFKD 'QQM!FKAFKD #Z EFGBVMU, $BNFM VTFT UIF org.apache.camel.component.http.DefaultHttpBinding UP IBOEMF IPX B SFTQPOTF JT XSJUUFO. *G ZPV MJLF, ZPV DBO DVTUPNJ[F UIJT CFIBWJPS FJUIFS CZ JNQMFNFOUJOH ZPVS PXO HttpBinding DMBTT PS CZ FYUFOEJOH DefaultHttpBinding BOE PWFSSJEJOH UIF BQQSPQSJBUF NFUIPET. 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DVTUPNJ[F UIF DefaultHttpBinding JO PSEFS UP DIBOHF IPX FYDFQUJPOT BSF SFUVSOFE:
public class MyHttpBinding extends DefaultHttpBinding { public MyHttpBinding(HttpEndpoint ep) { super(ep); } @Override public void doWriteExceptionResponse(Throwable exception, HttpServletResponse response) throws IOException { // we override the doWriteExceptionResponse as we only want to alter the binding how exceptions is

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

749

// written back to the client. // we just return HTTP 200 so the client thinks its okay response.setStatus(200); // and we return this fixed text response.getWriter().write("Something went wrong but we dont care"); } }

8F DBO UIFO DSFBUF BO JOTUBODF PG PVS CJOEJOH BOE SFHJTUFS JU JO UIF 4QSJOH SFHJTUSZ BT GPMMPXT:
<bean id="mybinding"class="com.mycompany.MyHttpBinding"/>

"OE UIFO XF DBO SFGFSFODF UIJT CJOEJOH XIFO XF EFGJOF UIF SPVUF:
<route><from uri="jetty:http://0.0.0.0:8080/myapp/ myservice?httpBindingRef=mybinding"/><to uri="bean:doSomething"/></route>

)BQQV E>KAIBOP >KA PB@ROFQV @LKCFDRO>QFLK :PV DBO DPOGJHVSF B MJTU PG +FUUZ IBOEMFST PO UIF FOEQPJOU, XIJDI DBO CF VTFGVM GPS FOBCMJOH BEWBODFE +FUUZ TFDVSJUZ GFBUVSFT. 5IFTF IBOEMFST BSF DPOGJHVSFE JO 4QSJOH 9.- BT GPMMPXT:
<-- Jetty Security handling --> <bean id="userRealm" class="org.mortbay.jetty.plus.jaas.JAASUserRealm"> <property name="name" value="tracker-users"/> <property name="loginModuleName" value="ldaploginmodule"/> </bean> <bean id="constraint" class="org.mortbay.jetty.security.Constraint"> <property name="name" value="BASIC"/> <property name="roles" value="tracker-users"/> <property name="authenticate" value="true"/> </bean> <bean id="constraintMapping" class="org.mortbay.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.mortbay.jetty.security.SecurityHandler"> <property name="userRealm" ref="userRealm"/> <property name="constraintMappings" ref="constraintMapping"/> </bean>

KA COLJ ">JBI 2.3 LKT>OAP ZPV DBO DPOGJHVSF B MJTU PG +FUUZ IBOEMFST BT GPMMPXT:

750

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<-- Jetty Security handling --> <bean id="constraint" class="org.eclipse.jetty.http.security.Constraint"> <property name="name" value="BASIC"/> <property name="roles" value="tracker-users"/> <property name="authenticate" value="true"/> </bean> <bean id="constraintMapping" class="org.eclipse.jetty.security.ConstraintMapping"> <property name="constraint" ref="constraint"/> <property name="pathSpec" value="/*"/> </bean> <bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler"> <property name="authenticator"> <bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/> </property> <property name="constraintMappings"> <list> <ref bean="constraintMapping"/> </list> </property> </bean>

:PV DBO UIFO EFGJOF UIF FOEQPJOU BT:


from("jetty:http://0.0.0.0:9080/myservice?handlers=securityHandler")

*G ZPV OFFE NPSF IBOEMFST, TFU UIF handlers PQUJPO FRVBM UP B DPNNB-TFQBSBUFE MJTU PG CFBO *%T. 'LT QL OBQROK > @RPQLJ '33/ 500 OBMIV JBPP>DB :PV NBZ XBOU UP SFUVSO B DVTUPN SFQMZ NFTTBHF XIFO TPNFUIJOH HPFT XSPOH, JOTUFBE PG UIF EFGBVMU SFQMZ NFTTBHF $BNFM +FUUZ SFQMJFT XJUI. :PV DPVME VTF B DVTUPN HttpBinding UP CF JO DPOUSPM PG UIF NFTTBHF NBQQJOH, CVU PGUFO JU NBZ CF FBTJFS UP VTF $BNFM'T &YDFQUJPO $MBVTF UP DPOTUSVDU UIF DVTUPN SFQMZ NFTTBHF. 'PS FYBNQMF BT TIPX IFSF, XIFSF XF SFUVSO Dude something went wrong XJUI )551 FSSPS DPEF 500:
from("jetty://http://localhost:{{port}}/myserver") // use onException to catch all exceptions and return a custom reply message .onException(Exception.class) .handled(true) // create a custom failure response .transform(constant("Dude something went wrong")) // we must remember to set error code 500 as handled(true) // otherwise would let Camel thing its a OK response (200)

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

751

.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500)) .end() // now just force an exception immediately .throwException(new IllegalArgumentException("I cannot do this"));

,RIQF-M>OQ %LOJ PRMMLOQ 'SPN $BNFM 2.3.0, DBNFM-KFUUZ TVQQPSU UP NVMUJQBSU GPSN QPTU PVU PG CPY. 5IF TVCNJUUFE GPSNEBUB BSF NBQQFE JOUP UIF NFTTBHF IFBEFS. $BNFM-KFUUZ DSFBUFT BO BUUBDINFOU GPS FBDI VQMPBEFE GJMF. 5IF GJMF OBNF JT NBQQFE UP UIF OBNF PG UIF BUUBDINFOU. 5IF DPOUFOU UZQF JT TFU BT UIF DPOUFOU UZQF PG UIF BUUBDINFOU GJMF OBNF. :PV DBO GJOE UIF FYBNQMF IFSF.
Listing 1. Note: getName() functions as shown below in versions 2.5 and higher. In earlier versions you receive the temporary file name for the attachment instead
// Set the jetty temp directory which store the file for multi part form // camel-jetty will clean up the file after it handled the request. // The option works rightly from Camel 2.4.0 getContext().getProperties().put("CamelJettyTempDir", "target"); from("jetty://http://localhost:{{port}}/test").process(new Processor() { public void process(Exchange exchange) throws Exception { Message in = exchange.getIn(); assertEquals("Get a wrong attachement size", 1, in.getAttachments().size()); // The file name is attachment id DataHandler data = in.getAttachment("NOTICE.txt"); assertNotNull("Should get the DataHandle NOTICE.txt", data); // This assert is wrong, but the correct content-type (application/ octet-stream) // will not be returned until Jetty makes it available - currently the content-type // returned is just the default for FileDataHandler (for the implentation being used) //assertEquals("Get a wrong content type", "text/plain", data.getContentType()); assertEquals("Got the wrong name", "NOTICE.txt", data.getName()); assertTrue("We should get the data from the DataHandle", data.getDataSource() .getInputStream().available() > 0); // The other form date can be get from the message header exchange.getOut().setBody(in.getHeader("comment")); } });

752

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)BQQV ),7 PRMMLOQ 'SPN $BNFM 2.3.0, DBNFM-KFUUZ TVQQPSUT UIF FOBCMJOH PG +FUUZ'T +.9 DBQBCJMJUJFT BU UIF DPNQPOFOU BOE FOEQPJOU MFWFM XJUI UIF FOEQPJOU DPOGJHVSBUJPO UBLJOH QSJPSJUZ. /PUF UIBU +.9 NVTU CF FOBCMFE XJUIJO UIF $BNFM DPOUFYU JO PSEFS UP FOBCMF +.9 TVQQPSU JO UIJT DPNQPOFOU BT UIF DPNQPOFOU QSPWJEFT +FUUZ XJUI B SFGFSFODF UP UIF .#FBO4FSWFS SFHJTUFSFE XJUI UIF $BNFM DPOUFYU. #FDBVTF UIF DBNFM-KFUUZ DPNQPOFOU DBDIFT BOE SFVTFT +FUUZ SFTPVSDFT GPS B HJWFO QSPUPDPM/IPTU/QPSU QBJSJOH, UIJT DPOGJHVSBUJPO PQUJPO XJMM POMZ CF FWBMVBUFE EVSJOH UIF DSFBUJPO PG UIF GJSTU FOEQPJOU UP VTF B QSPUPDPM/IPTU/QPSU QBJSJOH. 'PS FYBNQMF, HJWFO UXP SPVUFT DSFBUFE GSPN UIF GPMMPXJOH 9.- GSBHNFOUT, +.9 TVQQPSU XPVME SFNBJO FOBCMFE GPS BMM FOEQPJOUT MJTUFOJOH PO "IUUQT://0.0.0.0".
<from uri="jetty:https://0.0.0.0/myapp/myservice1/?enableJmx=true"/>

<from uri="jetty:https://0.0.0.0/myapp/myservice2/?enableJmx=false"/>

5IF DBNFM-KFUUZ DPNQPOFOU BMTP QSPWJEFT GPS EJSFDU DPOGJHVSBUJPO PG UIF +FUUZ .#FBO$POUBJOFS. +FUUZ DSFBUFT .#FBO OBNFT EZOBNJDBMMZ. *G ZPV BSF SVOOJOH BOPUIFS JOTUBODF PG +FUUZ PVUTJEF PG UIF $BNFM DPOUFYU BOE TIBSJOH UIF TBNF .#FBO4FSWFS CFUXFFO UIF JOTUBODFT, ZPV DBO QSPWJEF CPUI JOTUBODFT XJUI B SFGFSFODF UP UIF TBNF .#FBO$POUBJOFS JO PSEFS UP BWPJE OBNF DPMMJTJPOT XIFO SFHJTUFSJOH +FUUZ .#FBOT. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE )551

)(-& ".,/.-$-3
5IF +JOH DPNQPOFOU VTFT UIF +JOH -JCSBSZ UP QFSGPSN 9.- WBMJEBUJPO PG UIF NFTTBHF CPEZ VTJOH FJUIFS ` 3FMBY/( 9.- 4ZOUBY ` 3FMBY/( $PNQBDU 4ZOUBY .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jing</artifactId> <version>x.x.x</version>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

753

<!-- use the same version as your Camel core version --> </dependency>

/PUF UIBU UIF .47 DPNQPOFOU DBO BMTP TVQQPSU 3FMBY/( 9.- TZOUBY. 41( CLOJ>Q
rng:someLocalOrRemoteResource rnc:someLocalOrRemoteResource

8IFSF OKD NFBOT VTF UIF 3FMBY/( 9.- 4ZOUBY XIFSFBT OK@ NFBOT VTF 3FMBY/( $PNQBDU 4ZOUBY. 5IF GPMMPXJOH FYBNQMFT TIPX QPTTJCMF 63* WBMVFT $U>JMIB SOH:GPP/CBS.SOH SOD: IUUQ://GPP.DPN/ CBS.SOD #BP@OFMQFLK 3FGFSFODFT UIF 9.- GJMF CLL/?>O.OKD PO UIF DMBTTQBUI 3FGFSFODFT UIF 3FMBY/( $PNQBDU 4ZOUBY GJMF GSPN UIF 63-, IUUQ://GPP.DPN/CBS.SOD

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP .MQFLK useDom #BC>RIQ false #BP@OFMQFLK 4QFDJGJFT XIFUIFS %0.4PVSDF/%0.3FTVMU PS 4BY4PVSDF/4BY3FTVMU TIPVME CF VTFE CZ UIF WBMJEBUPS.

$U>JMIB 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DPOGJHVSF B SPVUF GSPN UIF FOEQPJOU AFOB@Q:PQ>OQ XIJDI UIFO HPFT UP POF PG UXP FOEQPJOUT, FJUIFS JL@H:S>IFA PS JL@H:FKS>IFA CBTFE PO XIFUIFS PS OPU UIF 9.- NBUDIFT UIF HJWFO 3FMBY/( $PNQBDU 4ZOUBY TDIFNB (XIJDI JT TVQQMJFE PO UIF DMBTTQBUI).
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <doTry> <to uri="rnc:org/apache/camel/component/validator/jing/schema.rnc"/> <to uri="mock:valid"/> <doCatch>

754

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<exception>org.apache.camel.ValidationException</exception> <to uri="mock:invalid"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route> </camelContext>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

),2 ".,/.-$-3
5IF +.4 DPNQPOFOU BMMPXT NFTTBHFT UP CF TFOU UP (PS DPOTVNFE GSPN) B +.4 2VFVF PS 5PQJD. 5IF JNQMFNFOUBUJPO PG UIF +.4 $PNQPOFOU VTFT 4QSJOH'T +.4 TVQQPSU GPS EFDMBSBUJWF USBOTBDUJPOT, VTJOH 4QSJOH'T JmsTemplate GPS TFOEJOH BOE B MessageListenerContainer GPS DPOTVNJOH. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jms</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
jms:[queue:|topic:]destinationName[?options]

8IFSF destinationName JT B +.4 RVFVF PS UPQJD OBNF. #Z EFGBVMU, UIF destinationName JT JOUFSQSFUFE BT B RVFVF OBNF. 'PS FYBNQMF, UP DPOOFDU UP UIF RVFVF, FOO.BAR VTF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

755

4PFKD @QFSB,0 *G ZPV BSF VTJOH "QBDIF "DUJWF.2, ZPV TIPVME QSFGFS UIF "DUJWF.2 DPNQPOFOU BT JU IBT CFFO PQUJNJ[FE GPS "DUJWF.2. "MM PG UIF PQUJPOT BOE TBNQMFT PO UIJT QBHF BSF BMTP WBMJE GPS UIF "DUJWF.2 DPNQPOFOU.

3O>KP>@QBA >KA @>@EFKD 4FF TFDUJPO Transactions and Cache Levels CFMPX JG ZPV BSF VTJOH USBOTBDUJPOT XJUI +.4 BT JU DBO JNQBDU QFSGPSNBODF.

1BNRBPQ/1BMIV LSBO ),2 .BLF TVSF UP SFBE UIF TFDUJPO Request-reply over JMS GVSUIFS CFMPX PO UIJT QBHF GPS JNQPSUBOU OPUFT BCPVU SFRVFTU/SFQMZ, BT $BNFM PGGFST B OVNCFS PG PQUJPOT UP DPOGJHVSF GPS QFSGPSNBODF, BOE DMVTUFSFE FOWJSPONFOUT.

jms:FOO.BAR

:PV DBO JODMVEF UIF PQUJPOBM queue: QSFGJY, JG ZPV QSFGFS:


jms:queue:FOO.BAR

5P DPOOFDU UP B UPQJD, ZPV must JODMVEF UIF topic: QSFGJY. 'PS FYBNQMF, UP DPOOFDU UP UIF UPQJD, Stocks.Prices, VTF:
jms:topic:Stocks.Prices

:PV BQQFOE RVFSZ PQUJPOT UP UIF 63* VTJOH UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

756

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

-LQBP

4PFKD

@QFSB,0

5IF +.4 DPNQPOFOU SFVTFT 4QSJOH 2'T JmsTemplate GPS TFOEJOH NFTTBHFT. 5IJT JT OPU JEFBM GPS VTF JO B OPO-+2&& DPOUBJOFS BOE UZQJDBMMZ SFRVJSFT TPNF DBDIJOH JO UIF +.4 QSPWJEFS UP BWPJE QPPS QFSGPSNBODF. *G ZPV JOUFOE UP VTF "QBDIF "DUJWF.2 BT ZPVS .FTTBHF #SPLFS - XIJDI JT B HPPE DIPJDF BT "DUJWF.2 SPDLT , UIFO XF SFDPNNFOE UIBU ZPV FJUIFS: ` 6TF UIF "DUJWF.2 DPNQPOFOU, XIJDI JT BMSFBEZ PQUJNJ[FE UP VTF "DUJWF.2 FGGJDJFOUMZ ` 6TF UIF PoolingConnectionFactory JO "DUJWF.2.

3O>KP>@QFLKP >KA ">@EB +BSBIP


*G ZPV BSF DPOTVNJOH NFTTBHFT BOE VTJOH USBOTBDUJPOT (transacted=true) UIFO UIF EFGBVMU TFUUJOHT GPS DBDIF MFWFM DBO JNQBDU QFSGPSNBODF. *G ZPV BSF VTJOH 9" USBOTBDUJPOT UIFO ZPV DBOOPU DBDIF BT JU DBO DBVTF UIF 9" USBOTBDUJPO UP OPU XPSL QSPQFSMZ. *G ZPV BSF KLQ VTJOH 9", UIFO ZPV TIPVME DPOTJEFS DBDIJOH BT JU TQFFET VQ QFSGPSNBODF, TVDI BT TFUUJOH cacheLevelName=CACHE_CONSUMER. 5ISPVHI $BNFM 2.7.Y, UIF EFGBVMU TFUUJOH GPS cacheLevelName JT CACHE_CONSUMER. :PV XJMM OFFE UP FYQMJDJUMZ TFU cacheLevelName=CACHE_NONE. *O $BNFM 2.8 POXBSET, UIF EFGBVMU TFUUJOH GPS cacheLevelName JT CACHE_AUTO. 5IJT EFGBVMU BVUP EFUFDUT UIF NPEF BOE TFUT UIF DBDIF MFWFM BDDPSEJOHMZ UP: $"$)&@$0/46.&3 = JG USBOTBDUFE=GBMTF $"$)&@/0/& = JG USBOTBDUFE=USVF 4P ZPV DBO TBZ UIF EFGBVMU TFUUJOH JT DPOTFSWBUJWF. $POTJEFS VTJOH cacheLevelName=CACHE_CONSUMER JG ZPV BSF VTJOH OPO-9" USBOTBDUJPOT.

#RO>?IB 2R?P@OFMQFLKP
*G ZPV XJTI UP VTF EVSBCMF UPQJD TVCTDSJQUJPOT, ZPV OFFE UP TQFDJGZ CPUI @IFBKQ(A BOE ARO>?IB2R?P@OFMQFLK->JB. 5IF WBMVF PG UIF clientId NVTU CF VOJRVF BOE DBO POMZ CF VTFE CZ B TJOHMF +.4 DPOOFDUJPO JOTUBODF JO ZPVS FOUJSF OFUXPSL. :PV NBZ QSFGFS UP VTF 7JSUVBM 5PQJDT JOTUFBE UP BWPJE UIJT MJNJUBUJPO. .PSF CBDLHSPVOE PO EVSBCMF NFTTBHJOH IFSF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

757

,BPP>DB 'B>ABO ,>MMFKD


8IFO VTJOH NFTTBHF IFBEFST, UIF +.4 TQFDJGJDBUJPO TUBUFT UIBU IFBEFS OBNFT NVTU CF WBMJE +BWB JEFOUJGJFST. 4P USZ UP OBNF ZPVS IFBEFST UP CF WBMJE +BWB JEFOUJGJFST. 0OF CFOFGJU PG EPJOH UIJT JT UIBU ZPV DBO UIFO VTF ZPVS IFBEFST JOTJEF B +.4 4FMFDUPS (XIPTF 42-92 TZOUBY NBOEBUFT +BWB JEFOUJGJFS TZOUBY GPS IFBEFST). " TJNQMF TUSBUFHZ GPS NBQQJOH IFBEFS OBNFT JT VTFE CZ EFGBVMU. 5IF TUSBUFHZ JT UP SFQMBDF BOZ EPUT BOE IZQIFOT JO UIF IFBEFS OBNF BT TIPXO CFMPX BOE UP SFWFSTF UIF SFQMBDFNFOU XIFO UIF IFBEFS OBNF JT SFTUPSFE GSPN B +.4 NFTTBHF TFOU PWFS UIF XJSF. 8IBU EPFT UIJT NFBO /P NPSF MPTJOH NFUIPE OBNFT UP JOWPLF PO B CFBO DPNQPOFOU, OP NPSF MPTJOH UIF GJMFOBNF IFBEFS GPS UIF 'JMF $PNQPOFOU, BOE TP PO. 5IF DVSSFOU IFBEFS OBNF TUSBUFHZ GPS BDDFQUJOH IFBEFS OBNFT JO $BNFM JT BT GPMMPXT: %PUT BSF SFQMBDFE CZ _DOT_ BOE UIF SFQMBDFNFOU JT SFWFSTFE XIFO $BNFM DPOTVNF UIF NFTTBHF )ZQIFO JT SFQMBDFE CZ _HYPHEN_ BOE UIF SFQMBDFNFOU JT SFWFSTFE XIFO $BNFM DPOTVNFT UIF NFTTBHF .MQFLKP :PV DBO DPOGJHVSF NBOZ EJGGFSFOU QSPQFSUJFT PO UIF +.4 FOEQPJOU XIJDI NBQ UP QSPQFSUJFT PO UIF +.4$POGJHVSBUJPO 10+0. 5IF PQUJPOT BSF EJWJEFE JOUP UXP UBCMFT, UIF GJSTU POF XJUI UIF NPTU DPNNPO PQUJPOT VTFE. 5IF MBUUFS DPOUBJOT UIF SFTU.

,LPQ @LJJLKIV RPBA LMQFLKP


.MQFLK
clientId

#BC>RIQ 5>IRB
null

#BP@OFMQFLK
4FUT UIF +.4 DMJFOU *% UP VTF. /PUF UIBU UIJT WBMVF, JG TQFDJGJFE, NVTU CF VOJRVF BOE DBO POMZ CF VTFE CZ B TJOHMF +.4 DPOOFDUJPO JOTUBODF. *U JT UZQJDBMMZ POMZ SFRVJSFE GPS EVSBCMF UPQJD TVCTDSJQUJPOT. :PV NBZ QSFGFS UP VTF 7JSUVBM 5PQJDT JOTUFBE. 4QFDJGJFT UIF EFGBVMU OVNCFS PG DPODVSSFOU DPOTVNFST. 'SPN ">JBI 2.10.3 POXBSET UIJT PQUJPO DBO BMTP CF VTFE XIFO EPJOH SFRVFTU/SFQMZ PWFS +.4. 4FF BMTP UIF maxMessagesPerTask PQUJPO UP DPOUSPM EZOBNJD TDBMJOH VQ/EPXO PG UISFBET. *G true, B QSPEVDFS XJMM CFIBWF MJLF B *O0OMZ FYDIBOHF XJUI UIF FYDFQUJPO UIBU JMSReplyTo IFBEFS JT TFOU PVU BOE OPU CF TVQQSFTTFE MJLF JO UIF DBTF PG InOnly. -JLF InOnly UIF QSPEVDFS XJMM OPU XBJU GPS B SFQMZ. " DPOTVNFS XJUI UIJT GMBH XJMM CFIBWF MJLF InOnly. 5IJT GFBUVSF DBO CF VTFE UP CSJEHF InOut SFRVFTUT UP BOPUIFS RVFVF TP UIBU B SPVUF PO UIF PUIFS RVFVF XJMM TFOE JUbT SFTQPOTF EJSFDUMZ CBDL UP UIF PSJHJOBM JMSReplyTo. 5IF EVSBCMF TVCTDSJCFS OBNF GPS TQFDJGZJOH EVSBCMF UPQJD TVCTDSJQUJPOT. 5IF clientId PQUJPO JRPQ CF DPOGJHVSFE BT XFMM. 4QFDJGJFT UIF NBYJNVN OVNCFS PG DPODVSSFOU DPOTVNFST. 'SPN ">JBI 2.10.3 POXBSET UIJT PQUJPO DBO BMTP CF VTFE XIFO EPJOH SFRVFTU/SFQMZ PWFS +.4. 4FF BMTP UIF maxMessagesPerTask PQUJPO UP DPOUSPM EZOBNJD TDBMJOH VQ/EPXO PG UISFBET. 5IF OVNCFS PG NFTTBHFT QFS UBTL. -1 JT VOMJNJUFE. *G ZPV VTF B SBOHF GPS DPODVSSFOU DPOTVNFST (FH NJO < NBY), UIFO UIJT PQUJPO DBO CF VTFE UP TFU B WBMVF UP FH 100 UP DPOUSPM IPX GBTU UIF DPOTVNFST XJMM TISJOL XIFO MFTT XPSL JT SFRVJSFE. 4FU UP true, JG ZPV XBOU UP TFOE NFTTBHF VTJOH UIF 2P4 TFUUJOHT TQFDJGJFE PO UIF NFTTBHF, JOTUFBE PG UIF 2P4 TFUUJOHT PO UIF +.4 FOEQPJOU. 5IF GPMMPXJOH UISFF IFBEFST BSF DPOTJEFSFE JMSPriority, JMSDeliveryMode, BOE JMSExpiration. :PV DBO QSPWJEF BMM PS POMZ TPNF PG UIFN. *G OPU QSPWJEFE, $BNFM XJMM GBMM CBDL UP VTF UIF WBMVFT GSPN UIF FOEQPJOU JOTUFBE. 4P, XIFO VTJOH UIJT PQUJPO, UIF IFBEFST PWFSSJEF UIF WBMVFT GSPN UIF FOEQPJOU. 5IF explicitQosEnabled PQUJPO, CZ DPOUSBTU, XJMM POMZ VTF PQUJPOT TFU PO UIF FOEQPJOU, BOE OPU WBMVFT GSPN UIF NFTTBHF IFBEFS.

concurrentConsumers

disableReplyTo

false

durableSubscriptionName

null

maxConcurrentConsumers

maxMessagesPerTask

-1

preserveMessageQos

false

758

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

,>MMFKD QL 2MOFKD ),2 .BOZ PG UIFTF QSPQFSUJFT NBQ UP QSPQFSUJFT PO 4QSJOH +.4, XIJDI $BNFM VTFT GPS TFOEJOH BOE SFDFJWJOH NFTTBHFT. 4P ZPV DBO HFU NPSF JOGPSNBUJPO BCPVU UIFTF QSPQFSUJFT CZ DPOTVMUJOH UIF SFMFWBOU 4QSJOH EPDVNFOUBUJPO.
1SPWJEFT BO FYQMJDJU 3FQMZ5P EFTUJOBUJPO, XIJDI PWFSSJEFT BOZ JODPNJOH WBMVF PG Message.getJMSReplyTo(). *G ZPV EP 3FRVFTU 3FQMZ PWFS +.4 UIFO J>HB PROB UP SFBE UIF TFDUJPO Request-reply over JMS GVSUIFS CFMPX GPS NPSF EFUBJMT, BOE UIF replyToType PQUJPO BT XFMM. ">JBI 2.9: "MMPXT GPS FYQMJDJUMZ TQFDJGZJOH XIJDI LJOE PG TUSBUFHZ UP VTF GPS SFQMZ5P RVFVFT XIFO EPJOH SFRVFTU/SFQMZ PWFS +.4. 1PTTJCMF WBMVFT BSF: Temporary, Shared, PS Exclusive. #Z EFGBVMU $BNFM XJMM VTF UFNQPSBSZ RVFVFT. )PXFWFS JG replyTo IBT CFFO DPOGJHVSFE, UIFO Shared JT VTFE CZ EFGBVMU. 5IJT PQUJPO BMMPXT ZPV UP VTF FYDMVTJWF RVFVFT JOTUFBE PG TIBSFE POFT. 4FF GVSUIFS CFMPX GPS NPSF EFUBJMT, BOE FTQFDJBMMZ UIF OPUFT BCPVU UIF JNQMJDBUJPOT JG SVOOJOH JO B DMVTUFSFE FOWJSPONFOU, BOE UIF GBDU UIBU Shared SFQMZ RVFVFT IBT MPXFS QFSGPSNBODF UIBO JUT BMUFSOBUJWFT Temporary BOE Exclusive. /OLAR@BO LKIV: 5IF UJNFPVU GPS XBJUJOH GPS B SFQMZ XIFO VTJOH UIF *O0VU &YDIBOHF 1BUUFSO (JO NJMMJTFDPOET). 5IF EFGBVMU JT 20 TFDPOET. 4FF CFMPX JO TFDUJPO About time to live GPS NPSF EFUBJMT. 4FF BMTP UIF requestTimeoutCheckerInterval PQUJPO. 4FUT UIF +.4 4FMFDUPS, XIJDI JT BO 42- 92 QSFEJDBUF UIBU JT VTFE UP GJMUFS NFTTBHFT XJUIJO UIF CSPLFS. :PV NBZ IBWF UP FODPEF TQFDJBM DIBSBDUFST TVDI BT = BT %3% !BCLOB ">JBI 2.3.0, XF EPO'U TVQQPSU UIJT PQUJPO JO $BNFM$POTVNFS5FNQMBUF 8IFO TFOEJOH NFTTBHFT, TQFDJGJFT UIF UJNF-UP-MJWF PG UIF NFTTBHF (JO NJMMJTFDPOET). 4FF CFMPX JO TFDUJPO About time to live GPS NPSF EFUBJMT. 4QFDJGJFT XIFUIFS UP VTF USBOTBDUFE NPEF GPS TFOEJOH/SFDFJWJOH NFTTBHFT VTJOH UIF *O0OMZ &YDIBOHF 1BUUFSO. ">JBI 2.1: 4QFDJGJFT XIFUIFS UP UFTU UIF DPOOFDUJPO PO TUBSUVQ. 5IJT FOTVSFT UIBU XIFO $BNFM TUBSUT UIBU BMM UIF +.4 DPOTVNFST IBWF B WBMJE DPOOFDUJPO UP UIF +.4 CSPLFS. *G B DPOOFDUJPO DBOOPU CF HSBOUFE UIFO $BNFM UISPXT BO FYDFQUJPO PO TUBSUVQ. 5IJT FOTVSFT UIBU $BNFM JT OPU TUBSUFE XJUI GBJMFE DPOOFDUJPOT. 'SPN ">JBI 2.8 POXBSET BMTP UIF +.4 QSPEVDFST JT UFTUFE BT XFMM.

replyTo

null

replyToType

null

requestTimeout

20000

selector

null

timeToLive transacted

null false

testConnectionOnStartup

false

II QEB LQEBO LMQFLKP


.MQFLK #BC>RIQ 5>IRB #BP@OFMQFLK
4QFDJGJFT XIFUIFS UIF DPOTVNFS BDDFQU NFTTBHFT XIJMF JU JT TUPQQJOH. :PV NBZ DPOTJEFS FOBCMJOH UIJT PQUJPO, JG ZPV TUBSU BOE TUPQ +.4 SPVUFT BU SVOUJNF, XIJMF UIFSF BSF TUJMM NFTTBHFT FORVFE PO UIF RVFVF. *G UIJT PQUJPO JT false, BOE ZPV TUPQ UIF +.4 SPVUF, UIFO NFTTBHFT NBZ CF SFKFDUFE, BOE UIF +.4 CSPLFS XPVME IBWF UP BUUFNQU SFEFMJWFSJFT, XIJDI ZFU BHBJO NBZ CF SFKFDUFE, BOE FWFOUVBMMZ UIF NFTTBHF NBZ CF NPWFE BU B EFBE MFUUFS RVFVF PO UIF +.4 CSPLFS. 5P BWPJE UIJT JUT SFDPNNFOEFE UP FOBCMF UIJT PQUJPO. 5IF +.4 BDLOPXMFEHFNFOU OBNF, XIJDI JT POF PG: SESSION_TRANSACTED, CLIENT_ACKNOWLEDGE, AUTO_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE 5IF +.4 BDLOPXMFEHFNFOU NPEF EFGJOFE BT BO *OUFHFS. "MMPXT ZPV UP TFU WFOEPS-TQFDJGJD FYUFOTJPOT UP UIF BDLOPXMFEHNFOU NPEF. 'PS UIF SFHVMBS NPEFT, JU JT QSFGFSBCMF UP VTF UIF acknowledgementModeName JOTUFBE. ">JBI 2.9.3/2.10.1: 8IFUIFS UP BMMPX TFOEJOH NFTTBHFT XJUI OP CPEZ. *G UIJT PQUJPO JT false BOE UIF NFTTBHF CPEZ JT OVMM, UIFO BO JMSException JT UISPXO. *G true, $BNFM XJMM BMXBZT NBLF B +.4 NFTTBHF DPQZ PG UIF NFTTBHF XIFO JU JT QBTTFE UP UIF QSPEVDFS GPS TFOEJOH. $PQZJOH UIF NFTTBHF JT OFFEFE JO TPNF TJUVBUJPOT, TVDI BT XIFO B replyToDestinationSelectorName JT TFU (JODJEFOUBMMZ, $BNFM XJMM TFU UIF alwaysCopyMessage PQUJPO UP true, JG B replyToDestinationSelectorName JT TFU) ">JBI 2.9: 8IFUIFS UIF JmsConsumer QSPDFTTFT UIF &YDIBOHF BTZODISPOPVTMZ. *G FOBCMFE UIFO UIF JmsConsumer NBZ QJDLVQ UIF OFYU NFTTBHF GSPN UIF +.4 RVFVF, XIJMF UIF QSFWJPVT NFTTBHF JT CFJOH QSPDFTTFE BTZODISPOPVTMZ (CZ UIF "TZODISPOPVT 3PVUJOH &OHJOF). 5IJT NFBOT UIBU NFTTBHFT NBZ CF QSPDFTTFE OPU 100% TUSJDUMZ JO PSEFS. *G EJTBCMFE (BT EFGBVMU) UIFO UIF &YDIBOHF JT GVMMZ QSPDFTTFE CFGPSF UIF JmsConsumer XJMM QJDLVQ UIF OFYU NFTTBHF GSPN UIF +.4 RVFVF. /PUF JG transacted IBT CFFO FOBCMFE, UIFO asyncConsumer=true EPFT OPU SVO BTZODISPOPVTMZ, BT USBOTBDUJPOT NVTU CF FYFDVUFE TZODISPOPVTMZ ($BNFM 3.0 NBZ TVQQPSU BTZOD USBOTBDUJPOT).

acceptMessagesWhileStopping

false

acknowledgementModeName

AUTO_ACKNOWLEDGE

acknowledgementMode

-1

allowNullBody

true

alwaysCopyMessage

false

asyncConsumer

false

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

759

asyncStartListener

false

">JBI 2.10: 8IFUIFS UP TUBSUVQ UIF JmsConsumer NFTTBHF MJTUFOFS BTZODISPOPVTMZ, XIFO TUBSUJOH B SPVUF. 'PS FYBNQMF JG B JmsConsumer DBOOPU HFU B DPOOFDUJPO UP B SFNPUF +.4 CSPLFS, UIFO JU NBZ CMPDL XIJMF SFUSZJOH BOE/PS GBJMPWFS. 5IJT XJMM DBVTF $BNFM UP CMPDL XIJMF TUBSUJOH SPVUFT. #Z TFUUJOH UIJT PQUJPO UP true, ZPV XJMM MFU SPVUFT TUBSUVQ, XIJMF UIF JmsConsumer DPOOFDUT UP UIF +.4 CSPLFS VTJOH B EFEJDBUFE UISFBE JO BTZODISPOPVT NPEF. *G UIJT PQUJPO JT VTFE, UIFO CFXBSF UIBU JG UIF DPOOFDUJPO DPVME OPU CF FTUBCMJTIFE, UIFO BO FYDFQUJPO JT MPHHFE BU WARN MFWFM, BOE UIF DPOTVNFS XJMM OPU CF BCMF UP SFDFJWF NFTTBHFT; :PV DBO UIFO SFTUBSU UIF SPVUF UP SFUSZ. ">JBI 2.10: 8IFUIFS UP TUPQ UIF JmsConsumer NFTTBHF MJTUFOFS BTZODISPOPVTMZ, XIFO TUPQQJOH B SPVUF. 4QFDJGJFT XIFUIFS UIF DPOTVNFS DPOUBJOFS TIPVME BVUP-TUBSUVQ. 4FUT UIF DBDIF MFWFM CZ OBNF GPS UIF VOEFSMZJOH +.4 SFTPVSDFT. 1PTTJCMF WBMVFT BSF: CACHE_AUTO, CACHE_CONNECTION, CACHE_CONSUMER, CACHE_NONE, BOE CACHE_SESSION. 5IF EFGBVMU TFUUJOH GPS ">JBI 2.8 BOE OFXFS JT CACHE_AUTO. 'PS ">JBI 2.7.1 BOE PMEFS UIF EFGBVMU JT CACHE_CONSUMER. 4FF UIF 4QSJOH EPDVNFOUBUJPO BOE 5SBOTBDUJPOT $BDIF -FWFMT GPS NPSF JOGPSNBUJPO. 4FUT UIF DBDIF MFWFM CZ *% GPS UIF VOEFSMZJOH +.4 SFTPVSDFT. 4FF cacheLevelName PQUJPO GPS NPSF EFUBJMT. 5IF DPOTVNFS UZQF UP VTF, XIJDI DBO CF POF PG: Simple, Default, PS Custom. 5IF DPOTVNFS UZQF EFUFSNJOFT XIJDI 4QSJOH +.4 MJTUFOFS UP VTF. Default XJMM VTF org.springframework.jms.listener.DefaultMessageListenerContainer, Simple XJMM VTF org.springframework.jms.listener.SimpleMessageListenerContainer. 8IFO Custom JT TQFDJGJFE, UIF MessageListenerContainerFactory EFGJOFE CZ UIF messageListenerContainerFactoryRef PQUJPO XJMM EFUFSNJOF XIBU org.springframework.jms.listener.AbstractMessageListenerContainer UP VTF (KBT LMQFLK FK ">JBI 2.10.2 LKT>OAP). 5IJT PQUJPO XBT UFNQPSBSZ SFNPWFE JO $BNFM 2.7 BOE 2.8. #VU IBT CFFO BEEFE CBDL GSPN $BNFM 2.9 POXBSET. 5IF EFGBVMU +.4 DPOOFDUJPO GBDUPSZ UP VTF GPS UIF listenerConnectionFactory BOE templateConnectionFactory, JG OFJUIFS JT TQFDJGJFE. ">JBI 2.10.4: 4QFDJGJFT XIBU EFGBVMU 5BTL&YFDVUPS UZQF UP VTF JO UIF %FGBVMU.FTTBHF-JTUFOFS$POUBJOFS, GPS CPUI DPOTVNFS FOEQPJOUT BOE UIF 3FQMZ5P DPOTVNFS PG QSPEVDFS FOEQPJOUT. 1PTTJCMF WBMVFT: SimpleAsync (VTFT 4QSJOH'T 4JNQMF"TZOD5BTL&YFDVUPS) PS ThreadPool (VTFT 4QSJOH'T 5ISFBE1PPM5BTL&YFDVUPS XJUI PQUJNBM WBMVFT - DBDIFE UISFBEQPPM-MJLF). *G OPU TFU, JU EFGBVMUT UP UIF QSFWJPVT CFIBWJPVS, XIJDI VTFT B DBDIFE UISFBE QPPM GPS DPOTVNFS FOEQPJOUT BOE 4JNQMF"TZOD GPS SFQMZ DPOTVNFST. 5IF VTF PG ThreadPool JT SFDPNNFOEFE UP SFEVDF "UISFBE USBTI" JO FMBTUJD DPOGJHVSBUJPOT XJUI EZOBNJDBMMZ JODSFBTJOH BOE EFDSFBTJOH DPODVSSFOU DPOTVNFST. 4QFDJGJFT XIFUIFS QFSTJTUFOU EFMJWFSZ JT VTFE CZ EFGBVMU. 4QFDJGJFT UIF +.4 %FTUJOBUJPO PCKFDU UP VTF PO UIJT FOEQPJOU. 4QFDJGJFT UIF +.4 EFTUJOBUJPO OBNF UP VTF PO UIJT FOEQPJOU. " QMVHHBCMF org.springframework.jms.support.destination.DestinationResolver UIBU BMMPXT ZPV UP VTF ZPVS PXO SFTPMWFS (GPS FYBNQMF, UP MPPLVQ UIF SFBM EFTUJOBUJPO JO B +/%* SFHJTUSZ). ">JBI 2.8: 6TF UIJT PQUJPO UP GPSDF EJTBCMJOH UJNF UP MJWF. 'PS FYBNQMF XIFO ZPV EP SFRVFTU/ SFQMZ PWFS +.4, UIFO $BNFM XJMM CZ EFGBVMU VTF UIF requestTimeout WBMVF BT UJNF UP MJWF PO UIF NFTTBHF CFJOH TFOU. 5IF QSPCMFN JT UIBU UIF TFOEFS BOE SFDFJWFS TZTUFNT IBWF UP IBWF UIFJS DMPDLT TZODISPOJ[FE, TP UIFZ BSF JO TZOD. 5IJT JT OPU BMXBZT TP FBTZ UP BSDIJWF. 4P ZPV DBO VTF disableTimeToLive=true UP KLQ TFU B UJNF UP MJWF WBMVF PO UIF TFOU NFTTBHF. 5IFO UIF NFTTBHF XJMM OPU FYQJSF PO UIF SFDFJWFS TZTUFN. 4FF CFMPX JO TFDUJPO About time to live GPS NPSF EFUBJMT. &OBCMFT FBHFS MPBEJOH PG +.4 QSPQFSUJFT BT TPPO BT B NFTTBHF JT SFDFJWFE, XIJDI JT HFOFSBMMZ JOFGGJDJFOU, CFDBVTF UIF +.4 QSPQFSUJFT NJHIU OPU CF SFRVJSFE. #VU UIJT GFBUVSF DBO TPNFUJNFT DBUDI FBSMZ BOZ JTTVFT XJUI UIF VOEFSMZJOH +.4 QSPWJEFS BOE UIF VTF PG +.4 QSPQFSUJFT. 5IJT GFBUVSF DBO BMTP CF VTFE GPS UFTUJOH QVSQPTFT, UP FOTVSF +.4 QSPQFSUJFT DBO CF VOEFSTUPPE BOE IBOEMFE DPSSFDUMZ. 4QFDJGJFT UIF +.4 &YDFQUJPO -JTUFOFS UIBU JT UP CF OPUJGJFE PG BOZ VOEFSMZJOH +.4 FYDFQUJPOT. ">JBI 2.8.2, 2.9: 4QFDJGJFT B org.springframework.util.ErrorHandler UP CF JOWPLFE JO DBTF PG BOZ VODBVHIU FYDFQUJPOT UISPXO XIJMF QSPDFTTJOH B Message. #Z EFGBVMU UIFTF FYDFQUJPOT XJMM CF MPHHFE BU UIF 8"3/ MFWFM, JG OP errorHandler IBT CFFO DPOGJHVSFE. 'SPN ">JBI 2.9.1: POXBSET ZPV DBO DPOGJHVSF MPHHJOH MFWFM BOE XIFUIFS TUBDL USBDFT TIPVME CF MPHHFE VTJOH UIF CFMPX UXP PQUJPOT. 5IJT NBLFT JU NVDI FBTJFS UP DPOGJHVSF, UIBO IBWJOH UP DPEF B DVTUPN errorHandler. ">JBI 2.9.1: "MMPXT UP DPOGJHVSF UIF EFGBVMU errorHandler MPHHJOH MFWFM GPS MPHHJOH VODBVHIU FYDFQUJPOT. ">JBI 2.9.1: "MMPXT UP DPOUSPM XIFUIFS TUBDLUSBDFT TIPVME CF MPHHFE PS OPU, CZ UIF EFGBVMU errorHandler.

asyncStopListener autoStartup

false true

cacheLevelName

$"$)&@"650 ($BNFM >= 2.8.0) $"$)&@$0/46.&3 ($BNFM <= 2.7.1)

cacheLevel

consumerType

Default

connectionFactory

null

defaultTaskExecutorType

(TFF EFTDSJQUJPO)

deliveryPersistent destination destinationName

true null null

destinationResolver

null

disableTimeToLive

false

eagerLoadingOfProperties

false

exceptionListener

null

errorHandler

null

errorHandlerLoggingLevel errorHandlerLogStackTrace

WARN true

760

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

explicitQosEnabled

false

4FU JG UIF deliveryMode, priority PS timeToLive RVBMJUJFT PG TFSWJDF TIPVME CF VTFE XIFO TFOEJOH NFTTBHFT. 5IJT PQUJPO JT CBTFE PO 4QSJOH'T JmsTemplate. 5IF deliveryMode, priority BOE timeToLive PQUJPOT BSF BQQMJFE UP UIF DVSSFOU FOEQPJOU. 5IJT DPOUSBTUT XJUI UIF preserveMessageQos PQUJPO, XIJDI PQFSBUFT BU NFTTBHF HSBOVMBSJUZ, SFBEJOH 2P4 QSPQFSUJFT FYDMVTJWFMZ GSPN UIF $BNFM *O NFTTBHF IFBEFST. 4QFDJGJFT XIFUIFS UIF MJTUFOFS TFTTJPO TIPVME CF FYQPTFE XIFO DPOTVNJOH NFTTBHFT. ">JBI 2.7: 8IFO VTJOH mapJmsMessage=false $BNFM XJMM DSFBUF B OFX +.4 NFTTBHF UP TFOE UP B OFX +.4 EFTUJOBUJPO JG ZPV UPVDI UIF IFBEFST (HFU PS TFU) EVSJOH UIF SPVUF. 4FU UIJT PQUJPO UP true UP GPSDF $BNFM UP TFOE UIF PSJHJOBM +.4 NFTTBHF UIBU XBT SFDFJWFE. 4QFDJGJFT UIF MJNJU GPS JEMF FYFDVUJPOT PG B SFDFJWF UBTL, OPU IBWJOH SFDFJWFE BOZ NFTTBHF XJUIJO JUT FYFDVUJPO. *G UIJT MJNJU JT SFBDIFE, UIF UBTL XJMM TIVU EPXO BOE MFBWF SFDFJWJOH UP PUIFS FYFDVUJOH UBTLT (JO UIF DBTF PG EZOBNJD TDIFEVMJOH; TFF UIF maxConcurrentConsumers TFUUJOH). ">JBI 2.8.2, 2.9: 4QFDJGZ UIF MJNJU GPS UIF OVNCFS PG DPOTVNFST UIBU BSF BMMPXFE UP CF JEMF BU BOZ HJWFO UJNF. ">JBI 2.10.3: 0OMZ BQQMJDBCMF XIFO TFOEJOH UP +.4 EFTUJOBUJPO VTJOH *O0OMZ (FH GJSF BOE GPSHFU). &OBCMJOH UIJT PQUJPO XJMM FOSJDI UIF $BNFM &YDIBOHF XJUI UIF BDUVBM +.4.FTTBHF*% UIBU XBT VTFE CZ UIF +.4 DMJFOU XIFO UIF NFTTBHF XBT TFOU UP UIF +.4 EFTUJOBUJPO. "MMPXT ZPV UP GPSDF UIF VTF PG B TQFDJGJD javax.jms.Message JNQMFNFOUBUJPO GPS TFOEJOH +.4 NFTTBHFT. 1PTTJCMF WBMVFT BSF: Bytes, Map, Object, Stream, Text. #Z EFGBVMU, $BNFM XPVME EFUFSNJOF XIJDI +.4 NFTTBHF UZQF UP VTF GSPN UIF *O CPEZ UZQF. 5IJT PQUJPO BMMPXT ZPV UP TQFDJGZ JU. 1MVHHBCMF TUSBUFHZ GPS FODPEJOH BOE EFDPEJOH +.4 LFZT TP UIFZ DBO CF DPNQMJBOU XJUI UIF +.4 TQFDJGJDBUJPO. $BNFM QSPWJEFT UXP JNQMFNFOUBUJPOT PVU PG UIF CPY: default BOE passthrough. 5IF default TUSBUFHZ XJMM TBGFMZ NBSTIBM EPUT BOE IZQIFOT (. BOE -). 5IF passthrough TUSBUFHZ MFBWFT UIF LFZ BT JT. $BO CF VTFE GPS +.4 CSPLFST XIJDI EP OPU DBSF XIFUIFS +.4 IFBEFS LFZT DPOUBJO JMMFHBM DIBSBDUFST. :PV DBO QSPWJEF ZPVS PXO JNQMFNFOUBUJPO PG UIF org.apache.camel.component.jms.JmsKeyFormatStrategy BOE SFGFS UP JU VTJOH UIF # OPUBUJPO. "MMPXT ZPV UP VTF ZPVS PXO JNQMFNFOUBUJPO PG UIF org.springframework.jms.core.JmsOperations JOUFSGBDF. $BNFM VTFT JmsTemplate BT EFGBVMU. $BO CF VTFE GPS UFTUJOH QVSQPTF, CVU OPU VTFE NVDI BT TUBUFE JO UIF TQSJOH "1* EPDT. *G true, $BNFM XJMM DSFBUF B JmsTransactionManager, JG UIFSF JT OP transactionManager JOKFDUFE XIFO PQUJPO transacted=true. 5IF +.4 DPOOFDUJPO GBDUPSZ VTFE GPS DPOTVNJOH NFTTBHFT. 4QFDJGJFT XIFUIFS $BNFM TIPVME BVUP NBQ UIF SFDFJWFE +.4 NFTTBHF UP BO BQQSPQJBUF QBZMPBE UZQF, TVDI BT javax.jms.TextMessage UP B String FUD. 4FF TFDUJPO BCPVU IPX NBQQJOH XPSLT CFMPX GPS NPSF EFUBJMT. -JNJUT UIF OVNCFS PG NFTTBHFT GFUDIFE BU NPTU, XIFO CSPXTJOH FOEQPJOUT VTJOH #SPXTF PS +.9 "1*. 5P VTF B DVTUPN 4QSJOH org.springframework.jms.support.converter.MessageConverter TP ZPV DBO CF 100% JO DPOUSPM IPX UP NBQ UP/GSPN B javax.jms.Message. 8IFO TFOEJOH, TQFDJGJFT XIFUIFS NFTTBHF *%T TIPVME CF BEEFE. ">JBI 2.10.2: 3FHJTUSZ *% PG UIF MessageListenerContainerFactory VTFE UP EFUFSNJOF XIBU org.springframework.jms.listener.AbstractMessageListenerContainer UP VTF UP DPOTVNF NFTTBHFT. 4FUUJOH UIJT XJMM BVUPNBUJDBMMZ TFU consumerType UP Custom. 4QFDJGJFT XIFUIFS UJNFTUBNQT TIPVME CF FOBCMFE CZ EFGBVMU PO TFOEJOH NFTTBHFT. 5IF QBTTXPSE GPS UIF DPOOFDUPS GBDUPSZ. 7BMVFT HSFBUFS UIBO 1 TQFDJGZ UIF NFTTBHF QSJPSJUZ XIFO TFOEJOH (XIFSF 0 JT UIF MPXFTU QSJPSJUZ BOE 9 JT UIF IJHIFTU). 5IF explicitQosEnabled PQUJPO JRPQ BMTP CF FOBCMFE JO PSEFS GPS UIJT PQUJPO UP IBWF BOZ FGGFDU. 4QFDJGJFT XIFUIFS UP JOIJCJU UIF EFMJWFSZ PG NFTTBHFT QVCMJTIFE CZ JUT PXO DPOOFDUJPO. 5IF UJNFPVU GPS SFDFJWJOH NFTTBHFT (JO NJMMJTFDPOET). 4QFDJGJFT UIF JOUFSWBM CFUXFFO SFDPWFSZ BUUFNQUT, J.F. XIFO B DPOOFDUJPO JT CFJOH SFGSFTIFE, JO NJMMJTFDPOET. 5IF EFGBVMU JT 5000 NT, UIBU JT, 5 TFDPOET. ">JBI 2.9.1: 4FUT UIF DBDIF MFWFM CZ OBNF GPS UIF SFQMZ DPOTVNFS XIFO EPJOH SFRVFTU/SFQMZ PWFS +.4. 5IJT PQUJPO POMZ BQQMJFT XIFO VTJOH GJYFE SFQMZ RVFVFT (OPU UFNQPSBSZ). $BNFM XJMM CZ EFGBVMU VTF: CACHE_CONSUMER GPS FYDMVTJWF PS TIBSFE X/ replyToSelectorName. "OE CACHE_SESSION GPS TIBSFE XJUIPVU replyToSelectorName. 4PNF +.4 CSPLFST TVDI BT *#. 8FC4QIFSF NBZ SFRVJSF UP TFU UIF replyToCacheLevelName=CACHE_NONE UP XPSL.

exposeListenerSession forceSendOriginalMessage

true false

idleTaskExecutionLimit

idleConsumerLimit

includeSentJMSMessageID

false

jmsMessageType

null

jmsKeyFormatStrategy

default

jmsOperations

null

lazyCreateTransactionManager listenerConnectionFactory mapJmsMessage

true null true

maximumBrowseSize

-1

messageConverter messageIdEnabled

null true

messageListenerContainerFactoryRef

null

messageTimestampEnabled password priority pubSubNoLocal receiveTimeout recoveryInterval

true null 4 false None 5000

replyToCacheLevelName

$"$)&@$0/46.&3

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

761

replyToDestinationSelectorName replyToDeliveryPersistent

null true

4FUT UIF +.4 4FMFDUPS VTJOH UIF GJYFE OBNF UP CF VTFE TP ZPV DBO GJMUFS PVU ZPVS PXO SFQMJFT GSPN UIF PUIFST XIFO VTJOH B TIBSFE RVFVF (UIBU JT, JG ZPV BSF OPU VTJOH B UFNQPSBSZ SFQMZ RVFVF). 4QFDJGJFT XIFUIFS UP VTF QFSTJTUFOU EFMJWFSZ CZ EFGBVMU GPS SFQMJFT. ">JBI 2.9.2: $POGJHVSFT IPX PGUFO $BNFM TIPVME DIFDL GPS UJNFE PVU &YDIBOHFT XIFO EPJOH SFRVFTU/SFQMZ PWFS +.4.#Z EFGBVMU $BNFM DIFDLT PODF QFS TFDPOE. #VU JG ZPV NVTU SFBDU GBTUFS XIFO B UJNFPVU PDDVST, UIFO ZPV DBO MPXFS UIJT JOUFSWBM, UP DIFDL NPSF GSFRVFOUMZ. 5IF UJNFPVU JT EFUFSNJOFE CZ UIF PQUJPO requestTimeout. @ABMOB@>QBA: &OBCMFE CZ EFGBVMU, JG ZPV TQFDJGZ B durableSubscriberName BOE B clientId. "MMPXT ZPV UP TQFDJGZ B DVTUPN UBTL FYFDVUPS GPS DPOTVNJOH NFTTBHFT. ">JBI 2.6: 5P VTF XIFO VTJOH 4QSJOH 2.Y XJUI $BNFM. "MMPXT ZPV UP TQFDJGZ B DVTUPN UBTL FYFDVUPS GPS DPOTVNJOH NFTTBHFT. 5IF +.4 DPOOFDUJPO GBDUPSZ VTFE GPS TFOEJOH NFTTBHFT. @ABMOB@>QBA: 4QFDJGJFT XIFUIFS UP VTF USBOTBDUFE NPEF GPS TFOEJOH NFTTBHFT VTJOH UIF *O0VU &YDIBOHF 1BUUFSO. "QQMJFT POMZ UP QSPEVDFS FOEQPJOUT. 4FF TFDUJPO &OBCMJOH 5SBOTBDUFE $POTVNQUJPO GPS NPSF EFUBJMT. 5IF 4QSJOH USBOTBDUJPO NBOBHFS UP VTF. 5IF OBNF PG UIF USBOTBDUJPO UP VTF. 5IF UJNFPVU WBMVF PG UIF USBOTBDUJPO (JO TFDPOET), JG VTJOH USBOTBDUFE NPEF. *G FOBCMFE BOE ZPV BSF VTJOH 3FRVFTU 3FQMZ NFTTBHJOH (*O0VU) BOE BO &YDIBOHF GBJMFE PO UIF DPOTVNFS TJEF, UIFO UIF DBVTFE Exception XJMM CF TFOE CBDL JO SFTQPOTF BT B javax.jms.ObjectMessage. *G UIF DMJFOU JT $BNFM, UIF SFUVSOFE Exception JT SFUISPXO. 5IJT BMMPXT ZPV UP VTF $BNFM +.4 BT B CSJEHF JO ZPVS SPVUJOH - GPS FYBNQMF, VTJOH QFSTJTUFOU RVFVFT UP FOBCMF SPCVTU SPVUJOH. /PUJDF UIBU JG ZPV BMTP IBWF QO>KPCBO$U@E>KDB FOBCMFE, UIJT PQUJPO UBLFT QSFDFEFODF. 5IF DBVHIU FYDFQUJPO JT SFRVJSFE UP CF TFSJBMJ[BCMF. 5IF PSJHJOBM Exception PO UIF DPOTVNFS TJEF DBO CF XSBQQFE JO BO PVUFS FYDFQUJPO TVDI BT org.apache.camel.RuntimeCamelException XIFO SFUVSOFE UP UIF QSPEVDFS. :PV DBO USBOTGFS UIF FYDIBOHF PWFS UIF XJSF JOTUFBE PG KVTU UIF CPEZ BOE IFBEFST. 5IF GPMMPXJOH GJFMET BSF USBOTGFSSFE: *O CPEZ, 0VU CPEZ, 'BVMU CPEZ, *O IFBEFST, 0VU IFBEFST, 'BVMU IFBEFST, FYDIBOHF QSPQFSUJFT, FYDIBOHF FYDFQUJPO. 5IJT SFRVJSFT UIBU UIF PCKFDUT BSF TFSJBMJ[BCMF. $BNFM XJMM FYDMVEF BOZ OPO-TFSJBMJ[BCMF PCKFDUT BOE MPH JU BU WARN MFWFM. :PV JRPQ FOBCMF UIJT PQUJPO PO CPUI UIF QSPEVDFS BOE DPOTVNFS TJEF, TP $BNFM LOPXT UIF QBZMPBET JT BO &YDIBOHF BOE OPU B SFHVMBS QBZMPBE. 5IF VTFSOBNF GPS UIF DPOOFDUPS GBDUPSZ. 4QFDJGJFT XIFUIFS JMSMessageID TIPVME BMXBZT CF VTFE BT JMSCorrelationID GPS (K.RQ NFTTBHFT. @ABMOB@>QBA (OBJLSBA COLJ ">JBI 2.5 LKT>OAP): 4QFDJGJFT XIFUIFS UIF PME +.4 "1* TIPVME CF VTFE.

requestTimeoutCheckerInterval

1000

subscriptionDurable taskExecutor taskExecutorSpring2 templateConnectionFactory transactedInOut transactionManager transactionName transactionTimeout

false null null null false null "JmsConsumer[destinationName]" null

transferException

false

transferExchange

false

username useMessageIDAsCorrelationID useVersion102

null false false

,BPP>DB ,>MMFKD ?BQTBBK ),2 >KA ">JBI $BNFM BVUPNBUJDBMMZ NBQT NFTTBHFT CFUXFFO javax.jms.Message BOE org.apache.camel.Message. 8IFO TFOEJOH B +.4 NFTTBHF, $BNFM DPOWFSUT UIF NFTTBHF CPEZ UP UIF GPMMPXJOH +.4 NFTTBHF UZQFT:
!LAV 3VMB
String org.w3c.dom.Node Map java.io.Serializable byte[] java.io.File java.io.Reader java.io.InputStream java.nio.ByteBuffer

),2 ,BPP>DB
javax.jms.TextMessage javax.jms.TextMessage javax.jms.MapMessage javax.jms.ObjectMessage javax.jms.BytesMessage javax.jms.BytesMessage javax.jms.BytesMessage javax.jms.BytesMessage javax.jms.BytesMessage

"LJJBKQ
c 5IF %0. XJMM CF DPOWFSUFE UP String. c c c c c c c

762

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

8IFO SFDFJWJOH B +.4 NFTTBHF, $BNFM DPOWFSUT UIF +.4 NFTTBHF UP UIF GPMMPXJOH CPEZ UZQF:
),2 ,BPP>DB
javax.jms.TextMessage javax.jms.BytesMessage javax.jms.MapMessage javax.jms.ObjectMessage

!LAV 3VMB
String byte[] Map<String, Object> Object

#FP>?IFKD >RQL-J>MMFKD LC ),2 JBPP>DBP


:PV DBO VTF UIF mapJmsMessage PQUJPO UP EJTBCMF UIF BVUP-NBQQJOH BCPWF. *G EJTBCMFE, $BNFM XJMM OPU USZ UP NBQ UIF SFDFJWFE +.4 NFTTBHF, CVU JOTUFBE VTFT JU EJSFDUMZ BT UIF QBZMPBE. 5IJT BMMPXT ZPV UP BWPJE UIF PWFSIFBE PG NBQQJOH BOE MFU $BNFM KVTU QBTT UISPVHI UIF +.4 NFTTBHF. 'PS JOTUBODF, JU FWFO BMMPXT ZPV UP SPVUF javax.jms.ObjectMessage +.4 NFTTBHFT XJUI DMBTTFT ZPV EP KLQ IBWF PO UIF DMBTTQBUI.

4PFKD > @RPQLJ ,BPP>DB"LKSBOQBO


:PV DBO VTF UIF messageConverter PQUJPO UP EP UIF NBQQJOH ZPVSTFMG JO B 4QSJOH org.springframework.jms.support.converter.MessageConverter DMBTT. 'PS FYBNQMF, JO UIF SPVUF CFMPX XF VTF B DVTUPN NFTTBHF DPOWFSUFS XIFO TFOEJOH B NFTTBHF UP UIF +.4 PSEFS RVFVF:
from("file://inbox/ order").to("jms:queue:order?messageConverter=#myMessageConverter");

:PV DBO BMTP VTF B DVTUPN NFTTBHF DPOWFSUFS XIFO DPOTVNJOH GSPN B +.4 EFTUJOBUJPO.

"LKQOLIIFKD QEB J>MMFKD PQO>QBDV PBIB@QBA


:PV DBO VTF UIF GJP,BPP>DB3VMB PQUJPO PO UIF FOEQPJOU 63- UP GPSDF B TQFDJGJD NFTTBHF UZQF GPS BMM NFTTBHFT. *O UIF SPVUF CFMPX, XF QPMM GJMFT GSPN B GPMEFS BOE TFOE UIFN BT javax.jms.TextMessage BT XF IBWF GPSDFE UIF +.4 QSPEVDFS FOEQPJOU UP VTF UFYU NFTTBHFT:
from("file://inbox/order").to("jms:queue:order?jmsMessageType=Text");

:PV DBO BMTP TQFDJGZ UIF NFTTBHF UZQF UP VTF GPS FBDI NFTTBCF CZ TFUUJOH UIF IFBEFS XJUI UIF LFZ CamelJmsMessageType. 'PS FYBNQMF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

763

from("file://inbox/order").setHeader("CamelJmsMessageType", JmsMessageType.Text).to("jms:queue:order");

5IF QPTTJCMF WBMVFT BSF EFGJOFE JO UIF enum DMBTT, org.apache.camel.jms.JmsMessageType. ,BPP>DB CLOJ>Q TEBK PBKAFKD 5IF FYDIBOHF UIBU JT TFOU PWFS UIF +.4 XJSF NVTU DPOGPSN UP UIF +.4 .FTTBHF TQFD. 'PS UIF exchange.in.header UIF GPMMPXJOH SVMFT BQQMZ GPS UIF IFBEFS HBVP: ,FZT TUBSUJOH XJUI JMS PS JMSX BSF SFTFSWFE. exchange.in.headers LFZT NVTU CF MJUFSBMT BOE BMM CF WBMJE +BWB JEFOUJGJFST (EP OPU VTF EPUT JO UIF LFZ OBNF). $BNFM SFQMBDFT EPUT & IZQIFOT BOE UIF SFWFSTF XIFO XIFO DPOTVNJOH +.4 NFTTBHFT: . JT SFQMBDFE CZ _DOT_ BOE UIF SFWFSTF SFQMBDFNFOU XIFO $BNFM DPOTVNFT UIF NFTTBHF. - JT SFQMBDFE CZ _HYPHEN_ BOE UIF SFWFSTF SFQMBDFNFOU XIFO $BNFM DPOTVNFT UIF NFTTBHF. 4FF BMTP UIF PQUJPO jmsKeyFormatStrategy, XIJDI BMMPXT VTF PG ZPVS PXO DVTUPN TUSBUFHZ GPS GPSNBUUJOH LFZT. 'PS UIF exchange.in.header, UIF GPMMPXJOH SVMFT BQQMZ GPS UIF IFBEFS S>IRBP: 5IF WBMVFT NVTU CF QSJNJUJWFT PS UIFJS DPVOUFS PCKFDUT (TVDI BT Integer, Long, Character). 5IF UZQFT, String, CharSequence, Date, BigDecimal BOE BigInteger BSF BMM DPOWFSUFE UP UIFJS toString() SFQSFTFOUBUJPO. "MM PUIFS UZQFT BSF ESPQQFE. $BNFM XJMM MPH XJUI DBUFHPSZ org.apache.camel.component.jms.JmsBinding BU #$!4& MFWFM JG JU ESPQT B HJWFO IFBEFS WBMVF. 'PS FYBNQMF:
2008-07-09 06:43:04,046 [main ] DEBUG JmsBinding - Ignoring non primitive header: order of class: org.apache.camel.component.jms.issues.DummyOrder with value: DummyOrder{orderId=333, itemId=4444, quantity=2}

,BPP>DB CLOJ>Q TEBK OB@BFSFKD $BNFM BEET UIF GPMMPXJOH QSPQFSUJFT UP UIF Exchange XIFO JU SFDFJWFT B NFTTBHF:
/OLMBOQV
org.apache.camel.jms.replyDestination

3VMB
javax.jms.Destination

#BP@OFMQFLK
5IF SFQMZ EFTUJOBUJPO.

$BNFM BEET UIF GPMMPXJOH +.4 QSPQFSUJFT UP UIF *O NFTTBHF IFBEFST XIFO JU SFDFJWFT B +.4 NFTTBHF:
'B>ABO 3VMB #BP@OFMQFLK

764

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

JMSCorrelationID JMSDeliveryMode JMSDestination JMSExpiration JMSMessageID JMSPriority JMSRedelivered JMSReplyTo JMSTimestamp JMSType JMSXGroupID

String int javax.jms.Destination long String int boolean javax.jms.Destination long String String

5IF +.4 DPSSFMBUJPO *%. 5IF +.4 EFMJWFSZ NPEF. 5IF +.4 EFTUJOBUJPO. 5IF +.4 FYQJSBUJPO. 5IF +.4 VOJRVF NFTTBHF *%. 5IF +.4 QSJPSJUZ (XJUI 0 BT UIF MPXFTU QSJPSJUZ BOE 9 BT UIF IJHIFTU). *T UIF +.4 NFTTBHF SFEFMJWFSFE. 5IF +.4 SFQMZ-UP EFTUJOBUJPO. 5IF +.4 UJNFTUBNQ. 5IF +.4 UZQF. 5IF +.4 HSPVQ *%.

"T BMM UIF BCPWF JOGPSNBUJPO JT TUBOEBSE +.4 ZPV DBO DIFDL UIF +.4 EPDVNFOUBUJPO GPS GVSUIFS EFUBJMT. ?LRQ RPFKD ">JBI QL PBKA >KA OB@BFSB JBPP>DBP >KA ),21BMIV3L 5IF +.4 DPNQPOFOU JT DPNQMFY BOE ZPV IBWF UP QBZ DMPTF BUUFOUJPO UP IPX JU XPSLT JO TPNF DBTFT. 4P UIJT JT B TIPSU TVNNBSZ PG TPNF PG UIF BSFBT/QJUGBMMT UP MPPL GPS. 8IFO $BNFM TFOET B NFTTBHF VTJOH JUT JMSProducer, JU DIFDLT UIF GPMMPXJOH DPOEJUJPOT: 5IF NFTTBHF FYDIBOHF QBUUFSO, 8IFUIFS B JMSReplyTo XBT TFU JO UIF FOEQPJOU PS JO UIF NFTTBHF IFBEFST, 8IFUIFS BOZ PG UIF GPMMPXJOH PQUJPOT IBWF CFFO TFU PO UIF +.4 FOEQPJOU: disableReplyTo, preserveMessageQos, explicitQosEnabled. "MM UIJT DBO CF B UBE DPNQMFY UP VOEFSTUBOE BOE DPOGJHVSF UP TVQQPSU ZPVS VTF DBTF.

)JP/OLAR@BO
5IF JmsProducer CFIBWFT BT GPMMPXT, EFQFOEJOH PO DPOGJHVSBUJPO:
$U@E>KDB />QQBOK
InOut InOut InOnly

.QEBO LMQFLKP
JMSReplyTo JT TFU JMSReplyTo JT TFU

#BP@OFMQFLK
$BNFM XJMM FYQFDU B SFQMZ, TFU B UFNQPSBSZ JMSReplyTo, BOE BGUFS TFOEJOH UIF NFTTBHF, JU XJMM TUBSU UP MJTUFO GPS UIF SFQMZ NFTTBHF PO UIF UFNQPSBSZ RVFVF. $BNFM XJMM FYQFDU B SFQMZ BOE, BGUFS TFOEJOH UIF NFTTBHF, JU XJMM TUBSU UP MJTUFO GPS UIF SFQMZ NFTTBHF PO UIF TQFDJGJFE JMSReplyTo RVFVF. $BNFM XJMM TFOE UIF NFTTBHF BOE KLQ FYQFDU B SFQMZ. #Z EFGBVMU, $BNFM EJTDBSET UIF JMSReplyTo EFTUJOBUJPO BOE DMFBST UIF JMSReplyTo IFBEFS CFGPSF TFOEJOH UIF NFTTBHF. $BNFM UIFO TFOET UIF NFTTBHF BOE EPFT KLQ FYQFDU B SFQMZ. $BNFM MPHT UIJT JO UIF MPH BU WARN MFWFM (DIBOHFE UP DEBUG MFWFM GSPN ">JBI 2.6 POXBSET. :PV DBO VTF preserveMessageQuo=true UP JOTUSVDU $BNFM UP LFFQ UIF JMSReplyTo. *O BMM TJUVBUJPOT UIF JmsProducer EPFT KLQ FYQFDU BOZ SFQMZ BOE UIVT DPOUJOVF BGUFS TFOEJOH UIF NFTTBHF.

InOnly

)JP"LKPRJBO
5IF JmsConsumer CFIBWFT BT GPMMPXT, EFQFOEJOH PO DPOGJHVSBUJPO:
$U@E>KDB />QQBOK
InOut

.QEBO LMQFLKP
-

#BP@OFMQFLK
$BNFM XJMM TFOE UIF SFQMZ CBDL UP UIF JMSReplyTo RVFVF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

765

InOnly -

disableReplyTo=true

$BNFM XJMM OPU TFOE B SFQMZ CBDL, BT UIF QBUUFSO JT InOnly. 5IJT PQUJPO TVQQSFTTFT SFQMJFT.

4P QBZ BUUFOUJPO UP UIF NFTTBHF FYDIBOHF QBUUFSO TFU PO ZPVS FYDIBOHFT. *G ZPV TFOE B NFTTBHF UP B +.4 EFTUJOBUJPO JO UIF NJEEMF PG ZPVS SPVUF ZPV DBO TQFDJGZ UIF FYDIBOHF QBUUFSO UP VTF, TFF NPSF BU 3FRVFTU 3FQMZ. 5IJT JT VTFGVM JG ZPV XBOU UP TFOE BO InOnly NFTTBHF UP B +.4 UPQJD:
from("activemq:queue:in") .to("bean:validateOrder") .to(ExchangePattern.InOnly, "activemq:topic:order") .to("bean:handleOrder");

1BRPB BKAMLFKQ >KA PBKA QL AFCCBOBKQ ABPQFK>QFLKP @LJMRQBA >Q ORKQFJB *G ZPV OFFE UP TFOE NFTTBHFT UP B MPU PG EJGGFSFOU +.4 EFTUJOBUJPOT, JU NBLFT TFOTF UP SFVTF B +.4 FOEQPJOU BOE TQFDJGZ UIF SFBM EFTUJOBUJPO JO B NFTTBHF IFBEFS. 5IJT BMMPXT $BNFM UP SFVTF UIF TBNF FOEQPJOU, CVU TFOE UP EJGGFSFOU EFTUJOBUJPOT. 5IJT HSFBUMZ SFEVDFT UIF OVNCFS PG FOEQPJOUT DSFBUFE BOE FDPOPNJ[FT PO NFNPSZ BOE UISFBE SFTPVSDFT. :PV DBO TQFDJGZ UIF EFTUJOBUJPO JO UIF GPMMPXJOH IFBEFST:
'B>ABO
CamelJmsDestination CamelJmsDestinationName

3VMB
javax.jms.Destination String

#BP@OFMQFLK
" EFTUJOBUJPO PCKFDU. 5IF EFTUJOBUJPO OBNF.

'PS FYBNQMF, UIF GPMMPXJOH SPVUF TIPXT IPX ZPV DBO DPNQVUF B EFTUJOBUJPO BU SVO UJNF BOE VTF JU UP PWFSSJEF UIF EFTUJOBUJPO BQQFBSJOH JO UIF +.4 63-:
from("file://inbox") .to("bean:computeDestination") .to("activemq:queue:dummy");

5IF RVFVF OBNF, dummy, JT KVTU B QMBDFIPMEFS. *U NVTU CF QSPWJEFE BT QBSU PG UIF +.4 FOEQPJOU 63-, CVU JU XJMM CF JHOPSFE JO UIJT FYBNQMF. *O UIF computeDestination CFBO, TQFDJGZ UIF SFBM EFTUJOBUJPO CZ TFUUJOH UIF CamelJmsDestinationName IFBEFS BT GPMMPXT:
public void setJmsHeader(Exchange exchange) { String id = .... exchange.getIn().setHeader("CamelJmsDestinationName", "order:" + id"); }

5IFO $BNFM XJMM SFBE UIJT IFBEFS BOE VTF JU BT UIF EFTUJOBUJPO JOTUFBE PG UIF POF DPOGJHVSFE PO UIF FOEQPJOU. 4P, JO UIJT FYBNQMF $BNFM TFOET UIF NFTTBHF UP activemq:queue:order:2, BTTVNJOH UIF id WBMVF XBT 2.

766

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*G CPUI UIF CamelJmsDestination BOE UIF CamelJmsDestinationName IFBEFST BSF TFU, CamelJmsDestination UBLFT QSJPSJUZ. "LKCFDROFKD AFCCBOBKQ ),2 MOLSFABOP :PV DBO DPOGJHVSF ZPVS +.4 QSPWJEFS JO 4QSJOH 9.- BT GPMMPXT:
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <jmxAgent id="agent" disabled="true"/> </camelContext> <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="connectionFactory"> <bean class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="vm://localhost?broker.persistent=false&amp;broker.useJmx=false"/> </bean> </property> </bean>

#BTJDBMMZ, ZPV DBO DPOGJHVSF BT NBOZ +.4 DPNQPOFOU JOTUBODFT BT ZPV XJTI BOE HJWF UIFN > RKFNRB K>JB RPFKD QEB id >QQOF?RQB. 5IF QSFDFEJOH FYBNQMF DPOGJHVSFT BO activemq DPNQPOFOU. :PV DPVME EP UIF TBNF UP DPOGJHVSF .24FSJFT, 5JC$P, #&", 4POJD BOE TP PO. 0ODF ZPV IBWF B OBNFE +.4 DPNQPOFOU, ZPV DBO UIFO SFGFS UP FOEQPJOUT XJUIJO UIBU DPNQPOFOU VTJOH 63*T. 'PS FYBNQMF GPS UIF DPNQPOFOU OBNF, activemq, ZPV DBO UIFO SFGFS UP EFTUJOBUJPOT VTJOH UIF 63* GPSNBU, activemq:[queue:|topic:]destinationName. :PV DBO VTF UIF TBNF BQQSPBDI GPS BMM PUIFS +.4 QSPWJEFST. 5IJT XPSLT CZ UIF 4QSJOH$BNFM$POUFYU MB[JMZ GFUDIJOH DPNQPOFOUT GSPN UIF TQSJOH DPOUFYU GPS UIF TDIFNF OBNF ZPV VTF GPS &OEQPJOU 63*T BOE IBWJOH UIF $PNQPOFOU SFTPMWF UIF FOEQPJOU 63*T.

4PFKD )-#( QL CFKA QEB "LKKB@QFLK%>@QLOV


*G ZPV BSF VTJOH B +2&& DPOUBJOFS, ZPV NJHIU OFFE UP MPPL VQ +/%* UP GJOE UIF +.4 ConnectionFactory SBUIFS UIBO VTF UIF VTVBM <bean> NFDIBOJTN JO 4QSJOH. :PV DBO EP UIJT VTJOH 4QSJOH'T GBDUPSZ CFBO PS UIF OFX 4QSJOH 9.- OBNFTQBDF. 'PS FYBNQMF:
<bean id="weblogic" class="org.apache.camel.component.jms.JmsComponent"> <property name="connectionFactory" ref="myConnectionFactory"/> </bean> <jee:jndi-lookup id="myConnectionFactory" jndi-name="jms/connectionFactory"/>

4FF 5IF KFF TDIFNB JO UIF 4QSJOH SFGFSFODF EPDVNFOUBUJPO GPS NPSF EFUBJMT BCPVU +/%* MPPLVQ.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

767

"LK@ROOBKQ "LKPRJFKD " DPNNPO SFRVJSFNFOU XJUI +.4 JT UP DPOTVNF NFTTBHFT DPODVSSFOUMZ JO NVMUJQMF UISFBET JO PSEFS UP NBLF BO BQQMJDBUJPO NPSF SFTQPOTJWF. :PV DBO TFU UIF concurrentConsumers PQUJPO UP TQFDJGZ UIF OVNCFS PG UISFBET TFSWJDJOH UIF +.4 FOEQPJOU, BT GPMMPXT:
from("jms:SomeQueue?concurrentConsumers=20"). bean(MyClass.class);

:PV DBO DPOGJHVSF UIJT PQUJPO JO POF PG UIF GPMMPXJOH XBZT: ` 0O UIF JmsComponent, ` 0O UIF FOEQPJOU 63* PS, ` #Z JOWPLJOH setConcurrentConsumers() EJSFDUMZ PO UIF JmsEndpoint. 1BNRBPQ-OBMIV LSBO ),2 $BNFM TVQQPSUT 3FRVFTU 3FQMZ PWFS +.4. *O FTTFODF UIF .&1 PG UIF &YDIBOHF TIPVME CF InOut XIFO ZPV TFOE B NFTTBHF UP B +.4 RVFVF. $BNFM PGGFST B OVNCFS PG PQUJPOT UP DPOGJHVSF SFRVFTU/SFQMZ PWFS +.4 UIBU JOGMVFODF QFSGPSNBODF BOE DMVTUFSFE FOWJSPONFOUT. 5IF UBCMF CFMPX TVNNBSJFT UIF PQUJPOT.
.MQFLK
Temporary

/BOCLOJ>K@B
'BTU

"IRPQBO
:FT

#BP@OFMQFLK
" UFNQPSBSZ RVFVF JT VTFE BT SFQMZ RVFVF, BOE BVUPNBUJD DSFBUFE CZ $BNFM. 5P VTF UIJT EP KLQ TQFDJGZ B SFQMZ5P RVFVF OBNF. "OE ZPV DBO PQUJPOBMMZ DPOGJHVSF replyToType=Temporary UP NBLF JU TUBOE PVU UIBU UFNQPSBSZ RVFVFT BSF JO VTF. " TIBSFE QFSTJTUFOU RVFVF JT VTFE BT SFQMZ RVFVF. 5IF RVFVF NVTU CF DSFBUFE CFGPSFIBOE, BMUIPVHI TPNF CSPLFST DBO DSFBUF UIFN PO UIF GMZ TVDI BT "QBDIF "DUJWF.2. 5P VTF UIJT ZPV NVTU TQFDJGZ UIF SFQMZ5P RVFVF OBNF. "OE ZPV DBO PQUJPOBMMZ DPOGJHVSF replyToType=Shared UP NBLF JU TUBOE PVU UIBU TIBSFE RVFVFT BSF JO VTF. " TIBSFE RVFVF DBO CF VTFE JO B DMVTUFSFE FOWJSPONFOU XJUI NVMUJQMF OPEFT SVOOJOH UIJT $BNFM BQQMJDBUJPO BU UIF TBNF UJNF. "MM VTJOH UIF TBNF TIBSFE SFQMZ RVFVF. 5IJT JT QPTTJCMF CFDBVTF +.4 .FTTBHF TFMFDUPST BSF VTFE UP DPSSFMBUF FYQFDUFE SFQMZ NFTTBHFT; UIJT JNQBDUT QFSGPSNBODF UIPVHI. +.4 .FTTBHF TFMFDUPST JT TMPXFS, BOE UIFSFGPSF OPU BT GBTU BT Temporary PS Exclusive RVFVFT. 4FF GVSUIFS CFMPX IPX UP UXFBL UIJT GPS CFUUFS QFSGPSNBODF. "O FYDMVTJWF QFSTJTUFOU RVFVF JT VTFE BT SFQMZ RVFVF. 5IF RVFVF NVTU CF DSFBUFE CFGPSFIBOE, BMUIPVHI TPNF CSPLFST DBO DSFBUF UIFN PO UIF GMZ TVDI BT "QBDIF "DUJWF.2. 5P VTF UIJT ZPV NVTU TQFDJGZ UIF SFQMZ5P RVFVF OBNF. "OE ZPV JRPQ DPOGJHVSF replyToType=Exclusive UP JOTUSVDU $BNFM UP VTF FYDMVTJWF RVFVFT, BT Shared JT VTFE CZ EFGBVMU, JG B replyTo RVFVF OBNF XBT DPOGJHVSFE. 8IFO VTJOH FYDMVTJWF SFQMZ RVFVFT, UIFO +.4 .FTTBHF TFMFDUPST BSF KLQ JO VTF, BOE UIFSFGPSF PUIFS BQQMJDBUJPOT NVTU OPU VTF UIJT RVFVF BT XFMM. "O FYDMVTJWF RVFVF @>KKLQ CF VTFE JO B DMVTUFSFE FOWJSPONFOU XJUI NVMUJQMF OPEFT SVOOJOH UIJT $BNFM BQQMJDBUJPO BU UIF TBNF UJNF; BT XF EP OPU IBWF DPOUSPM JG UIF SFQMZ RVFVF DPNFT CBDL UP UIF TBNF OPEF UIBU TFOU UIF SFRVFTU NFTTBHF; UIBU JT XIZ TIBSFE RVFVFT VTF +.4 .FTTBHF TFMFDUPST UP NBLF TVSF PG UIJT. 3ELRDE JG ZPV DPOGJHVSF FBDI &YDMVTJWF SFQMZ RVFVF XJUI BO VOJRVF OBNF QFS OPEF, UIFO ZPV DBO SVO UIJT JO B DMVTUFSFE FOWJSPONFOU. "T UIFO UIF SFQMZ NFTTBHF XJMM CF TFOU CBDL UP UIBU RVFVF GPS UIF HJWFO OPEF, UIBU BXBJUT UIF SFQMZ NFTTBHF. ">JBI 2.10.3: "MMPXT UP QSPDFTT SFQMZ NFTTBHFT DPODVSSFOUMZ VTJOH DPODVSSFOU NFTTBHF MJTUFOFST JO VTF. :PV DBO TQFDJGZ B SBOHF VTJOH UIF concurrentConsumers BOE maxConcurrentConsumers PQUJPOT. -LQF@B: 5IBU VTJOH Shared SFQMZ RVFVFT NBZ OPU XPSL BT XFMM XJUI DPODVSSFOU MJTUFOFST, TP VTF UIJT PQUJPO XJUI DBSF. ">JBI 2.10.3: "MMPXT UP QSPDFTT SFQMZ NFTTBHFT DPODVSSFOUMZ VTJOH DPODVSSFOU NFTTBHF MJTUFOFST JO VTF. :PV DBO TQFDJGZ B SBOHF VTJOH UIF concurrentConsumers BOE maxConcurrentConsumers PQUJPOT. -LQF@B: 5IBU VTJOH Shared SFQMZ RVFVFT NBZ OPU XPSL BT XFMM XJUI DPODVSSFOU MJTUFOFST, TP VTF UIJT PQUJPO XJUI DBSF.

Shared

4MPX

:FT

Exclusive

'BTU

/P (*:FT)

concurrentConsumers

'BTU

:FT

maxConcurrentConsumers

'BTU

:FT

5IF JmsProducer EFUFDUT UIF InOut BOE QSPWJEFT B JMSReplyTo IFBEFS XJUI UIF SFQMZ EFTUJOBUJPO UP CF VTFE. #Z EFGBVMU $BNFM VTFT B UFNQPSBSZ RVFVF, CVU ZPV DBO VTF UIF

768

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

replyTo PQUJPO PO UIF FOEQPJOU UP TQFDJGZ B GJYFE SFQMZ RVFVF (TFF NPSF CFMPX BCPVU GJYFE SFQMZ RVFVF). $BNFM XJMM BVUPNBUJD TFUVQ B DPOTVNFS XIJDI MJTUFO PO UIF SFQMZ RVFVF, TP ZPV TIPVME KLQ EP BOZUIJOH. 5IJT DPOTVNFS JT B 4QSJOH DefaultMessageListenerContainer XIJDI MJTUFO GPS SFQMJFT. )PXFWFS JU'T GJYFE UP 1 DPODVSSFOU DPOTVNFS. 5IBU NFBOT SFQMJFT XJMM CF QSPDFTTFE JO TFRVFODF BT UIFSF BSF POMZ 1 UISFBE UP QSPDFTT UIF SFQMJFT. *G ZPV XBOU UP QSPDFTT SFQMJFT GBTUFS, UIFO XF OFFE UP VTF DPODVSSFODZ. #VU KLQ VTJOH UIF concurrentConsumer PQUJPO. 8F TIPVME VTF UIF threads GSPN UIF $BNFM %4JOTUFBE, BT TIPXO JO UIF SPVUF CFMPX:
from(xxx) .inOut().to("activemq:queue:foo") .threads(5) .to(yyy) .to(zzz);

*O UIJT SPVUF XF JOTUSVDU $BNFM UP SPVUF SFQMJFT BTZODISPOPVTMZ VTJOH B UISFBE QPPM XJUI 5 UISFBET. 'SPN $BNFM 2.10.3 POXBSET ZPV DBO OPX DPOGJHVSF UIF MJTUFOFS UP VTF DPODVSSFOU UISFBET VTJOH UIF concurrentConsumers BOE maxConcurrentConsumers PQUJPOT. 5IJT BMMPXT ZPV UP FBTJFS DPOGJHVSF UIJT JO $BNFM BT TIPXO CFMPX:
from(xxx) .inOut().to("activemq:queue:foo?concurrentConsumers=5") .to(yyy) .to(zzz);

1BNRBPQ-OBMIV LSBO ),2 >KA RPFKD > PE>OBA CFUBA OBMIV NRBRB
*G ZPV VTF B GJYFE SFQMZ RVFVF XIFO EPJOH 3FRVFTU 3FQMZ PWFS +.4 BT TIPXO JO UIF FYBNQMF CFMPX, UIFO QBZ BUUFOUJPO.
from(xxx) .inOut().to("activemq:queue:foo?replyTo=bar") .to(yyy)

*O UIJT FYBNQMF UIF GJYFE SFQMZ RVFVF OBNFE "CBS" JT VTFE. #Z EFGBVMU $BNFM BTTVNFT UIF RVFVF JT TIBSFE XIFO VTJOH GJYFE SFQMZ RVFVFT, BOE UIFSFGPSF JU VTFT B JMSSelector UP POMZ QJDLVQ UIF FYQFDUFE SFQMZ NFTTBHFT (FH CBTFE PO UIF JMSCorrelationID). 4FF OFYU TFDUJPO GPS FYDMVTJWF GJYFE SFQMZ RVFVFT. 5IBU NFBOT JUT OPU BT GBTU BT UFNQPSBSZ RVFVFT. :PV DBO TQFFEVQ IPX PGUFO $BNFM XJMM QVMM GPS SFQMZ NFTTBHFT VTJOH UIF receiveTimeout PQUJPO. #Z EFGBVMU

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

769

JUT 1000 NJMMJT. 4P UP NBLF JU GBTUFS ZPV DBO TFU JU UP 250 NJMMJT UP QVMM 4 UJNFT QFS TFDPOE BT TIPXO:
from(xxx) .inOut().to("activemq:queue:foo?replyTo=bar&receiveTimeout=250") .to(yyy)

/PUJDF UIJT XJMM DBVTF UIF $BNFM UP TFOE QVMM SFRVFTUT UP UIF NFTTBHF CSPLFS NPSF GSFRVFOU, BOE UIVT SFRVJSF NPSF OFUXPSL USBGGJD. *U JT HFOFSBMMZ SFDPNNFOEFE UP VTF UFNQPSBSZ RVFVFT JG QPTTJCMF.

1BNRBPQ-OBMIV LSBO ),2 >KA RPFKD >K BU@IRPFSB CFUBA OBMIV NRBRB
S>FI>?IB >P LC ">JBI 2.9 *O UIF QSFWJPVT FYBNQMF, $BNFM XPVME BOUJDJQBUF UIF GJYFE SFQMZ RVFVF OBNFE "CBS" XBT TIBSFE, BOE UIVT JU VTFT B JMSSelector UP POMZ DPOTVNF SFQMZ NFTTBHFT XIJDI JU FYQFDUT. )PXFWFS UIFSF JT B ESBXCBDL EPJOH UIJT BT +.4 TFMFDUPT JT TMPXFS. "MTP UIF DPOTVNFS PO UIF SFQMZ RVFVF JT TMPXFS UP VQEBUF XJUI OFX +.4 TFMFDUPS JET. *O GBDU JU POMZ VQEBUFT XIFO UIF receiveTimeout PQUJPO UJNFT PVU, XIJDI CZ EFGBVMU JT 1 TFDPOE. 4P JO UIFPSZ UIF SFQMZ NFTTBHFT DPVME UBLF VQ UJMM BCPVU 1 TFD UP CF EFUFDUFE. 0O UIF PUIFS IBOE JG UIF GJYFE SFQMZ RVFVF JT FYDMVTJWF UP UIF $BNFM SFQMZ DPOTVNFS, UIFO XF DBO BWPJE VTJOH UIF +.4 TFMFDUPST, BOE UIVT CF NPSF QFSGPSNBOU. *O GBDU BT GBTU BT VTJOH UFNQPSBSZ RVFVFT. 4P JO ">JBI 2.9 POXBSET XF JOUSPEVDFE UIF ReplyToType PQUJPO XIJDI ZPV DBO DPOGJHVSF UP Exclusive UP UFMM $BNFM UIBU UIF SFQMZ RVFVF JT FYDMVTJWF BT TIPXO JO UIF FYBNQMF CFMPX:
from(xxx) .inOut().to("activemq:queue:foo?replyTo=bar&replyToType=Exclusive") .to(yyy)

.JOE UIBU UIF RVFVF NVTU CF FYDMVTJWF UP FBDI BOE FWFSZ FOEQPJOU. 4P JG ZPV IBWF UXP SPVUFT, UIFO UIFZ FBDI OFFE BO VOJRVF SFQMZ RVFVF BT TIPXO JO UIF OFYU FYBNQMF:
from(xxx) .inOut().to("activemq:queue:foo?replyTo=bar&replyToType=Exclusive") .to(yyy) from(aaa) .inOut().to("activemq:queue:order?replyTo=order.reply&replyToType=Exclusive") .to(bbb)

5IF TBNF BQQMJFT JG ZPV SVO JO B DMVTUFSFE FOWJSPONFOU. 5IFO FBDI OPEF JO UIF DMVTUFS NVTU VTF BO VOJRVF SFQMZ RVFVF OBNF. "T PUIFSXJTF FBDI OPEF JO UIF DMVTUFS NBZ QJDLVQ NFTTBHFT XIJDI

770

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

XBT JOUFOEFE BT B SFQMZ PO BOPUIFS OPEF. 'PS DMVTUFSFE FOWJSPONFOUT JUT SFDPNNFOEFE UP VTF TIBSFE SFQMZ RVFVFT JOTUFBE. 2VK@EOLKFWFKD @IL@HP ?BQTBBK PBKABOP >KA OB@BFSBOP 8IFO EPJOH NFTTBHJOH CFUXFFO TZTUFNT, JUT EFTJSBCMF UIBU UIF TZTUFNT IBWF TZODISPOJ[FE DMPDLT. 'PS FYBNQMF XIFO TFOEJOH B +.4 NFTTBHF, UIFO ZPV DBO TFU B UJNF UP MJWF WBMVF PO UIF NFTTBHF. 5IFO UIF SFDFJWFS DBO JOTQFDU UIJT WBMVF, BOE EFUFSNJOF JG UIF NFTTBHF JT BMSFBEZ FYQJSFE, BOE UIVT ESPQ UIF NFTTBHF JOTUFBE PG DPOTVNF BOE QSPDFTT JU. )PXFWFS UIJT SFRVJSFT UIBU CPUI TFOEFS BOE SFDFJWFS IBWF TZODISPOJ[FE DMPDLT. *G ZPV BSF VTJOH "DUJWF.2 UIFO ZPV DBO VTF UIF UJNFTUBNQ QMVHJO UP TZODISPOJ[F DMPDLT. ?LRQ QFJB QL IFSB 3FBE GJSTU BCPWF BCPVU TZODISPOJ[FE DMPDLT. 8IFO ZPV EP SFRVFTU/SFQMZ (*O0VU) PWFS +.4 XJUI $BNFM UIFO $BNFM VTFT B UJNFPVU PO UIF TFOEFS TJEF, XIJDI JT EFGBVMU 20 TFDPOET GSPN UIF requestTimeout PQUJPO. :PV DBO DPOUSPM UIJT CZ TFUUJOH B IJHIFS/MPXFS WBMVF. )PXFWFS UIF UJNF UP MJWF WBMVF JT TUJMM TFU PO UIF +.4 NFTTBHF CFJOH TFOE. 4P UIBU SFRVJSFT UIF DMPDLT UP CF TZODISPOJ[FE CFUXFFO UIF TZTUFNT. *G UIFZ BSF OPU, UIFO ZPV NBZ XBOU UP EJTBCMF UIF UJNF UP MJWF WBMVF CFJOH TFU. 5IJT JT OPX QPTTJCMF VTJOH UIF disableTimeToLive PQUJPO GSPN ">JBI 2.8 POXBSET. 4P JG ZPV TFU UIJT PQUJPO UP disableTimeToLive=true, UIFO $BNFM EPFT KLQ TFU BOZ UJNF UP MJWF WBMVF XIFO TFOEJOH +.4 NFTTBHFT. !RQ UIF SFRVFTU UJNFPVU JT TUJMM BDUJWF. 4P GPS FYBNQMF JG ZPV EP SFRVFTU/ SFQMZ PWFS +.4 BOE IBWF EJTBCMFE UJNF UP MJWF, UIFO $BNFM XJMM TUJMM VTF B UJNFPVU CZ 20 TFDPOET (UIF requestTimeout PQUJPO). 5IBU PQUJPO DBO PG DPVSTF BMTP CF DPOGJHVSFE. 4P UIF UXP PQUJPOT requestTimeout BOE disableTimeToLive HJWFT ZPV GJOF HSBJOFE DPOUSPM XIFO EPJOH SFRVFTU/SFQMZ. 8IFO ZPV EP GJSF BOE GPSHFU (*O0VU) PWFS +.4 XJUI $BNFM UIFO $BNFM CZ EFGBVMU EPFT KLQ TFU BOZ UJNF UP MJWF WBMVF PO UIF NFTTBHF. :PV DBO DPOGJHVSF B WBMVF CZ VTJOH UIF timeToLive PQUJPO. 'PS FYBNQMF UP JOEJDBUF B 5 TFD., ZPV TFU timeToLive=5000. 5IF PQUJPO disableTimeToLive DBO CF VTFE UP GPSDF EJTBCMJOH UIF UJNF UP MJWF, BMTP GPS *O0OMZ NFTTBHJOH. 5IF requestTimeout PQUJPO JT OPU CFJOH VTFE GPS *O0OMZ NFTTBHJOH. $K>?IFKD 3O>KP>@QBA "LKPRJMQFLK " DPNNPO SFRVJSFNFOU JT UP DPOTVNF GSPN B RVFVF JO B USBOTBDUJPO BOE UIFO QSPDFTT UIF NFTTBHF VTJOH UIF $BNFM SPVUF. 5P EP UIJT, KVTU FOTVSF UIBU ZPV TFU UIF GPMMPXJOH QSPQFSUJFT PO UIF DPNQPOFOU/FOEQPJOU: ` transacted = USVF ` transactionManager = B Transsaction Manager - UZQJDBMMZ UIF JmsTransactionManager 4FF UIF 5SBOTBDUJPOBM $MJFOU &*1 QBUUFSO GPS GVSUIFS EFUBJMT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

771

3O>KP>@QFLKP >KA 1BNRBPQ 1BMIV LSBO ),2 8IFO VTJOH 3FRVFTU 3FQMZ PWFS +.4 ZPV DBOOPU VTF B TJOHMF USBOTBDUJPO; +.4 XJMM OPU TFOE BOZ NFTTBHFT VOUJM B DPNNJU JT QFSGPSNFE, TP UIF TFSWFS TJEF XPO'U SFDFJWF BOZUIJOH BU BMM VOUJM UIF USBOTBDUJPO DPNNJUT. 5IFSFGPSF UP VTF 3FRVFTU 3FQMZ ZPV NVTU DPNNJU B USBOTBDUJPO BGUFS TFOEJOH UIF SFRVFTU BOE UIFO VTF B TFQBSBUF USBOTBDUJPO GPS SFDFJWJOH UIF SFTQPOTF.
5P BEESFTT UIJT JTTVF UIF +.4 DPNQPOFOU VTFT EJGGFSFOU QSPQFSUJFT UP TQFDJGZ USBOTBDUJPO VTF GPS POFXBZ NFTTBHJOH BOE SFRVFTU SFQMZ NFTTBHJOH: 5IF transacted QSPQFSUZ BQQMJFT LKIV UP UIF *O0OMZ NFTTBHF &YDIBOHF 1BUUFSO (.&1). 5IF transactedInOut QSPQFSUZ BQQMJFT UP UIF *O0VU(3FRVFTU 3FQMZ) NFTTBHF &YDIBOHF 1BUUFSO (.&1). *G ZPV XBOU UP VTF USBOTBDUJPOT GPS 3FRVFTU 3FQMZ(*O0VU .&1), ZPV JRPQ TFU transactedInOut=true.

S>FI>?IB >P LC ">JBI 2.10 :PV DBO MFWFSBHF UIF %.-$ USBOTBDUFE TFTTJPO "1* VTJOH UIF GPMMPXJOH QSPQFSUJFT PO DPNQPOFOU/FOEQPJOU: ` transacted = USVF ` lazyCreateTransactionManager = GBMTF 5IF CFOFGJU PG EPJOH TP JT UIBU UIF DBDIF-FWFM TFUUJOH XJMM CF IPOPSFE XIFO VTJOH MPDBM USBOTBDUJPOT XJUIPVU B DPOGJHVSFE 5SBOTBDUJPO.BOBHFS. 8IFO B 5SBOTBDUJPO.BOBHFS JT DPOGJHVSFE, OP DBDIJOH IBQQFOT BU %.-$ MFWFM BOE JUT OFDFTTBSZ UP SFMZ PO B QPPMFE DPOOFDUJPO GBDUPSZ. 'PS NPSF EFUBJMT BCPVU UIJT LJOE PG TFUVQ TFF IFSF BOE IFSF. 4PFKD ),21BMIV3L CLO I>QB OBMIFBP 8IFO VTJOH $BNFM BT B +.4 MJTUFOFS, JU TFUT BO &YDIBOHF QSPQFSUZ XJUI UIF WBMVF PG UIF 3FQMZ5P javax.jms.Destination PCKFDU, IBWJOH UIF LFZ ReplyTo. :PV DBO PCUBJO UIJT Destination BT GPMMPXT:
Destination replyDestination = exchange.getIn().getHeader(JmsConstants.JMS_REPLY_DESTINATION, Destination.class);

"OE UIFO MBUFS VTF JU UP TFOE B SFQMZ VTJOH SFHVMBS +.4 PS $BNFM.
// we need to pass in the JMS component, and in this sample we use ActiveMQ JmsEndpoint endpoint = JmsEndpoint.newInstance(replyDestination,

772

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

activeMQComponent); // now we have the endpoint we can use regular Camel API to send a message to it template.sendBody(endpoint, "Here is the late reply.");

" EJGGFSFOU TPMVUJPO UP TFOEJOH B SFQMZ JT UP QSPWJEF UIF replyDestination PCKFDU JO UIF TBNF &YDIBOHF QSPQFSUZ XIFO TFOEJOH. $BNFM XJMM UIFO QJDL VQ UIJT QSPQFSUZ BOE VTF JU GPS UIF SFBM EFTUJOBUJPO. 5IF FOEQPJOU 63* NVTU JODMVEF B EVNNZ EFTUJOBUJPO, IPXFWFS. 'PS FYBNQMF:
// we pretend to send it to some non existing dummy queue template.send("activemq:queue:dummy, new Processor() { public void process(Exchange exchange) throws Exception { // and here we override the destination with the ReplyTo destination object so the message is sent to there instead of dummy exchange.getIn().setHeader(JmsConstants.JMS_DESTINATION, replyDestination); exchange.getIn().setBody("Here is the late reply."); } }

4PFKD > OBNRBPQ QFJBLRQ *O UIF TBNQMF CFMPX XF TFOE B 3FRVFTU 3FQMZ TUZMF NFTTBHF &YDIBOHF (XF VTF UIF requestBody NFUIPE = InOut) UP UIF TMPX RVFVF GPS GVSUIFS QSPDFTTJOH JO $BNFM BOE XF XBJU GPS B SFUVSO SFQMZ:
// send a in-out with a timeout for 5 sec Object out = template.requestBody("activemq:queue:slow?requestTimeout=5000", "Hello World");

2>JMIBP +.4 JT VTFE JO NBOZ FYBNQMFT GPS PUIFS DPNQPOFOUT BT XFMM. #VU XF QSPWJEF B GFX TBNQMFT CFMPX UP HFU TUBSUFE.

1B@BFSFKD COLJ ),2


*O UIF GPMMPXJOH TBNQMF XF DPOGJHVSF B SPVUF UIBU SFDFJWFT +.4 NFTTBHFT BOE SPVUFT UIF NFTTBHF UP B 10+0:
from("jms:queue:foo"). to("bean:myBusinessLogic");

:PV DBO PG DPVSTF VTF BOZ PG UIF &*1 QBUUFSOT TP UIF SPVUF DBO CF DPOUFYU CBTFE. 'PS FYBNQMF, IFSF'T IPX UP GJMUFS BO PSEFS UPQJD GPS UIF CJH TQFOEFST:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

773

from("jms:topic:OrdersTopic"). filter().method("myBean", "isGoldCustomer"). to("jms:queue:BigSpendersQueue");

2BKAFKD QL > ),2


*O UIF TBNQMF CFMPX XF QPMM B GJMF GPMEFS BOE TFOE UIF GJMF DPOUFOU UP B +.4 UPQJD. "T XF XBOU UIF DPOUFOU PG UIF GJMF BT B TextMessage JOTUFBE PG B BytesMessage, XF OFFE UP DPOWFSU UIF CPEZ UP B String:
from("file://orders"). convertBodyTo(String.class). to("jms:topic:OrdersTopic");

4PFKD

KKLQ>QFLKP

$BNFM BMTP IBT BOOPUBUJPOT TP ZPV DBO VTF 10+0 $POTVNJOH BOE 10+0 1SPEVDJOH.

2MOFKD #2+ P>JMIB


5IF QSFDFEJOH FYBNQMFT VTF UIF +BWB %4-. $BNFM BMTP TVQQPSUT 4QSJOH 9.- %4-. )FSF JT UIF CJH TQFOEFS TBNQMF VTJOH 4QSJOH %4-:
<route> <from uri="jms:topic:OrdersTopic"/> <filter> <method bean="myBean" method="isGoldCustomer"/> <to uri="jms:queue:BigSpendersQueue"/> </filter> </route>

.QEBO P>JMIBP
+.4 BQQFBST JO NBOZ PG UIF FYBNQMFT GPS PUIFS DPNQPOFOUT BOE &*1 QBUUFSOT, BT XFMM JO UIJT $BNFM EPDVNFOUBUJPO. 4P GFFM GSFF UP CSPXTF UIF EPDVNFOUBUJPO. *G ZPV IBWF UJNF, DIFDL PVU UIF UIJT UVUPSJBM UIBU VTFT +.4 CVU GPDVTFT PO IPX XFMM 4QSJOH 3FNPUJOH BOE $BNFM XPSLT UPHFUIFS 5VUPSJBM-+NT3FNPUJOH.

774

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD ),2 >P > #B>A +BQQBO 0RBRB PQLOFKD $U@E>KDB


/PSNBMMZ, XIFO VTJOH +.4 BT UIF USBOTQPSU, JU POMZ USBOTGFST UIF CPEZ BOE IFBEFST BT UIF QBZMPBE. *G ZPV XBOU UP VTF +.4 XJUI B %FBE -FUUFS $IBOOFM, VTJOH B +.4 RVFVF BT UIF %FBE -FUUFS 2VFVF, UIFO OPSNBMMZ UIF DBVTFE &YDFQUJPO JT OPU TUPSFE JO UIF +.4 NFTTBHF. :PV DBO, IPXFWFS, VTF UIF QO>KPCBO$U@E>KDB PQUJPO PO UIF +.4 EFBE MFUUFS RVFVF UP JOTUSVDU $BNFM UP TUPSF UIF FOUJSF &YDIBOHF JO UIF RVFVF BT B javax.jms.ObjectMessage UIBU IPMET B org.apache.camel.impl.DefaultExchangeHolder. 5IJT BMMPXT ZPV UP DPOTVNF GSPN UIF %FBE -FUUFS 2VFVF BOE SFUSJFWF UIF DBVTFE FYDFQUJPO GSPN UIF &YDIBOHF QSPQFSUZ XJUI UIF LFZ Exchange.EXCEPTION_CAUGHT. 5IF EFNP CFMPX JMMVTUSBUFT UIJT:
// setup error handler to use JMS as queue and store the entire Exchange errorHandler(deadLetterChannel("jms:queue:dead?transferExchange=true"));

5IFO ZPV DBO DPOTVNF GSPN UIF +.4 RVFVF BOE BOBMZ[F UIF QSPCMFN:
from("jms:queue:dead").to("bean:myErrorAnalyzer"); // and in our bean String body = exchange.getIn().getBody(); Exception cause = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class); // the cause message is String problem = cause.getMessage();

4PFKD ),2 >P > #B>A +BQQBO "E>KKBI PQLOFKD BOOLO LKIV
:PV DBO VTF +.4 UP TUPSF UIF DBVTF FSSPS NFTTBHF PS UP TUPSF B DVTUPN CPEZ, XIJDI ZPV DBO JOJUJBMJ[F ZPVSTFMG. 5IF GPMMPXJOH FYBNQMF VTFT UIF .FTTBHF 5SBOTMBUPS &*1 UP EP B USBOTGPSNBUJPO PO UIF GBJMFE FYDIBOHF CFGPSF JU JT NPWFE UP UIF +.4 EFBE MFUUFS RVFVF:
// we sent it to a seda dead queue first errorHandler(deadLetterChannel("seda:dead")); // and on the seda dead queue we can do the custom transformation before its sent to the JMS queue from("seda:dead").transform(exceptionMessage()).to("jms:queue:dead");

)FSF XF POMZ TUPSF UIF PSJHJOBM DBVTF FSSPS NFTTBHF JO UIF USBOTGPSN. :PV DBO, IPXFWFS, VTF BOZ &YQSFTTJPO UP TFOE XIBUFWFS ZPV MJLF. 'PS FYBNQMF, ZPV DBO JOWPLF B NFUIPE PO B #FBO PS VTF B DVTUPN QSPDFTTPS. 2BKAFKD >K (K.KIV JBPP>DB >KA HBBMFKD QEB ),21BMIV3L EB>ABO 8IFO TFOEJOH UP B +.4 EFTUJOBUJPO VTJOH @>JBI-GJP UIF QSPEVDFS XJMM VTF UIF .&1 UP EFUFDU JG JUT *O0OMZ PS *O0VU NFTTBHJOH. )PXFWFS UIFSF DBO CF UJNFT XIFSF ZPV XBOU UP TFOE BO
$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9 775

*O0OMZ NFTTBHF CVU LFFQJOH UIF +.43FQMZ5P IFBEFS. 5P EP TP ZPV IBWF UP JOTUSVDU $BNFM UP LFFQ JU, PUIFSXJTF UIF +.43FQMZ5P IFBEFS XJMM CF ESPQQFE. 'PS FYBNQMF UP TFOE BO *O0OMZ NFTTBHF UP UIF GPP RVFVF, CVU XJUI B +.43FQMZ5P XJUI CBS RVFVF ZPV DBO EP BT GPMMPXT:
template.send("activemq:queue:foo?preserveMessageQos=true", new Processor() { public void process(Exchange exchange) throws Exception { exchange.getIn().setBody("World"); exchange.getIn().setHeader("JMSReplyTo", "bar"); } });

/PUJDF XF VTF preserveMessageQos=true UP JOTUSVDU $BNFM UP LFFQ UIF +.43FQMZ5P IFBEFS. 2BQQFKD ),2 MOLSFABO LMQFLKP LK QEB ABPQFK>QFLK 4PNF +.4 QSPWJEFST, MJLF *#.'T 8FC4QIFSF .2 OFFE PQUJPOT UP CF TFU PO UIF +.4 EFTUJOBUJPO. 'PS FYBNQMF, ZPV NBZ OFFE UP TQFDJGZ UIF UBSHFU$MJFOU PQUJPO. 4JODF UBSHFU$MJFOU JT B 8FC4QIFSF .2 PQUJPO BOE OPU B $BNFM 63* PQUJPO, ZPV OFFE UP TFU UIBU PO UIF +.4 EFTUJOBUJPO OBNF MJLF TP:
... .setHeader("CamelJmsDestinationName", constant("queue:///MY_QUEUE?targetClient=1")) .to("wmq:queue:MY_QUEUE?useMessageIDAsCorrelationID=true");

4PNF WFSTJPOT PG 8.2 XPO'U BDDFQU UIJT PQUJPO PO UIF EFTUJOBUJPO OBNF BOE ZPV XJMM HFU BO FYDFQUJPO MJLF: DPN.JCN.NTH.DMJFOU.KNT.%FUBJMFE+.4&YDFQUJPO: +.4$$0005: 5IF TQFDJGJFE WBMVF '.:@26&6& UBSHFU$MJFOU=1' JT OPU BMMPXFE GPS '9.4$@%&45*/"5*0/@/".&' " XPSLBSPVOE JT UP VTF B DVTUPN %FTUJOBUJPO3FTPMWFS:
JmsComponent wmq = new JmsComponent(connectionFactory); wmq.setDestinationResolver(new DestinationResolver(){ public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException { MQQueueSession wmqSession = (MQQueueSession) session; return wmqSession.createQueue("queue:///" + destinationName + "?targetClient=1"); } });

776

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 5SBOTBDUJPOBM $MJFOU #FBO *OUFHSBUJPO 5VUPSJBM-+NT3FNPUJOH +.45FNQMBUF HPUDIBT

),7 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.6 2Q>KA>OA ),7 "LKPRJBO "LKCFDRO>QFLK $PNQPOFOU BMMPXT DPOTVNFST UP TVCTDSJCF UP BO NCFBO'T /PUJGJDBUJPOT. 5IF DPNQPOFOU TVQQPSUT QBTTJOH UIF /PUJGJDBUJPO PCKFDU EJSFDUMZ UISPVHI UIF &YDIBOHF PS TFSJBMJ[JOH JU UP 9.BDDPSEJOH UP UIF TDIFNB QSPWJEFE XJUIJO UIJT QSPKFDU. 5IJT JT B DPOTVNFS POMZ DPNQPOFOU. &YDFQUJPOT BSF UISPXO JG ZPV BUUFNQU UP DSFBUF B QSPEVDFS GPS JU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jmx</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( %LOJ>Q
5IF DPNQPOFOU DBO DPOOFDU UP UIF MPDBM QMBUGPSN NCFBO TFSWFS XJUI UIF GPMMPXJOH 63*:
jmx://platform?options

" SFNPUF NCFBO TFSWFS VSM DBO CF QSPWJEFE GPMMPXJOH UIF JOJUJBM +.9 TDIFNF MJLF TP:
jmx:service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi?options

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, PQUJPOT=WBMVF&PQUJPO2=WBMVF&...

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

777

41( .MQFLKP
/OLMBOQV
GPSNBU VTFS QBTTXPSE PCKFDU%PNBJO PCKFDU/BNF OPUJGJDBUJPO'JMUFS IBOECBDL

1BNRFOBA
c c c ZFT c c c

#BC>RIQ
YNM c c c c c c

#BP@OFMQFLK
'PSNBU GPS UIF NFTTBHF CPEZ. &JUIFS "YNM" PS "SBX". *G YNM, UIF OPUJGJDBUJPO JT TFSJBMJ[FE UP YNM. *G SBX, UIFO UIF SBX KBWB PCKFDU JT TFU BT UIF CPEZ. $SFEFOUJBMT GPS NBLJOH B SFNPUF DPOOFDUJPO. $SFEFOUJBMT GPS NBLJOH B SFNPUF DPOOFDUJPO. 5IF EPNBJO GPS UIF NCFBO ZPV'SF DPOOFDUJOH UP. 5IF OBNF LFZ GPS UIF NCFBO ZPV'SF DPOOFDUJOH UP. 5IJT WBMVF JT NVUVBMMZ FYDMVTJWF XJUI UIF PCKFDU QSPQFSUJFT UIBU HFU QBTTFE. (TFF CFMPX) 3FGFSFODF UP B CFBO UIBU JNQMFNFOUT UIF NotificationFilter. 5IF #SFG TZOUBY TIPVME CF VTFE UP SFGFSFODF UIF CFBO WJB UIF 3FHJTUSZ. 7BMVF UP IBOECBDL UP UIF MJTUFOFS XIFO B OPUJGJDBUJPO JT SFDFJWFE. 5IJT WBMVF XJMM CF QVU JO UIF NFTTBHF IFBEFS XJUI UIF LFZ "KNY.IBOECBDL" ">JBI 2.11 *G USVF, UIF DPOTVNFS XJMM UISPX BO FYDFQUJPO XIFO VOBCMF UP FTUBCMJTI UIF +.9 DPOOFDUJPO VQPO TUBSUVQ. *G GBMTF, UIF DPOTVNFS XJMM BUUFNQU UP FTUBCMJTI UIF +.9 DPOOFDUJPO FWFSZ 'Y' TFDPOET VOUJM UIF DPOOFDUJPO JT NBEF f XIFSF 'Y' JT UIF DPOGJHVSFE reconnectDelay. ">JBI 2.11 *G USVF, UIF DPOTVNFS XJMM BUUFNQU UP SFDPOOFDU UP UIF +.9 TFSWFS XIFO BOZ DPOOFDUJPO GBJMVSF PDDVST. 5IF DPOTVNFS XJMM BUUFNQU UP SF-FTUBCMJTI UIF +.9 DPOOFDUJPO FWFSZ 'Y' TFDPOET VOUJM UIF DPOOFDUJPO JT NBEF-- XIFSF 'Y' JT UIF DPOGJHVSFE reconnectDelay. ">JBI 2.11 5IF OVNCFS PG TFDPOET UP XBJU CFGPSF SFUSZJOH DSFBUJPO PG UIF JOJUJBM DPOOFDUJPO PS CFGPSF SFDPOOFDUJOH B MPTU DPOOFDUJPO.

UFTU$POOFDUJPO0O4UBSUVQ

USVF

SFDPOOFDU0O$POOFDUJPO'BJMVSF

GBMTF

SFDPOOFDU%FMBZ

10 TFDPOET

.?GB@Q->JB "LKPQOR@QFLK
5IF 63* NVTU BMXBZT IBWF UIF PCKFDU%PNBJO QSPQFSUZ. *O BEEJUJPO, UIF 63* NVTU DPOUBJO FJUIFS PCKFDU/BNF PS POF PS NPSF QSPQFSUJFT UIBU TUBSU XJUI "LFZ."

#LJ>FK TFQE ->JB MOLMBOQV


8IFO UIF PCKFDU/BNF QSPQFSUZ JT QSPWJEFE, UIF GPMMPXJOH DPOTUSVDUPS JT VTFE UP CVJME UIF 0CKFDU/BNF GPS UIF NCFBO:
ObjectName(String domain, String key, String value)

5IF LFZ WBMVF JO UIF BCPWF XJMM CF "OBNF" BOE UIF WBMVF XJMM CF UIF WBMVF PG UIF PCKFDU/BNF QSPQFSUZ.

#LJ>FK TFQE '>PEQ>?IB


ObjectName(String domain, Hashtable<String,String> table)

5IF )BTIUBCMF JT DPOTUSVDUFE CZ FYUSBDUJOH QSPQFSUJFT UIBU TUBSU XJUI "LFZ." 5IF QSPQFSUJFT XJMM IBWF UIF "LFZ." QSFGJYFE TUSJQQFE QSJPS UP CVJMEJOH UIF )BTIUBCMF. 5IJT BMMPXT UIF 63* UP DPOUBJO B WBSJBCMF OVNCFS PG QSPQFSUJFT UP JEFOUJGZ UIF NCFBO.

778

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

$U>JMIB
from("jmx:platform?objectDomain=jmxExample&key.name=simpleBean"). to("log:jmxEvent");

'VMM FYBNQMF ,LKFQLO 3VMB "LKPRJBO S>FI>?IB >P LC ">JBI 2.8 0OF QPQVMBS VTF DBTF GPS +.9 JT DSFBUJOH B NPOJUPS CFBO UP NPOJUPS BO BUUSJCVUF PO B EFQMPZFE CFBO. 5IJT SFRVJSFT XSJUJOH B GFX MJOFT PG +BWB DPEF UP DSFBUF UIF +.9 NPOJUPS BOE EFQMPZ JU. "T TIPXO CFMPX:
CounterMonitor monitor = new CounterMonitor(); monitor.addObservedObject(makeObjectName("simpleBean")); monitor.setObservedAttribute("MonitorNumber"); monitor.setNotify(true); monitor.setInitThreshold(1); monitor.setGranularityPeriod(500); registerBean(monitor, makeObjectName("counter")); monitor.start();

5IF 2.8 WFSTJPO JOUSPEVDFT B OFX UZQF PG DPOTVNFS UIBU BVUPNBUJDBMMZ DSFBUFT BOE SFHJTUFST B NPOJUPS CFBO GPS UIF TQFDJGJFE PCKFDU/BNF BOE BUUSJCVUF. "EEJUJPOBM FOEQPJOU BUUSJCVUFT BMMPX UIF VTFS UP TQFDJGZ UIF BUUSJCVUF UP NPOJUPS, UZQF PG NPOJUPS UP DSFBUF, BOE BOZ PUIFS SFRVJSFE QSPQFSUJFT. 5IF DPEF TOJQQFU BCPWF JT DPOEFOTFE JOUP B TFU PG FOEQPJOU QSPQFSUJFT. 5IF DPOTVNFS VTFT UIFTF QSPQFSUJFT UP DSFBUF UIF $PVOUFS.POJUPS, SFHJTUFS JU, BOE UIFO TVCTDSJCF UP JUT DIBOHFT. "MM PG UIF +.9 NPOJUPS UZQFT BSF TVQQPSUFE.

$U>JMIB
from("jmx:platform?objectDomain=myDomain&objectName=simpleBean&" + "monitorType=counter&observedAttribute=MonitorNumber&initThreshold=1&" + "granularityPeriod=500").to("mock:sink");

5IF FYBNQMF BCPWF XJMM DBVTF B OFX .POJUPS #FBO UP CF DSFBUFE BOE EFQPZFE UP UIF MPDBM NCFBO TFSWFS UIBU NPOJUPST UIF ".POJUPS/VNCFS" BUUSJCVUF PO UIF "TJNQMF#FBO." "EEJUJPOBM UZQFT PG NPOJUPS CFBOT BOE PQUJPOT BSF EFUBJMFE CFMPX. 5IF OFXMZ EFQMPZFE NPOJUPS CFBO JT BVUPNBUJDBMMZ VOEFQMPZFE XIFO UIF DPOTVNFS JT TUPQQFE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

779

41( .MQFLKP CLO ,LKFQLO 3VMB


MOLMBOQV NPOJUPS5ZQF PCTFSWFE"UUSJCVUF HSBOVBMJUZ1FSJPE JOJU5ISFTIPME PGGTFU NPEVMVT EJGGFSFODF.PEF OPUJGZ)JHI OPUJGZ-PX IJHI5ISFTIPME MPX5ISFTIPME OPUJGZ%JGGFS OPUJGZ.BUDI TUSJOH5P$PNQBSF QVMB FOVN TUSJOH MPOH OVNCFS OVNCFS OVNCFS CPPMFBO CPPMFBO CPPMFBO OVNCFS OVNCFS CPPMFBO CPPMFBO TUSJOH >MMIFBP QL BMM BMM BMM DPVOUFS DPVOUFS DPVOUFS DPVOUFS, HBVHF HBVHF HBVHF HBVHF HBVHF TUSJOH TUSJOH TUSJOH ABP@OFMQFLK POF PG DPVOUFS, HVBHF, TUSJOH UIF BUUSJCVUF CFJOH PCTFSWFE HSBOVMBSJUZ QFSJPE (JO NJMMJT) GPS UIF BUUSJCVUF CFJOH PCTFSWFE. "T QFS +.9, EFGBVMU JT 10 TFDPOET JOJUJBM UISFTIPME WBMVF PGGTFU WBMVF NPEVMVT WBMVF USVF JG EJGGFSFODF TIPVME CF SFQPSUFE, GBMTF GPS BDUVBM WBMVF IJHI OPUJGJDBUJPO PO/PGG TXJUDI MPX OPUJGJDBUJPO PO/PGG TXJUDI UISFTIPME GPS SFQPSUJOH IJHI OPUJGJDBUJPO UISFTIPME GPS SFQPSUJOH MPX OPUJGJDBUPO USVF UP GJSF OPUJGJDBUJPO XIFO TUSJOH EJGGFST USVF UP GJSF OPUJGJDBUJPO XIFO TUSJOH NBUDIFT TUSJOH UP DPNQBSF BHBJOTU UIF BUUSJCVUF WBMVF

5IF NPOJUPS TUZMF DPOTVNFS JT POMZ TVQQPSUFE GPS UIF MPDBM NCFBO TFSWFS. +.9 EPFT OPU DVSSFOUMZ TVQQPSU SFNPUF EFQMPZNFOU PG NCFBOT XJUIPVU FJUIFS IBWJOH UIF DMBTTFT BMSFBEZ SFNPUFMZ EFQMPZFE PS BO BEBQUFS MJCSBSZ PO CPUI UIF DMJFOU BOE TFSWFS UP GBDJMJUBUF B QSPYZ EFQMPZNFOU. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE $BNFM +.9

780

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

)/

".,/.-$-3

5IF GM> DPNQPOFOU FOBCMFT ZPV UP TUPSF BOE SFUSJFWF +BWB PCKFDUT GSPN QFSTJTUFOU TUPSBHF VTJOH &+# 3'T +BWB 1FSTJTUFODF "SDIJUFDUVSF (+1"), XIJDI JT B TUBOEBSE JOUFSGBDF MBZFS UIBU XSBQT 0CKFDU/3FMBUJPOBM .BQQJOH (03.) QSPEVDUT TVDI BT 0QFO+1", )JCFSOBUF, 5PQ-JOL, BOE TP PO. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jpa</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

2BKAFKD QL QEB BKAMLFKQ :PV DBO TUPSF B +BWB FOUJUZ CFBO JO B EBUBCBTF CZ TFOEJOH JU UP B +1" QSPEVDFS FOEQPJOU. 5IF CPEZ PG UIF In NFTTBHF JT BTTVNFE UP CF BO FOUJUZ CFBO (UIBU JT, B 10+0 XJUI BO !&OUJUZ BOOPUBUJPO PO JU) PS B DPMMFDUJPO PS BSSBZ PG FOUJUZ CFBOT. *G UIF CPEZ EPFT OPU DPOUBJO POF PG UIF QSFWJPVT MJTUFE UZQFT, QVU B .FTTBHF 5SBOTMBUPS JO GSPOU PG UIF FOEQPJOU UP QFSGPSN UIF OFDFTTBSZ DPOWFSTJPO GJSTU. "LKPRJFKD COLJ QEB BKAMLFKQ $POTVNJOH NFTTBHFT GSPN B +1" DPOTVNFS FOEQPJOU SFNPWFT (PS VQEBUFT) FOUJUZ CFBOT JO UIF EBUBCBTF. 5IJT BMMPXT ZPV UP VTF B EBUBCBTF UBCMF BT B MPHJDBM RVFVF: DPOTVNFST UBLF NFTTBHFT GSPN UIF RVFVF BOE UIFO EFMFUF/VQEBUF UIFN UP MPHJDBMMZ SFNPWF UIFN GSPN UIF RVFVF. *G ZPV EP OPU XJTI UP EFMFUF UIF FOUJUZ CFBO XIFO JU IBT CFFO QSPDFTTFE (BOE XIFO SPVUJOH JT EPOF), ZPV DBO TQFDJGZ consumeDelete=false PO UIF 63*. 5IJT XJMM SFTVMU JO UIF FOUJUZ CFJOH QSPDFTTFE FBDI QPMM. *G ZPV XPVME SBUIFS QFSGPSN TPNF VQEBUF PO UIF FOUJUZ UP NBSL JU BT QSPDFTTFE (TVDI BT UP FYDMVEF JU GSPN B GVUVSF RVFSZ) UIFO ZPV DBO BOOPUBUF B NFUIPE XJUI !$POTVNFE XIJDI XJMM CF JOWPLFE PO ZPVS FOUJUZ CFBO XIFO UIF FOUJUZ CFBO XIFO JU IBT CFFO QSPDFTTFE (BOE XIFO SPVUJOH JT EPOF). 41( CLOJ>Q
jpa:[entityClassName][?options]

'PS TFOEJOH UP UIF FOEQPJOU, UIF entityClassName JT PQUJPOBM. *G TQFDJGJFE, JU IFMQT UIF 5ZQF $POWFSUFS UP FOTVSF UIF CPEZ JT PG UIF DPSSFDU UZQF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

781

'PS DPOTVNJOH, UIF entityClassName JT NBOEBUPSZ. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
entityType persistenceUnit consumeDelete consumeLockEntity flushOnSend maximumResults

#BC>RIQ 5>IRB
entityClassName camel true true true -1

#BP@OFMQFLK
0WFSSJEFT UIF entityClassName GSPN UIF 63*. 5IF +1" QFSTJTUFODF VOJU VTFE CZ EFGBVMU. )/ @LKPRJBO LKIV: *G true, UIF FOUJUZ JT EFMFUFE BGUFS JU JT DPOTVNFE; JG false, UIF FOUJUZ JT OPU EFMFUFE.

)/ @LKPRJBO LKIV: 4QFDJGJFT XIFUIFS PS OPU UP TFU BO FYDMVTJWF MPDL PO FBDI FOUJUZ CFBO XIJMF QSPDFTTJOH UIF SFTVMUT GSPN QPMMJOH. )/ )/ MOLAR@BO LKIV: 'MVTIFT UIF &OUJUZ.BOBHFS BGUFS UIF FOUJUZ CFBO IBT CFFO QFSTJTUFE. @LKPRJBO LKIV: 4FU UIF NBYJNVN OVNCFS PG SFTVMUT UP SFUSJFWF PO UIF 2VFSZ.

transactionManager

null

5IJT PQUJPO JT 3FHJTUSZ CBTFE XIJDI SFRVJSFT UIF # OPUBUJPO TP UIBU UIF HJWFO transactionManager CFJOH TQFDJGJFE DBO CF MPPLFE VQ QSPQFSMZ, F.H. transactionManager=#myTransactionManager. *U TQFDJGJFT UIF USBOTBDUJPO NBOBHFS UP VTF. *G OPOF QSPWJEFE, $BNFM XJMM VTF B JpaTransactionManager CZ EFGBVMU. $BO CF VTFE UP TFU B +5" USBOTBDUJPO NBOBHFS (GPS JOUFHSBUJPO XJUI BO &+# DPOUBJOFS). )/ )/ @LKPRJBO LKIV: %FMBZ JO NJMMJTFDPOET CFUXFFO FBDI QPMM. @LKPRJBO LKIV: .JMMJTFDPOET CFGPSF QPMMJOH TUBSUT.

consumer.delay consumer.initialDelay consumer.useFixedDelay

500 1000 false

)/ @LKPRJBO LKIV: 4FU UP true UP VTF GJYFE EFMBZ CFUXFFO QPMMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT. )/ @LKPRJBO LKIV: "O JOUFHFS WBMVF UP EFGJOF UIF NBYJNVN OVNCFS PG NFTTBHFT UP HBUIFS QFS QPMM. #Z EFGBVMU, OP NBYJNVN JT TFU. $BO CF VTFE UP BWPJE QPMMJOH NBOZ UIPVTBOET PG NFTTBHFT XIFO TUBSUJOH VQ UIF TFSWFS. 4FU B WBMVF PG 0 PS OFHBUJWF UP EJTBCMF. )/ )/ @LKPRJBO LKIV: 5P VTF B DVTUPN RVFSZ XIFO DPOTVNJOH EBUB. @LKPRJBO LKIV: 5P VTF B OBNFE RVFSZ XIFO DPOTVNJOH EBUB.

maxMessagesPerPoll consumer.query consumer.namedQuery consumer.nativeQuery

0 c c c

)/ @LKPRJBO LKIV: 5P VTF B DVTUPN OBUJWF RVFSZ XIFO DPOTVNJOH EBUB. :PV NBZ XBOU UP VTF UIF PQUJPO consumer.resultClass BMTP XIFO VTJOH OBUJWF RVFSJFT. ">JBI 2.7: )/ @LKPRJBO LKIV: %FGJOFT UIF UZQF PG UIF SFUVSOFE QBZMPBE (XF XJMM DBMM entityManager.createNativeQuery(nativeQuery, resultClass) JOTUFBE PG entityManager.createNativeQuery(nativeQuery)). 8JUIPVU UIJT PQUJPO, XF XJMM SFUVSO BO PCKFDU BSSBZ. 0OMZ IBT BO BGGFDU XIFO VTJOH JO DPOKVODUJPO XJUI OBUJWF RVFSZ XIFO DPOTVNJOH EBUB. ">JBI 2.7.5/2.8.3/2.9: )/ @LKPRJBO LKIV: 8IFUIFS UP SVO UIF DPOTVNFS JO USBOTBDUFE NPEF, CZ XIJDI BMM NFTTBHFT XJMM FJUIFS DPNNJU PS SPMMCBDL, XIFO UIF FOUJSF CBUDI IBT CFFO QSPDFTTFE. 5IF EFGBVMU CFIBWJPS (GBMTF) JT UP DPNNJU BMM UIF QSFWJPVTMZ TVDDFTTGVMMZ QSPDFTTFE NFTTBHFT, BOE POMZ SPMMCBDL UIF MBTU GBJMFE NFTTBHF. ">JBI 2.5: )/ MOLAR@BO LKIV: *OEJDBUFT UP VTF entityManager.persist(entity) JOTUFBE PG entityManager.merge(entity). /PUF: entityManager.persist(entity) EPFTO'U XPSL GPS EFUBDIFE FOUJUJFT (XIFSF UIF &OUJUZ.BOBHFS IBT UP FYFDVUF BO 61%"5& JOTUFBE PG BO */4&35 RVFSZ)!

consumer.resultClass

consumer.transacted

false

usePersist

false

,BPP>DB 'B>ABOP $BNFM BEET UIF GPMMPXJOH NFTTBHF IFBEFST UP UIF FYDIBOHF:
'B>ABO
CamelJpaTemplate

3VMB
JpaTemplate

#BP@OFMQFLK
5IF JpaTemplate PCKFDU UIBU JT VTFE UP BDDFTT UIF FOUJUZ CFBO. :PV OFFE UIJT PCKFDU JO TPNF TJUVBUJPOT, GPS JOTUBODF JO B UZQF DPOWFSUFS PS XIFO ZPV BSF EPJOH TPNF DVTUPN QSPDFTTJOH.

782

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"LKCFDROFKD $KQFQV,>K>DBO%>@QLOV *UT TUSPOHMZ BEWJTFE UP DPOGJHVSF UIF +1" DPNQPOFOU UP VTF B TQFDJGJD EntityManagerFactory JOTUBODF. *G GBJMFE UP EP TP FBDI JpaEndpoint XJMM BVUP DSFBUF UIFJS PXO JOTUBODF PG EntityManagerFactory XIJDI NPTU PGUFO JT OPU XIBU ZPV XBOU. 'PS FYBNQMF, ZPV DBO JOTUBOUJBUF B +1" DPNQPOFOU UIBU SFGFSFODFT UIF myEMFactory FOUJUZ NBOBHFS GBDUPSZ, BT GPMMPXT:
<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent"> <property name="entityManagerFactory" ref="myEMFactory"/> </bean>

*O ">JBI 2.3 UIF JpaComponent XJMM BVUP MPPLVQ UIF EntityManagerFactory GSPN UIF 3FHJTUSZ XIJDI NFBOT ZPV EP OPU OFFE UP DPOGJHVSF UIJT PO UIF JpaComponent BT TIPXO BCPWF. :PV POMZ OFFE UP EP TP JG UIFSF JT BNCJHVJUZ, JO XIJDI DBTF $BNFM XJMM MPH B 8"3/. "LKCFDROFKD 3O>KP>@QFLK,>K>DBO *UT TUSPOHMZ BEWJTFE UP DPOGJHVSF UIF TransactionManager JOTUBODF VTFE CZ UIF +1" DPNQPOFOU. *G GBJMFE UP EP TP FBDI JpaEndpoint XJMM BVUP DSFBUF UIFJS PXO JOTUBODF PG TransactionManager XIJDI NPTU PGUFO JT OPU XIBU ZPV XBOU. 'PS FYBNQMF, ZPV DBO JOTUBOUJBUF B +1" DPNQPOFOU UIBU SFGFSFODFT UIF myTransactionManager USBOTBDUJPO NBOBHFS, BT GPMMPXT:
<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent"> <property name="entityManagerFactory" ref="myEMFactory"/> <property name="transactionManager" ref="myTransactionManager"/> </bean>

*O ">JBI 2.3 UIF JpaComponent XJMM BVUP MPPLVQ UIF TransactionManager GSPN UIF 3FHJTUSZ XIJDI NFBOT ZPV EP OPU OFFE UP DPOGJHVSF UIJT PO UIF JpaComponent BT TIPXO BCPWF. :PV POMZ OFFE UP EP TP JG UIFSF JT BNCJHVJUZ, JO XIJDI DBTF $BNFM XJMM MPH B 8"3/. 4PFKD > @LKPRJBO TFQE > K>JBA NRBOV 'PS DPOTVNJOH POMZ TFMFDUFE FOUJUJFT, ZPV DBO VTF UIF consumer.namedQuery 63* RVFSZ PQUJPO. 'JSTU, ZPV IBWF UP EFGJOF UIF OBNFE RVFSZ JO UIF +1" &OUJUZ DMBTT:
@Entity @NamedQuery(name = "step1", query = "select x from MultiSteps x where x.step = 1") public class MultiSteps { ... }

"GUFS UIBU ZPV DBO EFGJOF B DPOTVNFS VSJ MJLF UIJT POF:
$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9 783

from("jpa://org.apache.camel.examples.MultiSteps?consumer.namedQuery=step1") .to("bean:myBusinessLogic");

4PFKD > @LKPRJBO TFQE > NRBOV 'PS DPOTVNJOH POMZ TFMFDUFE FOUJUJFT, ZPV DBO VTF UIF consumer.query 63* RVFSZ PQUJPO. :PV POMZ IBWF UP EFGJOF UIF RVFSZ PQUJPO:
from("jpa://org.apache.camel.examples.MultiSteps?consumer.query=select o from org.apache.camel.examples.MultiSteps o where o.step = 1") .to("bean:myBusinessLogic");

4PFKD > @LKPRJBO TFQE > K>QFSB NRBOV 'PS DPOTVNJOH POMZ TFMFDUFE FOUJUJFT, ZPV DBO VTF UIF consumer.nativeQuery 63* RVFSZ PQUJPO. :PV POMZ IBWF UP EFGJOF UIF OBUJWF RVFSZ PQUJPO:
from("jpa://org.apache.camel.examples.MultiSteps?consumer.nativeQuery=select * from MultiSteps where step = 1") .to("bean:myBusinessLogic");

*G ZPV VTF UIF OBUJWF RVFSZ PQUJPO, ZPV XJMM SFDFJWF BO PCKFDU BSSBZ JO UIF NFTTBHF CPEZ. $U>JMIB 4FF 5SBDFS &YBNQMF GPS BO FYBNQMF VTJOH +1" UP TUPSF USBDFE NFTTBHFT JOUP B EBUBCBTF. 4PFKD QEB )/ ?>PBA FABJMLQBKQ OBMLPFQLOV

*O UIJT TFDUJPO XF XJMM VTF UIF +1" CBTFE JEFNQPUFOU SFQPTJUPSZ. 'JSTU XF OFFE UP TFUVQ B persistence-unit JO UIF QFSTJTUFODF.YNM GJMF:
<persistence-unit name="idempotentDb" transaction-type="RESOURCE_LOCAL"> <class>org.apache.camel.processor.idempotent.jpa.MessageProcessed</class> <properties> <property name="openjpa.ConnectionURL" value="jdbc:derby:target/ idempotentTest;create=true"/> <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/> <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/> <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>

784

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

</properties> </persistence-unit>

4FDPOE XF IBWF UP TFUVQ B org.springframework.orm.jpa.JpaTemplate XIJDI JT VTFE CZ UIF org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository:


<!-- this is standard spring JPA configuration --> <bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> <!-- we use idempotentDB as the persitence unit name defined in the persistence.xml file --> <property name="persistenceUnitName" value="idempotentDb"/> </bean>

"GUFSXBSET XF DBO DPOGJHVSF PVS org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository:


<!-- we define our jpa based idempotent repository we want to use in the file consumer --> <bean id="jpaStore" class="org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository"> <!-- Here we refer to the spring jpaTemplate --> <constructor-arg index="0" ref="jpaTemplate"/> <!-- This 2nd parameter is the name (= a cateogry name). You can have different repositories with different names --> <constructor-arg index="1" value="FileConsumer"/> </bean>

"OE GJOBMMZ XF DBO DSFBUF PVS +1" JEFNQPUFOU SFQPTJUPSZ JO UIF TQSJOH 9.- GJMF BT XFMM:
<camel:camelContext> <camel:route id="JpaMessageIdRepositoryTest"> <camel:from uri="direct:start" /> <camel:idempotentConsumer messageIdRepositoryRef="jpaStore"> <camel:header>messageId</camel:header> <camel:to uri="mock:result" /> </camel:idempotentConsumer> </camel:route> </camel:camelContext>

2BB

IPL ` $POGJHVSJOH $BNFM

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

785

6EBK ORKKFKD QEFP ">JBI @LJMLKBKQ QBPQP FKPFAB VLRO (#$ *O DBTF ZPV SVO UIF UFTUT PG UIJT DPNQPOFOU EJSFDUMZ JOTJEF ZPVS *%& (BOE OPU OFDFTTBSJMZ UISPVHI .BWF MJLF:

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityMana is <openjpa-2.2.1-r422266:1396819 nonfatal user error> org.apache.openjpa.persistence.ArgumentExce runtime optimization, but the following listed types were not enhanced at build time or at class load time with a jav "org.apache.camel.examples.SendEmail". at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(Abstr at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTempl at org.apache.camel.processor.jpa.JpaRouteTest.cleanupRepository(JpaRouteTest.java:96) at org.apache.camel.processor.jpa.JpaRouteTest.createCamelContext(JpaRouteTest.java:67) at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:238) at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:208)

5IF QSPCMFN IFSF JT UIBU UIF TPVSDF IBT CFFO DPNQJMFE/SFDPNQJMFE UISPVHI ZPVS *%& BOE OPU UISPVHI .BWFO JUTFM UJNF. 5P PWFSDPNF UIJT ZPV XPVME OFFE UP FOBCMF EZOBNJD CZUF-DPEF FOIBODFNFOU PG 0QFO+1". "T BO FYBNQMF BT VTFE JO $BNFM JUTFMG JT 2.2.1, UIFO BT SVOOJOH UIF UFTUT JOTJEF ZPVS GBWPSJUF *%& ZPV XPVME OFFE UP QBTT UIF GPMMPXJO

-javaagent:<path_to_your_local_m2_cache>/org/apache/openjpa/openjpa/2.2.1/openjpa-2.2.1.jar

5IFO JU XJMM BMM CFDPNF HSFFO BHBJO

` ` `

$PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 5SBDFS &YBNQMF

)3/400 ".,/.-$-3
5IF jt400 DPNQPOFOU BMMPXT ZPV UP FYDIBOHFT NFTTBHFT XJUI BO "4/400 TZTUFN VTJOH EBUB RVFVFT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId>

786

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<artifactId>camel-jt400</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
jt400://user:password@system/QSYS.LIB/LIBRARY.LIB/QUEUE.DTAQ[?options]

5P DBMM SFNPUF QSPHSBN (">JBI 2.7)


jt400://user:password@system/QSYS.LIB/LIBRARY.LIB/program.PGM[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 41( LMQFLKP 'PS UIF EBUB RVFVF NFTTBHF FYDIBOHF:
->JB
ccsid format consumer.delay consumer.initialDelay consumer.userFixedDelay guiAvailable keyed searchKey searchType connectionPool

#BC>RIQ S>IRB
EFGBVMU TZTUFN $$4*% text 500 1000 false false false null EQ AS400ConnectionPool JOTUBODF

#BP@OFMQFLK
4QFDJGJFT UIF $$4*% UP VTF GPS UIF DPOOFDUJPO XJUI UIF "4/400 TZTUFN. 4QFDJGJFT UIF EBUB GPSNBU GPS TFOEJOH NFTTBHFT WBMJE PQUJPOT BSF: text (SFQSFTFOUFE CZ String) BOE binary (SFQSFTFOUFE CZ byte[]) %FMBZ JO NJMMJTFDPOET CFUXFFO FBDI QPMM. .JMMJTFDPOET CFGPSF QPMMJOH TUBSUT. true UP VTF GJYFE EFMBZ CFUXFFO QPMMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT. ">JBI 2.8: 4QFDJGJFT XIFUIFS "4/400 QSPNQUJOH JT FOBCMFE JO UIF FOWJSPONFOU SVOOJOH $BNFM. ">JBI 2.10: 8IFUIFS UP VTF LFZFE PS OPO-LFZFE EBUB RVFVFT. ">JBI 2.10: 4FBSDI LFZ GPS LFZFE EBUB RVFVFT. ">JBI 2.10: 4FBSDI UZQF XIJDI DBO CF B WBMVF PG EQ, NE, LT, LE, GT, PS GE. ">JBI 2.10: 3FGFSFODF UP BO DPN.JCN.BT400.BDDFTT."4400$POOFDUJPO1PPM JOTUBODF JO UIF 3FHJTUSZ. 5IJT JT VTFE GPS PCUBJOJOH DPOOFDUJPOT UP UIF "4/400 TZTUFN. 5IF MPPL VQ OPUBUJPO ('#' DIBSBDUFS) TIPVME CF VTFE.

'PS UIF SFNPUF QSPHSBN DBMM (">JBI 2.7)


->JB
outputFieldsIdx fieldsLength format guiAvailable connectionPool

#BC>RIQ S>IRB
c c text false AS400ConnectionPool JOTUBODF

#BP@OFMQFLK
4QFDJGJFT XIJDI GJFMET (QSPHSBN QBSBNFUFST) BSF PVUQVU QBSBNFUFST. 4QFDJGJFT UIF GJFMET (QSPHSBN QBSBNFUFST) MFOHUI BT JO UIF "4/400 QSPHSBN EFGJOJUJPO. ">JBI 2.10: 4QFDJGJFT UIF EBUB GPSNBU GPS TFOEJOH NFTTBHFT WBMJE PQUJPOT BSF: text (SFQSFTFOUFE CZ String) BOE binary (SFQSFTFOUFE CZ byte[]) ">JBI 2.8: 4QFDJGJFT XIFUIFS "4/400 QSPNQUJOH JT FOBCMFE JO UIF FOWJSPONFOU SVOOJOH $BNFM. ">JBI 2.10: 3FGFSFODF UP BO DPN.JCN.BT400.BDDFTT."4400$POOFDUJPO1PPM JOTUBODF JO UIF 3FHJTUSZ. 5IJT JT VTFE GPS PCUBJOJOH DPOOFDUJPOT UP UIF "4/400 TZTUFN. 5IF MPPL VQ OPUBUJPO ('#' DIBSBDUFS) TIPVME CF VTFE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

787

4P>DB 8IFO DPOGJHVSFE BT B DPOTVNFS FOEQPJOU, UIF FOEQPJOU XJMM QPMM B EBUB RVFVF PO B SFNPUF TZTUFN. 'PS FWFSZ FOUSZ PO UIF EBUB RVFVF, B OFX Exchange JT TFOU XJUI UIF FOUSZ'T EBUB JO UIF In NFTTBHF'T CPEZ, GPSNBUUFE FJUIFS BT B String PS B byte[], EFQFOEJOH PO UIF GPSNBU. 'PS B QSPWJEFS FOEQPJOU, UIF In NFTTBHF CPEZ DPOUFOUT XJMM CF QVU PO UIF EBUB RVFVF BT FJUIFS SBX CZUFT PS UFYU. "LKKB@QFLK MLLI S>FI>?IB >P LC ">JBI 2.10 $POOFDUJPO QPPMJOH JT JO VTF GSPN $BNFM 2.10 POXBSET. :PV DBO FYQMJDJU DPOGJHVSF B DPOOFDUJPO QPPM PO UIF +U400$PNQPOFOU, PS BT BO VSJ PQUJPO PO UIF FOEQPJOU.

1BJLQB MOLDO>J @>II (">JBI 2.7)


5IJT FOEQPJOU FYQFDUT UIF JOQVU UP CF FJUIFS B 4USJOH BSSBZ PS CZUF<> BSSBZ (EFQFOEJOH PO GPSNBU) BOE IBOEMFT BMM UIF $$4*% IBOEMJOH UISPVHI UIF OBUJWF KU400 MJCSBSZ NFDIBOJTNT. " QBSBNFUFS DBO CF omitted CZ QBTTJOH OVMM BT UIF WBMVF JO JUT QPTJUJPO (UIF SFNPUF QSPHSBN IBT UP TVQQPSU JU). "GUFS UIF QSPHSBN FYFDVUJPO UIF FOEQPJOU SFUVSOT FJUIFS B 4USJOH BSSBZ PS CZUF<> BSSBZ XJUI UIF WBMVFT BT UIFZ XFSF SFUVSOFE CZ UIF QSPHSBN (UIF JOQVU POMZ QBSBNFUFST XJMM DPOUBJO UIF TBNF EBUB BT UIF CFHJOOJOH PG UIF JOWPDBUJPO) 5IJT FOEQPJOU EPFT OPU JNQMFNFOU B QSPWJEFS FOEQPJOU! $U>JMIB *O UIF TOJQQFU CFMPX, UIF EBUB GPS BO FYDIBOHF TFOU UP UIF direct:george FOEQPJOU XJMM CF QVU JO UIF EBUB RVFVF PENNYLANE JO MJCSBSZ BEATLES PO B TZTUFN OBNFE LIVERPOOL. "OPUIFS VTFS DPOOFDUT UP UIF TBNF EBUB RVFVF UP SFDFJWF UIF JOGPSNBUJPO GSPN UIF EBUB RVFVF BOE GPSXBSE JU UP UIF mock:ringo FOEQPJOU.
public class Jt400RouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { from("direct:george").to("jt400://GEORGE:EGROEG@LIVERPOOL/QSYS.LIB/BEATLES.LIB/ PENNYLANE.DTAQ"); from("jt400://RINGO:OGNIR@LIVERPOOL/QSYS.LIB/BEATLES.LIB/ PENNYLANE.DTAQ").to("mock:ringo"); } }

788

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

1BJLQB MOLDO>J @>II BU>JMIB (">JBI 2.7)


*O UIF TOJQQFU CFMPX, UIF EBUB &YDIBOHF TFOU UP UIF EJSFDU:XPSL FOEQPJOU XJMM DPOUBJO UISFF TUSJOH UIBU XJMM CF VTFE BT UIF BSHVNFOUT GPS UIF QSPHSBN eDPNQVUFd JO UIF MJCSBSZ eBTTFUTd. 5IJT QSPHSBN XJMM XSJUF UIF PVUQVU WBMVFT JO UIF 2OE BOE 3SE QBSBNFUFST. "MM UIF QBSBNFUFST XJMM CF TFOU UP UIF EJSFDU:QMBZ FOEQPJOU.
public class Jt400RouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { from("direct:work").to("jt400://GRUPO:ATWORK@server/QSYS.LIB/assets.LIB/ compute.PGM?fieldsLength=10,10,512&ouputFieldsIdx=2,3").to(direct:play); } }

6OFQFKD QL HBVBA A>Q> NRBRBP


from("jms:queue:input") .to("jt400://username:password@system/lib.lib/MSGINDQ.DTAQ?keyed=true");

1B>AFKD COLJ HBVBA A>Q> NRBRBP


from("jt400://username:password@system/lib.lib/ MSGOUTDQ.DTAQ?keyed=true&searchKey=MYKEY&searchType=GE") .to("jms:queue:output");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

+ -&4 &$
S>FI>?IB >P LC ">JBI 2.5 5IF MBOHVBHF DPNQPOFOU BMMPXT ZPV UP TFOE &YDIBOHF UP BO FOEQPJOU XIJDI FYFDVUFT B TDSJQU CZ BOZ PG UIF TVQQPSUFE -BOHVBHFT JO $BNFM. #Z IBWJOH B DPNQPOFOU UP FYFDVUF MBOHVBHF TDSJQUT, JU BMMPXT NPSF EZOBNJD SPVUJOH DBQBCJMJUJFT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

789

'PS FYBNQMF CZ VTJOH UIF 3PVUJOH 4MJQ PS %ZOBNJD 3PVUFS &*1T ZPV DBO TFOE NFTTBHFT UP language FOEQPJOUT XIFSF UIF TDSJQU JT EZOBNJD EFGJOFE BT XFMM. 5IJT DPNQPOFOU JT QSPWJEFE PVU PG UIF CPY JO camel-core BOE IFODF OP BEEJUJPOBM +"3T JT OFFEFE. :PV POMZ IBWF UP JODMVEF BEEJUJPOBM $BNFM DPNQPOFOUT JG UIF MBOHVBHF PG DIPJDF NBOEBUFT JU, TVDI BT VTJOH (SPPWZ PS +BWB4DSJQU MBOHVBHFT. 41( CLOJ>Q
language://languageName[:script][?options]

"OE GSPN $BNFM 2.11 POXBSET ZPV DBO SFGFS UP BO FYUFSOBM SFTPVSDF GPS UIF TDSJQU VTJOH TBNF OPUBUJPO BT TVQQPSUFE CZ UIF PUIFS -BOHVBHFT JO $BNFM
language://languageName:resource:scheme:location][?options]

41( .MQFLKP 5IF DPNQPOFOU TVQQPSUT UIF GPMMPXJOH PQUJPOT.


->JB
languageName script transform

#BC>RIQ 5>IRB
null null true

3VMB
String String boolean

#BP@OFMQFLK
5IF OBNF PG UIF -BOHVBHF UP VTF, TVDI BT simple, groovy, javascript FUD. 5IJT PQUJPO JT NBOEBUPSZ. 5IF TDSJQU UP FYFDVUF. 8IFUIFS PS OPU UIF SFTVMU PG UIF TDSJQU TIPVME CF VTFE BT UIF OFX NFTTBHF CPEZ. #Z TFUUJOH UP false UIF TDSJQU JT FYFDVUFE CVU UIF SFTVMU PG UIF TDSJQU JT EJTDBSEFE. ">JBI 2.9: 8IFUIFS UP DBDIF UIF TDSJQU JG MPBEFE GSPN B SFTPVSDF. /PUF: GSPN ">JBI 2.10.3 B DBDIFE TDSJQU DBO CF GPSDFE UP SFMPBE BU SVOUJNF WJB +.9 VTJOH UIF DMFBS$POUFOU$BDIF PQFSBUJPO.

contentCache

true

boolean

,BPP>DB 'B>ABOP 5IF GPMMPXJOH NFTTBHF IFBEFST DBO CF VTFE UP BGGFDU UIF CFIBWJPS PG UIF DPNQPOFOU
'B>ABO
CamelLanguageScript

#BP@OFMQFLK
5IF TDSJQU UP FYFDVUF QSPWJEFE JO UIF IFBEFS. 5BLFT QSFDFEFODF PWFS TDSJQU DPOGJHVSFE PO UIF FOEQPJOU.

$U>JMIBP 'PS FYBNQMF ZPV DBO VTF UIF 4JNQMF MBOHVBHF UP .FTTBHF 5SBOTMBUPS B NFTTBHF:
String script = URLEncoder.encode("Hello ${body}", "UTF-8"); from("direct:start").to("language:simple:" + script).to("mock:result");

*O DBTF ZPV XBOU UP DPOWFSU UIF NFTTBHF CPEZ UZQF ZPV DBO EP UIJT BT XFMM:

790

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

String script = URLEncoder.encode("${mandatoryBodyAs(String)}", "UTF-8"); from("direct:start").to("language:simple:" + script).to("mock:result");

:PV DBO BMTP VTF UIF (SPPWZ MBOHVBHF, TVDI BT UIJT FYBNQMF XIFSF UIF JOQVU NFTTBHF XJMM CZ NVMUJQMJFE XJUI 2:
String script = URLEncoder.encode("request.body * 2", "UTF-8"); from("direct:start").to("language:groovy:" + script).to("mock:result");

:PV DBO BMTP QSPWJEF UIF TDSJQU BT B IFBEFS BT TIPXO CFMPX. )FSF XF VTF 91BUI MBOHVBHF UP FYUSBDU UIF UFYU GSPN UIF <foo> UBH.
Object out = producer.requestBodyAndHeader("language:xpath", "<foo>Hello World</foo>", Exchange.LANGUAGE_SCRIPT, "/foo/text()"); assertEquals("Hello World", out);

+L>AFKD P@OFMQP COLJ OBPLRO@BP S>FI>?IB >P LC ">JBI 2.9 :PV DBO TQFDJGZ B SFTPVSDF VSJ GPS B TDSJQU UP MPBE JO FJUIFS UIF FOEQPJOU VSJ, PS JO UIF Exchange.LANGUAGE_SCRIPT IFBEFS. 5IF VSJ NVTU TUBSU XJUI POF PG UIF GPMMPXJOH TDIFNFT: GJMF:, DMBTTQBUI:, PS IUUQ: 'PS FYBNQMF UP MPBE B TDSJQU GSPN UIF DMBTTQBUI:
from("direct:start") // load the script from the classpath .to("language:simple:classpath:org/apache/camel/component/language/ mysimplescript.txt") .to("mock:result");

#Z EFGBVMU UIF TDSJQU JT MPBEFE PODF BOE DBDIFE. )PXFWFS ZPV DBO EJTBCMF UIF contentCache PQUJPO BOE IBWF UIF TDSJQU MPBEFE PO FBDI FWBMVBUJPO. 'PS FYBNQMF JG UIF GJMF NZTDSJQU.UYU JT DIBOHFE PO EJTL, UIFO UIF VQEBUFE TDSJQU JT VTFE:
from("direct:start") // the script will be loaded on each message, as we disabled cache .to("language:simple:file:target/script/myscript.txt?contentCache=false") .to("mock:result");

'SPN ">JBI 2.11 POXBSET ZPV DBO SFGFS UP UIF SFTPVSDF TJNJMBS UP UIF PUIFS -BOHVBHFT JO $BNFM CZ QSFGJYJOH XJUI "resource:" BT TIPXO CFMPX:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

791

from("direct:start") // load the script from the classpath .to("language:simple:resource:classpath:org/apache/camel/component/language/ mysimplescript.txt") .to("mock:result");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE -BOHVBHFT 3PVUJOH 4MJQ %ZOBNJD 3PVUFS

+# / ".,/.-$-3
5IF IA>M DPNQPOFOU BMMPXT ZPV UP QFSGPSN TFBSDIFT JO -%"1 TFSWFST VTJOH GJMUFST BT UIF NFTTBHF QBZMPBE. 5IJT DPNQPOFOU VTFT TUBOEBSE +/%* (javax.naming QBDLBHF) UP BDDFTT UIF TFSWFS. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-ldap</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
ldap:ldapServerBean[?options]

5IF ldapServerBean QPSUJPO PG UIF 63* SFGFST UP B %JS$POUFYU CFBO JO UIF SFHJTUSZ. 5IF -%"1 DPNQPOFOU POMZ TVQQPSUT QSPEVDFS FOEQPJOUT, XIJDI NFBOT UIBU BO ldap 63* DBOOPU BQQFBS JO UIF from BU UIF TUBSU PG B SPVUF. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

792

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.MQFLKP
->JB
base scope QBHF4J[F

#BC>RIQ 5>IRB
ou=system subtree OP QBHJOH VTFE EFQFOET PO -%"1 4FSWFS (DPVME CF BMM PS OPOF)

#BP@OFMQFLK
5IF CBTF %/ GPS TFBSDIFT. 4QFDJGJFT IPX EFFQMZ UP TFBSDI UIF USFF PG FOUSJFT, TUBSUJOH BU UIF CBTF %/. 7BMVF DBO CF object, onelevel, PS subtree. ">JBI 2.6: 8IFO TQFDJGJFE UIF MEBQ NPEVMF VTFT QBHJOH UP SFUSJFWF BMM SFTVMUT (NPTU -%"1 4FSWFST UISPX BO FYDFQUJPO XIFO USZJOH UP SFUSJFWF NPSF UIBO 1000 FOUSJFT JO POF RVFSZ). 5P CF BCMF UP VTF UIJT B -EBQ$POUFYU (TVCDMBTT PG %JS$POUFYU) IBT UP CF QBTTFE JO BT MEBQ4FSWFS#FBO (PUIFSXJTF BO FYDFQUJPO JT UISPXO) ">JBI 2.6: $PNNB-TFQBSBUFE MJTU PG BUUSJCVUFT UIBU TIPVME CF TFU JO FBDI FOUSZ PG UIF SFTVMU

SFUVSOFE"UUSJCVUFT

1BPRIQ 5IF SFTVMU JT SFUVSOFE JO UIF 0VU CPEZ BT B ArrayList<javax.naming.directory.SearchResult> PCKFDU. #FO"LKQBUQ 5IF 63*, ldap:ldapserver, SFGFSFODFT B 4QSJOH CFBO XJUI UIF *%, ldapserver. 5IF ldapserver CFBO NBZ CF EFGJOFE BT GPMMPXT:
<bean id="ldapserver" class="javax.naming.directory.InitialDirContext" scope="prototype"> <constructor-arg> <props> <prop key="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</prop> <prop key="java.naming.provider.url">ldap://localhost:10389</prop> <prop key="java.naming.security.authentication">none</prop> </props> </constructor-arg> </bean>

5IF QSFDFEJOH FYBNQMF EFDMBSFT B SFHVMBS 4VO CBTFE -%"1 DirContext UIBU DPOOFDUT BOPOZNPVTMZ UP B MPDBMMZ IPTUFE -%"1 TFSWFS. 2>JMIBP 'PMMPXJOH PO GSPN UIF 4QSJOH DPOGJHVSBUJPO BCPWF, UIF DPEF TBNQMF CFMPX TFOET BO -%"1 SFRVFTU UP GJMUFS TFBSDI B HSPVQ GPS B NFNCFS. 5IF $PNNPO /BNF JT UIFO FYUSBDUFE GSPN UIF SFTQPOTF.
ProducerTemplate<Exchange> template = exchange .getContext().createProducerTemplate(); Collection<?> results = (Collection<?>) (template .sendBody(

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

793

DirContext PCKFDUT BSF KLQ SFRVJSFE UP TVQQPSU DPODVSSFODZ CZ DPOUSBDU. *U JT UIFSFGPSF JNQPSUBOU UIBU UIF EJSFDUPSZ DPOUFYU JT EFDMBSFE XJUI UIF TFUUJOH, scope="prototype", JO UIF bean EFGJOJUJPO PS UIBU UIF DPOUFYU TVQQPSUT DPODVSSFODZ. *O UIF 4QSJOH GSBNFXPSL, prototype TDPQFE PCKFDUT BSF JOTUBOUJBUFE FBDI UJNF UIFZ BSF MPPLFE VQ.

"ldap:ldapserver?base=ou=mygroup,ou=groups,ou=system", "(member=uid=huntc,ou=users,ou=system)")); if (results.size() > 0) { // Extract what we need from the device's profile Iterator<?> resultIter = results.iterator(); SearchResult searchResult = (SearchResult) resultIter .next(); Attributes attributes = searchResult .getAttributes(); Attribute deviceCNAttr = attributes.get("cn"); String deviceCN = (String) deviceCNAttr.get(); ...

*G OP TQFDJGJD GJMUFS JT SFRVJSFE - GPS FYBNQMF, ZPV KVTU OFFE UP MPPL VQ B TJOHMF FOUSZ - TQFDJGZ B XJMEDBSE GJMUFS FYQSFTTJPO. 'PS FYBNQMF, JG UIF -%"1 FOUSZ IBT B $PNNPO /BNF, VTF B GJMUFS FYQSFTTJPO MJLF:
(cn=*)

!FKAFKD RPFKD @OBABKQF>IP


" $BNFM FOE VTFS EPOBUFE UIJT TBNQMF DPEF IF VTFE UP CJOE UP UIF MEBQ TFSWFS VTJOH DSFEFOUJBMT.
Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); props.setProperty(Context.PROVIDER_URL, "ldap://localhost:389"); props.setProperty(Context.URL_PKG_PREFIXES, "com.sun.jndi.url"); props.setProperty(Context.REFERRAL, "ignore"); props.setProperty(Context.SECURITY_AUTHENTICATION, "simple"); props.setProperty(Context.SECURITY_PRINCIPAL, "cn=Manager"); props.setProperty(Context.SECURITY_CREDENTIALS, "secret"); SimpleRegistry reg = new SimpleRegistry();

794

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

reg.put("myldap", new InitialLdapContext(props, null)); CamelContext context = new DefaultCamelContext(reg); context.addRoutes( new RouteBuilder() { public void configure() throws Exception { from("direct:start").to("ldap:myldap?base=ou=test"); } } ); context.start(); ProducerTemplate template = context.createProducerTemplate(); Endpoint endpoint = context.getEndpoint("direct:start"); Exchange exchange = endpoint.createExchange(); exchange.getIn().setBody("(uid=test)"); Exchange out = template.send(endpoint, exchange); Collection<SearchResult> data = out.getOut().getBody(Collection.class); assert data != null; assert !data.isEmpty(); System.out.println(out.getOut().getBody()); context.stop();

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

+.& ".,/.-$-3
5IF ILD: DPNQPOFOU MPHT NFTTBHF FYDIBOHFT UP UIF VOEFSMZJOH MPHHJOH NFDIBOJTN. ">JBI 2.7 LO ?BQQBO VTFT TGM4K XIJDI BMMPXT ZPV UP DPOGJHVSF MPHHJOH WJB, BNPOH PUIFST: ` -PH4K ` -PHCBDL ` +%, 6UJM -PHHJOH MPHHJOH ">JBI 2.6 LO ILTBO VTFT DPNNPOT-MPHHJOH XIJDI BMMPXT ZPV UP DPOGJHVSF MPHHJOH WJB, BNPOH PUIFST: ` -PH4K ` +%, 6UJM -PHHJOH MPHHJOH ` 4JNQMF-PH - B TJNQMF QSPWJEFS JO DPNNPOT-MPHHJOH

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

795

3FGFS UP UIF DPNNPOT-MPHHJOH VTFS HVJEF GPS B NPSF DPNQMFUF PWFSWJFX PG IPX UP VTF BOE DPOGJHVSF DPNNPOT-MPHHJOH. 41( CLOJ>Q
log:loggingCategory[?options]

8IFSF ILDDFKD">QBDLOV JT UIF OBNF PG UIF MPHHJOH DBUFHPSZ UP VTF. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 'PS FYBNQMF, B MPH FOEQPJOU UZQJDBMMZ TQFDJGJFT UIF MPHHJOH MFWFM VTJOH UIF level PQUJPO, BT GPMMPXT:
log:org.apache.camel.example?level=DEBUG

5IF EFGBVMU MPHHFS MPHT FWFSZ FYDIBOHF (regular logging). #VU $BNFM BMTP TIJQT XJUI UIF Throughput MPHHFS, XIJDI JT VTFE XIFOFWFS UIF groupSize PQUJPO JT TQFDJGJFE. .MQFLKP
.MQFLK
level marker groupSize groupInterval groupDelay groupActiveOnly

#BC>RIQ
INFO null null null 0 true

3VMB
String String Integer Integer Integer boolean

#BP@OFMQFLK
-PHHJOH MFWFM UP VTF. 1PTTJCMF WBMVFT: ERROR, WARN, INFO, DEBUG, TRACE, OFF ">JBI 2.9: "O PQUJPOBM .BSLFS OBNF UP VTF. "O JOUFHFS UIBU TQFDJGJFT B HSPVQ TJ[F GPS UISPVHIQVU MPHHJOH. ">JBI 2.6: *G TQFDJGJFE XJMM HSPVQ NFTTBHF TUBUT CZ UIJT UJNF JOUFSWBM (JO NJMMJT) ">JBI 2.6: 4FU UIF JOJUJBM EFMBZ GPS TUBUT (JO NJMMJT) ">JBI 2.6: *G USVF, XJMM IJEF TUBUT XIFO OP OFX NFTTBHFT IBWF CFFO SFDFJWFE GPS B UJNF JOUFSWBM, JG GBMTF, TIPX TUBUT SFHBSEMFTT PG NFTTBHF USBGGJD

KLQB: HSPVQ%FMBZ BOE HSPVQ"DUJWF0OMZ BSF POMZ BQQMJDBCMF XIFO VTJOH HSPVQ*OUFSWBM %LOJ>QQFKD 5IF MPH GPSNBUT UIF FYFDVUJPO PG FYDIBOHFT UP MPH MJOFT. #Z EFGBVMU, UIF MPH VTFT LogFormatter UP GPSNBU UIF MPH PVUQVU, XIFSF LogFormatter IBT UIF GPMMPXJOH PQUJPOT:
.MQFLK
showAll showExchangeId showExchangePattern showProperties showHeaders showBodyType showBody showOut

#BC>RIQ
false false true false false true true false

#BP@OFMQFLK
2VJDL PQUJPO GPS UVSOJOH BMM PQUJPOT PO. (NVMUJMJOF, NBY$IBST IBT UP CF NBOVBMMZ TFU JG UP CF VTFE) 4IPX UIF VOJRVF FYDIBOHF *%. ">JBI 2.3: 4IPXT UIF .FTTBHF &YDIBOHF 1BUUFSO (PS .&1 GPS TIPSU). 4IPX UIF FYDIBOHF QSPQFSUJFT. 4IPX UIF *O NFTTBHF IFBEFST. 4IPX UIF *O CPEZ +BWB UZQF. 4IPX UIF *O CPEZ. *G UIF FYDIBOHF IBT BO 0VU NFTTBHF, TIPX UIF 0VU NFTTBHF.

796

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

IPL > ILD FK QEB #2+ *O ">JBI 2.2 POXBSET UIFSF JT B log EJSFDUMZ JO UIF %4-, CVU JU IBT B EJGGFSFOU QVSQPTF. *UT NFBOU GPS MJHIUXFJHIU BOE IVNBO MPHT. 4FF NPSF EFUBJMT BU -PH&*1.
showException showCaughtException false false *G UIF FYDIBOHF IBT BO FYDFQUJPO, TIPX UIF FYDFQUJPO NFTTBHF (OP TUBDL USBDF). *G UIF FYDIBOHF IBT B DBVHIU FYDFQUJPO, TIPX UIF FYDFQUJPO NFTTBHF (OP TUBDL USBDF). " DBVHIU FYDFQUJPO JT TUPSFE BT B QSPQFSUZ PO UIF FYDIBOHF (VTJOH UIF LFZ Exchange.EXCEPTION_CAUGHT) BOE GPS JOTUBODF B doCatch DBO DBUDI FYDFQUJPOT. 4FF 5SZ $BUDI 'JOBMMZ. 4IPX UIF TUBDL USBDF, JG BO FYDIBOHF IBT BO FYDFQUJPO. 0OMZ FGGFDUJWF JG POF PG showAll, showException PS showCaughtException BSF FOBCMFE. ">JBI 2.9: 8IFUIFS $BNFM TIPVME TIPX GJMF CPEJFT PS OPU (FH TVDI BT KBWB.JP.'JMF). ">JBI 2.1: 8IFUIFS $BNFM TIPVME TIPX java.util.concurrent.Future CPEJFT PS OPU. *G FOBCMFE $BNFM DPVME QPUFOUJBMMZ XBJU VOUJM UIF Future UBTL JT EPOF. 8JMM CZ EFGBVMU OPU XBJU. ">JBI 2.8: 8IFUIFS $BNFM TIPVME TIPX TUSFBN CPEJFT PS OPU (FH TVDI BT KBWB.JP.*OQVU4USFBN). #FXBSF JG ZPV FOBCMF UIJT PQUJPO UIFO ZPV NBZ OPU CF BCMF MBUFS UP BDDFTT UIF NFTTBHF CPEZ BT UIF TUSFBN IBWF BMSFBEZ CFFO SFBE CZ UIJT MPHHFS. 5P SFNFEZ UIJT ZPV XJMM IBWF UP VTF 4USFBN DBDIJOH. *G true, FBDI QJFDF PG JOGPSNBUJPO JT MPHHFE PO B OFX MJOF. -JNJUT UIF OVNCFS PG DIBSBDUFST MPHHFE QFS MJOF. 5IF EFGBVMU WBMVF JT 10000 GSPN ">JBI 2.9 POXBSET.

showStackTrace showFiles showFuture

false false false

showStreams multiline maxChars

false false c

1BDRI>O ILDDBO P>JMIB *O UIF SPVUF CFMPX XF MPH UIF JODPNJOH PSEFST BU DEBUG MFWFM CFGPSF UIF PSEFS JT QSPDFTTFE:
from("activemq:orders").to("log:com.mycompany.order?level=DEBUG").to("bean:processOrder");

0S VTJOH 4QSJOH 9.- UP EFGJOF UIF SPVUF:


<route> <from uri="activemq:orders"/> <to uri="log:com.mycompany.order?level=DEBUG"/> <to uri="bean:processOrder"/> </route>

1BDRI>O ILDDBO TFQE CLOJ>QQBO P>JMIB *O UIF SPVUF CFMPX XF MPH UIF JODPNJOH PSEFST BU INFO MFWFM CFGPSF UIF PSEFS JT QSPDFTTFE.
from("activemq:orders"). to("log:com.mycompany.order?showAll=true&multiline=true").to("bean:processOrder");

3EOLRDEMRQ ILDDBO TFQE DOLRM2FWB P>JMIB *O UIF SPVUF CFMPX XF MPH UIF UISPVHIQVU PG UIF JODPNJOH PSEFST BU DEBUG MFWFM HSPVQFE CZ 10 NFTTBHFT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

797

+LDDFKD PQOB>J ?LAFBP 'PS PMEFS WFSTJPOT PG $BNFM UIBU EP OPU TVQQPSU UIF TIPX'JMFT PS TIPX4USFBNT QSPQFSUJFT BCPWF, ZPV DBO TFU UIF GPMMPXJOH QSPQFSUZ JOTUFBE PO UIF $BNFM$POUFYU UP MPH CPUI TUSFBN BOE GJMF CPEJFT:
camelContext.getProperties().put(Exchange.LOG_DEBUG_BODY_STREAMS, true);

from("activemq:orders"). to("log:com.mycompany.order?level=DEBUG&groupSize=10").to("bean:processOrder");

3EOLRDEMRQ ILDDBO TFQE DOLRM(KQBOS>I P>JMIB 5IJT SPVUF XJMM SFTVMU JO NFTTBHF TUBUT MPHHFE FWFSZ 10T, XJUI BO JOJUJBM 60T EFMBZ BOE TUBUT TIPVME CF EJTQMBZFE FWFO JG UIFSF JTO'U BOZ NFTTBHF USBGGJD.

from("activemq:orders"). to("log:com.mycompany.order?level=DEBUG&groupInterval=10000&groupDelay=60000&groupActiveOnly=false").t

5IF GPMMPXJOH XJMM CF MPHHFE:


"Received: 1000 new messages, with total 2000 so far. Last group took: 10000 millis which is: 100 messages per second. average: 100"

%RII @RPQLJFW>QFLK LC QEB ILDDFKD LRQMRQ S>FI>?IB >P LC ">JBI 2.11 8JUI UIF PQUJPOT PVUMJOFE JO UIF 'PSNBUUJOH TFDUJPO, ZPV DBO DPOUSPM NVDI PG UIF PVUQVU PG UIF MPHHFS. )PXFWFS, MPH MJOFT XJMM BMXBZT GPMMPX UIJT TUSVDUVSF:
Exchange[Id:ID-machine-local-50656-1234567901234-1-2, ExchangePattern:InOut, Properties:{CamelToEndpoint=log://org.apache.camel.component.log.TEST?showAll=true, CamelCreatedTimestamp=Thu Mar 28 00:00:00 WET 2013}, Headers:{breadcrumbId=ID-machine-local-50656-1234567901234-1-1}, BodyType:String, Body:Hello World, Out: null]

5IJT GPSNBU JT VOTVJUBCMF JO TPNF DBTFT, QFSIBQT CFDBVTF ZPV OFFE UP... ` ... GJMUFS UIF IFBEFST BOE QSPQFSUJFT UIBU BSF QSJOUFE, UP TUSJLF B CBMBODF CFUXFFO JOTJHIU BOE WFSCPTJUZ. ` ... BEKVTU UIF MPH NFTTBHF UP XIBUFWFS ZPV EFFN NPTU SFBEBCMF.

798

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

` ... UBJMPS MPH NFTTBHFT GPS EJHFTUJPO CZ MPH NJOJOH TZTUFNT, F.H. 4QMVOL. ` ... QSJOU TQFDJGJD CPEZ UZQFT EJGGFSFOUMZ. ` ... FUD. 8IFOFWFS ZPV SFRVJSF BCTPMVUF DVTUPNJ[BUJPO, ZPV DBO DSFBUF B DMBTT UIBU JNQMFNFOUT UIF ExchangeFormatter JOUFSGBDF. 8JUIJO UIF format(Exchange) NFUIPE ZPV IBWF BDDFTT UP UIF GVMM &YDIBOHF, TP ZPV DBO TFMFDU BOE FYUSBDU UIF QSFDJTF JOGPSNBUJPO ZPV OFFE, GPSNBU JU JO B DVTUPN NBOOFS BOE SFUVSO JU. 5IF SFUVSO WBMVF XJMM CFDPNF UIF GJOBM MPH NFTTBHF. :PV DBO IBWF UIF -PH DPNQPOFOU QJDL VQ ZPVS DVTUPN ExchangeFormatter JO FJUIFS PG UXP XBZT: $UMIF@FQIV FKPQ>KQF>QFKD QEB +LD"LJMLKBKQ FK VLRO 1BDFPQOV:
<bean name="log" class="org.apache.camel.component.log.LogComponent"> <property name="exchangeFormatter" ref="myCustomFormatter" /> </bean>

"LKSBKQFLK LSBO @LKCFDRO>QFLK: 4JNQMZ CZ SFHJTUFSJOH B CFBO XJUI UIF OBNF logFormatter; UIF -PH $PNQPOFOU JT JOUFMMJHFOU FOPVHI UP QJDL JU VQ BVUPNBUJDBMMZ.
<bean name="logFormatter" class="com.xyz.MyCustomExchangeFormatter" />

/05&: UIF ExchangeFormatter HFUT BQQMJFE UP >II +LD BKAMLFKQP TFQEFK QE>Q ">JBI "LKQBUQ. *G ZPV OFFE EJGGFSFOU &YDIBOHF'PSNBUUFST GPS EJGGFSFOU FOEQPJOUT, KVTU JOTUBOUJBUF UIF -PH$PNQPOFOU BT NBOZ UJNFT BT OFFEFE, BOE VTF UIF SFMFWBOU CFBO OBNF BT UIF FOEQPJOU QSFGJY. 2BB IPL ` ` ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 5SBDFS )PX EP * VTF MPH4K )PX EP * VTF +BWB 1.4 MPHHJOH -PH&*1 GPS VTJOH log EJSFDUMZ JO UIF %4- GPS IVNBO MPHT.

+4"$-$ ((-#$7$1
S>FI>?IB >P LC ">JBI 2.2

-# 2$ 1"') ".,/.-$-3

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

799

5IF IR@BKB DPNQPOFOU JT CBTFE PO UIF "QBDIF -VDFOF QSPKFDU. "QBDIF -VDFOF JT B QPXFSGVM IJHI-QFSGPSNBODF, GVMM-GFBUVSFE UFYU TFBSDI FOHJOF MJCSBSZ XSJUUFO FOUJSFMZ JO +BWB. 'PS NPSF EFUBJMT BCPVU -VDFOF, QMFBTF TFF UIF GPMMPXJOH MJOLT ` IUUQ://MVDFOF.BQBDIF.PSH/KBWB/EPDT/ ` IUUQ://MVDFOF.BQBDIF.PSH/KBWB/EPDT/GFBUVSFT.IUNM 5IF MVDFOF DPNQPOFOU JO DBNFM GBDJMJUBUFT JOUFHSBUJPO BOE VUJMJ[BUJPO PG -VDFOF FOEQPJOUT JO FOUFSQSJTF JOUFHSBUJPO QBUUFSOT BOE TDFOBSJPT. 5IF MVDFOF DPNQPOFOU EPFT UIF GPMMPXJOH ` CVJMET B TFBSDIBCMF JOEFY PG EPDVNFOUT XIFO QBZMPBET BSF TFOU UP UIF -VDFOF &OEQPJOU ` GBDJMJUBUFT QFSGPSNJOH PG JOEFYFE TFBSDIFT JO $BNFM 5IJT DPNQPOFOU POMZ TVQQPSUT QSPEVDFS FOEQPJOUT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-lucene</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
lucene:searcherName:insert[?options] lucene:searcherName:query[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... (KPBOQ .MQFLKP
->JB
analyzer indexDir srcDir

#BC>RIQ 5>IRB
StandardAnalyzer ./indexDirectory null

#BP@OFMQFLK
"O "OBMZ[FS CVJMET 5PLFO4USFBNT, XIJDI BOBMZ[F UFYU. *U UIVT SFQSFTFOUT B QPMJDZ GPS FYUSBDUJOH JOEFY UFSNT GSPN UFYU. 5IF WBMVF GPS BOBMZ[FS DBO CF BOZ DMBTT UIBU FYUFOET UIF BCTUSBDU DMBTT PSH.BQBDIF.MVDFOF.BOBMZTJT."OBMZ[FS. -VDFOF BMTP PGGFST B SJDI TFU PG BOBMZ[FST PVU PG UIF CPY " GJMF TZTUFN EJSFDUPSZ JO XIJDI JOEFY GJMFT BSF DSFBUFE VQPO BOBMZTJT PG UIF EPDVNFOU CZ UIF TQFDJGJFE BOBMZ[FS "O PQUJPOBM EJSFDUPSZ DPOUBJOJOH GJMFT UP CF VTFE UP CF BOBMZ[FE BOE BEEFE UP UIF JOEFY BU QSPEVDFS TUBSUVQ.

0RBOV .MQFLKP
->JB #BC>RIQ 5>IRB #BP@OFMQFLK

800

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

analyzer indexDir maxHits

StandardAnalyzer ./indexDirectory 10

"O "OBMZ[FS CVJMET 5PLFO4USFBNT, XIJDI BOBMZ[F UFYU. *U UIVT SFQSFTFOUT B QPMJDZ GPS FYUSBDUJOH JOEFY UFSNT GSPN UFYU. 5IF WBMVF GPS BOBMZ[FS DBO CF BOZ DMBTT UIBU FYUFOET UIF BCTUSBDU DMBTT PSH.BQBDIF.MVDFOF.BOBMZTJT."OBMZ[FS. -VDFOF BMTP PGGFST B SJDI TFU PG BOBMZ[FST PVU PG UIF CPY " GJMF TZTUFN EJSFDUPSZ JO XIJDI JOEFY GJMFT BSF DSFBUFE VQPO BOBMZTJT PG UIF EPDVNFOU CZ UIF TQFDJGJFE BOBMZ[FS "O JOUFHFS WBMVF UIBU MJNJUT UIF SFTVMU TFU PG UIF TFBSDI PQFSBUJPO

2BKAFKD/1B@BFSFKD ,BPP>DBP QL/COLJ QEB @>@EB

,BPP>DB 'B>ABOP
'B>ABO
QUERY

#BP@OFMQFLK
5IF -VDFOF 2VFSZ UP QFSGPSNFE PO UIF JOEFY. 5IF RVFSZ NBZ JODMVEF XJMEDBSET BOE QISBTFT

+R@BKB /OLAR@BOP
5IJT DPNQPOFOU TVQQPSUT 2 QSPEVDFS FOEQPJOUT. ` FKPBOQ - 5IF JOTFSU QSPEVDFS CVJMET B TFBSDIBCMF JOEFY CZ BOBMZ[JOH UIF CPEZ JO JODPNJOH FYDIBOHFT BOE BTTPDJBUJOH JU XJUI B UPLFO ("DPOUFOU"). ` NRBOV - 5IF RVFSZ QSPEVDFS QFSGPSNT TFBSDIFT PO B QSF-DSFBUFE JOEFY. 5IF RVFSZ VTFT UIF TFBSDIBCMF JOEFY UP QFSGPSN TDPSF & SFMFWBODF CBTFE TFBSDIFT. 2VFSJFT BSF TFOU WJB UIF JODPNJOH FYDIBOHF DPOUBJOT B IFBEFS QSPQFSUZ OBNF DBMMFE '26&3:'. 5IF WBMVF PG UIF IFBEFS QSPQFSUZ '26&3:' JT B -VDFOF 2VFSZ. 'PS NPSF EFUBJMT PO IPX UP DSFBUF -VDFOF 2VFSJFT DIFDL PVU IUUQ://MVDFOF.BQBDIF.PSH/KBWB/3@0@0/ RVFSZQBSTFSTZOUBY.IUNM

+R@BKB /OL@BPPLO
5IFSF JT B QSPDFTTPS DBMMFE -VDFOF2VFSZ1SPDFTTPS BWBJMBCMF UP QFSGPSN RVFSJFT BHBJOTU MVDFOF XJUIPVU UIF OFFE UP DSFBUF B QSPEVDFS. +R@BKB 4P>DB 2>JMIBP

$U>JMIB 1: "OB>QFKD > +R@BKB FKABU


RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start"). to("lucene:whitespaceQuotesIndex:insert? analyzer=#whitespaceAnalyzer&indexDir=#whitespace&srcDir=#load_dir"). to("mock:result");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

801

} };

$U>JMIB 2: +L>AFKD MOLMBOQFBP FKQL QEB )-#( OBDFPQOV FK QEB ">JBI "LKQBUQ
@Override protected JndiRegistry createRegistry() throws Exception { JndiRegistry registry = new JndiRegistry(createJndiContext()); registry.bind("whitespace", new File("./whitespaceIndexDir")); registry.bind("load_dir", new File("src/test/resources/sources")); registry.bind("whitespaceAnalyzer", new WhitespaceAnalyzer()); return registry; } ... CamelContext context = new DefaultCamelContext(createRegistry());

$U>JMIB 2: /BOCLOJFKD PB>O@EBP RPFKD > 0RBOV /OLAR@BO


RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:start"). setHeader("QUERY", constant("Seinfeld")). to("lucene:searchIndex:query? analyzer=#whitespaceAnalyzer&indexDir=#whitespace&maxHits=20"). to("direct:next"); from("direct:next").process(new Processor() { public void process(Exchange exchange) throws Exception { Hits hits = exchange.getIn().getBody(Hits.class); printResults(hits); } private void printResults(Hits hits) { LOG.debug("Number of hits: " + hits.getNumberOfHits()); for (int i = 0; i < hits.getNumberOfHits(); i++) { LOG.debug("Hit " + i + " Index Location:" + hits.getHit().get(i).getHitLocation()); LOG.debug("Hit " + i + " Score:" + hits.getHit().get(i).getScore()); LOG.debug("Hit " + i + " Data:" + hits.getHit().get(i).getData()); } } }).to("mock:searchResult");

802

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

} };

$U>JMIB 3: /BOCLOJFKD PB>O@EBP RPFKD > 0RBOV /OL@BPPLO


RouteBuilder builder = new RouteBuilder() { public void configure() { try { from("direct:start"). setHeader("QUERY", constant("Rodney Dangerfield")). process(new LuceneQueryProcessor("target/stdindexDir", analyzer, null, 20)). to("direct:next"); } catch (Exception e) { e.printStackTrace(); } from("direct:next").process(new Processor() { public void process(Exchange exchange) throws Exception { Hits hits = exchange.getIn().getBody(Hits.class); printResults(hits); } private void printResults(Hits hits) { LOG.debug("Number of hits: " + hits.getNumberOfHits()); for (int i = 0; i < hits.getNumberOfHits(); i++) { LOG.debug("Hit " + i + " Index Location:" + hits.getHit().get(i).getHitLocation()); LOG.debug("Hit " + i + " Score:" + hits.getHit().get(i).getScore()); LOG.debug("Hit " + i + " Data:" + hits.getHit().get(i).getData()); } } }).to("mock:searchResult"); } };

, (+ ".,/.-$-3
5IF NBJM DPNQPOFOU QSPWJEFT BDDFTT UP &NBJM WJB 4QSJOH'T .BJM TVQQPSU BOE UIF VOEFSMZJOH +BWB.BJM TZTUFN. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

803

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-mail</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q .BJM FOEQPJOUT DBO IBWF POF PG UIF GPMMPXJOH 63* GPSNBUT (GPS UIF QSPUPDPMT, 4.51, 1013, PS *."1, SFTQFDUJWFMZ):
smtp://[username@]host[:port][?options] pop3://[username@]host[:port][?options] imap://[username@]host[:port][?options]

5IF NBJM DPNQPOFOU BMTP TVQQPSUT TFDVSF WBSJBOUT PG UIFTF QSPUPDPMT (MBZFSFE PWFS 44-). :PV DBO FOBCMF UIF TFDVSF QSPUPDPMT CZ BEEJOH s UP UIF TDIFNF:
smtps://[username@]host[:port][?options] pop3s://[username@]host[:port][?options] imaps://[username@]host[:port][?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

2>JMIB BKAMLFKQP
5ZQJDBMMZ, ZPV TQFDJGZ B 63* XJUI MPHJO DSFEFOUJBMT BT GPMMPXT (UBLJOH 4.51 BT BO FYBNQMF):
smtp://[username@]host[:port][?password=somepwd]

"MUFSOBUJWFMZ, JU JT QPTTJCMF UP TQFDJGZ CPUI UIF VTFS OBNF BOE UIF QBTTXPSE BT RVFSZ PQUJPOT:
smtp://host[:port]?password=somepwd&username=someuser

'PS FYBNQMF:
smtp://mycompany.mailserver:30?password=tiger&username=scott

804

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

&BOLKFJL J>FI .G>O 8F IBWF EJTDPWFSFE UIBU UIF HFSPOJNP NBJM .jar (W1.6) IBT B CVH XIFO QPMMJOH NBJMT XJUI BUUBDINFOUT. *U DBOOPU DPSSFDUMZ JEFOUJGZ UIF Content-Type. 4P, JG ZPV BUUBDI B .jpeg GJMF UP B NBJM BOE ZPV QPMM JU, UIF Content-Type JT SFTPMWFE BT text/plain BOE OPU BT image/jpeg. 'PS UIBU SFBTPO, XF IBWF BEEFE BO org.apache.camel.component.ContentTypeResolver 41* JOUFSGBDF XIJDI FOBCMFT ZPV UP QSPWJEF ZPVS PXO JNQMFNFOUBUJPO BOE GJY UIJT CVH CZ SFUVSOJOH UIF DPSSFDU .JNF UZQF CBTFE PO UIF GJMF OBNF. 4P JG UIF GJMF OBNF FOET XJUI jpeg/jpg, ZPV DBO SFUVSO image/jpeg.
:PV DBO TFU ZPVS DVTUPN SFTPMWFS PO UIF MailComponent JOTUBODF PS PO UIF MailEndpoint JOTUBODF.

/./3 LO (, / 1013 IBT TPNF MJNJUBUJPOT BOE FOE VTFST BSF FODPVSBHFE UP VTF *."1 JG QPTTJCMF.

4PFKD JL@H-J>FI CLO QBPQFKD :PV DBO VTF B NPDL GSBNFXPSL GPS VOJU UFTUJOH, XIJDI BMMPXT ZPV UP UFTU XJUIPVU UIF OFFE GPS B SFBM NBJM TFSWFS. )PXFWFS ZPV TIPVME SFNFNCFS UP OPU JODMVEF UIF NPDL-NBJM XIFO ZPV HP JOUP QSPEVDUJPO PS PUIFS FOWJSPONFOUT XIFSF ZPV OFFE UP TFOE NBJMT UP B SFBM NBJM TFSWFS. +VTU UIF QSFTFODF PG UIF NPDL-KBWBNBJM.KBS PO UIF DMBTTQBUI NFBOT UIBU JU XJMM LJDL JO BOE BWPJE TFOEJOH UIF NBJMT.

#BC>RIQ MLOQP
%FGBVMU QPSU OVNCFST BSF TVQQPSUFE. *G UIF QPSU OVNCFS JT PNJUUFE, $BNFM EFUFSNJOFT UIF QPSU OVNCFS UP VTF CBTFE PO UIF QSPUPDPM.
/OLQL@LI
SMTP SMTPS POP3 POP3S IMAP IMAPS

#BC>RIQ /LOQ -RJ?BO


25 465 110 995 143 993

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

805

.MQFLKP
/OLMBOQV
host port username password ignoreUriScheme defaultEncoding contentType folderName destination to replyTo CC BCC from subject

#BC>RIQ
c 4FF %FGBVMU1PSUT c null false null text/plain INBOX username@host username@host alias@host null null camel@localhost c

#BP@OFMQFLK
5IF IPTU OBNF PS *1 BEESFTT UP DPOOFDU UP. 5IF 5$1 QPSU OVNCFS UP DPOOFDU PO. 5IF VTFS OBNF PO UIF FNBJM TFSWFS. 5IF QBTTXPSE PO UIF FNBJM TFSWFS. *G false, $BNFM VTFT UIF TDIFNF UP EFUFSNJOF UIF USBOTQPSU QSPUPDPM (101, *."1, 4.51 FUD.) 5IF EFGBVMU FODPEJOH UP VTF GPS .JNF .FTTBHFT. 5IF NBJM NFTTBHF DPOUFOU UZQF. 6TF text/html GPS )5.- NBJMT. 5IF GPMEFS UP QPMM. @ABMOB@>QBA 6TF UIF to PQUJPO JOTUFBE. 5IF TO SFDJQJFOUT (SFDFJWFST PG UIF FNBJM). 5IF 50 SFDJQJFOUT (UIF SFDFJWFST PG UIF NBJM). 4FQBSBUF NVMUJQMF FNBJM BEESFTTFT XJUI B DPNNB. "T PG ">JBI 2.8.4, 2.9.1+, UIF 3FQMZ-5P SFDJQJFOUT (UIF SFDFJWFST PG UIF SFTQPOTF NBJM). 4FQBSBUF NVMUJQMF FNBJM BEESFTTFT XJUI B DPNNB. 5IF $$ SFDJQJFOUT (UIF SFDFJWFST PG UIF NBJM). 4FQBSBUF NVMUJQMF FNBJM BEESFTTFT XJUI B DPNNB. 5IF #$$ SFDJQJFOUT (UIF SFDFJWFST PG UIF NBJM). 4FQBSBUF NVMUJQMF FNBJM BEESFTTFT XJUI B DPNNB. 5IF '30. FNBJM BEESFTT. "T PG ">JBI 2.3, UIF 4VCKFDU PG UIF NFTTBHF CFJOH TFOU. /PUF: 4FUUJOH UIF TVCKFDU JO UIF IFBEFS UBLFT QSFDFEFODF PWFS UIJT PQUJPO. %FMFUFT UIF NFTTBHFT BGUFS UIFZ IBWF CFFO QSPDFTTFE. 5IJT JT EPOF CZ TFUUJOH UIF DELETED GMBH PO UIF NBJM NFTTBHF. *G false, UIF SEEN GMBH JT TFU JOTUFBE. "T PG ">JBI 2.10 ZPV DBO PWFSSJEF UIJT DPOGJHVSBUJPO PQUJPO CZ TFUUJOH B IFBEFS XJUI UIF LFZ delete UP EFUFSNJOF JG UIF NBJM TIPVME CF EFMFUFE PS OPU. *U JT QPTTJCMF UP DPOGJHVSF B DPOTVNFS FOEQPJOU TP UIBU JU QSPDFTTFT POMZ VOTFFO NFTTBHFT (UIBU JT, OFX NFTTBHFT) PS BMM NFTTBHFT. /PUF UIBU $BNFM BMXBZT TLJQT EFMFUFE NFTTBHFT. 5IF EFGBVMU PQUJPO PG true XJMM GJMUFS UP POMZ VOTFFO NFTTBHFT. 1013 EPFT OPU TVQQPSU UIF SEEN GMBH, TP UIJT PQUJPO JT OPU TVQQPSUFE JO 1013; VTF *."1 JOTUFBE. ">JBI 2.10: $POTVNFS POMZ. "GUFS QSPDFTTJOH B NBJM NFTTBHF, JU DBO CF DPQJFE UP B NBJM GPMEFS XJUI UIF HJWFO OBNF. :PV DBO PWFSSJEF UIJT DPOGJHVSBUJPO WBMVF, XJUI B IFBEFS XJUI UIF LFZ copyTo, BMMPXJOH ZPV UP DPQZ NFTTBHFT UP GPMEFS OBNFT DPOGJHVSFE BU SVOUJNF. 4FUT UIF NBYJNVN OVNCFS PG NFTTBHFT UP DPOTVNF EVSJOH B QPMM. 5IJT DBO CF VTFE UP BWPJE PWFSMPBEJOH B NBJM TFSWFS, JG B NBJMCPY GPMEFS DPOUBJOT B MPU PG NFTTBHFT. %FGBVMU WBMVF PG -1 NFBOT OP GFUDI TJ[F BOE BMM NFTTBHFT XJMM CF DPOTVNFE. 4FUUJOH UIF WBMVF UP 0 JT B TQFDJBM DPSOFS DBTF, XIFSF $BNFM XJMM OPU DPOTVNF BOZ NFTTBHFT BU BMM. 4QFDJGJFT UIF LFZ UP BO */ NFTTBHF IFBEFS UIBU DPOUBJOT BO BMUFSOBUJWF FNBJM CPEZ. 'PS FYBNQMF, JG ZPV TFOE FNBJMT JO text/html GPSNBU BOE XBOU UP QSPWJEF BO BMUFSOBUJWF NBJM CPEZ GPS OPO-)5.- FNBJM DMJFOUT, TFU UIF BMUFSOBUJWF NBJM CPEZ XJUI UIJT LFZ BT B IFBEFS. &OBCMF EFCVH NPEF PO UIF VOEFSMZJOH NBJM GSBNFXPSL. 5IF 46/ .BJM GSBNFXPSL MPHT UIF EFCVH NFTTBHFT UP System.out CZ EFGBVMU. 5IF DPOOFDUJPO UJNFPVU JO NJMMJTFDPOET. %FGBVMU JT 30 TFDPOET. .JMMJTFDPOET CFGPSF UIF QPMMJOH TUBSUT. $BNFM XJMM QPMM UIF NBJMCPY POMZ PODF B NJOVUF CZ EFGBVMU UP BWPJE PWFSMPBEJOH UIF NBJM TFSWFS. 4FU UP true UP VTF B GJYFE EFMBZ CFUXFFO QPMMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT. ">JBI 2.8.3/2.9: 8IFUIFS UIF DPOTVNFS TIPVME EJTDPOOFDU BGUFS QPMMJOH. *G FOBCMFE UIJT GPSDFT $BNFM UP DPOOFDU PO FBDI QPMM. ">JBI 2.10.4: 8IFUIFS UIF DPOTVNFS TIPVME DMPTF UIF GPMEFS BGUFS QPMMJOH. 4FUUJOH UIJT PQUJPO UP false BOE IBWJOH disconnect=false BT XFMM, UIFO UIF DPOTVNFS LFFQ UIF GPMEFS PQFO CFUXFFO QPMMT. 4FU BOZ BEEJUJPOBM KBWB NBJM QSPQFSUJFT. 'PS JOTUBODF JG ZPV XBOU UP TFU B TQFDJBM QSPQFSUZ XIFO VTJOH 1013 ZPV DBO OPX QSPWJEF UIF PQUJPO EJSFDUMZ JO UIF 63* TVDI BT: mail.pop3.forgettopheaders=true. :PV DBO TFU NVMUJQMF TVDI PQUJPOT, GPS FYBNQMF: mail.pop3.forgettopheaders=true&mail.mime.encodefilename=true. ">JBI 2.8: 4QFDJGJFT XIFUIFS $BNFM TIPVME NBQ UIF SFDFJWFE NBJM NFTTBHF UP $BNFM CPEZ/IFBEFST. *G TFU UP USVF, UIF CPEZ PG UIF NBJM NFTTBHF JT NBQQFE UP UIF CPEZ PG UIF $BNFM */ NFTTBHF BOE UIF NBJM IFBEFST BSF NBQQFE UP */ IFBEFST. *G UIJT PQUJPO JT TFU UP GBMTF UIFO UIF */ NFTTBHF DPOUBJOT B SBX javax.mail.Message. :PV DBO SFUSJFWF UIJT SBX NFTTBHF CZ DBMMJOH exchange.getIn().getBody(javax.mail.Message.class).

delete

false

unseen

true

copyTo

null

fetchSize

-1

alternativeBodyHeader

CamelMailAlternativeBody

debugMode connectionTimeout consumer.initialDelay consumer.delay consumer.useFixedDelay disconnect

false 30000 1000 60000 false false

closeFolder

true

mail.XXX

null

mapMailMessage

true

806

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

maxMessagesPerPoll

4QFDJGJFT UIF NBYJNVN OVNCFS PG NFTTBHFT UP HBUIFS QFS QPMM. #Z EFGBVMU, OP NBYJNVN JT TFU. $BO CF VTFE UP TFU B MJNJU PG F.H. 1000 UP BWPJE EPXOMPBEJOH UIPVTBOET PG GJMFT XIFO UIF TFSWFS TUBSUT VQ. 4FU B WBMVF PG 0 PS OFHBUJWF UP EJTBCMF UIJT PQUJPO. 4QFDJGJFT B QMVHHBCMF org.springframework.mail.javamail.JavaMailSender JOTUBODF JO PSEFS UP VTF B DVTUPN FNBJM JNQMFNFOUBUJPO. *G OPOF QSPWJEFE, $BNFM VTFT UIF EFGBVMU org.springframework.mail.javamail.JavaMailSenderImpl. 0QUJPO UP MFU $BNFM JHOPSF VOTVQQPSUFE DIBSTFU JO UIF MPDBM +7. XIFO TFOEJOH NBJMT. *G UIF DIBSTFU JT VOTVQQPSUFE UIFO charset=XXX (XIFSF XXX SFQSFTFOUT UIF VOTVQQPSUFE DIBSTFU) JT SFNPWFE GSPN UIF content-type BOE JU SFMJFT PO UIF QMBUGPSN EFGBVMU JOTUFBE. ">JBI 2.10: 3FGFSFODF UP B org.apache.camel.util.jsse.SSLContextParameters JO UIF 3FHJTUSZ.c 5IJT SFGFSFODF PWFSSJEFT BOZ DPOGJHVSFE 44-$POUFYU1BSBNFUFST BU UIF DPNQPOFOU MFWFM.c 4FF 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ. ">JBI 2.11: 3FGFST UP B javax.mail.search.SearchTerm XIJDI BMMPXT UP GJMUFS NBJMT CBTFE PO TFBSDI DSJUFSJB TVDI BT TVCKFDU, CPEZ, GSPN, TFOU BGUFS B DFSUBJO EBUF FUD. 4FF GVSUIFS CFMPX GPS FYBNQMFT. ">JBI 2.11: 5P DPOGJHVSF TFBSDI UFSNT EJSFDUMZ GSPN UIF FOEQPJOU VSJ, XIJDI TVQQPSUT B MJNJUFE OVNCFS PG UFSNT EFGJOFE CZ UIF org.apache.camel.component.mail.SimpleSearchTerm DMBTT. 4FF GVSUIFS CFMPX GPS FYBNQMFT.

javaMailSender

null

ignoreUnsupportedCharset

false

sslContextParameters

null

searchTerm

null

searchTerm.xxx

null

22+ PRMMLOQ 5IF VOEFSMZJOH NBJM GSBNFXPSL JT SFTQPOTJCMF GPS QSPWJEJOH 44- TVQQPSU. c:PV NBZ FJUIFS DPOGJHVSF 44-/5-4 TVQQPSU CZ DPNQMFUFMZ TQFDJGZJOH UIF OFDFTTBSZ +BWB .BJM "1* DPOGJHVSBUJPO PQUJPOT, PS ZPV NBZ QSPWJEF B DPOGJHVSFE 44-$POUFYU1BSBNFUFST UISPVHI UIF DPNQPOFOU PS FOEQPJOU DPOGJHVSBUJPO.

4PFKD QEB )22$ "LKCFDRO>QFLK 4QFIFQV


"T PG ">JBI 2.10, UIF NBJM DPNQPOFOU TVQQPSUT 44-/5-4 DPOGJHVSBUJPO UISPVHI UIF $BNFM +44& $POGJHVSBUJPO 6UJMJUZ.c 5IJT VUJMJUZ HSFBUMZ EFDSFBTFT UIF BNPVOU PG DPNQPOFOU TQFDJGJD DPEF ZPV OFFE UP XSJUF BOE JT DPOGJHVSBCMF BU UIF FOEQPJOU BOE DPNQPOFOU MFWFMT.c 5IF GPMMPXJOH FYBNQMFT EFNPOTUSBUF IPX UP VTF UIF VUJMJUZ XJUI UIF NBJM DPNQPOFOU. /OLDO>JJ>QF@ @LKCFDRO>QFLK LC QEB BKAMLFKQ

KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/truststore.jks"); ksp.setPassword("keystorePassword"); TrustManagersParameters tmp = new TrustManagersParameters(); tmp.setKeyStore(ksp); SSLContextParameters scp = new SSLContextParameters(); scp.setTrustManagers(tmp); Registry registry = ... registry.bind("sslContextParameters", scp); ... from(...) &nbsp; &nbsp; .to("smtps://smtp.google.com?username=user@gmail.com&password=password&sslContextParameters=#sslContex

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

807

2MOFKD #2+ ?>PBA @LKCFDRO>QFLK LC BKAMLFKQ

... <camel:sslContextParameters id="sslContextParameters"> <camel:trustManagers> <camel:keyStore resource="/users/home/server/truststore.jks" password="keystorePassword"/> </camel:trustManagers> </camel:sslContextParameters>... ... <to uri="smtps://smtp.google.com?username=user@gmail.com&password=password&sslContextParameters=#sslContex

"LKCFDROFKD )>S>,>FI #FOB@QIV


$BNFM VTFT 46/ +BWB.BJM, XIJDI POMZ USVTUT DFSUJGJDBUFT JTTVFE CZ XFMM LOPXO $FSUJGJDBUF "VUIPSJUJFT (UIF EFGBVMU +7. USVTU DPOGJHVSBUJPO). *G ZPV JTTVF ZPVS PXO DFSUJGJDBUFT, ZPV IBWF UP JNQPSU UIF $" DFSUJGJDBUFT JOUP UIF +7.'T +BWB USVTU/LFZ TUPSF GJMFT, PWFSSJEF UIF EFGBVMU +7. USVTU/LFZ TUPSF GJMFT (TFF SSLNOTES.txt JO +BWB.BJM GPS EFUBJMT). ,>FI ,BPP>DB "LKQBKQ $BNFM VTFT UIF NFTTBHF FYDIBOHF'T */ CPEZ BT UIF .JNF.FTTBHF UFYU DPOUFOU. 5IF CPEZ JT DPOWFSUFE UP String.class. $BNFM DPQJFT BMM PG UIF FYDIBOHF'T */ IFBEFST UP UIF .JNF.FTTBHF IFBEFST. 5IF TVCKFDU PG UIF .JNF.FTTBHF DBO CF DPOGJHVSFE VTJOH B IFBEFS QSPQFSUZ PO UIF */ NFTTBHF. 5IF DPEF CFMPX EFNPOTUSBUFT UIJT:
from("direct:a").setHeader("subject", constant(subject)).to("smtp://james2@localhost");

5IF TBNF BQQMJFT GPS PUIFS .JNF.FTTBHF IFBEFST TVDI BT SFDJQJFOUT, TP ZPV DBO VTF B IFBEFS QSPQFSUZ BT To:
Map<String, Object> map = new HashMap<String, Object>(); map.put("To", "davsclaus@apache.org"); map.put("From", "jstrachan@apache.org"); map.put("Subject", "Camel rocks"); String body = "Hello Claus.\nYes it does.\n\nRegards James."; template.sendBodyAndHeaders("smtp://davsclaus@apache.org", body, map);

2FK@B ">JBI 2.11 8IFO VTJOH UIF .BJM1SPEVDFS UIF TFOE UIF NBJM UP TFSWFS, ZPV TIPVME CF BCMF UP HFU UIF NFTTBHF JE PG UIF .JNF.FTTBHF XJUI UIF LFZ CamelMailMessageId GSPN UIF $BNFM NFTTBHF IFBEFS.

808

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

'B>ABOP Q>HB MOB@BABK@B LSBO MOB-@LKCFDROBA OB@FMFBKQP 5IF SFDJQJFOUT TQFDJGJFE JO UIF NFTTBHF IFBEFST BMXBZT UBLF QSFDFEFODF PWFS SFDJQJFOUT QSFDPOGJHVSFE JO UIF FOEQPJOU 63*. 5IF JEFB JT UIBU JG ZPV QSPWJEF BOZ SFDJQJFOUT JO UIF NFTTBHF IFBEFST, UIBU JT XIBU ZPV HFU. 5IF SFDJQJFOUT QSF-DPOGJHVSFE JO UIF FOEQPJOU 63* BSF USFBUFE BT B GBMMCBDL. *O UIF TBNQMF DPEF CFMPX, UIF FNBJM NFTTBHF JT TFOU UP davsclaus@apache.org, CFDBVTF JU UBLFT QSFDFEFODF PWFS UIF QSF-DPOGJHVSFE SFDJQJFOU, info@mycompany.com. "OZ CC BOE BCC TFUUJOHT JO UIF FOEQPJOU 63* BSF BMTP JHOPSFE BOE UIPTF SFDJQJFOUT XJMM OPU SFDFJWF BOZ NBJM. 5IF DIPJDF CFUXFFO IFBEFST BOE QSF-DPOGJHVSFE TFUUJOHT JT BMM PS OPUIJOH: UIF NBJM DPNQPOFOU either UBLFT UIF SFDJQJFOUT FYDMVTJWFMZ GSPN UIF IFBEFST PS FYDMVTJWFMZ GSPN UIF QSFDPOGJHVSFE TFUUJOHT. *U JT OPU QPTTJCMF UP NJY BOE NBUDI IFBEFST BOE QSF-DPOGJHVSFE TFUUJOHT.
Map<String, Object> headers = new HashMap<String, Object>(); headers.put("to", "davsclaus@apache.org"); template.sendBodyAndHeaders("smtp://admin@localhost?to=info@mycompany.com", "Hello World", headers);

,RIQFMIB OB@FMFBKQP CLO B>PFBO @LKCFDRO>QFLK *U JT QPTTJCMF UP TFU NVMUJQMF SFDJQJFOUT VTJOH B DPNNB-TFQBSBUFE PS B TFNJDPMPO-TFQBSBUFE MJTU. 5IJT BQQMJFT CPUI UP IFBEFS TFUUJOHT BOE UP TFUUJOHT JO BO FOEQPJOU 63*. 'PS FYBNQMF:
Map<String, Object> headers = new HashMap<String, Object>(); headers.put("to", "davsclaus@apache.org ; jstrachan@apache.org ; ningjiang@apache.org");

5IF QSFDFEJOH FYBNQMF VTFT B TFNJDPMPO, ;, BT UIF TFQBSBUPS DIBSBDUFS. 2BQQFKD PBKABO K>JB >KA BJ>FI :PV DBO TQFDJGZ SFDJQJFOUT JO UIF GPSNBU, name <email>, UP JODMVEF CPUI UIF OBNF BOE UIF FNBJM BEESFTT PG UIF SFDJQJFOU. 'PS FYBNQMF, ZPV EFGJOF UIF GPMMPXJOH IFBEFST PO UIF B .FTTBHF:
Map headers = new HashMap(); map.put("To", "Claus Ibsen <davsclaus@apache.org>"); map.put("From", "James Strachan <jstrachan@apache.org>"); map.put("Subject", "Camel is cool");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

809

24- )>S>,>FI 46/ +BWB.BJM JT VTFE VOEFS UIF IPPE GPS DPOTVNJOH BOE QSPEVDJOH NBJMT. 8F FODPVSBHF FOE-VTFST UP DPOTVMU UIFTF SFGFSFODFT XIFO VTJOH FJUIFS 1013 PS *."1 QSPUPDPM. /PUF QBSUJDVMBSMZ UIBU 1013 IBT B NVDI NPSF MJNJUFE TFU PG GFBUVSFT UIBO *."1. 46/ 1013 "1* 46/ *."1 "1* "OE HFOFSBMMZ BCPVU UIF ."*- 'MBHT 2>JMIBP 8F TUBSU XJUI B TJNQMF SPVUF UIBU TFOET UIF NFTTBHFT SFDFJWFE GSPN B +.4 RVFVF BT FNBJMT. 5IF FNBJM BDDPVOU JT UIF admin BDDPVOU PO mymailserver.com.
from("jms://queue:subscription").to("smtp://admin@mymailserver.com?password=secret");

*O UIF OFYU TBNQMF, XF QPMM B NBJMCPY GPS OFX FNBJMT PODF FWFSZ NJOVUF. /PUJDF UIBU XF VTF UIF TQFDJBM consumer PQUJPO GPS TFUUJOH UIF QPMM JOUFSWBM, consumer.delay, BT 60000 NJMMJTFDPOET = 60 TFDPOET.
from("imap://admin@mymailserver.com password=secret&unseen=true&consumer.delay=60000") .to("seda://mails");

*O UIJT TBNQMF XF XBOU UP TFOE B NBJM UP NVMUJQMF SFDJQJFOUT:


// all the recipients of this mail are: // To: camel@riders.org , easy@riders.org // CC: me@you.org // BCC: someone@somewhere.org String recipients = "&To=camel@riders.org,easy@riders.org&CC=me@you.org&BCC=someone@somewhere.org"; from("direct:a").to("smtp://you@mymailserver.com?password=secret&From=you@apache.org" + recipients);

2BKAFKD J>FI TFQE >QQ>@EJBKQ P>JMIB 5IF NBJM DPNQPOFOU TVQQPSUT BUUBDINFOUT. *O UIF TBNQMF CFMPX, XF TFOE B NBJM NFTTBHF DPOUBJOJOH B QMBJO UFYU NFTTBHF XJUI B MPHP GJMF BUUBDINFOU.
// create an exchange with a normal body and attachment to be produced as email Endpoint endpoint = context.getEndpoint("smtp://james@mymailserver.com?password=secret");

810

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

QQ>@EJBKQP >OB KLQ PRMMLOQ ?V >II ">JBI @LJMLKBKQP 5IF Attachments API JT CBTFE PO UIF +BWB "DUJWBUJPO 'SBNFXPSL BOE JT HFOFSBMMZ POMZ VTFE CZ UIF .BJM "1*. 4JODF NBOZ PG UIF PUIFS $BNFM DPNQPOFOUT EP OPU TVQQPSU BUUBDINFOUT, UIF BUUBDINFOUT DPVME QPUFOUJBMMZ CF MPTU BT UIFZ QSPQBHBUF BMPOH UIF SPVUF. 5IF SVMF PG UIVNC, UIFSFGPSF, JT UP BEE BUUBDINFOUT KVTU CFGPSF TFOEJOH B NFTTBHF UP UIF NBJM FOEQPJOU.

// create the exchange with the mail message that is multipart with a file and a Hello World text/plain message. Exchange exchange = endpoint.createExchange(); Message in = exchange.getIn(); in.setBody("Hello World"); in.addAttachment("logo.jpeg", new DataHandler(new FileDataSource("src/test/data/ logo.jpeg"))); // create a producer that can produce the exchange (= send the mail) Producer producer = endpoint.createProducer(); // start the producer producer.start(); // and let it go (processes the exchange by sending the email) producer.process(exchange);

22+ P>JMIB *O UIJT TBNQMF, XF XBOU UP QPMM PVS (PPHMF NBJM JOCPY GPS NBJMT. 5P EPXOMPBE NBJM POUP B MPDBM NBJM DMJFOU, (PPHMF NBJM SFRVJSFT ZPV UP FOBCMF BOE DPOGJHVSF 44-. 5IJT JT EPOF CZ MPHHJOH JOUP ZPVS (PPHMF NBJM BDDPVOU BOE DIBOHJOH ZPVS TFUUJOHT UP BMMPX *."1 BDDFTT. (PPHMF IBWF FYUFOTJWF EPDVNFOUBUJPO PO IPX UP EP UIJT.
from("imaps://imap.gmail.com?username=YOUR_USERNAME@gmail.com&password=YOUR_PASSWORD" + "&delete=false&unseen=true&consumer.delay=60000").to("log:newmail");

5IF QSFDFEJOH SPVUF QPMMT UIF (PPHMF NBJM JOCPY GPS OFX NBJMT PODF FWFSZ NJOVUF BOE MPHT UIF SFDFJWFE NFTTBHFT UP UIF newmail MPHHFS DBUFHPSZ. 3VOOJOH UIF TBNQMF XJUI DEBUG MPHHJOH FOBCMFE, XF DBO NPOJUPS UIF QSPHSFTT JO UIF MPHT:
2008-05-08 06:32:09,640 DEBUG MailConsumer - Connecting to MailStore imaps//imap.gmail.com:993 (SSL enabled), folder=INBOX 2008-05-08 06:32:11,203 DEBUG MailConsumer - Polling mailfolder: imaps//imap.gmail.com:993 (SSL enabled), folder=INBOX 2008-05-08 06:32:11,640 DEBUG MailConsumer - Fetching 1 messages. Total 1 messages. 2008-05-08 06:32:12,171 DEBUG MailConsumer - Processing message: messageNumber=[332],

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

811

from=[James Bond <007@mi5.co.uk>], to=YOUR_USERNAME@gmail.com], subject=[... 2008-05-08 06:32:12,187 INFO newmail - Exchange[MailMessage: messageNumber=[332], from=[James Bond <007@mi5.co.uk>], to=YOUR_USERNAME@gmail.com], subject=[...

"LKPRJFKD J>FIP TFQE >QQ>@EJBKQ P>JMIB *O UIJT TBNQMF XF QPMM B NBJMCPY BOE TUPSF BMM BUUBDINFOUT GSPN UIF NBJMT BT GJMFT. 'JSTU, XF EFGJOF B SPVUF UP QPMM UIF NBJMCPY. "T UIJT TBNQMF JT CBTFE PO HPPHMF NBJM, JU VTFT UIF TBNF SPVUF BT TIPXO JO UIF 44- TBNQMF:
from("imaps://imap.gmail.com?username=YOUR_USERNAME@gmail.com&password=YOUR_PASSWORD" + "&delete=false&unseen=true&consumer.delay=60000").process(new MyMailProcessor());

*OTUFBE PG MPHHJOH UIF NBJM XF VTF B QSPDFTTPS XIFSF XF DBO QSPDFTT UIF NBJM GSPN KBWB DPEF:
public void process(Exchange exchange) throws Exception { // the API is a bit clunky so we need to loop Map<String, DataHandler> attachments = exchange.getIn().getAttachments(); if (attachments.size() > 0) { for (String name : attachments.keySet()) { DataHandler dh = attachments.get(name); // get the file name String filename = dh.getName(); // get the content and convert it to byte[] byte[] data = exchange.getContext().getTypeConverter() .convertTo(byte[].class, dh.getInputStream()); // write the data to a file FileOutputStream out = new FileOutputStream(filename); out.write(data); out.flush(); out.close(); } } }

"T ZPV DBO TFF UIF "1* UP IBOEMF BUUBDINFOUT JT B CJU DMVOLZ CVU JU'T UIFSF TP ZPV DBO HFU UIF javax.activation.DataHandler TP ZPV DBO IBOEMF UIF BUUBDINFOUT VTJOH TUBOEBSE "1*. 'LT QL PMIFQ > J>FI JBPP>DB TFQE >QQ>@EJBKQP *O UIJT FYBNQMF XF DPOTVNF NBJM NFTTBHFT XIJDI NBZ IBWF B OVNCFS PG BUUBDINFOUT. 8IBU XF XBOU UP EP JT UP VTF UIF 4QMJUUFS &*1 QFS JOEJWJEVBM BUUBDINFOU, UP QSPDFTT UIF BUUBDINFOUT TFQBSBUFMZ. 'PS FYBNQMF JG UIF NBJM NFTTBHF IBT 5 BUUBDINFOUT, XF XBOU UIF 4QMJUUFS UP QSPDFTT GJWF NFTTBHFT, FBDI IBWJOH B TJOHMF BUUBDINFOU. 5P EP UIJT XF OFFE UP QSPWJEF B DVTUPN

812

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

&YQSFTTJPO UP UIF 4QMJUUFS XIFSF XF QSPWJEF B -JTU<.FTTBHF> UIBU DPOUBJOT UIF GJWF NFTTBHFT XJUI UIF TJOHMF BUUBDINFOU. 5IF DPEF JT QSPWJEFE PVU PG UIF CPY JO $BNFM 2.10 POXBSET JO UIF camel-mail DPNQPOFOU. 5IF DPEF JT JO UIF DMBTT: org.apache.camel.component.mail.SplitAttachmentsExpression, XIJDI ZPV DBO GJOE UIF TPVSDF DPEF IFSF *O UIF $BNFM SPVUF ZPV UIFO OFFE UP VTF UIJT &YQSFTTJPO JO UIF SPVUF BT TIPXO CFMPX:
from("pop3://james@mymailserver.com?password=secret&consumer.delay=1000") .to("log:email") // use the SplitAttachmentsExpression which will split the message per attachment .split(new SplitAttachmentsExpression()) // each message going to this mock has a single attachment .to("mock:split") .end();

*G ZPV VTF 9.- %4- UIFO ZPV OFFE UP EFDMBSF B NFUIPE DBMM FYQSFTTJPO JO UIF 4QMJUUFS BT TIPXO CFMPX
<split> <method beanType="org.apache.camel.component.mail.SplitAttachmentsExpression"/> <to uri="mock:split"/> </split>

4PFKD @RPQLJ 2B>O@E3BOJ S>FI>?IB >P LC ">JBI 2.11 :PV DBO DPOGJHVSF B searchTerm PO UIF MailEndpoint XIJDI BMMPXT ZPV UP GJMUFS PVU VOXBOUFE NBJMT. 'PS FYBNQMF UP GJMUFS NBJMT UP DPOUBJO $BNFM JO FJUIFS 4VCKFDU PS 5FYU ZPV DBO EP BT GPMMPXT:
<route> <from uri="imaps://mymailseerver?username=foo&password=secret&searchTerm.subjectOrBody=Camel"/> <to uri="bean:myBean"/> </route>

/PUJDF XF VTF UIF "searchTerm.subjectOrBody" BT QBSBNFUFS LFZ UP JOEJDBUF UIBU XF XBOU UP TFBSDI PO NBJM TVCKFDU PS CPEZ, UP DPOUBJO UIF XPSE "$BNFM". 5IF DMBTT org.apache.camel.component.mail.SimpleSearchTerm IBT B OVNCFS PG PQUJPOT ZPV DBO DPOGJHVSF: 0S UP HFU UIF OFX VOTFFO FNBJMT HPJOH 24 IPVST CBDL JO UJNF ZPV DBO EP. /PUJDF UIF "OPX-24I" TZOUBY. 4FF UIF UBCMF CFMPX GPS NPSF EFUBJMT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

813

<route> <from uri="imaps://mymailseerver?username=foo&password=secret&searchTerm.fromSentDate=now-24h"/> <to uri="bean:myBean"/> </route>

:PV DBO IBWF NVMUJQMF TFBSDI5FSN JO UIF FOEQPJOU VSJ DPOGJHVSBUJPO. 5IFZ XPVME UIFO CF DPNCJOFE UPHFUIFS VTJOH "/% PQFSBUPS, FH TP CPUI DPOEJUJPOT NVTU NBUDI. 'PS FYBNQMF UP HFU UIF MBTU VOTFFO FNBJMT HPJOH CBDL 24 IPVST XIJDI IBT $BNFM JO UIF NBJM TVCKFDU ZPV DBO EP:

<route> <from uri="imaps://mymailseerver?username=foo&password=secret&searchTerm.subject=Camel&searchTerm.fromSentDa <to uri="bean:myBean"/> </route>

.MQFLK
VOTFFO TVCKFDU0S#PEZ TVCKFDU CPEZ GSPN UP

#BC>RIQ
true null null null null null

#BP@OFMQFLK
8IFUIFS UP MJNJU CZ VOTFFO NBJMT POMZ. 5P MJNJU CZ TVCKFDU PS CPEZ UP DPOUBJO UIF XPSE. 5IF TVCKFDU NVTU DPOUBJO UIF XPSE. 5IF CPEZ NVTU DPOUBJO UIF XPSE. 5IF NBJM NVTU CF GSPN B HJWFO FNBJM QBUUFSO. 5IF NBJM NVTU CF UP B HJWFO FNBJM QBUUFSO. 5IF NBJM NVTU CF TFOU BGUFS PS FRVBMT ((&) B HJWFO EBUF. 5IF EBUF QBUUFSO JT yyyy-MM-dd HH:mm:SS, FH VTF "2012-01-01 00:00:00" UP CF GSPN UIF ZFBS 2012 POXBSET. :PV DBO VTF "now" GPS DVSSFOU UJNFTUBNQ. 5IF "OPX" TZOUBY TVQQPSUT BO PQUJPOBM PGGTFU, UIBU DBO CF TQFDJGJFE BT FJUIFS + PS - XJUI B OVNFSJD WBMVF. 'PS FYBNQMF GPS MBTU 24 IPVST, ZPV DBO VTF "now - 24h" PS XJUIPVU TQBDFT "now-24h". /PUJDF UIBU $BNFM TVQQPSUT TIPSUIBOET GPS IPVST, NJOVUFT, BOE TFDPOET. 5IF NBJM NVTU CF TFOU CFGPSF PS FRVBMT (#&) B HJWFO EBUF. 5IF EBUF QBUUFSO JT yyyy-MM-dd HH:mm:SS, FH VTF "2012-01-01 00:00:00" UP CF CFGPSF UIF ZFBS 2012. :PV DBO VTF "now" GPS DVSSFOU UJNFTUBNQ. 5IF "OPX" TZOUBY TVQQPSUT BO PQUJPOBM PGGTFU, UIBU DBO CF TQFDJGJFE BT FJUIFS + PS - XJUI B OVNFSJD WBMVF. 'PS FYBNQMF GPS MBTU 24 IPVST, ZPV DBO VTF "now - 24h" PS XJUIPVU TQBDFT "now-24h". /PUJDF UIBU $BNFM TVQQPSUT TIPSUIBOET GPS IPVST, NJOVUFT, BOE TFDPOET.

GSPN4FOU%BUF

null

UP4FOU%BUF

null

5IF SimpleSearchTerm JT EFTJHOFE UP CF FBTJMZ DPOGJHVSBCMF GSPN B 10+0, TP ZPV DBO BMTP DPOGJHVSF JU VTJOH B <CFBO> TUZMF JO 9.<bean id="mySearchTerm" class="org.apache.camel.component.mail.SimpleSearchTerm"> <property name="subject" value="Order"/> <property name="to" value="acme-order@acme.com"/> <property name="fromSentDate" value="now"/> </bean>

:PV DBO UIFO SFGFS UP UIJT CFBO, VTJOH #CFBO*E JO ZPVS $BNFM SPVUF BT TIPXO:
<route> <from uri="imaps://mymailseerver?username=foo&password=secret&searchTerm=#mySearchTerm"/> <to uri="bean:myBean"/> </route>

814

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*O +BWB UIFSF JT B CVJMEFS DMBTT UP CVJME DPNQPVOE SearchTerm}}s using the {{org.apache.camel.component.mail.SearchTermBuilder DMBTT. 5IJT BMMPXT ZPV UP CVJME DPNQMFY UFSNT TVDI BT:
// we just want the unseen mails which is not spam SearchTermBuilder builder = new SearchTermBuilder(); builder.unseen().body(Op.not, "Spam").subject(Op.not, "Spam") // which was sent from either foo or bar .from("foo@somewhere.com").from(Op.or, "bar@somewhere.com"); // .. and we could continue building the terms SearchTerm term = builder.build();

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

,(-

".,/.-$-3

5IF JFK>: DPNQPOFOU JT B USBOTQPSU GPS XPSLJOH XJUI "QBDIF .*/" .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-mina</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
mina:tcp://hostname[:port][?options] mina:udp://hostname[:port][?options] mina:vm://hostname[:port][?options]

:PV DBO TQFDJGZ B DPEFD JO UIF 3FHJTUSZ VTJOH UIF @LAB@ PQUJPO. *G ZPV BSF VTJOH 5$1 BOE OP DPEFD JT TQFDJGJFE UIFO UIF textline GMBH JT VTFE UP EFUFSNJOF JG UFYU MJOF CBTFE DPEFD PS PCKFDU TFSJBMJ[BUJPO TIPVME CF VTFE JOTUFBE. #Z EFGBVMU UIF PCKFDU TFSJBMJ[BUJPO JT VTFE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

815

'PS 6%1 JG OP DPEFD JT TQFDJGJFE UIF EFGBVMU VTFT B CBTJD ByteBuffer CBTFE DPEFD. 5IF 7. QSPUPDPM JT VTFE BT B EJSFDU GPSXBSEJOH NFDIBOJTN JO UIF TBNF +7.. 4FF UIF .*/" 7.-1JQF "1* EPDVNFOUBUJPO GPS EFUBJMT. " .JOB QSPEVDFS IBT B EFGBVMU UJNFPVU WBMVF PG 30 TFDPOET, XIJMF JU XBJUT GPS B SFTQPOTF GSPN UIF SFNPUF TFSWFS. *O OPSNBM VTF, camel-mina POMZ TVQQPSUT NBSTIBMMJOH UIF CPEZ DPOUFOU_NFTTBHF IFBEFST BOE FYDIBOHF QSPQFSUJFT BSF OPU TFOU. )PXFWFS, UIF PQUJPO, QO>KPCBO$U@E>KDB, EPFT BMMPX ZPV UP USBOTGFS UIF FYDIBOHF JUTFMG PWFS UIF XJSF. 4FF PQUJPOT CFMPX. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
codec codec disconnect textline textlineDelimiter sync lazySessionCreation timeout encoding

#BC>RIQ 5>IRB
null null false false DEFAULT true true 3000 JVM Default

#BP@OFMQFLK
:PV DBO SFGFS UP B OBNFE ProtocolCodecFactory JOTUBODF JO ZPVS 3FHJTUSZ TVDI BT ZPVS 4QSJOH ApplicationContext, XIJDI JT UIFO VTFE GPS UIF NBSTIBMMJOH. :PV NVTU VTF UIF # OPUBUJPO UP MPPL VQ ZPVS DPEFD JO UIF 3FHJTUSZ. 'PS FYBNQMF, VTF #myCodec UP MPPL VQ B CFBO XJUI UIF id WBMVF, myCodec. ">JBI 2.3: 8IFUIFS PS OPU UP EJTDPOOFDU(DMPTF) GSPN .JOB TFTTJPO SJHIU BGUFS VTF. $BO CF VTFE GPS CPUI DPOTVNFS BOE QSPEVDFS. 0OMZ VTFE GPS 5$1. *G OP DPEFD JT TQFDJGJFE, ZPV DBO VTF UIJT GMBH UP JOEJDBUF B UFYU MJOF CBTFE DPEFD; JG OPU TQFDJGJFE PS UIF WBMVF JT false, UIFO 0CKFDU 4FSJBMJ[BUJPO JT BTTVNFE PWFS 5$1. 0OMZ VTFE GPS 5$1 BOE JG QBUQIFKB=QORB. 4FUT UIF UFYU MJOF EFMJNJUFS UP VTF. 1PTTJCMF WBMVFT BSF: DEFAULT, AUTO, WINDOWS, UNIX PS MAC. *G OPOF QSPWJEFE, $BNFM XJMM VTF DEFAULT. 5IJT EFMJNJUFS JT VTFE UP NBSL UIF FOE PG UFYU. :PV DBO DPOGJHVSF UIF FYDIBOHF QBUUFSO UP CF FJUIFS *O0OMZ (EFGBVMU) PS *O0VU. 4FUUJOH sync=true NFBOT B TZODISPOPVT FYDIBOHF (*O0VU), XIFSF UIF DMJFOU DBO SFBE UIF SFTQPOTF GSPN .*/" (UIF FYDIBOHF 0VU NFTTBHF). 4FTTJPOT DBO CF MB[JMZ DSFBUFE UP BWPJE FYDFQUJPOT, JG UIF SFNPUF TFSWFS JT OPU VQ BOE SVOOJOH XIFO UIF $BNFM QSPEVDFS JT TUBSUFE. :PV DBO DPOGJHVSF UIF UJNFPVU UIBU TQFDJGJFT IPX MPOH UP XBJU GPS B SFTQPOTF GSPN B SFNPUF TFSWFS. 5IF UJNFPVU VOJU JT JO NJMMJTFDPOET, TP 60000 JT 60 TFDPOET. 5IF UJNFPVU JT POMZ VTFE GPS .JOB QSPEVDFS. :PV DBO DPOGJHVSF UIF FODPEJOH (B DIBSTFU OBNF) UP VTF GPS UIF 5$1 UFYUMJOF DPEFD BOE UIF 6%1 QSPUPDPM. *G OPU QSPWJEFE, $BNFM XJMM VTF UIF +7. EFGBVMU $IBSTFU. 0OMZ VTFE GPS 5$1. :PV DBO USBOTGFS UIF FYDIBOHF PWFS UIF XJSF JOTUFBE PG KVTU UIF CPEZ. 5IF GPMMPXJOH GJFMET BSF USBOTGFSSFE: *O CPEZ, 0VU CPEZ, GBVMU CPEZ, *O IFBEFST, 0VU IFBEFST, GBVMU IFBEFST, FYDIBOHF QSPQFSUJFT, FYDIBOHF FYDFQUJPO. 5IJT SFRVJSFT UIBU UIF PCKFDUT BSF serializable. $BNFM XJMM FYDMVEF BOZ OPO-TFSJBMJ[BCMF PCKFDUT BOE MPH JU BU WARN MFWFM. :PV DBO FOBCMF UIF "QBDIF .*/" MPHHJOH GJMUFS. "QBDIF .*/" VTFT slf4j MPHHJOH BU INFO MFWFM UP MPH BMM JOQVU BOE PVUQVU. :PV DBO TFU B MJTU PG .JOB *P'JMUFST UP SFHJTUFS. 5IF filters WBMVF NVTU CF POF PG UIF GPMMPXJOH: ` ">JBI 2.2: DPNNB-TFQBSBUFE MJTU PG CFBO SFGFSFODFT (F.H. #filterBean1,#filterBean2) XIFSF FBDI CFBO NVTU CF PG UZQF org.apache.mina.common.IoFilter. ` ?BCLOB ">JBI 2.2: B SFGFSFODF UP B CFBO PG UZQF List<org.apache.mina.common.IoFilter>. "T PG 2.1, ZPV DBO TFU UIF UFYUMJOF QSPUPDPM FODPEFS NBY MJOF MFOHUI. #Z EFGBVMU UIF EFGBVMU WBMVF PG .JOB JUTFMG JT VTFE XIJDI BSF Integer.MAX_VALUE. "T PG 2.1, ZPV DBO TFU UIF UFYUMJOF QSPUPDPM EFDPEFS NBY MJOF MFOHUI. #Z EFGBVMU UIF EFGBVMU WBMVF PG .JOB JUTFMG JT VTFE XIJDI BSF 1024. 5IF 5$1 QSPEVDFS JT UISFBE TBGF BOE TVQQPSUT DPODVSSFODZ NVDI CFUUFS. 5IJT PQUJPO BMMPXT ZPV UP DPOGJHVSF UIF OVNCFS PG UISFBET JO JUT UISFBE QPPM GPS DPODVSSFOU QSPEVDFST. -LQB: $BNFM IBT B QPPMFE TFSWJDF XIJDI FOTVSFE JU XBT BMSFBEZ UISFBE TBGF BOE TVQQPSUFE DPODVSSFODZ BMSFBEZ. 5IF NJOB DPNQPOFOU JOTUBMMT B EFGBVMU DPEFD JG CPUI, codec JT null BOE textline JT false. 4FUUJOH allowDefaultCodec UP false QSFWFOUT UIF NJOB DPNQPOFOU GSPN JOTUBMMJOH B EFGBVMU DPEFD BT UIF GJSTU FMFNFOU JO UIF GJMUFS DIBJO. 5IJT JT VTFGVM JO TDFOBSJPT XIFSF BOPUIFS GJMUFS NVTU CF UIF GJSTU JO UIF GJMUFS DIBJO, MJLF UIF 44- GJMUFS. ">JBI 2.3: *G TZOD JT FOBCMFE UIFO UIJT PQUJPO EJDUBUFT .JOB$POTVNFS JG JU TIPVME EJTDPOOFDU XIFSF UIFSF JT OP SFQMZ UP TFOE CBDL.

transferExchange minaLogger

false false

filters

null

encoderMaxLineLength decoderMaxLineLength

-1 -1

producerPoolSize

16

allowDefaultCodec

true

disconnectOnNoReply

true

816

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

noReplyLogLevel

WARN

">JBI 2.3: *G TZOD JT FOBCMFE UIJT PQUJPO EJDUBUFT .JOB$POTVNFS XIJDI MPHHJOH MFWFM UP VTF XIFO MPHHJOH B UIFSF JT OP SFQMZ UP TFOE CBDL. 7BMVFT BSF: FATAL, ERROR, INFO, DEBUG, OFF.

4PFKD > @RPQLJ @LAB@ 4FF UIF .JOB EPDVNFOUBUJPO IPX UP XSJUF ZPVS PXO DPEFD. 5P VTF ZPVS DVTUPN DPEFD XJUI camel-mina, ZPV TIPVME SFHJTUFS ZPVS DPEFD JO UIF 3FHJTUSZ; GPS FYBNQMF, CZ DSFBUJOH B CFBO JO UIF 4QSJOH 9.- GJMF. 5IFO VTF UIF codec PQUJPO UP TQFDJGZ UIF CFBO *% PG ZPVS DPEFD. 4FF )-7 UIBU IBT B DVTUPN DPEFD. 2>JMIB TFQE PVK@=C>IPB *O UIJT TBNQMF, $BNFM FYQPTFT B TFSWJDF UIBU MJTUFOT GPS 5$1 DPOOFDUJPOT PO QPSU 6200. 8F VTF UIF QBUQIFKB DPEFD. *O PVS SPVUF, XF DSFBUF B .JOB DPOTVNFS FOEQPJOU UIBU MJTUFOT PO QPSU 6200:
from("mina:tcp://localhost:" + port1 + "?textline=true&sync=false").to("mock:result");

"T UIF TBNQMF JT QBSU PG B VOJU UFTU, XF UFTU JU CZ TFOEJOH TPNF EBUB UP JU PO QPSU 6200.
MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedBodiesReceived("Hello World"); template.sendBody("mina:tcp://localhost:" + port1 + "?textline=true&sync=false", "Hello World"); assertMockEndpointsSatisfied();

2>JMIB TFQE PVK@=QORB *O UIF OFYU TBNQMF, XF IBWF B NPSF DPNNPO VTF DBTF XIFSF XF FYQPTF B 5$1 TFSWJDF PO QPSU 6201 BMTP VTF UIF UFYUMJOF DPEFD. )PXFWFS, UIJT UJNF XF XBOU UP SFUVSO B SFTQPOTF, TP XF TFU UIF sync PQUJPO UP true PO UIF DPOTVNFS.
from("mina:tcp://localhost:" + port2 + "?textline=true&sync=true").process(new Processor() { public void process(Exchange exchange) throws Exception { String body = exchange.getIn().getBody(String.class); exchange.getOut().setBody("Bye " + body); } });

5IFO XF UFTU UIF TBNQMF CZ TFOEJOH TPNF EBUB BOE SFUSJFWJOH UIF SFTQPOTF VTJOH UIF template.requestBody() NFUIPE. "T XF LOPX UIF SFTQPOTF JT B String, XF DBTU JU UP

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

817

String BOE DBO BTTFSU UIBU UIF SFTQPOTF JT, JO GBDU, TPNFUIJOH XF IBWF EZOBNJDBMMZ TFU JO PVS QSPDFTTPS DPEF MPHJD.
String response = (String)template.requestBody("mina:tcp://localhost:" + port2 + "?textline=true&sync=true", "World"); assertEquals("Bye World", response);

2>JMIB TFQE 2MOFKD #2+ 4QSJOH %4- DBO, PG DPVSTF, BMTP CF VTFE GPS .*/". *O UIF TBNQMF CFMPX XF FYQPTF B 5$1 TFSWFS PO QPSU 5555:
<route> <from uri="mina:tcp://localhost:5555?textline=true"/> <to uri="bean:myTCPOrderHandler"/> </route>

*O UIF SPVUF BCPWF, XF FYQPTF B 5$1 TFSWFS PO QPSU 5555 VTJOH UIF UFYUMJOF DPEFD. 8F MFU UIF 4QSJOH CFBO XJUI *%, myTCPOrderHandler, IBOEMF UIF SFRVFTU BOE SFUVSO B SFQMZ. 'PS JOTUBODF, UIF IBOEMFS CFBO DPVME CF JNQMFNFOUFE BT GPMMPXT:
public String handleOrder(String payload) { ... return "Order: OK" }

"LKCFDROFKD ,FK> BKAMLFKQP RPFKD 2MOFKD ?B>K PQVIB $POGJHVSBUJPO PG .JOB FOEQPJOUT JT QPTTJCMF VTJOH SFHVMBS 4QSJOH CFBO TUZMF DPOGJHVSBUJPO JO UIF 4QSJOH %4-. )PXFWFS, JO UIF VOEFSMZJOH "QBDIF .JOB UPPMLJU, JU JT SFMBUJWFMZ EJGGJDVMU UP TFU VQ UIF BDDFQUPS BOE UIF DPOOFDUPS, CFDBVTF ZPV DBO not VTF TJNQMF TFUUFST. 5P SFTPMWF UIJT EJGGJDVMUZ, XF MFWFSBHF UIF MinaComponent BT B 4QSJOH GBDUPSZ CFBO UP DPOGJHVSF UIJT GPS VT. *G ZPV SFBMMZ OFFE UP DPOGJHVSF UIJT ZPVSTFMG, UIFSF BSF TFUUFST PO UIF MinaEndpoint UP TFU UIFTF XIFO OFFEFE. 5IF TBNQMF CFMPX TIPXT UIF GBDUPSZ BQQSPBDI:
<!-- Creating mina endpoints is a bit complex so we reuse MinaComponnet as a factory bean to create our endpoint, this is the easiest to do --> <bean id="myMinaFactory" class="org.apache.camel.component.mina.MinaComponent"> <!-- we must provide a camel context so we refer to it by its id --> <constructor-arg index="0" ref="myCamel"/> </bean>

818

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<!-- This is our mina endpoint configured with spring, we will use the factory above to create it for us. The goal is to invoke the createEndpoint method with the mina configuration parameter we defined using the constructor-arg option --> <bean id="myMinaEndpoint" factory-bean="myMinaFactory" factory-method="createEndpoint"> <!-- and here we can pass it our configuration --> <constructor-arg index="0" ref="myMinaConfig"/> </bean> <!-- this is our mina configuration with plain properties --> <bean id="myMinaConfig" class="org.apache.camel.component.mina.MinaConfiguration"> <property name="protocol" value="tcp"/> <property name="host" value="localhost"/> <property name="port" value="1234"/> <property name="sync" value="false"/> </bean>

"OE UIFO XF DBO SFGFS UP PVS FOEQPJOU EJSFDUMZ JO UIF SPVUF, BT GPMMPXT:
<route> <!-- here we route from or mina endpoint we have defined above --> <from ref="myMinaEndpoint"/> <to uri="mock:result"/> </route>

"ILPFKD 2BPPFLK 6EBK "LJMIBQB 8IFO BDUJOH BT B TFSWFS ZPV TPNFUJNFT XBOU UP DMPTF UIF TFTTJPO XIFO, GPS FYBNQMF, B DMJFOU DPOWFSTJPO JT GJOJTIFE. 5P JOTUSVDU $BNFM UP DMPTF UIF TFTTJPO, ZPV TIPVME BEE B IFBEFS XJUI UIF LFZ CamelMinaCloseSessionWhenComplete TFU UP B CPPMFBO true WBMVF. 'PS JOTUBODF, UIF FYBNQMF CFMPX XJMM DMPTF UIF TFTTJPO BGUFS JU IBT XSJUUFO UIF bye NFTTBHF CBDL UP UIF DMJFOU:
from("mina:tcp://localhost:8080?sync=true&textline=true").process(new Processor() { public void process(Exchange exchange) throws Exception { String body = exchange.getIn().getBody(String.class); exchange.getOut().setBody("Bye " + body); exchange.getOut().setHeader(MinaConstants.MINA_CLOSE_SESSION_WHEN_COMPLETE, true); } });

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

819

&BQ QEB (L2BPPFLK CLO JBPP>DB S>FI>?IB PFK@B ">JBI 2.1 :PV DBO HFU UIF *P4FTTJPO GSPN UIF NFTTBHF IFBEFS XJUI UIJT LFZ .JOB&OEQPJOU.)&"%&3@.*/"@*04&44*0/, BOE BMTP HFU UIF MPDBM IPTU BEESFTT XJUI UIF LFZ .JOB&OEQPJOU.)&"%&3@-0$"-@"%%3&44 BOE SFNPUF IPTU BEESFTT XJUI UIF LFZ .JOB&OEQPJOU.)&"%&3@3&.05&@"%%3&44. "LKCFDROFKD ,FK> CFIQBOP 'JMUFST QFSNJU ZPV UP VTF TPNF .JOB 'JMUFST, TVDI BT SslFilter. :PV DBO BMTP JNQMFNFOU TPNF DVTUPNJ[FE GJMUFST. 1MFBTF OPUF UIBU codec BOE logger BSF BMTP JNQMFNFOUFE BT .JOB GJMUFST PG UZQF, IoFilter. "OZ GJMUFST ZPV NBZ EFGJOF BSF BQQFOEFE UP UIF FOE PG UIF GJMUFS DIBJO; UIBU JT, BGUFS codec BOE logger. 'PS JOTUBODF, UIF FYBNQMF CFMPX XJMM TFOE B LFFQ-BMJWF NFTTBHF BGUFS 10 TFDPOET PG JOBDUJWJUZ:
public class KeepAliveFilter extends IoFilterAdapter { @Override public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { session.setIdleTime(IdleStatus.BOTH_IDLE, 10); nextFilter.sessionCreated(session); } @Override public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { session.write("NOOP"); // NOOP is a FTP command for keep alive nextFilter.sessionIdle(session, status); } }

"T $BNFM .JOB NBZ VTF B SFRVFTU-SFQMZ TDIFNF, UIF FOEQPJOU BT B DMJFOU XPVME MJLF UP ESPQ TPNF NFTTBHF, TVDI BT HSFFUJOH XIFO UIF DPOOFDUJPO JT FTUBCMJTIFE. 'PS FYBNQMF, XIFO ZPV DPOOFDU UP BO '51 TFSWFS, ZPV XJMM HFU B 220 NFTTBHF XJUI B HSFFUJOH (220 Welcome to Pure-FTPd). *G ZPV EPO'U ESPQ UIF NFTTBHF, ZPVS SFRVFTU-SFQMZ TDIFNF XJMM CF CSPLFO.
public class DropGreetingFilter extends IoFilterAdapter { @Override public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { if (message instanceof String) { String ftpMessage = (String) message; // "220" is given as greeting. "200 Zzz" is given as a response to "NOOP" (keep alive) if (ftpMessage.startsWith("220") || or ftpMessage.startsWith("200 Zzz")) {

820

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*G VTJOH UIF SslFilter ZPV OFFE UP BEE UIF mina-filter-ssl +"3 UP UIF DMBTTQBUI.

// Dropping greeting return; } } nextFilter.messageReceived(session, message); } }

5IFO, ZPV DBO DPOGJHVSF ZPVS FOEQPJOU VTJOH 4QSJOH %4-:


<bean id="myMinaFactory" class="org.apache.camel.component.mina.MinaComponent"> <constructor-arg index="0" ref="camelContext" /> </bean> <bean id="myMinaEndpoint" factory-bean="myMinaFactory" factory-method="createEndpoint"> <constructor-arg index="0" ref="myMinaConfig"/> </bean> <bean id="myMinaConfig" class="org.apache.camel.component.mina.MinaConfiguration"> <property name="protocol" value="tcp" /> <property name="host" value="localhost" /> <property name="port" value="2121" /> <property name="sync" value="true" /> <property name="minaLogger" value="true" /> <property name="filters" ref="listFilters"/> </bean> <bean id="listFilters" class="java.util.ArrayList" > <constructor-arg> <list value-type="org.apache.mina.common.IoFilter"> <bean class="com.example.KeepAliveFilter"/> <bean class="com.example.DropGreetingFilter"/> </list> </constructor-arg> </bean>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

821

$BNFM /FUUZ

,."* ".,/.-$-3
5FTUJOH PG EJTUSJCVUFE BOE BTZODISPOPVT QSPDFTTJOH JT OPUPSJPVTMZ EJGGJDVMU. 5IF .PDL, 5FTU BOE %BUB4FU FOEQPJOUT XPSL HSFBU XJUI UIF $BNFM 5FTUJOH 'SBNFXPSL UP TJNQMJGZ ZPVS VOJU BOE JOUFHSBUJPO UFTUJOH VTJOH &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT BOE $BNFM'T MBSHF SBOHF PG $PNQPOFOUT UPHFUIFS XJUI UIF QPXFSGVM #FBO *OUFHSBUJPO. 5IF .PDL DPNQPOFOU QSPWJEFT B QPXFSGVM EFDMBSBUJWF UFTUJOH NFDIBOJTN, XIJDI JT TJNJMBS UP K.PDL JO UIBU JU BMMPXT EFDMBSBUJWF FYQFDUBUJPOT UP CF DSFBUFE PO BOZ .PDL FOEQPJOU CFGPSF B UFTU CFHJOT. 5IFO UIF UFTU JT SVO, XIJDI UZQJDBMMZ GJSFT NFTTBHFT UP POF PS NPSF FOEQPJOUT, BOE GJOBMMZ UIF FYQFDUBUJPOT DBO CF BTTFSUFE JO B UFTU DBTF UP FOTVSF UIF TZTUFN XPSLFE BT FYQFDUFE. 5IJT BMMPXT ZPV UP UFTU WBSJPVT UIJOHT MJLF: ` 5IF DPSSFDU OVNCFS PG NFTTBHFT BSF SFDFJWFE PO FBDI FOEQPJOU, ` 5IF DPSSFDU QBZMPBET BSF SFDFJWFE, JO UIF SJHIU PSEFS, ` .FTTBHFT BSSJWF PO BO FOEQPJOU JO PSEFS, VTJOH TPNF &YQSFTTJPO UP DSFBUF BO PSEFS UFTUJOH GVODUJPO, ` .FTTBHFT BSSJWF NBUDI TPNF LJOE PG 1SFEJDBUF TVDI BT UIBU TQFDJGJD IFBEFST IBWF DFSUBJO WBMVFT, PS UIBU QBSUT PG UIF NFTTBHFT NBUDI TPNF QSFEJDBUF, TVDI BT CZ FWBMVBUJOH BO 91BUI PS 92VFSZ &YQSFTTJPO. -LQB UIBU UIFSF JT BMTP UIF 5FTU FOEQPJOU XIJDI JT B .PDL FOEQPJOU, CVU XIJDI VTFT B TFDPOE FOEQPJOU UP QSPWJEF UIF MJTU PG FYQFDUFE NFTTBHF CPEJFT BOE BVUPNBUJDBMMZ TFUT VQ UIF .PDL FOEQPJOU BTTFSUJPOT. *O PUIFS XPSET, JU'T B .PDL FOEQPJOU UIBU BVUPNBUJDBMMZ TFUT VQ JUT BTTFSUJPOT GSPN TPNF TBNQMF NFTTBHFT JO B 'JMF PS EBUBCBTF, GPS FYBNQMF. 41( CLOJ>Q
mock:someName[?options]

8IFSF PLJB->JB DBO CF BOZ TUSJOH UIBU VOJRVFMZ JEFOUJGJFT UIF FOEQPJOU. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
reportGroup

#BC>RIQ
null

#BP@OFMQFLK
" TJ[F UP VTF B UISPVHIQVU MPHHFS GPS SFQPSUJOH

822

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

,L@H BKAMLFKQP HBBM OB@BFSBA $U@E>KDBP FK JBJLOV FKABCFKFQBIV 3FNFNCFS UIBU .PDL JT EFTJHOFE GPS UFTUJOH. 8IFO ZPV BEE .PDL FOEQPJOUT UP B SPVUF, FBDI &YDIBOHF TFOU UP UIF FOEQPJOU XJMM CF TUPSFE (UP BMMPX GPS MBUFS WBMJEBUJPO) JO NFNPSZ VOUJM FYQMJDJUMZ SFTFU PS UIF +7. JT SFTUBSUFE. *G ZPV BSF TFOEJOH IJHI WPMVNF BOE/PS MBSHF NFTTBHFT, UIJT NBZ DBVTF FYDFTTJWF NFNPSZ VTF. *G ZPVS HPBM JT UP UFTU EFQMPZBCMF SPVUFT JOMJOF, DPOTJEFS VTJOH /PUJGZ#VJMEFS PS "EWJDF8JUI JO ZPVS UFTUT JOTUFBE PG BEEJOH .PDL FOEQPJOUT UP SPVUFT EJSFDUMZ.
'SPN $BNFM 2.10 POXBSET UIFSF BSF UXP OFX PQUJPOT retainFirst, BOE retainLast UIBU DBO CF VTFE UP MJNJU UIF OVNCFS PG NFTTBHFT UIF .PDL FOEQPJOUT LFFQ JO NFNPSZ.

2FJMIB $U>JMIB )FSF'T B TJNQMF FYBNQMF PG .PDL FOEQPJOU JO VTF. 'JSTU, UIF FOEQPJOU JT SFTPMWFE PO UIF DPOUFYU. 5IFO XF TFU BO FYQFDUBUJPO, BOE UIFO, BGUFS UIF UFTU IBT SVO, XF BTTFSU UIBU PVS FYQFDUBUJPOT IBWF CFFO NFU.
MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class); resultEndpoint.expectedMessageCount(2); // send some messages ... // now lets assert that the mock:foo endpoint received 2 messages resultEndpoint.assertIsSatisfied();

:PV UZQJDBMMZ BMXBZT DBMM UIF BTTFSU*T4BUJTGJFE() NFUIPE UP UFTU UIBU UIF FYQFDUBUJPOT XFSF NFU BGUFS SVOOJOH B UFTU. $BNFM XJMM CZ EFGBVMU XBJU 10 TFDPOET XIFO UIF assertIsSatisfied() JT JOWPLFE. 5IJT DBO CF DPOGJHVSFE CZ TFUUJOH UIF setResultWaitTime(millis) NFUIPE.

4PFKD >PPBOQ/BOFLA
S>FI>?IB >P LC ">JBI 2.7 8IFO UIF BTTFSUJPO JT TBUJTGJFE UIFO $BNFM XJMM TUPQ XBJUJOH BOE DPOUJOVF GSPN UIF assertIsSatisfied NFUIPE. 5IBU NFBOT JG B OFX NFTTBHF BSSJWFT PO UIF NPDL FOEQPJOU, KVTU B CJU MBUFS, UIBU BSSJWBM XJMM OPU BGGFDU UIF PVUDPNF PG UIF BTTFSUJPO. 4VQQPTF ZPV EP XBOU UP UFTU UIBU OP OFX NFTTBHFT BSSJWFT BGUFS B QFSJPE UIFSFBGUFS, UIFO ZPV DBO EP UIBU CZ TFUUJOH UIF setAssertPeriod NFUIPE, GPS FYBNQMF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

823

MockEndpoint resultEndpoint = context.resolveEndpoint("mock:foo", MockEndpoint.class); resultEndpoint.setAssertPeriod(5000); resultEndpoint.expectedMessageCount(2); // send some messages ... // now lets assert that the mock:foo endpoint received 2 messages resultEndpoint.assertIsSatisfied();

2BQQFKD BUMB@Q>QFLKP :PV DBO TFF GSPN UIF KBWBEPD PG .PDL&OEQPJOU UIF WBSJPVT IFMQFS NFUIPET ZPV DBO VTF UP TFU FYQFDUBUJPOT. 5IF NBJO NFUIPET BSF BT GPMMPXT:
,BQELA
FYQFDUFE.FTTBHF$PVOU(JOU) FYQFDUFE.JOJNVN.FTTBHF$PVOU(JOU) FYQFDUFE#PEJFT3FDFJWFE(...) FYQFDUFE)FBEFS3FDFJWFE(...) FYQFDUT"TDFOEJOH(&YQSFTTJPO) FYQFDUT%FTDFOEJOH(&YQSFTTJPO) FYQFDUT/P%VQMJDBUFT(&YQSFTTJPO)

#BP@OFMQFLK
5P EFGJOF UIF FYQFDUFE NFTTBHF DPVOU PO UIF FOEQPJOU. 5P EFGJOF UIF NJOJNVN OVNCFS PG FYQFDUFE NFTTBHFT PO UIF FOEQPJOU. 5P EFGJOF UIF FYQFDUFE CPEJFT UIBU TIPVME CF SFDFJWFE (JO PSEFS). 5P EFGJOF UIF FYQFDUFE IFBEFS UIBU TIPVME CF SFDFJWFE 5P BEE BO FYQFDUBUJPO UIBU NFTTBHFT BSF SFDFJWFE JO PSEFS, VTJOH UIF HJWFO &YQSFTTJPO UP DPNQBSF NFTTBHFT. 5P BEE BO FYQFDUBUJPO UIBU NFTTBHFT BSF SFDFJWFE JO PSEFS, VTJOH UIF HJWFO &YQSFTTJPO UP DPNQBSF NFTTBHFT. 5P BEE BO FYQFDUBUJPO UIBU OP EVQMJDBUF NFTTBHFT BSF SFDFJWFE; VTJOH BO &YQSFTTJPO UP DBMDVMBUF B VOJRVF JEFOUJGJFS GPS FBDI NFTTBHF. 5IJT DPVME CF TPNFUIJOH MJLF UIF JMSMessageID JG VTJOH +.4, PS TPNF VOJRVF SFGFSFODF OVNCFS XJUIJO UIF NFTTBHF.

)FSF'T BOPUIFS FYBNQMF:


resultEndpoint.expectedBodiesReceived("firstMessageBody", "secondMessageBody", "thirdMessageBody");

AAFKD BUMB@Q>QFLKP QL PMB@FCF@ JBPP>DBP


*O BEEJUJPO, ZPV DBO VTF UIF NFTTBHF(JOU NFTTBHF*OEFY) NFUIPE UP BEE BTTFSUJPOT BCPVU B TQFDJGJD NFTTBHF UIBU JT SFDFJWFE. 'PS FYBNQMF, UP BEE FYQFDUBUJPOT PG UIF IFBEFST PS CPEZ PG UIF GJSTU NFTTBHF (VTJOH [FSPCBTFE JOEFYJOH MJLF java.util.List), ZPV DBO VTF UIF GPMMPXJOH DPEF:
resultEndpoint.message(0).header("foo").isEqualTo("bar");

5IFSF BSF TPNF FYBNQMFT PG UIF .PDL FOEQPJOU JO VTF JO UIF DBNFM-DPSF QSPDFTTPS UFTUT. ,L@HFKD BUFPQFKD BKAMLFKQP S>FI>?IB >P LC ">JBI 2.7 $BNFM OPX BMMPXT ZPV UP BVUPNBUJDBMMZ NPDL FYJTUJOH FOEQPJOUT JO ZPVS $BNFM SPVUFT.

824

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

'LT FQ TLOHP (JMLOQ>KQ: 5IF FOEQPJOUT BSF TUJMM JO BDUJPO. 8IBU IBQQFOT EJGGFSFOUMZ JT UIBU B .PDL FOEQPJOU JT JOKFDUFE BOE SFDFJWFT UIF NFTTBHF GJSTU BOE UIFO EFMFHBUFT UIF NFTTBHF UP UIF UBSHFU FOEQPJOU. :PV DBO WJFX UIJT BT B LJOE PG JOUFSDFQU BOE EFMFHBUF PS FOEQPJOU MJTUFOFS. 4VQQPTF ZPV IBWF UIF HJWFO SPVUF CFMPX:
Listing 1. Route
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("direct:foo").to("log:foo").to("mock:result"); from("direct:foo").transform(constant("Bye World")); } }; }

:PV DBO UIFO VTF UIF adviceWith GFBUVSF JO $BNFM UP NPDL BMM UIF FOEQPJOUT JO B HJWFO SPVUF GSPN ZPVS VOJU UFTU, BT TIPXO CFMPX:
Listing 1. adviceWith mocking all endpoints
public void testAdvisedMockEndpoints() throws Exception { // advice the first route using the inlined AdviceWith route builder // which has extended capabilities than the regular route builder context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // mock all endpoints mockEndpoints(); } }); getMockEndpoint("mock:direct:start").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World"); getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // additional test to ensure correct endpoints in registry assertNotNull(context.hasEndpoint("direct:start"));

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

825

assertNotNull(context.hasEndpoint("direct:foo")); assertNotNull(context.hasEndpoint("log:foo")); assertNotNull(context.hasEndpoint("mock:result")); // all the endpoints was mocked assertNotNull(context.hasEndpoint("mock:direct:start")); assertNotNull(context.hasEndpoint("mock:direct:foo")); assertNotNull(context.hasEndpoint("mock:log:foo")); }

/PUJDF UIBU UIF NPDL FOEQPJOUT JT HJWFO UIF VSJ mock:<endpoint>, GPS FYBNQMF mock:direct:foo. $BNFM MPHT BU INFO MFWFM UIF FOEQPJOUT CFJOH NPDLFE:
INFO Adviced endpoint [direct://foo] with mock endpoint [mock:direct:foo]

*UT BMTP QPTTJCMF UP POMZ NPDL DFSUBJO FOEQPJOUT VTJOH B QBUUFSO. 'PS FYBNQMF UP NPDL BMM log FOEQPJOUT ZPV EP BT TIPXO:
Listing 1. adviceWith mocking only log endpoints using a pattern
public void testAdvisedMockEndpointsWithPattern() throws Exception { // advice the first route using the inlined AdviceWith route builder // which has extended capabilities than the regular route builder context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // mock only log endpoints mockEndpoints("log*"); } }); // now we can refer to log:foo as a mock and set our expectations getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World"); getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // additional test to ensure correct endpoints in registry assertNotNull(context.hasEndpoint("direct:start")); assertNotNull(context.hasEndpoint("direct:foo")); assertNotNull(context.hasEndpoint("log:foo")); assertNotNull(context.hasEndpoint("mock:result")); // only the log:foo endpoint was mocked assertNotNull(context.hasEndpoint("mock:log:foo")); assertNull(context.hasEndpoint("mock:direct:start")); assertNull(context.hasEndpoint("mock:direct:foo")); }

826

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

,L@HBA BKAMLFKQP >OB TFQELRQ M>O>JBQBOP &OEQPJOUT XIJDI BSF NPDLFE XJMM IBWF UIFJS QBSBNFUFST TUSJQQFE PGG. 'PS FYBNQMF UIF FOEQPJOU "MPH:GPP TIPX"MM=USVF" XJMM CF NPDLFE UP UIF GPMMPXJOH FOEQPJOU "NPDL:MPH:GPP". /PUJDF UIF QBSBNFUFST IBWF CFFO SFNPWFE. 5IF QBUUFSO TVQQPSUFE DBO CF B XJMEDBSE PS B SFHVMBS FYQSFTTJPO. 4FF NPSF EFUBJMT BCPVU UIJT BU *OUFSDFQU BT JUT UIF TBNF NBUDIJOH GVODUJPO VTFE CZ $BNFM.

,L@HFKD BUFPQFKD BKAMLFKQP RPFKD QEB camel-test @LJMLKBKQ


*OTUFBE PG VTJOH UIF adviceWith UP JOTUSVDU $BNFM UP NPDL FOEQPJOUT, ZPV DBO FBTJMZ FOBCMF UIJT CFIBWJPS XIFO VTJOH UIF camel-test 5FTU ,JU. 5IF TBNF SPVUF DBO CF UFTUFE BT GPMMPXT. /PUJDF UIBU XF SFUVSO "*" GSPN UIF isMockEndpoints NFUIPE, XIJDI UFMMT $BNFM UP NPDL BMM FOEQPJOUT. *G ZPV POMZ XBOU UP NPDL BMM log FOEQPJOUT ZPV DBO SFUVSO "log*" JOTUFBE.
Listing 1. isMockEndpoints using camel-test kit
public class IsMockEndpointsJUnit4Test extends CamelTestSupport { @Override public String isMockEndpoints() { // override this method and return the pattern for which endpoints to mock. // use * to indicate all return "*"; } @Test public void testMockAllEndpoints() throws Exception { // notice we have automatic mocked all endpoints and the name of the endpoints is "mock:uri" getMockEndpoint("mock:direct:start").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:log:foo").expectedBodiesReceived("Bye World"); getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // additional test to ensure correct endpoints in registry assertNotNull(context.hasEndpoint("direct:start")); assertNotNull(context.hasEndpoint("direct:foo")); assertNotNull(context.hasEndpoint("log:foo")); assertNotNull(context.hasEndpoint("mock:result")); // all the endpoints was mocked assertNotNull(context.hasEndpoint("mock:direct:start"));

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

827

.JOE UIBU NPDLJOH FOEQPJOUT DBVTFT UIF NFTTBHFT UP CF DPQJFE XIFO UIFZ BSSJWF PO UIF NPDL. 5IBU NFBOT $BNFM XJMM VTF NPSF NFNPSZ. 5IJT NBZ OPU CF TVJUBCMF XIFO ZPV TFOE JO B MPU PG NFTTBHFT.

assertNotNull(context.hasEndpoint("mock:direct:foo")); assertNotNull(context.hasEndpoint("mock:log:foo")); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("direct:foo").to("log:foo").to("mock:result"); from("direct:foo").transform(constant("Bye World")); } }; } }

,L@HFKD BUFPQFKD BKAMLFKQP TFQE 7,+ #2+


*G ZPV EP OPU VTF UIF camel-test DPNQPOFOU GPS VOJU UFTUJOH (BT TIPXO BCPWF) ZPV DBO VTF B EJGGFSFOU BQQSPBDI XIFO VTJOH 9.- GJMFT GPS SPVUFT. 5IF TPMVUJPO JT UP DSFBUF B OFX 9.- GJMF VTFE CZ UIF VOJU UFTU BOE UIFO JODMVEF UIF JOUFOEFE 9.- GJMF XIJDI IBT UIF SPVUF ZPV XBOU UP UFTU. 4VQQPTF XF IBWF UIF SPVUF JO UIF camel-route.xml GJMF:
Listing 1. camel-route.xml
<!-- this camel route is in the camel-route.xml file --> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <to uri="direct:foo"/> <to uri="log:foo"/> <to uri="mock:result"/> </route> <route> <from uri="direct:foo"/> <transform> <constant>Bye World</constant>

828

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

</transform> </route> </camelContext>

5IFO XF DSFBUF B OFX 9.- GJMF BT GPMMPXT, XIFSF XF JODMVEF UIF camel-route.xml GJMF BOE EFGJOF B TQSJOH CFBO XJUI UIF DMBTT org.apache.camel.impl.InterceptSendToMockEndpointStrategy XIJDI UFMMT $BNFM UP NPDL BMM FOEQPJOUT:
Listing 1. test-camel-route.xml
<!-- the Camel route is defined in another XML file --> <import resource="camel-route.xml"/> <!-- bean which enables mocking all endpoints --> <bean id="mockAllEndpoints" class="org.apache.camel.impl.InterceptSendToMockEndpointStrategy"/>

5IFO JO ZPVS VOJU UFTU ZPV MPBE UIF OFX 9.- GJMF (test-camel-route.xml) JOTUFBE PG camel-route.xml. 5P POMZ NPDL BMM -PH FOEQPJOUT ZPV DBO EFGJOF UIF QBUUFSO JO UIF DPOTUSVDUPS GPS UIF CFBO:
<bean id="mockAllEndpoints" class="org.apache.camel.impl.InterceptSendToMockEndpointStrategy"> <constructor-arg index="0" value="log*"/> </bean>

,L@HFKD BKAMLFKQP >KA PHFM PBKAFKD QL LOFDFK>I BKAMLFKQ


S>FI>?IB >P LC ">JBI 2.10 4PNFUJNFT ZPV XBOU UP FBTJMZ NPDL BOE TLJQ TFOEJOH UP B DFSUBJO FOEQPJOUT. 4P UIF NFTTBHF JT EFUPVSFE BOE TFOE UP UIF NPDL FOEQPJOU POMZ. 'SPN $BNFM 2.10 POXBSET ZPV DBO OPX VTF UIF mockEndpointsAndSkip NFUIPE VTJOH "EWJDF8JUI PS UIF <5FTU ,JU>. 5IF FYBNQMF CFMPX XJMM TLJQ TFOEJOH UP UIF UXP FOEQPJOUT "direct:foo", BOE "direct:bar".
Listing 1. adviceWith mock and skip sending to endpoints
public void testAdvisedMockEndpointsWithSkip() throws Exception { // advice the first route using the inlined AdviceWith route builder // which has extended capabilities than the regular route builder context.getRouteDefinitions().get(0).adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // mock sending to direct:foo and direct:bar and skip send to it

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

829

mockEndpointsAndSkip("direct:foo", "direct:bar"); } }); getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedMessageCount(1); getMockEndpoint("mock:direct:bar").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // the message was not send to the direct:foo route and thus not sent to the seda endpoint SedaEndpoint seda = context.getEndpoint("seda:foo", SedaEndpoint.class); assertEquals(0, seda.getCurrentQueueSize()); }

5IF TBNF FYBNQMF VTJOH UIF 5FTU ,JU


Listing 1. isMockEndpointsAndSkip using camel-test kit
public class IsMockEndpointsAndSkipJUnit4Test extends CamelTestSupport { @Override public String isMockEndpointsAndSkip() { // override this method and return the pattern for which endpoints to mock, // and skip sending to the original endpoint. return "direct:foo"; } @Test public void testMockEndpointAndSkip() throws Exception { // notice we have automatic mocked the direct:foo endpoints and the name of the endpoints is "mock:uri" getMockEndpoint("mock:result").expectedBodiesReceived("Hello World"); getMockEndpoint("mock:direct:foo").expectedMessageCount(1); template.sendBody("direct:start", "Hello World"); assertMockEndpointsSatisfied(); // the message was not send to the direct:foo route and thus not sent to the seda endpoint SedaEndpoint seda = context.getEndpoint("seda:foo", SedaEndpoint.class); assertEquals(0, seda.getCurrentQueueSize()); } @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("direct:foo").to("mock:result");

830

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("direct:foo").transform(constant("Bye World")).to("seda:foo"); } }; } }

+FJFQFKD QEB KRJ?BO LC JBPP>DBP QL HBBM S>FI>?IB >P LC ">JBI 2.10 5IF .PDL FOEQPJOUT XJMM CZ EFGBVMU LFFQ B DPQZ PG FWFSZ &YDIBOHF UIBU JU SFDFJWFE. 4P JG ZPV UFTU XJUI B MPU PG NFTTBHFT, UIFO JU XJMM DPOTVNF NFNPSZ. 'SPN $BNFM 2.10 POXBSET XF IBWF JOUSPEVDFE UXP PQUJPOT retainFirst BOE retainLast UIBU DBO CF VTFE UP TQFDJGZ UP POMZ LFFQ /'UI PG UIF GJSTU BOE/PS MBTU &YDIBOHFT. 'PS FYBNQMF JO UIF DPEF CFMPX, XF POMZ XBOU UP SFUBJO B DPQZ PG UIF GJSTU 5 BOE MBTU 5 &YDIBOHFT UIF NPDL SFDFJWFT.
MockEndpoint mock = getMockEndpoint("mock:data"); mock.setRetainFirst(5); mock.setRetainLast(5); mock.expectedMessageCount(2000); ... mock.assertIsSatisfied();

6TJOH UIJT IBT TPNF MJNJUBUJPOT. 5IF getExchanges() BOE getReceivedExchanges() NFUIPET PO UIF MockEndpoint XJMM SFUVSO POMZ UIF SFUBJOFE DPQJFT PG UIF &YDIBOHFT. 4P JO UIF FYBNQMF BCPWF, UIF MJTU XJMM DPOUBJO 10 &YDIBOHFT; UIF GJSTU GJWF, BOE UIF MBTU GJWF. 5IF retainFirst BOE retainLast PQUJPOT BMTP IBWF MJNJUBUJPOT PO XIJDI FYQFDUBUJPO NFUIPET ZPV DBO VTF. 'PS FYBNQMF UIF FYQFDUFE999 NFUIPET UIBU XPSL PO NFTTBHF CPEJFT, IFBEFST, FUD. XJMM POMZ PQFSBUF PO UIF SFUBJOFE NFTTBHFT. *O UIF FYBNQMF BCPWF UIFZ DBO UFTU POMZ UIF FYQFDUBUJPOT PO UIF 10 SFUBJOFE NFTTBHFT. 3BPQFKD TFQE >OOFS>I QFJBP S>FI>?IB >P LC ">JBI 2.7 5IF .PDL FOEQPJOU TUPSFT UIF BSSJWBM UJNF PG UIF NFTTBHF BT B QSPQFSUZ PO UIF &YDIBOHF.
Date time = exchange.getProperty(Exchange.RECEIVED_TIMESTAMP, Date.class);

:PV DBO VTF UIJT JOGPSNBUJPO UP LOPX XIFO UIF NFTTBHF BSSJWFE PO UIF NPDL. #VU JU BMTP QSPWJEFT GPVOEBUJPO UP LOPX UIF UJNF JOUFSWBM CFUXFFO UIF QSFWJPVT BOE OFYU NFTTBHF BSSJWFE

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

831

PO UIF NPDL. :PV DBO VTF UIJT UP TFU FYQFDUBUJPOT VTJOH UIF arrives %4- PO UIF .PDL FOEQPJOU. 'PS FYBNQMF UP TBZ UIBU UIF GJSTU NFTTBHF TIPVME BSSJWF CFUXFFO 0-2 TFDPOET CFGPSF UIF OFYU ZPV DBO EP:
mock.message(0).arrives().noLaterThan(2).seconds().beforeNext();

:PV DBO BMTP EFGJOF UIJT BT UIBU 2OE NFTTBHF (0 JOEFY CBTFE) TIPVME BSSJWF OP MBUFS UIBO 0-2 TFDPOET BGUFS UIF QSFWJPVT:
mock.message(1).arrives().noLaterThan(2).seconds().afterPrevious();

:PV DBO BMTP VTF CFUXFFO UP TFU B MPXFS CPVOE. 'PS FYBNQMF TVQQPTF UIBU JU TIPVME CF CFUXFFO 1-4 TFDPOET:
mock.message(1).arrives().between(1, 4).seconds().afterPrevious();

:PV DBO BMTP TFU UIF FYQFDUBUJPO PO BMM NFTTBHFT, GPS FYBNQMF UP TBZ UIBU UIF HBQ CFUXFFO UIFN TIPVME CF BU NPTU 1 TFDPOE:
mock.allMessages().arrives().noLaterThan(1).seconds().beforeNext();

2BB

IPL ` ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4QSJOH 5FTUJOH 5FTUJOH

,25 ".,/.-$-3
5IF .47 DPNQPOFOU QFSGPSNT 9.- WBMJEBUJPO PG UIF NFTTBHF CPEZ VTJOH UIF .47 -JCSBSZ BOE BOZ PG UIF TVQQPSUFE 9.- TDIFNB MBOHVBHFT, TVDI BT 9.- 4DIFNB PS 3FMBY/( 9.- 4ZOUBY. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-msv</artifactId>

832

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

QFJB RKFQP *O UIF FYBNQMF BCPWF XF VTF seconds BT UIF UJNF VOJU, CVU $BNFM PGGFST milliseconds, BOE minutes BT XFMM.

<version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

/PUF UIBU UIF +JOH DPNQPOFOU BMTP TVQQPSUT 3FMBY/( $PNQBDU 4ZOUBY 41( CLOJ>Q
msv:someLocalOrRemoteResource[?options]

8IFSF PLJB+L@>I.O1BJLQB1BPLRO@B JT TPNF 63- UP B MPDBM SFTPVSDF PO UIF DMBTTQBUI PS B GVMM 63- UP B SFNPUF SFTPVSDF PS SFTPVSDF PO UIF GJMF TZTUFN. 'PS FYBNQMF
msv:org/foo/bar.rng msv:file:../foo/bar.rng msv:http://acme.com/cheese.rng

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
useDom

#BC>RIQ
true

#BP@OFMQFLK
8IFUIFS %0.4PVSDF/%0.3FTVMU PS 4BY4PVSDF/4BY3FTVMU TIPVME CF VTFE CZ UIF WBMJEBUPS. -LQB: %0. NVTU CF VTFE CZ UIF .47 DPNQPOFOU.

$U>JMIB 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DPOGJHVSF B SPVUF GSPN FOEQPJOU AFOB@Q:PQ>OQ XIJDI UIFO HPFT UP POF PG UXP FOEQPJOUT, FJUIFS JL@H:S>IFA PS JL@H:FKS>IFA CBTFE PO XIFUIFS PS OPU UIF 9.- NBUDIFT UIF HJWFO 3FMBY/( 9.- 4DIFNB (XIJDI JT TVQQMJFE PO UIF DMBTTQBUI).
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:start"/> <doTry>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

833

<to uri="msv:org/apache/camel/component/validator/msv/schema.rng"/> <to uri="mock:valid"/> <doCatch> <exception>org.apache.camel.ValidationException</exception> <to uri="mock:invalid"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route> </camelContext>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

,8! 3(2
S>FI>?IB >P LC ">JBI 2.7 5IF JV?>QFP: DPNQPOFOU BMMPXT ZPV UP RVFSZ, QPMM, JOTFSU, VQEBUF BOE EFMFUF EBUB JO B SFMBUJPOBM EBUBCBTF VTJOH .Z#BUJT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-mybatis</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
mybatis:statementName[?options]

8IFSF PQ>QBJBKQ->JB JT UIF TUBUFNFOU OBNF JO UIF .Z#BUJT 9.- NBQQJOH GJMF XIJDI NBQT UP UIF RVFSZ, JOTFSU, VQEBUF PS EFMFUF PQFSBUJPO ZPV XJTI UP FWBMVBUF.

834

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 5IJT DPNQPOFOU XJMM CZ EFGBVMU MPBE UIF .Z#BUJT 4RM.BQ$POGJH GJMF GSPN UIF SPPU PG UIF DMBTTQBUI XJUI UIF FYQFDUFE OBNF PG SqlMapConfig.xml. *G UIF GJMF JT MPDBUFE JO BOPUIFS MPDBUJPO, ZPV XJMM OFFE UP DPOGJHVSF UIF configurationUri PQUJPO PO UIF MyBatisComponent DPNQPOFOU. .MQFLKP
.MQFLK
consumer.onConsume

3VMB
String

#BC>RIQ
null

#BP@OFMQFLK
4UBUFNFOUT UP SVO BGUFS DPOTVNJOH. $BO CF VTFE, GPS FYBNQMF, UP VQEBUF SPXT BGUFS UIFZ IBWF CFFO DPOTVNFE BOE QSPDFTTFE JO $BNFM. 4FF TBNQMF MBUFS. .VMUJQMF TUBUFNFOUT DBO CF TFQBSBUFE XJUI DPNNBT. *G true FBDI SPX SFUVSOFE XIFO QPMMJOH XJMM CF QSPDFTTFE JOEJWJEVBMMZ. *G false UIF FOUJSF List PG EBUB JT TFU BT UIF */ CPEZ. 4FUT XIFUIFS FNQUZ SFTVMU TFUT TIPVME CF SPVUFE. .BOEBUPSZ UP TQFDJGZ GPS UIF QSPEVDFS UP DPOUSPM XIJDI LJOE PG PQFSBUJPO UP JOWPLF. 5IF FOVN WBMVFT BSF: SelectOne, SelectList, Insert, InsertList, Update, UpdateList, Delete, BOE DeleteList. -LQF@B: InsertList JT BWBJMBCMF BT PG $BNFM 2.10, BOE UpdateList, DeleteList JT BWBJMBCMF BT PG $BNFM 2.11. "O JOUFHFS UP EFGJOF UIF NBYJNVN NFTTBHFT UP HBUIFS QFS QPMM. #Z EFGBVMU, OP NBYJNVN JT TFU. $BO CF VTFE UP TFU B MJNJU PG F.H. 1000 UP BWPJE XIFO TUBSUJOH VQ UIF TFSWFS UIBU UIFSF BSF UIPVTBOET PG GJMFT. 4FU B WBMVF PG 0 PS OFHBUJWF UP EJTBCMF JU. ">JBI 2.11: 5IF FYFDVUPS UZQF UP CF VTFE XIJMF FYFDVUJOH TUBUFNFOUT. 5IF TVQQPSUFE WBMVFT BSF: TJNQMF, SFVTF, CBUDI. #Z EFGBVMU, UIF WBMVF JT OPU TQFDJGJFE BOE JT FRVBM UP XIBU .Z#BUJT VTFT, J.F. PFJMIB. PFJMIB FYFDVUPS EPFT OPUIJOH TQFDJBM. OBRPB FYFDVUPS SFVTFT QSFQBSFE TUBUFNFOUT. ?>Q@E FYFDVUPS SFVTFT TUBUFNFOUT BOE CBUDIFT VQEBUFT.

consumer.useIterator consumer.routeEmptyResultSet

boolean boolean

true false

statementType

StatementType

null

maxMessagesPerPoll

int

executorType

String

null

,BPP>DB 'B>ABOP $BNFM XJMM QPQVMBUF UIF SFTVMU NFTTBHF, FJUIFS */ PS 065 XJUI B IFBEFS XJUI UIF TUBUFNFOU VTFE:
'B>ABO
CamelMyBatisStatementName CamelMyBatisResult

3VMB
String Object

#BP@OFMQFLK
5IF PQ>QBJBKQ->JB VTFE (GPS FYBNQMF: JOTFSU"DDPVOU). 5IF OBPMLKPB SFUVSOFE GSPN .U#BUJT JO BOZ PG UIF PQFSBUJPOT. 'PS JOTUBODF BO INSERT DPVME SFUVSO UIF BVUP-HFOFSBUFE LFZ, PS OVNCFS PG SPXT FUD.

,BPP>DB !LAV 5IF SFTQPOTF GSPN .Z#BUJT XJMM POMZ CF TFU BT UIF CPEZ JG JU'T B SELECT TUBUFNFOU. 5IBU NFBOT, GPS FYBNQMF, GPS INSERT TUBUFNFOUT $BNFM XJMM OPU SFQMBDF UIF CPEZ. 5IJT BMMPXT ZPV UP DPOUJOVF SPVUJOH BOE LFFQ UIF PSJHJOBM CPEZ. 5IF SFTQPOTF GSPN .Z#BUJT JT BMXBZT TUPSFE JO UIF IFBEFS XJUI UIF LFZ CamelMyBatisResult. 2>JMIBP 'PS FYBNQMF JG ZPV XJTI UP DPOTVNF CFBOT GSPN B +.4 RVFVF BOE JOTFSU UIFN JOUP B EBUBCBTF ZPV DPVME EP UIF GPMMPXJOH:
$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9 835

from("activemq:queue:newAccount"). to("mybatis:insertAccount?statementType=Insert");

/PUJDF XF IBWF UP TQFDJGZ UIF statementType, BT XF OFFE UP JOTUSVDU $BNFM XIJDI LJOE PG PQFSBUJPO UP JOWPLF. 8IFSF FKPBOQ @@LRKQ JT UIF .Z#BUJT *% JO UIF 42- NBQQJOH GJMF:
<!-- Insert example, using the Account parameter class --> <insert id="insertAccount" parameterType="Account"> insert into ACCOUNT ( ACC_ID, ACC_FIRST_NAME, ACC_LAST_NAME, ACC_EMAIL ) values ( #{id}, #{firstName}, #{lastName}, #{emailAddress} ) </insert>

4PFKD 2Q>QBJBKQ3VMB CLO ?BQQBO @LKQOLI LC ,V!>QFP 8IFO SPVUJOH UP BO .Z#BUJT FOEQPJOU ZPV XJMM XBOU NPSF GJOF HSBJOFE DPOUSPM TP ZPV DBO DPOUSPM XIFUIFS UIF 42- TUBUFNFOU UP CF FYFDVUFE JT B SELECT, UPDATE, DELETE PS INSERT FUD. 4P GPS JOTUBODF JG XF XBOU UP SPVUF UP BO .Z#BUJT FOEQPJOU JO XIJDI UIF */ CPEZ DPOUBJOT QBSBNFUFST UP B SELECT TUBUFNFOU XF DBO EP:
from("direct:start") .to("mybatis:selectAccountById?statementType=SelectOne") .to("mock:result");

*O UIF DPEF BCPWF XF DBO JOWPLF UIF .Z#BUJT TUBUFNFOU selectAccountById BOE UIF */ CPEZ TIPVME DPOUBJO UIF BDDPVOU JE XF XBOU UP SFUSJFWF, TVDI BT BO Integer UZQF. 8F DBO EP UIF TBNF GPS TPNF PG UIF PUIFS PQFSBUJPOT, TVDI BT SelectList:
from("direct:start") .to("mybatis:selectAllAccounts?statementType=SelectList") .to("mock:result");

"OE UIF TBNF GPS UPDATE, XIFSF XF DBO TFOE BO Account PCKFDU BT UIF */ CPEZ UP .Z#BUJT:
from("direct:start") .to("mybatis:updateAccount?statementType=Update") .to("mock:result");

836

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD (KPBOQ+FPQ 2Q>QBJBKQ3VMB


S>FI>?IB >P LC ">JBI 2.10 .Z#BUJT BMMPXT ZPV UP JOTFSU NVMUJQMF SPXT VTJOH JUT GPS-FBDI CBUDI ESJWFS. 5P VTF UIJT, ZPV OFFE UP VTF UIF <GPSFBDI> JO UIF NBQQFS 9.- GJMF. 'PS FYBNQMF BT TIPXO CFMPX:
<!-- Batch Insert example, using the Account parameter class --> <insert id="batchInsertAccount" parameterType="java.util.List"> insert into ACCOUNT ( ACC_ID, ACC_FIRST_NAME, ACC_LAST_NAME, ACC_EMAIL ) values ( <foreach item="Account" collection="list" open="" close="" separator="),("> #{Account.id}, #{Account.firstName}, #{Account.lastName}, #{Account.emailAddress} </foreach> ) </insert>

5IFO ZPV DBO JOTFSU NVMUJQMF SPXT, CZ TFOEJOH B $BNFM NFTTBHF UP UIF mybatis FOEQPJOU XIJDI VTFT UIF InsertList TUBUFNFOU UZQF, BT TIPXO CFMPX:
from("direct:start") .to("mybatis:batchInsertAccount?statementType=InsertList") .to("mock:result");

4PFKD 4MA>QB+FPQ 2Q>QBJBKQ3VMB


S>FI>?IB >P LC ">JBI 2.11 .Z#BUJT BMMPXT ZPV UP VQEBUF NVMUJQMF SPXT VTJOH JUT GPS-FBDI CBUDI ESJWFS. 5P VTF UIJT, ZPV OFFE UP VTF UIF <GPSFBDI> JO UIF NBQQFS 9.- GJMF. 'PS FYBNQMF BT TIPXO CFMPX:
<update id="batchUpdateAccount" parameterType="java.util.Map"> update ACCOUNT set ACC_EMAIL = #{emailAddress} where ACC_ID in <foreach item="Account" collection="list" open="(" close=")" separator=","> #{Account.id} </foreach> </update>

5IFO ZPV DBO VQEBUF NVMUJQMF SPXT, CZ TFOEJOH B $BNFM NFTTBHF UP UIF NZCBUJT FOEQPJOU XIJDI VTFT UIF 6QEBUF-JTU TUBUFNFOU UZQF, BT TIPXO CFMPX:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

837

from("direct:start") .to("mybatis:batchUpdateAccount?statementType=UpdateList") .to("mock:result");

4PFKD #BIBQB+FPQ 2Q>QBJBKQ3VMB


S>FI>?IB >P LC ">JBI 2.11 .Z#BUJT BMMPXT ZPV UP EFMFUF NVMUJQMF SPXT VTJOH JUT GPS-FBDI CBUDI ESJWFS. 5P VTF UIJT, ZPV OFFE UP VTF UIF <GPSFBDI> JO UIF NBQQFS 9.- GJMF. 'PS FYBNQMF BT TIPXO CFMPX:
<delete id="batchDeleteAccountById" parameterType="java.util.List"> delete from ACCOUNT where ACC_ID in <foreach item="AccountID" collection="list" open="(" close=")" separator=","> #{AccountID} </foreach> </delete>

5IFO ZPV DBO EFMFUF NVMUJQMF SPXT, CZ TFOEJOH B $BNFM NFTTBHF UP UIF NZCBUJT FOEQPJOU XIJDI VTFT UIF %FMFUF-JTU TUBUFNFOU UZQF, BT TIPXO CFMPX:
from("direct:start") .to("mybatis:batchDeleteAccount?statementType=DeleteList") .to("mock:result");

-LQF@B LK (KPBOQ+FPQ, 4MA>QB+FPQ >KA #BIBQB+FPQ 2Q>QBJBKQ3VMBP


1BSBNFUFS PG BOZ UZQF (-JTU, .BQ, FUD.) DBO CF QBTTFE UP NZCBUJT BOE BO FOE VTFS JT SFTQPOTJCMF GPS IBOEMJOH JU BT SFRVJSFE XJUI UIF IFMQ PG NZCBUJT EZOBNJD RVFSJFT DBQBCJMJUJFT.

2@EBARIBA MLIIFKD BU>JMIB


4JODF UIJT DPNQPOFOU EPFT OPU TVQQPSU TDIFEVMFE QPMMJOH, ZPV OFFE UP VTF BOPUIFS NFDIBOJTN GPS USJHHFSJOH UIF TDIFEVMFE QPMMT, TVDI BT UIF 5JNFS PS 2VBSU[ DPNQPOFOUT. *O UIF TBNQMF CFMPX XF QPMM UIF EBUBCBTF, FWFSZ 30 TFDPOET VTJOH UIF 5JNFS DPNQPOFOU BOE TFOE UIF EBUB UP UIF +.4 RVFVF:

838

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("timer://pollTheDatabase?delay=30000").to("mbatis:selectAllAccounts").to("activemq:queue:allAccou

"OE UIF .Z#BUJT 42- NBQQJOH GJMF VTFE:


<!-- Select with no parameters using the result map for Account class. --> <select id="selectAllAccounts" resultMap="AccountResult"> select * from ACCOUNT </select>

4PFKD LK"LKPRJB
5IJT DPNQPOFOU TVQQPSUT FYFDVUJOH TUBUFNFOUT >CQBO EBUB IBWF CFFO DPOTVNFE BOE QSPDFTTFE CZ $BNFM. 5IJT BMMPXT ZPV UP EP QPTU VQEBUFT JO UIF EBUBCBTF. /PUJDF BMM TUBUFNFOUT NVTU CF UPDATE TUBUFNFOUT. $BNFM TVQQPSUT FYFDVUJOH NVMUJQMF TUBUFNFOUT XIPTF OBNFT TIPVME CF TFQBSBUFE CZ DPNNBT. 5IF SPVUF CFMPX JMMVTUSBUFT XF FYFDVUF UIF @LKPRJB @@LRKQ TUBUFNFOU EBUB JT QSPDFTTFE. 5IJT BMMPXT VT UP DIBOHF UIF TUBUVT PG UIF SPX JO UIF EBUBCBTF UP QSPDFTTFE, TP XF BWPJE DPOTVNJOH JU UXJDF PS NPSF.
from("mybatis:selectUnprocessedAccounts?consumer.onConsume=consumeAccount").to("mock:results");

"OE UIF TUBUFNFOUT JO UIF TRMNBQ GJMF:


<select id="selectUnprocessedAccounts" resultMap="AccountResult"> select * from ACCOUNT where PROCESSED = false </select>

<update id="consumeAccount" parameterType="Account"> update ACCOUNT set PROCESSED = true where ACC_ID = #{id} </update>

/>OQF@FM>QFKD FK QO>KP>@QFLKP
4FUUJOH VQ B USBOTBDUJPO NBOBHFS VOEFS DBNFM-NZCBUJT DBO CF B MJUUMF CJU GJEEMZ, BT JU JOWPMWFT FYUFSOBMJTJOH UIF EBUBCBTF DPOGJHVSBUJPO PVUTJEF UIF TUBOEBSE .Z#BUJT SqlMapConfig.xml GJMF. 5IF GJSTU QBSU SFRVJSFT UIF TFUVQ PG B DataSource. 5IJT JT UZQJDBMMZ B QPPM (FJUIFS %#$1, PS D3Q0), XIJDI OFFET UP CF XSBQQFE JO B 4QSJOH QSPYZ. 5IJT QSPYZ FOBCMFT OPO-4QSJOH VTF PG UIF DataSource UP QBSUJDJQBUF JO 4QSJOH USBOTBDUJPOT (UIF .Z#BUJT SqlSessionFactory EPFT KVTU UIJT).

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

839

<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <constructor-arg> <bean class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="org.postgresql.Driver"/> <property name="jdbcUrl" value="jdbc:postgresql://localhost:5432/ myDatabase"/> <property name="user" value="myUser"/> <property name="password" value="myPassword"/> </bean> </constructor-arg> </bean>

5IJT IBT UIF BEEJUJPOBM CFOFGJU PG FOBCMJOH UIF EBUBCBTF DPOGJHVSBUJPO UP CF FYUFSOBMJTFE VTJOH QSPQFSUZ QMBDFIPMEFST. " USBOTBDUJPO NBOBHFS JT UIFO DPOGJHVSFE UP NBOBHF UIF PVUFSNPTU DataSource:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>

" NZCBUJT-TQSJOH SqlSessionFactoryBean UIFO XSBQT UIBU TBNF DataSource:


<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- standard mybatis config file --> <property name="configLocation" value="/META-INF/SqlMapConfig.xml"/> <!-- externalised mappers --> <property name="mapperLocations" value="classpath*:META-INF/mappers/**/*.xml"/> </bean>

5IF DBNFM-NZCBUJT DPNQPOFOU JT UIFO DPOGJHVSFE XJUI UIBU GBDUPSZ:


<bean id="mybatis" class="org.apache.camel.component.mybatis.MyBatisComponent"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean>

'JOBMMZ, B USBOTBDUJPO QPMJDZ JT EFGJOFE PWFS UIF UPQ PG UIF USBOTBDUJPO NBOBHFS, XIJDI DBO UIFO CF VTFE BT VTVBM:
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="txManager"/> <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/> </bean>

840

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<camelContext id="my-model-context" xmlns="http://camel.apache.org/schema/spring"> <route id="insertModel"> <from uri="direct:insert"/> <transacted ref="PROPAGATION_REQUIRED"/> <to uri="mybatis:myModel.insert?statementType=Insert"/> </route> </camelContext>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

- &(.2
S>FI>?IB >P LC ">JBI 2.3 5IF /BHJPT DPNQPOFOU BMMPXT ZPV UP TFOE QBTTJWF DIFDLT UP /BHJPT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-nagios</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
nagios://host[:port][?Options]

$BNFM QSPWJEFT UXP BCJMJUJFT XJUI UIF /BHJPT DPNQPOFOU. :PV DBO TFOE QBTTJWF DIFDL NFTTBHFT CZ TFOEJOH B NFTTBHF UP JUT FOEQPJOU. $BNFM BMTP QSPWJEFT B &WFOU/PUJGFS XIJDI BMMPXT ZPV UP TFOE OPUJGJDBUJPOT UP /BHJPT. .MQFLKP
->JB
host

#BC>RIQ 5>IRB
OPOF

#BP@OFMQFLK
5IJT JT UIF BEESFTT PG UIF /BHJPT IPTU XIFSF DIFDLT TIPVME CF TFOE.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

841

port password connectionTimeout timeout nagiosSettings sendSync encryptionMethod

c c 5000 5000 c true No

5IF QPSU OVNCFS PG UIF IPTU. 1BTTXPSE UP CF BVUIFOUJDBUFE XIFO TFOEJOH DIFDLT UP /BHJPT. $POOFDUJPO UJNFPVU JO NJMMJT. 4FOEJOH UJNFPVU JO NJMMJT. 5P VTF BO BMSFBEZ DPOGJHVSFE com.googlecode.jsendnsca.core.NagiosSettings PCKFDU. 5IFO BOZ PG UIF PUIFS PQUJPOT BSF OPU JO VTF, JG VTJOH UIJT. 8IFUIFS PS OPU UP VTF TZODISPOPVT XIFO TFOEJOH B QBTTJWF DIFDL. 4FUUJOH JU UP false XJMM BMMPX $BNFM UP DPOUJOVF SPVUJOH UIF NFTTBHF BOE UIF QBTTJWF DIFDL NFTTBHF XJMM CF TFOE BTZODISPOPVTMZ. ">JBI 2.9: 5P TQFDJGZ BO FODSZQUJPO NFUIPE. 1PTTJCMF WBMVFT: No, Xor, PS TripleDes.

'B>ABOP
->JB
CamelNagiosHostName CamelNagiosLevel CamelNagiosServiceName

#BP@OFMQFLK
5IJT JT UIF BEESFTT PG UIF /BHJPT IPTU XIFSF DIFDLT TIPVME CF TFOE. 5IJT IFBEFS XJMM PWFSSJEF BOZ FYJTUJOH IPTUOBNF DPOGJHVSFE PO UIF FOEQPJOU. 5IJT JT UIF TFWFSJUZ MFWFM. :PV DBO VTF WBMVFT CRITICAL, WARNING, OK. $BNFM XJMM CZ EFGBVMU VTF OK. 5IF TFSWJF OBNF. 8JMM EFGBVMU VTF UIF $BNFM$POUFYU OBNF.

2BKAFKD JBPP>DB BU>JMIBP :PV DBO TFOE B NFTTBHF UP /BHJPT XIFSF UIF NFTTBHF QBZMPBE DPOUBJOT UIF NFTTBHF. #Z EFGBVMU JU XJMM CF OK MFWFM BOE VTF UIF $BNFM$POUFYU OBNF BT UIF TFSWJDF OBNF. :PV DBO PWFSSVMF UIFTF WBMVFT VTJOH IFBEFST BT TIPXO BCPWF. 'PS FYBNQMF XF TFOE UIF Hello Nagios NFTTBHF UP /BHJPT BT GPMMPXT:
template.sendBody("direct:start", "Hello Nagios"); from("direct:start").to("nagios:127.0.0.1:5667?password=secret").to("mock:result");

5P TFOE B CRITICAL NFTTBHF ZPV DBO TFOE UIF IFBEFST TVDI BT:
Map headers = new HashMap(); headers.put(NagiosConstants.LEVEL, "CRITICAL"); headers.put(NagiosConstants.HOST_NAME, "myHost"); headers.put(NagiosConstants.SERVICE_NAME, "myService"); template.sendBodyAndHeaders("direct:start", "Hello Nagios", headers);

4PFKD NagiosEventNotifer 5IF /BHJPT DPNQPOFOU BMTP QSPWJEFT BO &WFOU/PUJGFS XIJDI ZPV DBO VTF UP TFOE FWFOUT UP /BHJPT. 'PS FYBNQMF XF DBO FOBCMF UIJT GSPN +BWB BT GPMMPXT:
NagiosEventNotifier notifier = new NagiosEventNotifier(); notifier.getConfiguration().setHost("localhost"); notifier.getConfiguration().setPort(5667);

842

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

notifier.getConfiguration().setPassword("password"); CamelContext context = ... context.getManagementStrategy().addEventNotifier(notifier); return context;

*O 4QSJOH 9.- JUT KVTU B NBUUFS PG EFGJOJOH B 4QSJOH CFBO XJUI UIF UZQF EventNotifier BOE $BNFM XJMM QJDL JU VQ BT EPDVNFOUFE IFSF: "EWBODFE DPOGJHVSBUJPO PG $BNFM$POUFYU VTJOH 4QSJOH. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

-$338 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.3 5IF KBQQV DPNQPOFOU JO $BNFM JT B TPDLFU DPNNVOJDBUJPO DPNQPOFOU, CBTFE PO UIF /FUUZ QSPKFDU. /FUUZ JT B /*0 DMJFOU TFSWFS GSBNFXPSL XIJDI FOBCMFT RVJDL BOE FBTZ EFWFMPQNFOU PG OFUXPSL BQQMJDBUJPOT TVDI BT QSPUPDPM TFSWFST BOE DMJFOUT. /FUUZ HSFBUMZ TJNQMJGJFT BOE TUSFBNMJOFT OFUXPSL QSPHSBNNJOH TVDI BT 5$1 BOE 6%1 TPDLFU TFSWFS. 5IJT DBNFM DPNQPOFOU TVQQPSUT CPUI QSPEVDFS BOE DPOTVNFS FOEQPJOUT. 5IF /FUUZ DPNQPOFOU IBT TFWFSBM PQUJPOT BOE BMMPXT GJOF-HSBJOFE DPOUSPM PG B OVNCFS PG 5$1/6%1 DPNNVOJDBUJPO QBSBNFUFST (CVGGFS TJ[FT, LFFQ"MJWFT, UDQ/P%FMBZ FUD) BOE GBDJMJUBUFT CPUI *O-0OMZ BOE *O-0VU DPNNVOJDBUJPO PO B $BNFM SPVUF. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-netty</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

843

41( CLOJ>Q 5IF 63* TDIFNF GPS B OFUUZ DPNQPOFOU JT BT GPMMPXT


netty:tcp://localhost:99999[?options] netty:udp://remotehost:99999/[?options]

5IJT DPNQPOFOU TVQQPSUT QSPEVDFS BOE DPOTVNFS FOEQPJOUT GPS CPUI 5$1 BOE 6%1. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
keepAlive tcpNoDelay backlog broadcast connectTimeout reuseAddress sync synchronous ssl sendBufferSize receiveBufferSize

#BC>RIQ 5>IRB
true true c false 10000 true true false false 65536 bytes 65536 bytes null

#BP@OFMQFLK
4FUUJOH UP FOTVSF TPDLFU JT OPU DMPTFE EVF UP JOBDUJWJUZ 4FUUJOH UP JNQSPWF 5$1 QSPUPDPM QFSGPSNBODF ">JBI 2.9.6/2.10.4/2.11: "MMPXT UP DPOGJHVSF B CBDLMPH GPS OFUUZ DPOTVNFS (TFSWFS). /PUF UIF CBDLMPH JT KVTU B CFTU FGGPSU EFQFOEJOH PO UIF 04. 4FUUJOH UIJT PQUJPO UP B WBMVF TVDI BT 200, 500 PS 1000, UFMMT UIF 5$1 TUBDL IPX MPOH UIF "BDDFQU" RVFVF DBO CF. *G UIJT PQUJPO JT OPU DPOGJHVSFE, UIFO UIF CBDLMPH EFQFOET PO 04 TFUUJOH. 4FUUJOH UP DIPPTF .VMUJDBTU PWFS 6%1 5JNF UP XBJU GPS B TPDLFU DPOOFDUJPO UP CF BWBJMBCMF. 7BMVF JT JO NJMMJT. 4FUUJOH UP GBDJMJUBUF TPDLFU NVMUJQMFYJOH 4FUUJOH UP TFU FOEQPJOU BT POF-XBZ PS SFRVFTU-SFTQPOTF ">JBI 2.10: 8IFUIFS "TZODISPOPVT 3PVUJOH &OHJOF JT OPU JO VTF. false UIFO UIF "TZODISPOPVT 3PVUJOH &OHJOF JT VTFE, true UP GPSDF QSPDFTTJOH TZODISPOPVT. 4FUUJOH UP TQFDJGZ XIFUIFS 44- FODSZQUJPO JT BQQMJFE UP UIJT FOEQPJOU 5IF 5$1/6%1 CVGGFS TJ[FT UP CF VTFE EVSJOH PVUCPVOE DPNNVOJDBUJPO. 4J[F JT CZUFT. 5IF 5$1/6%1 CVGGFS TJ[FT UP CF VTFE EVSJOH JOCPVOE DPNNVOJDBUJPO. 4J[F JT CZUFT. ">JBI 2.11/2.10.4: "MMPXT UP DPOGJHVSF BEEJUJPOBM OFUUZ PQUJPOT VTJOH "PQUJPO." BT QSFGJY. 'PS FYBNQMF "PQUJPO.DIJME.LFFQ"MJWF=GBMTF" UP TFU UIF OFUUZ PQUJPO "DIJME.LFFQ"MJWF=GBMTF". 4FF UIF /FUUZ EPDVNFOUBUJPO GPS QPTTJCMF PQUJPOT UIBU DBO CF VTFE. 5IF OVNCFS PG BMMPDBUFE UISFBET BU DPNQPOFOU TUBSUVQ. %FGBVMUT UP 10. -LQB: 5IJT PQUJPO JT SFNPWFE GSPN $BNFM 2.9.2 POXBSET. "T XF SFMZ PO /FUUZT EFGBVMU TFUUJOHT. 5IF NBYJNVN OVNCFS PG UISFBET UIBU NBZ CF BMMPDBUFE UP UIJT FOEQPJOU. %FGBVMUT UP 100. -LQB: 5IJT PQUJPO JT SFNPWFE GSPN $BNFM 2.9.2 POXBSET. "T XF SFMZ PO /FUUZT EFGBVMU TFUUJOHT. 8IFUIFS PS OPU UP EJTDPOOFDU(DMPTF) GSPN /FUUZ $IBOOFM SJHIU BGUFS VTF. $BO CF VTFE GPS CPUI DPOTVNFS BOE QSPEVDFS. $IBOOFMT DBO CF MB[JMZ DSFBUFE UP BWPJE FYDFQUJPOT, JG UIF SFNPUF TFSWFS JT OPU VQ BOE SVOOJOH XIFO UIF $BNFM QSPEVDFS JT TUBSUFE. 0OMZ VTFE GPS 5$1. :PV DBO USBOTGFS UIF FYDIBOHF PWFS UIF XJSF JOTUFBE PG KVTU UIF CPEZ. 5IF GPMMPXJOH GJFMET BSF USBOTGFSSFE: *O CPEZ, 0VU CPEZ, GBVMU CPEZ, *O IFBEFST, 0VU IFBEFST, GBVMU IFBEFST, FYDIBOHF QSPQFSUJFT, FYDIBOHF FYDFQUJPO. 5IJT SFRVJSFT UIBU UIF PCKFDUT BSF TFSJBMJ[BCMF. $BNFM XJMM FYDMVEF BOZ OPO-TFSJBMJ[BCMF PCKFDUT BOE MPH JU BU 8"3/ MFWFM. *G TZOD JT FOBCMFE UIFO UIJT PQUJPO EJDUBUFT /FUUZ$POTVNFS JG JU TIPVME EJTDPOOFDU XIFSF UIFSF JT OP SFQMZ UP TFOE CBDL. *G TZOD JT FOBCMFE UIJT PQUJPO EJDUBUFT /FUUZ$POTVNFS XIJDI MPHHJOH MFWFM UP VTF XIFO MPHHJOH B UIFSF JT OP SFQMZ UP TFOE CBDL. 7BMVFT BSF: FATAL, ERROR, INFO, DEBUG, OFF. ">JBI 2.4: 5IF OFUUZ DPNQPOFOU JOTUBMMT B EFGBVMU DPEFD JG CPUI, FODPEFS/EFPDEFS JT OVMM BOE UFYUMJOF JT GBMTF. 4FUUJOH BMMPX%FGBVMU$PEFD UP GBMTF QSFWFOUT UIF OFUUZ DPNQPOFOU GSPN JOTUBMMJOH B EFGBVMU DPEFD BT UIF GJSTU FMFNFOU JO UIF GJMUFS DIBJO. ">JBI 2.4: 0OMZ VTFE GPS 5$1. *G OP DPEFD JT TQFDJGJFE, ZPV DBO VTF UIJT GMBH UP JOEJDBUF B UFYU MJOF CBTFE DPEFD; JG OPU TQFDJGJFE PS UIF WBMVF JT GBMTF, UIFO 0CKFDU 4FSJBMJ[BUJPO JT BTTVNFE PWFS 5$1.

option.XXX

corePoolSize maxPoolSize disconnect lazyChannelCreation

10 100 false true

transferExchange

false

disconnectOnNoReply noReplyLogLevel

true WARN

allowDefaultCodec

true

textline

false

844

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

delimiter decoderMaxLineLength autoAppendDelimiter encoding workerCount

LINE 1024 true null null

">JBI 2.4: 5IF EFMJNJUFS UP VTF GPS UIF UFYUMJOF DPEFD. 1PTTJCMF WBMVFT BSF LINE BOE NULL. ">JBI 2.4: 5IF NBY MJOF MFOHUI UP VTF GPS UIF UFYUMJOF DPEFD. ">JBI 2.4: 8IFUIFS PS OPU UP BVUP BQQFOE NJTTJOH FOE EFMJNJUFS XIFO TFOEJOH VTJOH UIF UFYUMJOF DPEFD. ">JBI 2.4: 5IF FODPEJOH (B DIBSTFU OBNF) UP VTF GPS UIF UFYUMJOF DPEFD. *G OPU QSPWJEFE, $BNFM XJMM VTF UIF +7. EFGBVMU $IBSTFU. ">JBI 2.9: 8IFO OFUUZ XPSLT PO OJP NPEF, JU VTFT EFGBVMU XPSLFS$PVOU QBSBNFUFS GSPN /FUUZ, XIJDI JT DQV@DPSF@UISFBET*2. 6TFS DBO VTF UIJT PQFSBUJPO UP PWFSSJEF UIF EFGBVMU XPSLFS$PVOU GSPN /FUUZ ">JBI 2.9: 3FGFSFODF UP B org.apache.camel.util.jsse.SSLContextParameters JO UIF 3FHJTUSZ.c 5IJT SFGFSFODF PWFSSJEFT BOZ DPOGJHVSFE 44-$POUFYU1BSBNFUFST BU UIF DPNQPOFOU MFWFM.c 4FF 6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ. ">JBI 2.9: $POGJHVSFT UIF CVGGFS TJ[F QSFEJDUPS. 4FF EFUBJMT BU +FUUZ EPDVNFOUBUJPO BOE UIJT NBJM UISFBE. ">JBI 2.11: $POGJHVSFT XIFUIFS UIF TFSWFS OFFET DMJFOU BVUIFOUJDBUJPO XIFO VTJOH 44-. ">JBI 2.10.2: 8IFUIFS UP VTF PSEFSFE UISFBE QPPM, UP FOTVSF FWFOUT BSF QSPDFTTFE PSEFSMZ PO UIF TBNF DIBOOFM. 4FF EFUBJMT BU UIF OFUUZ KBWBEPD PG org.jboss.netty.handler.execution.OrderedMemoryAwareThreadPoolExecutor GPS NPSF EFUBJMT. ">JBI 2.10.2: 5IF DPSF QPPM TJ[F GPS UIF PSEFSFE UISFBE QPPM, JG JUT JO VTF. ">JBI 2.10.4/">JBI 2.11: 1SPEVDFS POMZ. 8IFUIFS QSPEVDFS QPPM JT FOBCMFE PS OPU. ">JBI 2.10.3: 1SPEVDFS POMZ. 4FUT UIF DBQ PO UIF OVNCFS PG PCKFDUT UIBU DBO CF BMMPDBUFE CZ UIF QPPM (DIFDLFE PVU UP DMJFOUT, PS JEMF BXBJUJOH DIFDLPVU) BU B HJWFO UJNF. 6TF B OFHBUJWF WBMVF GPS OP MJNJU. ">JBI 2.10.3: 1SPEVDFS POMZ. 4FUT UIF NJOJNVN OVNCFS PG JOTUBODFT BMMPXFE JO UIF QSPEVDFS QPPM CFGPSF UIF FWJDUPS UISFBE (JG BDUJWF) TQBXOT OFX PCKFDUT. ">JBI 2.10.3: 1SPEVDFS POMZ. 4FUT UIF DBQ PO UIF OVNCFS PG "JEMF" JOTUBODFT JO UIF QPPM. ">JBI 2.10.3: 1SPEVDFS POMZ. 4FUT UIF NJOJNVN BNPVOU PG UJNF (WBMVF JO NJMMJT) BO PCKFDU NBZ TJU JEMF JO UIF QPPM CFGPSF JU JT FMJHJCMF GPS FWJDUJPO CZ UIF JEMF PCKFDU FWJDUPS.

sslContextParametersRef receiveBufferSizePredictor needClientAuth

null null false

orderedThreadPoolExecutor

true

maximumPoolSize producerPoolEnabled producerPoolMaxActive producerPoolMinIdle producerPoolMaxIdle producerPoolMinEvictableIdle

16 true -1 0 100 30000

1BDFPQOV ?>PBA .MQFLKP $PEFD )BOEMFST BOE 44- ,FZTUPSFT DBO CF FOMJTUFE JO UIF 3FHJTUSZ, TVDI BT JO UIF 4QSJOH 9.GJMF. 5IF WBMVFT UIBU DPVME CF QBTTFE JO, BSF UIF GPMMPXJOH:
->JB
passphrase keyStoreFormat securityProvider keyStoreFile trustStoreFile sslHandler encoder encorders decoder decoders

#BP@OFMQFLK
QBTTXPSE TFUUJOH UP VTF JO PSEFS UP FODSZQU/EFDSZQU QBZMPBET TFOU VTJOH 44) LFZTUPSF GPSNBU UP CF VTFE GPS QBZMPBE FODSZQUJPO. %FGBVMUT UP "+,4" JG OPU TFU 4FDVSJUZ QSPWJEFS UP CF VTFE GPS QBZMPBE FODSZQUJPO. %FGBVMUT UP "4VO9509" JG OPU TFU. $MJFOU TJEF DFSUJGJDBUF LFZTUPSF UP CF VTFE GPS FODSZQUJPO 4FSWFS TJEF DFSUJGJDBUF LFZTUPSF UP CF VTFE GPS FODSZQUJPO 3FGFSFODF UP B DMBTT UIBU DPVME CF VTFE UP SFUVSO BO 44- )BOEMFS " DVTUPN ChannelHandler DMBTT UIBU DBO CF VTFE UP QFSGPSN TQFDJBM NBSTIBMMJOH PG PVUCPVOE QBZMPBET. .VTU PWFSSJEF org.jboss.netty.channel.ChannelDownStreamHandler. " MJTU PG FODPEFST UP CF VTFE. :PV DBO VTF B 4USJOH XIJDI IBWF WBMVFT TFQBSBUFE CZ DPNNB, BOE IBWF UIF WBMVFT CF MPPLFE VQ JO UIF 3FHJTUSZ. +VTU SFNFNCFS UP QSFGJY UIF WBMVF XJUI # TP $BNFM LOPXT JU TIPVME MPPLVQ. " DVTUPN ChannelHandler DMBTT UIBU DBO CF VTFE UP QFSGPSN TQFDJBM NBSTIBMMJOH PG JOCPVOE QBZMPBET. .VTU PWFSSJEF org.jboss.netty.channel.ChannelUpStreamHandler. " MJTU PG EFDPEFST UP CF VTFE. :PV DBO VTF B 4USJOH XIJDI IBWF WBMVFT TFQBSBUFE CZ DPNNB, BOE IBWF UIF WBMVFT CF MPPLFE VQ JO UIF 3FHJTUSZ. +VTU SFNFNCFS UP QSFGJY UIF WBMVF XJUI # TP $BNFM LOPXT JU TIPVME MPPLVQ.

(JMLOQ>KQ: 3FBE CFMPX BCPVU VTJOH OPO TIBSFBCMF FODPEFST/EFDPEFST.

4PFKD KLK PE>OB>?IB BK@LABOP LO AB@LABOP


*G ZPVS FODPEFST PS EFDPEFST JT OPU TIBSFBCMF (FH UIFZ IBWF UIF !4IBSFBCMF DMBTT BOOPUBUJPO), UIFO ZPVS FODPEFS/EFDPEFS NVTU JNQMFNFOU UIF

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

845

org.apache.camel.component.netty.ChannelHandlerFactory JOUFSGBDF, BOE SFUVSO B OFX JOTUBODF JO UIF newChannelHandler NFUIPE. 5IJT JT UP FOTVSF UIF FODPEFS/ EFDPEFS DBO TBGFMZ CF VTFE. *G UIJT JT OPU UIF DBTF, UIFO UIF /FUUZ DPNQPOFOU XJMM MPH B 8"3/ XIFO BO FOEQPJOU JT DSFBUFE. 5IF /FUUZ DPNQPOFOU PGGFST B org.apache.camel.component.netty.ChannelHandlerFactories GBDUPSZ DMBTT, UIBU IBT B OVNCFS PG DPNNPOMZ VTFE NFUIPET. 2BKAFKD ,BPP>DBP QL/COLJ > -BQQV BKAMLFKQ

-BQQV /OLAR@BO
*O 1SPEVDFS NPEF, UIF DPNQPOFOU QSPWJEFT UIF BCJMJUZ UP TFOE QBZMPBET UP B TPDLFU FOEQPJOU VTJOH FJUIFS 5$1 PS 6%1 QSPUPDPMT (XJUI PQUJPOBM 44- TVQQPSU). 5IF QSPEVDFS NPEF TVQQPSUT CPUI POF-XBZ BOE SFRVFTU-SFTQPOTF CBTFE PQFSBUJPOT.

-BQQV "LKPRJBO
*O $POTVNFS NPEF, UIF DPNQPOFOU QSPWJEFT UIF BCJMJUZ UP: MJTUFO PO B TQFDJGJFE TPDLFU VTJOH FJUIFS 5$1 PS 6%1 QSPUPDPMT (XJUI PQUJPOBM 44TVQQPSU), SFDFJWF SFRVFTUT PO UIF TPDLFU VTJOH UFYU/YNM, CJOBSZ BOE TFSJBMJ[FE PCKFDU CBTFE QBZMPBET BOE TFOE UIFN BMPOH PO B SPVUF BT NFTTBHF FYDIBOHFT. 5IF DPOTVNFS NPEF TVQQPSUT CPUI POF-XBZ BOE SFRVFTU-SFTQPOTF CBTFE PQFSBUJPOT. 4P>DB 2>JMIBP

4#/ -BQQV BKAMLFKQ RPFKD 1BNRBPQ-1BMIV >KA PBOF>IFWBA L?GB@Q M>VIL>A


RouteBuilder builder = new RouteBuilder() { public void configure() { from("netty:udp://localhost:5155?sync=true") .process(new Processor() { public void process(Exchange exchange) throws Exception { Poetry poetry = (Poetry) exchange.getIn().getBody(); poetry.setPoet("Dr. Sarojini Naidu"); exchange.getOut().setBody(poetry);

846

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

} } } };

3"/ ?>PBA -BQQV @LKPRJBO BKAMLFKQ RPFKD .KB-T>V @LJJRKF@>QFLK


RouteBuilder builder = new RouteBuilder() { public void configure() { from("netty:tcp://localhost:5150") .to("mock:result"); } };

K 22+/3"/ ?>PBA -BQQV @LKPRJBO BKAMLFKQ RPFKD 1BNRBPQ1BMIV @LJJRKF@>QFLK


4PFKD QEB )22$ "LKCFDRO>QFLK 4QFIFQV "T PG $BNFM 2.9, UIF /FUUZ DPNQPOFOU TVQQPSUT 44-/5-4 DPOGJHVSBUJPO UISPVHI UIF $BNFM +44& $POGJHVSBUJPO 6UJMJUZ.c 5IJT VUJMJUZ HSFBUMZ EFDSFBTFT UIF BNPVOU PG DPNQPOFOU TQFDJGJD DPEF ZPV OFFE UP XSJUF BOE JT DPOGJHVSBCMF BU UIF FOEQPJOU BOE DPNQPOFOU MFWFMT.c 5IF GPMMPXJOH FYBNQMFT EFNPOTUSBUF IPX UP VTF UIF VUJMJUZ XJUI UIF /FUUZ DPNQPOFOU.
/OLDO>JJ>QF@ @LKCFDRO>QFLK LC QEB @LJMLKBKQ
KeyStoreParameters ksp = new KeyStoreParameters(); ksp.setResource("/users/home/server/keystore.jks"); ksp.setPassword("keystorePassword"); KeyManagersParameters kmp = new KeyManagersParameters(); kmp.setKeyStore(ksp); kmp.setKeyPassword("keyPassword"); SSLContextParameters scp = new SSLContextParameters(); scp.setKeyManagers(kmp); NettyComponent nettyComponent = getContext().getComponent("netty", NettyComponent.class); nettyComponent.setSslContextParameters(scp);

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

847

2MOFKD #2+ ?>PBA @LKCFDRO>QFLK LC BKAMLFKQ


... <camel:sslContextParameters id="sslContextParameters"> <camel:keyManagers keyPassword="keyPassword"> <camel:keyStore resource="/users/home/server/keystore.jks" password="keystorePassword"/> </camel:keyManagers> </camel:sslContextParameters>... ... <to uri="netty:tcp://localhost:5150?sync=true&ssl=true&sslContextParameters=#sslContextParameters"/> ...

4PFKD !>PF@ 22+/3+2 @LKCFDRO>QFLK LK QEB )BQQV "LJMLKBKQ


JndiRegistry registry = new JndiRegistry(createJndiContext()); registry.bind("password", "changeit"); registry.bind("ksf", new File("src/test/resources/keystore.jks")); registry.bind("tsf", new File("src/test/resources/keystore.jks")); context.createRegistry(registry); context.addRoutes(new RouteBuilder() { public void configure() { String netty_ssl_endpoint = "netty:tcp://localhost:5150?sync=true&ssl=true&passphrase=#password" + "&keyStoreFile=#ksf&trustStoreFile=#tsf"; String return_string = "When You Go Home, Tell Them Of Us And Say," + "For Your Tomorrow, We Gave Our Today."; from(netty_ssl_endpoint) .process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setBody(return_string); } } } });

4PFKD ,RIQFMIB "LAB@P


*O DFSUBJO DBTFT JU NBZ CF OFDFTTBSZ UP BEE DIBJOT PG FODPEFST BOE EFDPEFST UP UIF OFUUZ QJQFMJOF. 5P BEE NVMUQJMF DPEFDT UP B DBNFM OFUUZ FOEQPJOU UIF 'FODPEFST' BOE 'EFDPEFST' VSJ QBSBNFUFST TIPVME CF VTFE. -JLF UIF 'FODPEFS' BOE 'EFDPEFS' QBSBNFUFST UIFZ BSF VTFE UP TVQQMZ SFGFSFODFT (UP MJTUT PG $IBOOFM6QTUSFBN)BOEMFST BOE $IBOOFM%PXOTUSFBN)BOEMFST) UIBU
848 $) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

TIPVME CF BEEFE UP UIF QJQFMJOF. /PUF UIBU JG FODPEFST JT TQFDJGJFE UIFO UIF FODPEFS QBSBN XJMM CF JHOPSFE, TJNJMBSMZ GPS EFDPEFST BOE UIF EFDPEFS QBSBN. 5IF MJTUT PG DPEFDT OFFE UP CF BEEFE UP UIF $BNFM'T SFHJTUSZ TP UIFZ DBO CF SFTPMWFE XIFO UIF FOEQPJOU JT DSFBUFE.
ChannelHandlerFactory lengthDecoder = ChannelHandlerFactories.newLengthFieldBasedFrameDecoder(1048576, 0, 4, 0, 4); StringDecoder stringDecoder = new StringDecoder(); registry.bind("length-decoder", lengthDecoder); registry.bind("string-decoder", stringDecoder); LengthFieldPrepender lengthEncoder = new LengthFieldPrepender(4); StringEncoder stringEncoder = new StringEncoder(); registry.bind("length-encoder", lengthEncoder); registry.bind("string-encoder", stringEncoder); List<ChannelHandler> decoders = new ArrayList<ChannelHandler>(); decoders.add(lengthDecoder); decoders.add(stringDecoder); List<ChannelHandler> encoders = new ArrayList<ChannelHandler>(); encoders.add(lengthEncoder); encoders.add(stringEncoder); registry.bind("encoders", encoders); registry.bind("decoders", decoders);

4QSJOH'T OBUJWF DPMMFDUJPOT TVQQPSU DBO CF VTFE UP TQFDJGZ UIF DPEFD MJTUT JO BO BQQMJDBUJPO DPOUFYU
<util:list id="decoders" list-class="java.util.LinkedList"> <bean class="org.apache.camel.component.netty.ChannelHandlerFactories" factory-method="newLengthFieldBasedFrameDecoder"> <constructor-arg value="1048576"/> <constructor-arg value="0"/> <constructor-arg value="4"/> <constructor-arg value="0"/> <constructor-arg value="4"/> </bean> <bean class="org.jboss.netty.handler.codec.string.StringDecoder"/> </util:list> <util:list id="encoders" list-class="java.util.LinkedList"> <bean class="org.jboss.netty.handler.codec.frame.LengthFieldPrepender"> <constructor-arg value="4"/> </bean> <bean class="org.jboss.netty.handler.codec.string.StringEncoder"/> </util:list> <bean id="length-encoder" class="org.jboss.netty.handler.codec.frame.LengthFieldPrepender">

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

849

3FBE GVSUIFS BCPWF BCPVU VTJOH OPO TIBSFBCMF FODPEFST/EFDPEFST.

<constructor-arg value="4"/> </bean> <bean id="string-encoder" class="org.jboss.netty.handler.codec.string.StringEncoder"/> <bean id="length-decoder" class="org.apache.camel.component.netty.ChannelHandlerFactories" factory-method="newLengthFieldBasedFrameDecoder"> <constructor-arg value="1048576"/> <constructor-arg value="0"/> <constructor-arg value="4"/> <constructor-arg value="0"/> <constructor-arg value="4"/> </bean> <bean id="string-decoder" class="org.jboss.netty.handler.codec.string.StringDecoder"/> </beans>

5IF CFBO OBNFT DBO UIFO CF VTFE JO OFUUZ FOEQPJOU EFGJOJUJPOT FJUIFS BT B DPNNB TFQBSBUFE MJTU PS DPOUBJOFE JO B -JTU F.H.

from("direct:multiple-codec").to("netty:tcp://localhost:{{port}}?encoders=#encoders&sync=false");

from("netty:tcp://localhost:{{port}}?decoders=#length-decoder,#string-decoder&sync=false").to("mock:mu } }; } }

PS WJB TQSJOH.
<camelContext id="multiple-netty-codecs-context" xmlns="http://camel.apache.org/schema/ spring"> <route> <from uri="direct:multiple-codec"/> <to uri="netty:tcp://localhost:5150?encoders=#encoders&amp;sync=false"/> </route> <route> <from uri="netty:tcp://localhost:5150?decoders=#length-decoder,#string-decoder&amp;sync=false"/> <to uri="mock:multiple-codec"/>

850

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

</route> </camelContext>

"ILPFKD "E>KKBI 6EBK "LJMIBQB 8IFO BDUJOH BT B TFSWFS ZPV TPNFUJNFT XBOU UP DMPTF UIF DIBOOFM XIFO, GPS FYBNQMF, B DMJFOU DPOWFSTJPO JT GJOJTIFE. :PV DBO EP UIJT CZ TJNQMZ TFUUJOH UIF FOEQPJOU PQUJPO disconnect=true. )PXFWFS ZPV DBO BMTP JOTUSVDU $BNFM PO B QFS NFTTBHF CBTJT BT GPMMPXT. 5P JOTUSVDU $BNFM UP DMPTF UIF DIBOOFM, ZPV TIPVME BEE B IFBEFS XJUI UIF LFZ CamelNettyCloseChannelWhenComplete TFU UP B CPPMFBO true WBMVF. 'PS JOTUBODF, UIF FYBNQMF CFMPX XJMM DMPTF UIF DIBOOFM BGUFS JU IBT XSJUUFO UIF CZF NFTTBHF CBDL UP UIF DMJFOU:
from("netty:tcp://localhost:8080").process(new Processor() { public void process(Exchange exchange) throws Exception { String body = exchange.getIn().getBody(String.class); exchange.getOut().setBody("Bye " + body); // some condition which determines if we should close if (close) { exchange.getOut().setHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); } } });

AAFKD @RPQLJ @E>KKBI MFMBIFKB C>@QLOFBP QL D>FK @LJMIBQB @LKQOLI LSBO > @OB>QBA MFMBIFKB S>FI>?IB >P LC ">JBI 2.5 $VTUPN DIBOOFM QJQFMJOFT QSPWJEF DPNQMFUF DPOUSPM UP UIF VTFS PWFS UIF IBOEMFS/ JOUFSDFQUPS DIBJO CZ JOTFSUJOH DVTUPN IBOEMFS(T), FODPEFS(T) & EFDPEFST XJUIPVU IBWJOH UP TQFDJGZ UIFN JO UIF /FUUZ &OEQPJOU 63- JO B WFSZ TJNQMF XBZ. *O PSEFS UP BEE B DVTUPN QJQFMJOF, B DVTUPN DIBOOFM QJQFMJOF GBDUPSZ NVTU CF DSFBUFE BOE SFHJTUFSFE XJUI UIF DPOUFYU WJB UIF DPOUFYU SFHJTUSZ (+/%*3FHJTUSZ,PS UIF DBNFM-TQSJOH "QQMJDBUJPO$POUFYU3FHJTUSZ FUD). " DVTUPN QJQFMJOF GBDUPSZ NVTU CF DPOTUSVDUFE BT GPMMPXT ` " 1SPEVDFS MJOLFE DIBOOFM QJQFMJOF GBDUPSZ NVTU FYUFOE UIF BCTUSBDU DMBTT ClientPipelineFactory. ` " $POTVNFS MJOLFE DIBOOFM QJQFMJOF GBDUPSZ NVTU FYUFOE UIF BCTUSBDU DMBTT ServerPipelineFactory.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

851

` 5IF DMBTTFT TIPVME PWFSSJEF UIF HFU1JQFMJOF() NFUIPE JO PSEFS UP JOTFSU DVTUPN IBOEMFS(T), FODPEFS(T) BOE EFDPEFS(T). /PU PWFSSJEJOH UIF HFU1JQFMJOF() NFUIPE DSFBUFT B QJQFMJOF XJUI OP IBOEMFST, FODPEFST PS EFDPEFST XJSFE UP UIF QJQFMJOF. 5IF FYBNQMF CFMPX TIPXT IPX 4FSWFS$IBOOFM 1JQFMJOF GBDUPSZ NBZ CF DSFBUFE
Listing 1. Using custom pipeline factory
public class SampleServerChannelPipelineFactory extends ServerPipelineFactory { private int maxLineSize = 1024; public ChannelPipeline getPipeline() throws Exception { ChannelPipeline channelPipeline = Channels.pipeline(); channelPipeline.addLast("encoder-SD", new StringEncoder(CharsetUtil.UTF_8)); channelPipeline.addLast("decoder-DELIM", new DelimiterBasedFrameDecoder(maxLineSize, true, Delimiters.lineDelimiter())); channelPipeline.addLast("decoder-SD", new StringDecoder(CharsetUtil.UTF_8)); // here we add the default Camel ServerChannelHandler for the consumer, to allow Camel to route the message etc. channelPipeline.addLast("handler", new ServerChannelHandler(consumer)); return channelPipeline; } }

5IF DVTUPN DIBOOFM QJQFMJOF GBDUPSZ DBO UIFO CF BEEFE UP UIF SFHJTUSZ BOE JOTUBOUJBUFE/VUJMJ[FE PO B DBNFM SPVUF JO UIF GPMMPXJOH XBZ
Registry registry = camelContext.getRegistry(); serverPipelineFactory = new TestServerChannelPipelineFactory(); registry.bind("spf", serverPipelineFactory); context.addRoutes(new RouteBuilder() { public void configure() { String netty_ssl_endpoint = "netty:tcp://localhost:5150?serverPipelineFactory=#spf" String return_string = "When You Go Home, Tell Them Of Us And Say," + "For Your Tomorrow, We Gave Our Today."; from(netty_ssl_endpoint) .process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setBody(return_string); } } } });

2BB

IPL ` $POGJHVSJOH $BNFM

852

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

` ` `

$PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE .*/"

-,1 ".,/.-$-3
5IF KJO DPNQPOFOU JT BO BEBQUFS UP UIF /PSNBMJ[FE .FTTBHF 3PVUFS (/.3) JO 4FSWJDF.JY, XIJDI JT JOUFOEFE GPS VTF CZ $BNFM BQQMJDBUJPOT EFQMPZFE EJSFDUMZ JOUP UIF 04(J DPOUBJOFS. :PV DBO FYDIBOHF PCKFDUT XJUI /.3 BOE OPU POMZ 9.- MJLF UIJT JT UIF DBTF XJUI UIF +#* TQFDJGJDBUJPO. 5IF JOUFSFTU PG UIJT DPNQPOFOU JT UIBU ZPV DBO JOUFSDPOOFDU DBNFM SPVUFT EFQMPZFE JO EJGGFSFOU 04(* CVOEMFT. #Z DPOUSBTU, UIF +#* DPNQPOFOU JT JOUFOEFE GPS VTF CZ $BNFM BQQMJDBUJPOT EFQMPZFE JOUP UIF 4FSWJDF.JY +#* DPOUBJOFS. (KPQ>IIFKD FK M>@EB 2BOSF@BJFU

5IF /.3 DPNQPOFOU JT QSPWJEFE XJUI "QBDIF 4FSWJDF.JY. *U JT KLQ EJTUSJCVUFE XJUI $BNFM. 5P JOTUBMM UIF /.3 DPNQPOFOU JO 4FSWJDF.JY, FOUFS UIF GPMMPXJOH DPNNBOE JO UIF 4FSWJDF.JY DPOTPMF XJOEPX:
features:install nmr camel-nmr

(KPQ>IIFKD FK MI>FK

M>@EB *>O>C

*O QMBJO ,BSBG UIF ONS DPNQPOFOU DBO BMTP CF JOTUBMMFE VTJOH UIF TFSWJDFNJY BSUJGBDUT:
features:chooseurl camel <version> features:addurl mvn:org.apache.servicemix.nmr/apache-servicemix-nmr/1.5.0/xml/features features:install camel-blueprint nmr camel-nmr install -s mvn:org.apache.servicemix.camel/org.apache.servicemix.camel.component/4.4.2

"LKCFDRO>QFLK :PV BMTP OFFE UP JOTUBOUJBUF UIF /.3 DPNQPOFOU. :PV DBO EP UIJT CZ FEJUJOH ZPVS 4QSJOH DPOGJHVSBUJPO GJMF, META-INF/spring/*.xml, BOE BEEJOH UIF GPMMPXJOH bean JOTUBODF:
<beans xmlns:osgi="http://www.springframework.org/schema/osgi" ... > ... <bean id="nmr" class="org.apache.servicemix.camel.nmr.ServiceMixComponent"> <property name="nmr"> <osgi:reference interface="org.apache.servicemix.nmr.api.NMR" />

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

853

</property> </bean> ... </beans>

-,1 @LKPRJBO >KA MOLAR@BO BKAMLFKQP 5IF GPMMPXJOH DPEF:


from("nmr:MyServiceEndpoint")

"VUPNBUJDBMMZ FYQPTFT B OFX FOEQPJOU UP UIF CVT XJUI FOEQPJOU OBNF MyServiceEndpoint (TFF 63*-GPSNBU). 8IFO BO /.3 FOEQPJOU BQQFBST BU UIF FOE PG B SPVUF, GPS FYBNQMF:
to("nmr:MyServiceEndpoint")

5IF NFTTBHFT TFOU CZ UIJT QSPEVDFS FOEQPJOU BSF TFOU UP UIF BMSFBEZ EFQMPZFE /.3 FOEQPJOU. 41( CLOJ>Q
nmr:endpointName

41( .MQFLKP
.MQFLK
runAsSubject

#BC>RIQ 5>IRB
false

#BP@OFMQFLK
M>@EB 2BOSF@B,FU 4.4: 8IFO UIJT JT TFU UP true PO B DPOTVNFS FOEQPJOU, UIF FOEQPJOU XJMM CF JOWPLFE PO CFIBMG PG UIF Subject UIBU JT TFU PO UIF Exchange (J.F. UIF DBMM UP Subject.getSubject(AccessControlContext) XJMM SFUVSO UIF Subject JOTUBODF) 8IFO UIJT JT TFU UP true PO B DPOTVNFS FOEQPJOU, BO JODPNJOH, TZODISPOPVT /.3 &YDIBOHF XJMM CF IBOEMFE PO UIF TFOEFS'T UISFBE JOTUFBE PG CFJOH IBOEMFE PO B OFX UISFBE PG UIF /.3 FOEQPJOU'T UISFBE QPPM M>@EB 2BOSF@B,FU 4.4: 8IFO UIJT JT TFU UP B WBMVF HSFBUFS UIBO 0, UIF QSPEVDFS FOEQPJOU XJMM UJNFPVU JG JU EPFTO'U SFDFJWF B SFTQPOTF GSPN UIF /.3 XJUIJO UIF HJWFO UJNFPVU QFSJPE (JO NJMMJTFDPOET). $POGJHVSJOH B UJNFPVU WBMVF XJMM TXJUDI UP VTJOH TZODISPOPVT JOUFSBDUJPOT XJUI UIF /.3 JOTUFBE PG UIF VTVBM BTZODISPOPVT NFTTBHJOH.

synchronous

false

timeout

$U>JMIBP
$POTVNFS

854

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("nmr:MyServiceEndpoint") // consume nmr exchanges asynchronously from("nmr:MyServiceEndpoint?synchronous=true").to() // consume nmr exchanges synchronously and use the same thread as defined by NMR ThreadPool

1SPEVDFS
from()...to("nmr:MyServiceEndpoint") // produce nmr exchanges asynchronously from()...to("nmr:MyServiceEndpoint?timeout=10000") // produce nmr exchanges synchronously and wait till 10s to receive response

4PFKD 2QOB>J ?LAFBP *G ZPV BSF VTJOH B TUSFBN UZQF BT UIF NFTTBHF CPEZ, ZPV TIPVME CF BXBSF UIBU B TUSFBN JT POMZ DBQBCMF PG CFJOH SFBE PODF. 4P JG ZPV FOBCMF DEBUG MPHHJOH, UIF CPEZ JT VTVBMMZ MPHHFE BOE UIVT SFBE. 5P EFBM XJUI UIJT, $BNFM IBT B streamCaching PQUJPO UIBU DBO DBDIF UIF TUSFBN, FOBCMJOH ZPV UP SFBE JU NVMUJQMF UJNFT.
from("nmr:MyEndpoint").streamCaching().to("xslt:transform.xsl", "bean:doSomething");

5IF TUSFBN DBDIJOH JT EFGBVMU FOBCMFE, TP JU JT OPU OFDFTTBSZ UP TFU UIF streamCaching() PQUJPO. 8F TUPSF CJH JOQVU TUSFBNT (CZ EFGBVMU, PWFS 64,) JO B temp GJMF VTJOH CachedOutputStream. 8IFO ZPV DMPTF UIF JOQVU TUSFBN, UIF UFNQ GJMF XJMM CF EFMFUFE.

3BPQFKD
/.3 DBNFM SPVUFT DBO CF UFTUFE VTJOH UIF DBNFM VOJU UFTU BQQSPBDI FWFO JG UIFZ XJMM CF EFQMPZFE OFYU JO EJGGFSFOU CVOEMFT PO BO 04(* SVOUJNF. 8JUI UIJT BJN JO WJFX, ZPV XJMM FYUFOE UIF 4FSWJDF.JY/.3 .PDL DMBTT org.apache.servicemix.camel.nmr.AbstractComponentTest XIJDI XJMM DSFBUF B /.3 CVT, SFHJTUFS UIF $BNFM /.3 $PNQPOFOU BOE UIF FOEQPJOUT EFGJOFE JOUP UIF $BNFM SPVUFT.
public class ExchangeUsingNMRTest extends AbstractComponentTest { @Test public void testProcessing() throws InterruptedException { MockEndpoint mock = getMockEndpoint("mock:simple"); mock.expectedBodiesReceived("Simple message body"); template.sendBody("direct:simple", "Simple message body"); assertMockEndpointsSatisfied();

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

855

} @Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { from("direct:simple").to("nmr:simple"); from("nmr:simple?synchronous=true").to("mock:simple"); } }; } }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

04 139 ".,/.-$-3
5IF NR>OQW: DPNQPOFOU QSPWJEFT B TDIFEVMFE EFMJWFSZ PG NFTTBHFT VTJOH UIF 2VBSU[ TDIFEVMFS. &BDI FOEQPJOU SFQSFTFOUT B EJGGFSFOU UJNFS (JO 2VBSU[ UFSNT, B 5SJHHFS BOE +PC%FUBJM). .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-quartz</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
quartz://timerName?options quartz://groupName/timerName?options quartz://groupName/timerName?cron=expression quartz://timerName?cron=expression

856

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

5IF DPNQPOFOU VTFT FJUIFS B CronTrigger PS B SimpleTrigger. *G OP DSPO FYQSFTTJPO JT QSPWJEFE, UIF DPNQPOFOU VTFT B TJNQMF USJHHFS. *G OP groupName JT QSPWJEFE, UIF RVBSU[ DPNQPOFOU VTFT UIF Camel HSPVQ OBNF. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
/>O>JBQBO
cron trigger.repeatCount trigger.repeatInterval job.name job.XXX trigger.XXX stateful fireNow

#BC>RIQ
None 0 0 null null null false false

#BP@OFMQFLK
4QFDJGJFT B cron FYQSFTTJPO (OPU DPNQBUJCMF XJUI UIF trigger.* PS job.* PQUJPOT). 4JNQMF5SJHHFS: )PX NBOZ UJNFT TIPVME UIF UJNFS SFQFBU 4JNQMF5SJHHFS: 5IF BNPVOU PG UJNF JO NJMMJTFDPOET CFUXFFO SFQFBUFE USJHHFST. 4FUT UIF KPC OBNF. 4FUT UIF KPC PQUJPO XJUI UIF XXX TFUUFS OBNF. 4FUT UIF USJHHFS PQUJPO XJUI UIF XXX TFUUFS OBNF. 6TFT B 2VBSU[ StatefulJob JOTUFBE PG UIF EFGBVMU KPC. /FX UP $BNFM 2.2.0, JG JU JT USVF XJMM GJSF UIF USJHHFS XIFO UIF SPVUF JT TUBSU XIFO VTJOH 4JNQMF5SJHHFS.

'PS FYBNQMF, UIF GPMMPXJOH SPVUJOH SVMF XJMM GJSF UXP UJNFS FWFOUT UP UIF mock:results FOEQPJOU:
from("quartz://myGroup/ myTimerName?trigger.repeatInterval=2&trigger.repeatCount=1").routeId("myRoute").to("mock:result");

8IFO VTJOH B 4UBUFGVM+PC, UIF +PC%BUB.BQ JT SF-QFSTJTUFE BGUFS FWFSZ FYFDVUJPO PG UIF KPC, UIVT QSFTFSWJOH TUBUF GPS UIF OFYU FYFDVUJPO. "LKCFDROFKD NR>OQW.MOLMBOQFBP CFIB #Z EFGBVMU 2VBSU[ XJMM MPPL GPS B quartz.properties GJMF JO UIF SPPU PG UIF DMBTTQBUI. *G ZPV BSF VTJOH 8"3 EFQMPZNFOUT UIJT NFBOT KVTU ESPQ UIF RVBSU[.QSPQFSUJFT JO WEB-INF/ classes. )PXFWFS UIF $BNFM 2VBSU[ DPNQPOFOU BMTP BMMPXT ZPV UP DPOGJHVSF QSPQFSUJFT:
/>O>JBQBO
properties propertiesFile

#BC>RIQ
null null

3VMB
Properties String

#BP@OFMQFLK
">JBI 2.4: :PV DBO DPOGJHVSF B java.util.Properties JOTUBODF. ">JBI 2.4: 'JMF OBNF PG UIF QSPQFSUJFT UP MPBE GSPN UIF DMBTTQBUI

5P EP UIJT ZPV DBO DPOGJHVSF UIJT JO 4QSJOH 9.- BT GPMMPXT


<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent"> <property name="propertiesFile" value="com/mycompany/myquartz.properties"/> </bean>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

857

1RKKFKD FK .2&F >KA E>SFKD JRIQFMIB ?RKAIBP TFQE NR>OQW OLRQBP *G ZPV SVO JO 04(J TVDI BT "QBDIF 4FSWJDF.JY, PS "QBDIF ,BSBG, BOE IBWF NVMUJQMF CVOEMFT XJUI $BNFM SPVUFT UIBU TUBSU GSPN 2VBSU[ FOEQPJOUT, UIFO NBLF TVSF JG ZPV BTTJHO BO id UP UIF <DBNFM$POUFYU> UIBU UIJT JE JT VOJRVF, BT UIJT JT SFRVJSFE CZ UIF QuartzScheduler JO UIF 04(J DPOUBJOFS. *G ZPV EP OPU TFU BOZ id PO <DBNFM$POUFYU> UIFO B VOJRVF JE JT BVUP BTTJHOFE, BOE UIFSF JT OP QSPCMFN. 2Q>OQFKD QEB 0R>OQW P@EBARIBO S>FI>?IB >P LC ">JBI 2.4 5IF 2VBSU[ DPNQPOFOU PGGFST BO PQUJPO UP MFU UIF 2VBSU[ TDIFEVMFS CF TUBSUFE EFMBZFE, PS OPU BVUP TUBSUFE BU BMM.
/>O>JBQBO
startDelayedSeconds autoStartScheduler

#BC>RIQ
0 true

3VMB
int boolean

#BP@OFMQFLK
">JBI 2.4: 4FDPOET UP XBJU CFGPSF TUBSUJOH UIF RVBSU[ TDIFEVMFS. ">JBI 2.4: 8IFUIFS PS OPU UIF TDIFEVMFS TIPVME CF BVUP TUBSUFE.

5P EP UIJT ZPV DBO DPOGJHVSF UIJT JO 4QSJOH 9.- BT GPMMPXT


<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent"> <property name="startDelayedSeconds" value="5"/> </bean>

"IRPQBOFKD S>FI>?IB >P LC ">JBI 2.4 *G ZPV VTF 2VBSU[ JO DMVTUFSFE NPEF, F.H. UIF JobStore JT DMVTUFSFE. 5IFO GSPN $BNFM 2.4 POXBSET UIF 2VBSU[ DPNQPOFOU XJMM KLQ QBVTF/SFNPWF USJHHFST XIFO B OPEF JT CFJOH TUPQQFE/ TIVUEPXO. 5IJT BMMPXT UIF USJHHFS UP LFFQ SVOOJOH PO UIF PUIFS OPEFT JO UIF DMVTUFS. -LQB: 8IFO SVOOJOH JO DMVTUFSFE OPEF OP DIFDLJOH JT EPOF UP FOTVSF VOJRVF KPC OBNF/ HSPVQ GPS FOEQPJOUT. ,BPP>DB 'B>ABOP $BNFM BEET UIF HFUUFST GSPN UIF 2VBSU[ &YFDVUJPO $POUFYU BT IFBEFS WBMVFT. 5IF GPMMPXJOH IFBEFST BSF BEEFE: calendar, fireTime, jobDetail, jobInstance, jobRuntTime, mergedJobDataMap, nextFireTime, previousFireTime, refireCount, result, scheduledFireTime, scheduler, trigger, triggerName, triggerGroup. 5IF fireTime IFBEFS DPOUBJOT UIF java.util.Date PG XIFO UIF FYDIBOHF XBT GJSFE.

858

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD "OLK 3OFDDBOP 2VBSU[ TVQQPSUT $SPO-MJLF FYQSFTTJPOT GPS TQFDJGZJOH UJNFST JO B IBOEZ GPSNBU. :PV DBO VTF UIFTF FYQSFTTJPOT JO UIF cron 63* QBSBNFUFS; UIPVHI UP QSFTFSWF WBMJE 63* FODPEJOH XF BMMPX + UP CF VTFE JOTUFBE PG TQBDFT. 2VBSU[ QSPWJEFT B MJUUMF UVUPSJBM PO IPX UP VTF DSPO FYQSFTTJPOT. 'PS FYBNQMF, UIF GPMMPXJOH XJMM GJSF B NFTTBHF FWFSZ GJWF NJOVUFT TUBSUJOH BU 12QN (OPPO) UP 6QN PO XFFLEBZT:
from("quartz://myGroup/myTimerName?cron=0+0/ 5+12-18+?+*+MON-FRI").to("activemq:Totally.Rocks");

XIJDI JT FRVJWBMFOU UP VTJOH UIF DSPO FYQSFTTJPO


0 0/5 12-18 ? * MON-FRI

5IF GPMMPXJOH UBCMF TIPXT UIF 63* DIBSBDUFS FODPEJOHT XF VTF UP QSFTFSWF WBMJE 63* TZOUBY:
41( "E>O>@QBO
+

"OLK @E>O>@QBO
Space

2MB@FCVFKD QFJB WLKB S>FI>?IB >P LC ">JBI 2.8.1 5IF 2VBSU[ 4DIFEVMFS BMMPXT ZPV UP DPOGJHVSF UJNF [POF QFS USJHHFS. 'PS FYBNQMF UP VTF B UJNF[POF PG ZPVS DPVOUSZ, UIFO ZPV DBO EP BT GPMMPXT:
quartz://groupName/timerName?cron=0+0/5+12-18+?+*+MON-FRI&trigger.timeZone=Europe/ Stockholm

5IF UJNF;POF WBMVF JT UIF WBMVFT BDDFQUFE CZ java.util.TimeZone. *O $BNFM 2.8.0 PS PMEFS WFSTJPOT ZPV XPVME IBWF UP QSPWJEF ZPVS DVTUPN String UP java.util.TimeZone 5ZQF $POWFSUFS UP CF BCMF DPOGJHVSF UIJT GSPN UIF FOEQPJOU VSJ. 'SPN $BNFM 2.8.1 POXBSET XF IBWF JODMVEFE TVDI B 5ZQF $POWFSUFS JO UIF DBNFM-DPSF. 2BB IPL ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 5JNFS

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

859

04("*%(7/) ".,/.-$-3
5IF NRF@HCFU DPNQPOFOU BEBQUT UIF 2VJDL'*9/+ '*9 FOHJOF GPS VTJOH JO $BNFM . 5IJT DPNQPOFOU VTFT UIF TUBOEBSE 'JOBODJBM *OUFSDIBOHF ('*9) QSPUPDPM GPS NFTTBHF USBOTQPSU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-quickfix</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
quickfix:configFile[?sessionID=sessionID]

5IF @LKCFD%FIB JT UIF OBNF PG UIF 2VJDL'*9/+ DPOGJHVSBUJPO UP VTF GPS UIF '*9 FOHJOF (MPDBUFE BT B SFTPVSDF GPVOE JO ZPVS DMBTTQBUI). 5IF PQUJPOBM TFTTJPO*% JEFOUJGJFT B TQFDJGJD '*9 TFTTJPO. 5IF GPSNBU PG UIF TFTTJPO*% JT:

(BeginString):(SenderCompID)[/(SenderSubID)[/(SenderLocationID)]]->(TargetCompID)[/(TargetSubID)[/(Tar

&YBNQMF 63*T:
quickfix:config.cfg quickfix:config.cfg?sessionID=FIX.4.2:MyTradingCompany->SomeExchange

$-#/.(-32
'*9 TFTTJPOT BSF FOEQPJOUT GPS UIF NRF@HCFU DPNQPOFOU. "O FOEQPJOU 63* NBZ TQFDJGZ B TJOHMF TFTTJPO PS BMM TFTTJPOT NBOBHFE CZ B TQFDJGJD 2VJDL'*9/+ FOHJOF. 5ZQJDBM BQQMJDBUJPOT XJMM VTF POMZ POF '*9 FOHJOF CVU BEWBODFE VTFST NBZ DSFBUF NVMUJQMF '*9 FOHJOFT CZ SFGFSFODJOH EJGGFSFOU DPOGJHVSBUJPO GJMFT JO NRF@HCFU DPNQPOFOU FOEQPJOU 63*T. 8IFO B DPOTVNFS EPFT OPU JODMVEF B TFTTJPO *% JO UIF FOEQPJOU 63*, JU XJMM SFDFJWF FYDIBOHFT GPS BMM TFTTJPOT NBOBHFE CZ UIF '*9 FOHJOF BTTPDJBUFE XJUI UIF DPOGJHVSBUJPO GJMF TQFDJGJFE JO UIF 63*. *G B QSPEVDFS EPFT OPU TQFDJGZ B TFTTJPO JO UIF FOEQPJOU 63* UIFO JU NVTU JODMVEF UIF TFTTJPO-SFMBUFE GJFMET JO UIF '*9 NFTTBHF CFJOH TFOU. *G B TFTTJPO JT TQFDJGJFE JO UIF 63* UIFO UIF DPNQPOFOU XJMM BVUPNBUJDBMMZ JOKFDU UIF TFTTJPO-SFMBUFE GJFMET JOUP UIF '*9 NFTTBHF.

860

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

/OBSFLRP 5BOPFLKP 5IF NRF@HCFU DPNQPOFOU XBT SFXSJUUFO GPS $BNFM 2.5. 'PS JOGPSNBUJPO BCPVU VTJOH UIF NRF@HCFU DPNQPOFOU QSJPS UP 2.5 TFF UIF EPDVNFOUBUJPO TFDUJPO CFMPX. $U@E>KDB %LOJ>Q 5IF FYDIBOHF IFBEFST JODMVEF JOGPSNBUJPO UP IFMQ XJUI FYDIBOHF GJMUFSJOH, SPVUJOH BOE PUIFS QSPDFTTJOH. 5IF GPMMPXJOH IFBEFST BSF BWBJMBCMF:
'B>ABO ->JB
&WFOU$BUFHPSZ 4FTTJPO*% .FTTBHF5ZQF %BUB%JDUJPOBSZ

#BP@OFMQFLK
0OF PG AppMessageReceived, AppMessageSent, AdminMessageReceived, AdminMessageSent, SessionCreated, SessionLogon, SessionLogoff. 4FF UIF QuickfixjEventCategory FOVN. 5IF '*9 NFTTBHF 4FTTJPO*% 5IF '*9 .TH5ZQF UBH WBMVF 4QFDJGJFT B EBUB EJDUJPOBSZ UP VTFE GPS QBSTJOH BO JODPNJOH NFTTBHF. $BO CF BO JOTUBODF PG B EBUB EJDUJPOBSZ PS B SFTPVSDF QBUI GPS B 2VJDL'*9/+ EBUB EJDUJPOBSZ GJMF

5IF %BUB%JDUJPOBSZ IFBEFS JT VTFGVM JG TUSJOH NFTTBHFT BSF CFJOH SFDFJWFE BOE OFFE UP CF QBSTFE JO B SPVUF. 2VJDL'*9/+ SFRVJSFT B EBUB EJDUJPOBSZ UP QBSTF DFSUBJO UZQFT PG NFTTBHFT (XJUI SFQFBUJOH HSPVQT, GPS FYBNQMF). #Z JOKFDUJOH B %BUB%JDUJPOBSZ IFBEFS JO UIF SPVUF BGUFS SFDFJWJOH B NFTTBHF TUSJOH, UIF '*9 FOHJOF DBO QSPQFSMZ QBSTF UIF EBUB. 0RF@H%(7/) "LKCFDRO>QFLK $UQBKPFLKP 8IFO VTJOH 2VJDL'*9/+ EJSFDUMZ, POF UZQJDBMMZ XSJUFT DPEF UP DSFBUF JOTUBODFT PG MPHHJOH BEBQUFST, NFTTBHF TUPSFT BOE DPNNVOJDBUJPO DPOOFDUPST. 5IF NRF@HCFU DPNQPOFOU XJMM BVUPNBUJDBMMZ DSFBUF JOTUBODFT PG UIFTF DMBTTFT CBTFE PO JOGPSNBUJPO JO UIF DPOGJHVSBUJPO GJMF. *U BMTP QSPWJEFT EFGBVMUT GPS NBOZ PG UIF DPNNPO SFRVJSFE TFUUJOHT BOE BEET BEEJUJPOBM DBQBCJMJUJFT (MJLF UIF BCJMJUZ UP BDUJWBUF +.9 TVQQPSU). 5IF GPMMPXJOH TFDUJPOT EFTDSJCF IPX UIF NRF@HCFU DPNQPOFOU QSPDFTTFT UIF 2VJDL'*9/+ DPOGJHVSBUJPO. 'PS DPNQSFIFOTJWF JOGPSNBUJPO BCPVU 2VJDL'*9/+ DPOGJHVSBUJPO, TFF UIF 2'+ VTFS NBOVBM.

"LJJRKF@>QFLK "LKKB@QLOP
8IFO UIF DPNQPOFOU EFUFDUT BO JOJUJBUPS PS BDDFQUPS TFTTJPO TFUUJOH JO UIF 2VJDL'*9/+ DPOGJHVSBUJPO GJMF JU XJMM BVUPNBUJDBMMZ DSFBUF UIF DPSSFTQPOEJOH JOJUJBUPS BOE/PS BDDFQUPS DPOOFDUPS. 5IFTF TFUUJOHT DBO CF JO UIF EFGBVMU PS JO B TQFDJGJD TFTTJPO TFDUJPO PG UIF DPOGJHVSBUJPO GJMF.
2BPPFLK 2BQQFKD
ConnectionType=initiator ConnectionType=acceptor

"LJMLKBKQ

@QFLK

$SFBUF BO JOJUJBUPS DPOOFDUPS $SFBUF BO BDDFQUPS DPOOFDUPS

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

861

5IF UISFBEJOH NPEFM GPS UIF 2VJDL'*9/+ TFTTJPO DPOOFDUPST DBO BMTP CF TQFDJGJFE. 5IFTF TFUUJOHT BGGFDU BMM TFTTJPOT JO UIF DPOGJHVSBUJPO GJMF BOE NVTU CF QMBDFE JO UIF TFUUJOHT EFGBVMU TFDUJPO.
#BC>RIQ/&IL?>I 2BQQFKD
ThreadModel=ThreadPerConnector ThreadModel=ThreadPerSession

"LJMLKBKQ

@QFLK

6TF SocketInitiator PS SocketAcceptor (EFGBVMU) 6TF ThreadedSocketInitiator PS ThreadedSocketAcceptor

+LDDFKD
5IF 2VJDL'*9/+ MPHHFS JNQMFNFOUBUJPO DBO CF TQFDJGJFE CZ JODMVEJOH UIF GPMMPXJOH TFUUJOHT JO UIF EFGBVMU TFDUJPO PG UIF DPOGJHVSBUJPO GJMF. 5IF ScreenLog JT UIF EFGBVMU JG OPOF PG UIF GPMMPXJOH TFUUJOHT BSF QSFTFOU JO UIF DPOGJHVSBUJPO. *U'T BO FSSPS UP JODMVEF TFUUJOHT UIBU JNQMZ NPSF UIBO POF MPH JNQMFNFOUBUJPO. 5IF MPH GBDUPSZ JNQMFNFOUBUJPO DBO BMTP CF TFU EJSFDUMZ PO UIF 2VJDLGJY DPNQPOFOU. 5IJT XJMM PWFSSJEF BOZ SFMBUFE WBMVFT JO UIF 2VJDL'*9/+ TFUUJOHT GJMF.
#BC>RIQ/&IL?>I 2BQQFKD
ScreenLogShowEvents ScreenLogShowIncoming ScreenLogShowOutgoing SLF4J* FileLogPath JdbcDriver

"LJMLKBKQ
6TF B ScreenLog 6TF B ScreenLog 6TF B ScreenLog

@QFLK

">JBI 2.6+. 6TF B SLF4JLog. "OZ PG UIF 4-'4+ TFUUJOHT XJMM DBVTF UIJT MPH UP CF VTFE. 6TF B FileLog 6TF B JdbcLog

,BPP>DB 2QLOB
5IF 2VJDL'*9/+ NFTTBHF TUPSF JNQMFNFOUBUJPO DBO CF TQFDJGJFE CZ JODMVEJOH UIF GPMMPXJOH TFUUJOHT JO UIF EFGBVMU TFDUJPO PG UIF DPOGJHVSBUJPO GJMF. 5IF MemoryStore JT UIF EFGBVMU JG OPOF PG UIF GPMMPXJOH TFUUJOHT BSF QSFTFOU JO UIF DPOGJHVSBUJPO. *U'T BO FSSPS UP JODMVEF TFUUJOHT UIBU JNQMZ NPSF UIBO POF NFTTBHF TUPSF JNQMFNFOUBUJPO. 5IF NFTTBHF TUPSF GBDUPSZ JNQMFNFOUBUJPO DBO BMTP CF TFU EJSFDUMZ PO UIF 2VJDLGJY DPNQPOFOU. 5IJT XJMM PWFSSJEF BOZ SFMBUFE WBMVFT JO UIF 2VJDL'*9/+ TFUUJOHT GJMF.
#BC>RIQ/&IL?>I 2BQQFKD
JdbcDriver FileStorePath SleepycatDatabaseDir

"LJMLKBKQ
6TF B JdbcStore 6TF B FileStore 6TF B SleepcatStore

@QFLK

,BPP>DB %>@QLOV
" NFTTBHF GBDUPSZ JT VTFE UP DPOTUSVDU EPNBJO PCKFDUT GSPN SBX '*9 NFTTBHFT. 5IF EFGBVMU NFTTBHF GBDUPSZ JT DefaultMessageFactory. )PXFWFS, BEWBODFE BQQMJDBUJPOT NBZ SFRVJSF B DVTUPN NFTTBHF GBDUPSZ. 5IJT DBO CF TFU PO UIF 2VJDL'*9/+ DPNQPOFOU.

862

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

),7
#BC>RIQ/&IL?>I 2BQQFKD
UseJmx

"LJMLKBKQ

@QFLK

JG Y, UIFO FOBCMF 2VJDL'*9/+ +.9

.QEBO #BC>RIQP
5IF DPNQPOFOU QSPWJEFT TPNF EFGBVMU TFUUJOHT GPS XIBU BSF OPSNBMMZ SFRVJSFE TFUUJOHT JO 2VJDL'*9/+ DPOGJHVSBUJPO GJMFT. SessionStartTime BOE SessionEndTime EFGBVMU UP "00:00:00", NFBOJOH UIF TFTTJPO XJMM OPU CF BVUPNBUJDBMMZ TUBSUFE BOE TUPQQFE. 5IF HeartBtInt (IFBSUCFBU JOUFSWBM) EFGBVMUT UP 30 TFDPOET.

,FKFJ>I (KFQF>QLO "LKCFDRO>QFLK $U>JMIB


[SESSION] ConnectionType=initiator BeginString=FIX.4.4 SenderCompID=YOUR_SENDER TargetCompID=YOUR_TARGET

4PFKD QEB (K.RQ ,BPP>DB $U@E>KDB />QQBOK ">JBI 2.8+ "MUIPVHI UIF '*9 QSPUPDPM JT FWFOU-ESJWFO BOE BTZODISPOPVT, UIFSF BSF TQFDJGJD QBJST PG NFTTBHFT UIBU SFQSFTFOU B SFRVFTU-SFQMZ NFTTBHF FYDIBOHF. 5P VTF BO *O0VU FYDIBOHF QBUUFSO, UIFSF TIPVME CF B TJOHMF SFRVFTU NFTTBHF BOE TJOHMF SFQMZ NFTTBHF UP UIF SFRVFTU. &YBNQMFT JODMVEF BO 0SEFS4UBUVT3FRVFTU NFTTBHF BOE 6TFS3FRVFTU.

(JMIBJBKQFKD (K.RQ $U@E>KDBP CLO "LKPRJBOP


"EE "FYDIBOHF1BUUFSO=*O0VU" UP UIF 2VJDL'*9/+ FOQPJOU 63*. 5IF MessageOrderStatusService JO UIF FYBNQMF CFMPX JT B CFBO XJUI B TZODISPOPVT TFSWJDF NFUIPE. 5IF NFUIPE SFUVSOT UIF SFTQPOTF UP UIF SFRVFTU (BO &YFDVUJPO3FQPSU JO UIJT DBTF) XIJDI JT UIFO TFOU CBDL UP UIF SFRVFTUPS TFTTJPO.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

863

from("quickfix:examples/ inprocess.cfg?sessionID=FIX.4.2:MARKET->TRADER&exchangePattern=InOut") .filter(header(QuickfixjEndpoint.MESSAGE_TYPE_KEY).isEqualTo(MsgType.ORDER_STATUS_REQUEST)) .bean(new MarketOrderStatusService());

(JMIBJBKQFKD (K.RQ $U@E>KDBP CLO /OLAR@BOP


'PS QSPEVDFST, TFOEJOH B NFTTBHF XJMM CMPDL VOUJM B SFQMZ JT SFDFJWFE PS B UJNFPVU PDDVST. 5IFSF JT OP TUBOEBSE XBZ UP DPSSFMBUF SFQMZ NFTTBHFT JO '*9. 5IFSFGPSF, B DPSSFMBUJPO DSJUFSJB NVTU CF EFGJOFE GPS FBDI UZQF PG *O0VU FYDIBOHF. 5IF DPSSFMBUJPO DSJUFSJB BOE UJNFPVU DBO CF TQFDJGJFE VTJOH Exchange QSPQFSUJFT. #BP@OFMQFLK $PSSFMBUJPO $SJUFSJB $PSSFMBUJPO 5JNFPVU JO .JMMJTFDPOET *BV 2QOFKD "$PSSFMBUJPO$SJUFSJB" *BV "LKPQ>KQ 2VJDLGJYK1SPEVDFS.$033&-"5*0/@$3*5&3*"@,&: #BC>RIQ /POF

"$PSSFMBUJPO5JNFPVU"

2VJDLGJYK1SPEVDFS.$033&-"5*0/@5*.&065@,&:

1000

5IF DPSSFMBUJPO DSJUFSJB JT EFGJOFE XJUI B MessagePredicate PCKFDU. 5IF GPMMPXJOH FYBNQMF XJMM USFBU B '*9 &YFDVUJPO3FQPSU GSPN UIF TQFDJGJFE TFTTJPO XIFSF UIF USBOTBDUJPO UZQF JT 45"564 BOE UIF 0SEFS *% NBUDIFT PVS SFRVFTU. 5IF TFTTJPO *% TIPVME CF GPS UIF requestor, UIF TFOEFS BOE UBSHFU $PNQ*% GJFMET XJMM CF SFWFSTFE XIFO MPPLJOH GPS UIF SFQMZ.
exchange.setProperty(QuickfixjProducer.CORRELATION_CRITERIA_KEY, new MessagePredicate(new SessionID(sessionID), MsgType.EXECUTION_REPORT) .withField(ExecTransType.FIELD, Integer.toString(ExecTransType.STATUS)) .withField(OrderID.FIELD, request.getString(OrderID.FIELD)));

$U>JMIB
5IF TPVSDF DPEF DPOUBJOT BO FYBNQMF DBMMFE RequestReplyExample UIBU EFNPOTUSBUFT UIF *O0VU FYDIBOHFT GPS B DPOTVNFS BOE QSPEVDFS. 5IJT FYBNQMF DSFBUFT B TJNQMF )551 TFSWFS FOEQPJOU UIBU BDDFQUT PSEFS TUBUVT SFRVFTUT. 5IF )551 SFRVFTU JT DPOWFSUFE UP B '*9 0SEFS4UBUVT3FRVFTU.FTTBHF, JT BVHNFOUFE XJUI B DPSSFMBUJPO DSJUFSJB, BOE JT UIFO SPVUFE UP B RVJDLGJY FOEQPJOU. 5IF SFTQPOTF JT UIFO DPOWFSUFE

864

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

UP B +40/-GPSNBUUFE TUSJOH BOE TFOU CBDL UP UIF )551 TFSWFS FOEQPJOU UP CF QSPWJEFE BT UIF XFC SFTQPOTF. 5IF 4QSJOH DPOGJHVSBUJPO IBWF DIBOHFE GSPN $BNFM 2.9 POXBSET. 4FF GVSUIFS CFMPX GPS FYBNQMF. 2MOFKD "LKCFDRO>QFLK ">JBI 2.6 - 2.8.U 5IF 2VJDL'*9/+ DPNQPOFOU JODMVEFT B 4QSJOH FactoryBean GPS DPOGJHVSJOH UIF TFTTJPO TFUUJOHT XJUIJO B 4QSJOH DPOUFYU. " UZQF DPOWFSUFS GPS 2VJDL'*9/+ TFTTJPO *% TUSJOHT JT BMTP JODMVEFE. 5IF GPMMPXJOH FYBNQMF TIPXT B TJNQMF DPOGJHVSBUJPO PG BO BDDFQUPS BOE JOJUJBUPS TFTTJPO XJUI EFGBVMU TFUUJOHT GPS CPUI TFTTJPOT.
<!-- camel route --> <camelContext id="quickfixjContext" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="quickfix:example"/> <filter> <simple>${in.header.EventCategory} == 'AppMessageReceived'</simple> <to uri="log:test"/> </filter> </route> </camelContext> <!-- quickfix component --> <bean id="quickfix" class="org.apache.camel.component.quickfixj.QuickfixjComponent"> <property name="engineSettings"> <util:map> <entry key="quickfix:example" value-ref="quickfixjSettings"/> </util:map> </property> <property name="messageFactory"> <bean class="org.apache.camel.component.quickfixj.QuickfixjSpringTest.CustomMessageFactory"/> </property> </bean> <!-- quickfix settings --> <bean id="quickfixjSettings" class="org.apache.camel.component.quickfixj.QuickfixjSettingsFactory"> <property name="defaultSettings"> <util:map> <entry key="SocketConnectProtocol" value="VM_PIPE"/> <entry key="SocketAcceptProtocol" value="VM_PIPE"/> <entry key="UseDataDictionary" value="N"/> </util:map> </property> <property name="sessionSettings"> <util:map>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

865

<entry key="FIX.4.2:INITIATOR->ACCEPTOR"> <util:map> <entry key="ConnectionType" value="initiator"/> <entry key="SocketConnectHost" value="localhost"/> <entry key="SocketConnectPort" value="5000"/> </util:map> </entry> <entry key="FIX.4.2:ACCEPTOR->INITIATOR"> <util:map> <entry key="ConnectionType" value="acceptor"/> <entry key="SocketAcceptPort" value="5000"/> </util:map> </entry> </util:map> </property> </bean>

">JBI 2.9 LKT>OAP 5IF 2VJDL'*9/+ DPNQPOFOU JODMVEFT B QuickfixjConfiguration DMBTT GPS DPOGJHVSJOH UIF TFTTJPO TFUUJOHT. " UZQF DPOWFSUFS GPS 2VJDL'*9/+ TFTTJPO *% TUSJOHT JT BMTP JODMVEFE. 5IF GPMMPXJOH FYBNQMF TIPXT B TJNQMF DPOGJHVSBUJPO PG BO BDDFQUPS BOE JOJUJBUPS TFTTJPO XJUI EFGBVMU TFUUJOHT GPS CPUI TFTTJPOT.
<!-- camel route --> <camelContext id="quickfixjContext" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="quickfix:example"/> <filter> <simple>${in.header.EventCategory} == 'AppMessageReceived'</simple> <to uri="log:test"/> </filter> </route> </camelContext> <!-- quickfix component --> <bean id="quickfix" class="org.apache.camel.component.quickfixj.QuickfixjComponent"> <property name="configurations"> <util:map> <entry key="example" value-ref="quickfixjConfiguration"/> </util:map> </property> <property name="messageFactory"> <bean class="org.apache.camel.component.quickfixj.QuickfixjSpringTest.CustomMessageFactory"/> </property> </bean> <!-- quickfix settings --> <bean id="quickfixjConfiguration" class="org.apache.camel.component.quickfixj.QuickfixjConfiguration"> <property name="defaultSettings">

866

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<util:map> <entry key="SocketConnectProtocol" value="VM_PIPE"/> <entry key="SocketAcceptProtocol" value="VM_PIPE"/> <entry key="UseDataDictionary" value="N"/> </util:map> </property> <property name="sessionSettings"> <util:map> <entry key="FIX.4.2:INITIATOR->ACCEPTOR"> <util:map> <entry key="ConnectionType" value="initiator"/> <entry key="SocketConnectHost" value="localhost"/> <entry key="SocketConnectPort" value="5000"/> </util:map> </entry> <entry key="FIX.4.2:ACCEPTOR->INITIATOR"> <util:map> <entry key="ConnectionType" value="acceptor"/> <entry key="SocketAcceptPort" value="5000"/> </util:map> </entry> </util:map> </property> </bean>

$U@BMQFLK E>KAIFKD 2VJDL'*9/+ CFIBWJPS DBO CF NPEJGJFE JG DFSUBJO FYDFQUJPOT BSF UISPXO EVSJOH QSPDFTTJOH PG B NFTTBHF. *G B RejectLogon FYDFQUJPO JT UISPXO XIJMF QSPDFTTJOH BO JODPNJOH MPHPO BENJOJTUSBUJWF NFTTBHF, UIFO UIF MPHPO XJMM CF SFKFDUFE. /PSNBMMZ, 2VJDL'*9/+ IBOEMFT UIF MPHPO QSPDFTT BVUPNBUJDBMMZ. )PXFWFS, TPNFUJNFT BO PVUHPJOH MPHPO NFTTBHF NVTU CF NPEJGJFE UP JODMVEF DSFEFOUJBMT SFRVJSFE CZ B '*9 DPVOUFSQBSUZ. *G UIF '*9 MPHPO NFTTBHF CPEZ JT NPEJGJFE XIFO TFOEJOH B MPHPO NFTTBHF (&WFOU$BUFHPSZ=AdminMessageSent UIF NPEJGJFE NFTTBHF XJMM CF TFOU UP UIF DPVOUFSQBSUZ. *U JT JNQPSUBOU UIBU UIF PVUHPJOH MPHPO NFTTBHF JT CFJOH QSPDFTTFE synchronously. *G JU JT QSPDFTTFE BTZODISPOPVTMZ (PO BOPUIFS UISFBE), UIF '*9 FOHJOF XJMM JNNFEJBUFMZ TFOE UIF VONPEJGJFE PVUHPJOH NFTTBHF XIFO JU'T DBMMCBDL NFUIPE SFUVSOT. %(7 2BNRBK@B -RJ?BO ,>K>DBJBKQ *G BO BQQMJDBUJPO FYDFQUJPO JT UISPXO EVSJOH synchronous FYDIBOHF QSPDFTTJOH, UIJT XJMM DBVTF 2VJDL'*9/+ UP OPU JODSFNFOU JODPNJOH '*9 NFTTBHF TFRVFODF OVNCFST BOE XJMM DBVTF B SFTFOE PG UIF DPVOUFSQBSUZ NFTTBHF. 5IJT '*9 QSPUPDPM CFIBWJPS JT QSJNBSJMZ JOUFOEFE UP IBOEMF transport FSSPST SBUIFS UIBO BQQMJDBUJPO FSSPST. 5IFSF BSF SJTLT BTTPDJBUFE XJUI VTJOH UIJT NFDIBOJTN UP IBOEMF BQQMJDBUJPO FSSPST. 5IF QSJNBSZ SJTL JT UIBU UIF NFTTBHF XJMM SFQFBUFEMZ DBVTF BQQMJDBUJPO FSSPST FBDI UJNF JU'T SF-SFDFJWFE. " CFUUFS TPMVUJPO JT UP QFSTJTU UIF JODPNJOH

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

867

NFTTBHF (EBUBCBTF, +.4 RVFVF) JNNFEJBUFMZ CFGPSF QSPDFTTJOH JU. 5IJT BMTP BMMPXT UIF BQQMJDBUJPO UP QSPDFTT NFTTBHFT BTZODISPOPVTMZ XJUIPVU MPTJOH NFTTBHFT XIFO FSSPST PDDVS. "MUIPVHI JU'T QPTTJCMF UP TFOE NFTTBHFT UP B '*9 TFTTJPO CFGPSF JU'T MPHHFE PO (UIF NFTTBHFT XJMM CF TFOU BU MPHPO UJNF), JU JT VTVBMMZ B CFUUFS QSBDUJDF UP XBJU VOUJM UIF TFTTJPO JT MPHHFE PO. 5IJT FMJNJOBUFT UIF SFRVJSFE TFRVFODF OVNCFS SFTZODISPOJ[BUJPO TUFQT BU MPHPO. 8BJUJOH GPS TFTTJPO MPHPO DBO CF EPOF CZ TFUUJOH VQ B SPVUF UIBU QSPDFTTFT UIF SessionLogon FWFOU DBUFHPSZ BOE TJHOBMT UIF BQQMJDBUJPO UP TUBSU TFOEJOH NFTTBHFT. 4FF UIF '*9 QSPUPDPM TQFDJGJDBUJPOT BOE UIF 2VJDL'*9/+ EPDVNFOUBUJPO GPS NPSF EFUBJMT BCPVU '*9 TFRVFODF OVNCFS NBOBHFNFOU. 1LRQB $U>JMIBP 4FWFSBM FYBNQMFT BSF JODMVEFE JO UIF 2VJDL'*9/+ DPNQPOFOU TPVSDF DPEF (UFTU TVCEJSFDUPSJFT). 0OF PG UIFTF FYBNQMFT JNQMFNFOUT B USJWBM USBEF FYDFDVUJPO TJNVMBUJPO. 5IF FYBNQMF EFGJOFT BO BQQMJDBUJPO DPNQPOFOU UIBU VTFT UIF 63* TDIFNF "USBEF-FYFDVUPS". 5IF GPMMPXJOH SPVUF SFDFJWFT NFTTBHFT GPS UIF USBEF FYFDVUPS TFTTJPO BOE QBTTFT BQQMJDBUJPO NFTTBHFT UP UIF USBEF FYFDVUPS DPNQPOFOU.
from("quickfix:examples/inprocess.cfg?sessionID=FIX.4.2:MARKET->TRADER").

filter(header(QuickfixjEndpoint.EVENT_CATEGORY_KEY).isEqualTo(QuickfixjEventCategory.AppMessageReceive to("trade-executor:market");

5IF USBEF FYFDVUPS DPNQPOFOU HFOFSBUFT NFTTBHFT UIBU BSF SPVUFE CBDL UP UIF USBEF TFTTJPO. 5IF TFTTJPO *% NVTU CF TFU JO UIF '*9 NFTTBHF JUTFMG TJODF OP TFTTJPO *% JT TQFDJGJFE JO UIF FOEQPJOU 63*.
from("trade-executor:market").to("quickfix:examples/inprocess.cfg");

5IF USBEFS TFTTJPO DPOTVNFT FYFDVUJPO SFQPSU NFTTBHFT GSPN UIF NBSLFU BOE QSPDFTTFT UIFN.
from("quickfix:examples/inprocess.cfg?sessionID=FIX.4.2:TRADER->MARKET"). filter(header(QuickfixjEndpoint.MESSAGE_TYPE_KEY).isEqualTo(MsgType.EXECUTION_REPORT)). bean(new MyTradeExecutionProcessor());

04("*%(7/) ".,/.-$-3 /1(.1 3. " ,$+ 2.5


5IF NRF@HCFU DPNQPOFOU JT BO JNQMFNFOUBUJPO PG UIF 2VJDL'*9/+ FOHJOF GPS +BWB . 5IJT FOHJOF BMMPXT UP DPOOFDU UP B '*9 TFSWFS XIJDI JT VTFE UP FYDIBOHF GJOBODJBM NFTTBHFT BDDPSEJOH UP '*9 QSPUPDPM TUBOEBSE. -LQB: 5IF DPNQPOFOU DBO CF VTFE UP TFOE/SFDFJWFT NFTTBHFT UP B '*9 TFSWFS.

868

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( CLOJ>Q
quickfix-server:config file quickfix-client:config file

8IFSF @LKCFD CFIB JT UIF MPDBUJPO (JO ZPVS DMBTTQBUI) PG UIF RVJDLGJY DPOGJHVSBUJPO GJMF VTFE UP DPOGJHVSF UIF FOHJOF BU UIF TUBSUVQ. -LQB: *OGPSNBUJPO BCPVU QBSBNFUFST BWBJMBCMF GPS RVJDLGJY DBO CF GPVOE PO 2VJDL'*9/+ XFC TJUF. 5IF RVJDLGJY-TFSWFS FOEQPJOU NVTU CF VTFE UP SFDFJWF GSPN '*9 TFSWFS '*9 NFTTBHFT BOE RVJDLGJY-DMJFOU FOEQPJOU JO UIF DBTF UIBU ZPV XBOU UP TFOE NFTTBHFT UP B '*9 HBUFXBZ. $U@E>KDB A>Q> CLOJ>Q 5IF 2VJDL'*9/+ FOHJOF JT MJLF $9' DPNQPOFOU B NFTTBHJOH CVT VTJOH .*/" BT QSPUPDPM MBZFS UP DSFBUF UIF TPDLFU DPOOFDUJPO XJUI UIF '*9 FOHJOF HBUFXBZ. 8IFO 2VJDL'*9/+ FOHJOF SFDFJWFT B NFTTBHF, UIFO JU DSFBUF B 2VJDL'JY..FTTBHF JOTUBODF XIJDI JT OFYU SFDFJWFE CZ UIF DBNFM FOEQPJOU. 5IJT PCKFDU JT B 'NBQQJOH PCKFDU' DSFBUFE GSPN B '*9 NFTTBHF GPSNBUUFE JOJUJBMMZ BT B DPMMFDUJPO PG LFZ WBMVF QBJST EBUB. :PV DBO VTF UIJT PCKFDU PS ZPV DBO VTF UIF NFUIPE 'UP4USJOH' UP SFUSJFWF UIF PSJHJOBM '*9 NFTTBHF. -LQB: "MUFSOBUJWFMZ, ZPV DBO VTF DBNFM CJOEZ EBUBGPSNBU UP USBOTGPSN UIF '*9 NFTTBHF JOUP ZPVS PXO KBWB 10+0 8IFO B NFTTBHF NVTU CF TFOE UP 2VJDL'JY, UIFO ZPV NVTU DSFBUF B 2VJDL'JY..FTTBHF JOTUBODF. 2>JMIBP %JSFDUJPO : UP '*9 HBUFXBZ
<route> <from uri="activemq:queue:fix"/> <bean ref="fixService" method="createFixMessage"/> // bean method in charge to transform message into a QuickFix.Message <to uri="quickfix-client:META-INF/quickfix/client.cfg"/> // Quickfix engine who will send the FIX messages to the gateway </route>

%JSFDUJPO : GSPN '*9 HBUFXBZ


<route> <from uri="quickfix-server:META-INF/quickfix/server.cfg"/> // QuickFix engine who will receive the message from FIX gateway <bean ref="fixService" method="parseFixMessage"/> // bean method parsing the QuickFix.Message

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

869

<to uri="uri="activemq:queue:fix"/>" </route>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

/1(-3$1 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.1 5IF MOFKQBO DPNQPOFOU QSPWJEFT B XBZ UP EJSFDU QBZMPBET PO B SPVUF UP B QSJOUFS. 0CWJPVTMZ UIF QBZMPBE IBT UP CF B GPSNBUUFE QJFDF PG QBZMPBE JO PSEFS GPS UIF DPNQPOFOU UP BQQSPQSJBUFMZ QSJOU JU. 5IF PCKFDUJWF JT UP CF BCMF UP EJSFDU TQFDJGJD QBZMPBET BT KPCT UP B MJOF QSJOUFS JO B DBNFM GMPX. 5IJT DPNQPOFOU POMZ TVQQPSUT B DBNFM QSPEVDFS FOEQPJOU. 5IF GVODUJPOBMJUZ BMMPXT GPS UIF QBZMPBE UP CF QSJOUFE PO B EFGBVMU QSJOUFS, OBNFE MPDBM, SFNPUF PS XJSFMFTTMZ MJOLFE QSJOUFS VTJOH UIF KBWBY QSJOUJOH "1* VOEFS UIF DPWFST. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-printer</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q 4JODF UIF 63* TDIFNF GPS B QSJOUFS IBT OPU CFFO TUBOEBSEJ[FE (UIF OFBSFTU UIJOH UP B TUBOEBSE CFJOH UIF *&5' QSJOU TUBOEBSE) BOE UIFSFGPSF OPU VOJGPSNMZ BQQMJFE CZ WFOEPST, XF IBWF DIPTFO "IMO" BT UIF TDIFNF.
lpr://localhost/default[?options] lpr://remotehost:port/path/to/printer[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

870

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.MQFLKP
->JB
mediaSize copies sides flavor mimeType mediaTray printerPrefix sendToPrinter

#BC>RIQ 5>IRB
MediaSizeName.NA_LETTER 1 Sides.ONE_SIDED DocFlavor.BYTE_ARRAY AUTOSENSE AUTOSENSE OVMM USVF

#BP@OFMQFLK
4FUT UIF TUBUJPOBSZ BT EFGJOFE CZ FOVNFSBUJPO TFUUJOHT JO UIF KBWBY.QSJOU.BUUSJCVUF.TUBOEBSE..FEJB4J[F/BNF "1*. 5IF EFGBVMU TFUUJOH JT UP VTF /PSUI "NFSJDBO -FUUFS TJ[FE TUBUJPOBSZ 4FUT OVNCFS PG DPQJFT CBTFE PO UIF KBWBY.QSJOU.BUUSJCVUF.TUBOEBSE.$PQJFT "1* 4FUT POF TJEFE PS UXP TJEFE QSJOUJOH CBTFE PO UIF KBWBY.QSJOU.BUUSJCVUF.TUBOEBSE.4JEFT "1* 4FUT %PD'MBWPS CBTFE PO UIF KBWBY.QSJOU.%PD'MBWPS "1* 4FUT NJNF5ZQFT TVQQPSUFE CZ UIF KBWBY.QSJOU.%PD'MBWPS "1* 4JODF ">JBI 2.11.U TFUT .FEJB5SBZ TVQQPSUFE CZ UIF KBWBY.QSJOU.%PD'MBWPS "1* 4JODF ">JBI 2.11.U TFUT UIF QSFGJY OBNF PG UIF QSJOUFS, JU JT VTFGVM XIFO UIF QSJOUFS OBNF JT OPU TUBSU XJUI //IPTUOBNF/QSJOUFS 4FUUJOH UIJT PQUJPO UP false QSFWFOUT TFOEJOH PG UIF QSJOU EBUB UP UIF QSJOUFS

2BKAFKD ,BPP>DBP QL > /OFKQBO

/OFKQBO /OLAR@BO
4FOEJOH EBUB UP UIF QSJOUFS JT WFSZ TUSBJHIUGPSXBSE BOE JOWPMWFT DSFBUJOH B QSPEVDFS FOEQPJOU UIBU DBO CF TFOU NFTTBHF FYDIBOHFT PO JO SPVUF. 4P>DB 2>JMIBP

$U>JMIB 1: /OFKQFKD QBUQ ?>PBA M>VIL>AP LK > #BC>RIQ MOFKQBO RPFKD IBQQBO PQ>QFLK>OV >KA LKB-PFABA JLAB
RouteBuilder builder = new RouteBuilder() { public void configure() { from(file://inputdir/?delete=true) .to("lpr://localhost/default?copies=2" + "&flavor=DocFlavor.INPUT_STREAM&" + "&mimeType=AUTOSENSE" + "&mediaSize=na-letter" + "&sides=one-sided") }};

$U>JMIB 2: /OFKQFKD &(% ?>PBA M>VIL>AP LK > 1BJLQB MOFKQBO RPFKD 4 PQ>QFLK>OV >KA LKB-PFABA JLAB
RouteBuilder builder = new RouteBuilder() { public void configure() {

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

871

from(file://inputdir/?delete=true) .to("lpr://remotehost/sales/salesprinter" + "?copies=2&sides=one-sided" + "&mimeType=GIF&mediaSize=iso-a4" + "&flavor=DocFlavor.INPUT_STREAM") }};

$U>JMIB 3: /OFKQFKD )/$& ?>PBA M>VIL>AP LK > 1BJLQB MOFKQBO RPFKD )>M>KBPB /LPQ@>OA PQ>QFLK>OV >KA LKB-PFABA JLAB
RouteBuilder builder = new RouteBuilder() { public void configure() { from(file://inputdir/?delete=true) .to("lpr://remotehost/sales/salesprinter" + "?copies=2&sides=one-sided" + "&mimeType=JPEG" + "&mediaSize=japanese-postcard" + "&flavor=DocFlavor.INPUT_STREAM") }};

/1./$13($2 ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.3 41( CLOJ>Q
properties:key[?options]

8IFSF HBV JT UIF LFZ GPS UIF QSPQFSUZ UP MPPLVQ .MQFLKP


->JB
cache locations ignoreMissingLocation propertyPrefix propertySuffix fallbackToUnaugmentedProperty

3VMB
boolean String boolean String String boolean

#BC>RIQ
true null false null null true

#BP@OFMQFLK
8IFUIFS PS OPU UP DBDIF MPBEFE QSPQFSUJFT. " MJTU PG MPDBUJPOT UP MPBE QSPQFSUJFT. :PV DBO VTF DPNNB UP TFQBSBUF NVMUJQMF MPDBUJPOT. 5IJT PQUJPO XJMM PWFSSJEF BOZ EFGBVMU MPDBUJPOT BOE LKIV VTF UIF MPDBUJPOT GSPN UIJT PQUJPO. ">JBI 2.10: 8IFUIFS UP TJMFOUMZ JHOPSF JG B MPDBUJPO DBOOPU CF MPDBUFE, TVDI BT B QSPQFSUJFT GJMF OPU GPVOE. ">JBI 2.9 0QUJPOBM QSFGJY QSFQFOEFE UP QSPQFSUZ OBNFT CFGPSF SFTPMVUJPO. ">JBI 2.9 0QUJPOBM TVGGJY BQQFOEFE UP QSPQFSUZ OBNFT CFGPSF SFTPMVUJPO. ">JBI 2.9 *G USVF, GJSTU BUUFNQU SFTPMVUJPO PG QSPQFSUZ OBNF BVHNFOUFE XJUI propertyPrefix BOE propertySuffix CFGPSF GBMMJOH CBDL UIF QMBJO QSPQFSUZ OBNF TQFDJGJFE. *G GBMTF, POMZ UIF BVHNFOUFE QSPQFSUZ OBNF JT TFBSDIFE.

872

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

prefixToken suffixToken

String String

\\ ^^

">JBI 2.9 5IF UPLFO UP JOEJDBUF UIF CFHJOOJOH PG B QSPQFSUZ UPLFO. ">JBI 2.9 5IF UPLFO UP JOEJDBUF UIF FOE PG B QSPQFSUZ UPLFO.

42(-& /1./$138/+ "$'.+#$1


S>FI>?IB >P LC ">JBI 2.3 $BNFM OPX QSPWJEFT B OFX PropertiesComponent JO @>JBI-@LOB XIJDI BMMPXT ZPV UP VTF QSPQFSUZ QMBDFIPMEFST XIFO EFGJOJOH $BNFM &OEQPJOU 63*T. 5IJT XPSLT NVDI MJLF ZPV XPVME EP JG VTJOH 4QSJOH'T <property-placeholder> UBH. )PXFWFS 4QSJOH IBWF B MJNJUBUJPO XIJDI QSFWFOUT 3SE QBSUZ GSBNFXPSLT UP MFWFSBHF 4QSJOH QSPQFSUZ QMBDFIPMEFST UP UIF GVMMFTU. 4FF NPSF BU )PX EP * VTF 4QSJOH 1SPQFSUZ 1MBDFIPMEFS XJUI $BNFM 9.-. 5IF QSPQFSUZ QMBDFIPMEFS JT HFOFSBMMZ JO VTF XIFO EPJOH: MPPLVQ PS DSFBUJOH FOEQPJOUT MPPLVQ PG CFBOT JO UIF 3FHJTUSZ BEEJUJPOBM TVQQPSUFE JO 4QSJOH 9.- (TFF CFMPX JO FYBNQMFT) VTJOH #MVFQSJOU 1SPQFSUZ1MBDFIPMEFS XJUI $BNFM 1SPQFSUJFT DPNQPOFOU 2VKQ>U 5IF TZOUBY UP VTF $BNFM'T QSPQFSUZ QMBDFIPMEFS JT UP VTF \\key^^ GPS FYBNQMF \\file.uri^^ XIFSF file.uri JT UIF QSPQFSUZ LFZ. :PV DBO VTF QSPQFSUZ QMBDFIPMEFST JO QBSUT PG UIF FOEQPJOU 63*'T XIJDI GPS FYBNQMF ZPV DBO VTF QMBDFIPMEFST GPS QBSBNFUFST JO UIF 63*T. /OLMBOQV1BPLISBO $BNFM QSPWJEFT B QMVHHBCMF NFDIBOJTN XIJDI BMMPXT 3SE QBSU UP QSPWJEF UIFJS PXO SFTPMWFS UP MPPLVQ QSPQFSUJFT. $BNFM QSPWJEFT B EFGBVMU JNQMFNFOUBUJPO org.apache.camel.component.properties.DefaultPropertiesResolver XIJDI JT DBQBCMF PG MPBEJOH QSPQFSUJFT GSPN UIF GJMF TZTUFN, DMBTTQBUI PS 3FHJTUSZ. :PV DBO QSFGJY UIF MPDBUJPOT XJUI FJUIFS: ref: ">JBI 2.4: UP MPPLVQ JO UIF 3FHJTUSZ file: UP MPBE UIF GSPN GJMF TZTUFN classpath: UP MPBE GSPN DMBTTQBUI (UIJT JT BMTP UIF EFGBVMU JG OP QSFGJY JT QSPWJEFE) blueprint: ">JBI 2.7: UP VTF B TQFDJGJD 04(J CMVFQSJOU QMBDFIPMEFS TFSWJDF #BCFKFKD IL@>QFLK 5IF PropertiesResolver OFFE UP LOPX B MPDBUJPO(T) XIFSF UP SFTPMWF UIF QSPQFSUJFT. :PV DBO EFGJOF 1 UP NBOZ MPDBUJPOT. *G ZPV EFGJOF UIF MPDBUJPO JO B TJOHMF 4USJOH QSPQFSUZ ZPV DBO TFQBSBUF NVMUJQMF MPDBUJPOT XJUI DPNNB TVDI BT:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

873

1BPLISFKD MOLMBOQV COLJ )>S> @LAB :PV DBO VTF UIF NFUIPE resolvePropertyPlaceholders PO UIF CamelContext UP SFTPMWF B QSPQFSUZ GSPN BOZ +BWB DPEF.

!OFADFKD 2MOFKD >KA ">JBI MOLMBOQV MI>@BELIABOP 'SPN $BNFM 2.10 POXBSET, ZPV DBO CSJEHF UIF 4QSJOH QSPQFSUZ QMBDFIPMEFS XJUI $BNFM, TFF GVSUIFS CFMPX GPS NPSF EFUBJMT.

pc.setLocation("com/mycompany/myprop.properties,com/mycompany/other.properties");

4PFKD PVPQBJ >KA BKSFOLKJBKQ S>OF>?IBP FK IL@>QFLKP


S>FI>?IB >P LC ">JBI 2.7 5IF MPDBUJPO OPX TVQQPSUT VTJOH QMBDFIPMEFST GPS +7. TZTUFN QSPQFSUJFT BOE 04 FOWJSPONFOUT WBSJBCMFT. 'PS FYBNQMF:
location=file:${karaf.home}/etc/foo.properties

*O UIF MPDBUJPO BCPWF XF EFGJOFE B MPDBUJPO VTJOH UIF GJMF TDIFNF VTJOH UIF +7. TZTUFN QSPQFSUZ XJUI LFZ karaf.home. 5P VTF BO 04 FOWJSPONFOU WBSJBCMF JOTUFBE ZPV XPVME IBWF UP QSFGJY XJUI FOW:
location=file:${env:APP_HOME}/etc/foo.properties

8IFSF APP_HOME JT BO 04 FOWJSPONFOU. :PV DBO IBWF NVMUJQMF QMBDFIPMEFST JO UIF TBNF MPDBUJPO, TVDI BT:
location=file:${env:APP_HOME}/etc/${prop.name}.properties

"LKCFDROFKD FK )>S> #2+ :PV IBWF UP DSFBUF BOE SFHJTUFS UIF PropertiesComponent VOEFS UIF OBNF properties TVDI BT:

874

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

PropertiesComponent pc = new PropertiesComponent(); pc.setLocation("classpath:com/mycompany/myprop.properties"); context.addComponent("properties", pc);

"LKCFDROFKD FK 2MOFKD 7,+ 4QSJOH 9.- PGGFST UXP WBSJBUJPOT UP DPOGJHVSF. :PV DBO EFGJOF B TQSJOH CFBO BT B PropertiesComponent XIJDI SFTFNCMFT UIF XBZ EPOF JO +BWB %4-. 0S ZPV DBO VTF UIF <propertyPlaceholder> UBH.
<bean id="properties" class="org.apache.camel.component.properties.PropertiesComponent"> <property name="location" value="classpath:com/mycompany/myprop.properties"/> </bean>

6TJOH UIF <propertyPlaceholder> UBH NBLFT UIF DPOGJHVSBUJPO B CJU NPSF GSFTI TVDI BT:
<camelContext ...> <propertyPlaceholder id="properties" location="com/mycompany/myprop.properties"/> </camelContext>

4PFKD > /OLMBOQFBP COLJ QEB 1BDFPQOV S>FI>?IB >P LC ">JBI 2.4 'PS FYBNQMF JO 04(J ZPV NBZ XBOU UP FYQPTF B TFSWJDF XIJDI SFUVSOT UIF QSPQFSUJFT BT B java.util.Properties PCKFDU. 5IFO ZPV DPVME TFUVQ UIF 1SPQFSUJFT DPNQPOFOU BT GPMMPXT:
<propertyPlaceholder id="properties" location="ref:myProperties"/>

8IFSF myProperties JT UIF JE UP VTF GPS MPPLVQ JO UIF 04(J SFHJTUSZ. /PUJDF XF VTF UIF ref: QSFGJY UP UFMM $BNFM UIBU JU TIPVME MPPLVQ UIF QSPQFSUJFT GPS UIF 3FHJTUSZ. $U>JMIBP RPFKD MOLMBOQFBP @LJMLKBKQ 8IFO VTJOH QSPQFSUZ QMBDFIPMEFST JO UIF FOEQPJOU 63*T ZPV DBO FJUIFS VTF UIF properties: DPNQPOFOU PS EFGJOF UIF QMBDFIPMEFST EJSFDUMZ JO UIF 63*. 8F XJMM TIPX FYBNQMF PG CPUI DBTFT, TUBSUJOH XJUI UIF GPSNFS.
// properties cool.end=mock:result

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

875

2MB@FCVFKD QEB @>@EB LMQFLK FKPFAB 7,+ $BNFM 2.10 POXBSET TVQQPSUT TQFDJGZJOH B WBMVF GPS UIF DBDIF PQUJPO CPUI JOTJEF UIF 4QSJOH BT XFMM BT UIF #MVFQSJOU 9.-.

// route from("direct:start").to("properties:{{cool.end}}");

:PV DBO BMTP VTF QMBDFIPMEFST BT B QBSU PG UIF FOEQPJOU VSJ:


// properties cool.foo=result // route from("direct:start").to("properties:mock:{{cool.foo}}");

*O UIF FYBNQMF BCPWF UIF UP FOEQPJOU XJMM CF SFTPMWFE UP mock:result. :PV DBO BMTP IBWF QSPQFSUJFT XJUI SFGFS UP FBDI PUIFS TVDI BT:
// properties cool.foo=result cool.concat=mock:{{cool.foo}} // route from("direct:start").to("properties:mock:{{cool.concat}}");

/PUJDF IPX cool.concat SFGFS UP BOPUIFS QSPQFSUZ. 5IF properties: DPNQPOFOU BMTP PGGFST ZPV UP PWFSSJEF BOE QSPWJEF B MPDBUJPO JO UIF HJWFO VSJ VTJOH UIF locations PQUJPO:
from("direct:start").to("properties:bar.end?locations=com/mycompany/ bar.properties");

$U>JMIBP :PV DBO BMTP VTF QSPQFSUZ QMBDFIPMEFST EJSFDUMZ JO UIF FOEQPJOU VSJT XJUIPVU IBWJOH UP VTF properties:.
// properties cool.foo=result

876

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

// route from("direct:start").to("mock:{{cool.foo}}");

"OE ZPV DBO VTF UIFN JO NVMUJQMF XIFSFWFS ZPV XBOU UIFN:
// properties cool.start=direct:start cool.showid=true cool.result=result // route from("{{cool.start}}") .to("log:{{cool.start}}?showBodyType=false&showExchangeId={{cool.showid}}") .to("mock:{{cool.result}}");

:PV DBO BMTP ZPVS QSPQFSUZ QMBDFIPMEFST XIFO VTJOH 1SPEVDFS5FNQMBUF GPS FYBNQMF:
template.sendBody("{{cool.start}}", "Hello World");

$U>JMIB TFQE 2FJMIB I>KDR>DB 5IF 4JNQMF MBOHVBHF OPX BMTP TVQQPSU VTJOH QSPQFSUZ QMBDFIPMEFST, GPS FYBNQMF JO UIF SPVUF CFMPX:
// properties cheese.quote=Camel rocks // route from("direct:start") .transform().simple("Hi ${body} do you think ${properties:cheese.quote}?");

:PV DBO BMTP TQFDJGZ UIF MPDBUJPO JO UIF 4JNQMF MBOHVBHF GPS FYBNQMF:
// bar.properties bar.quote=Beer tastes good // route from("direct:start") .transform().simple("Hi ${body}. ${properties:com/mycompany/ bar.properties:bar.quote}.");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

877

AAFQFLK>I MOLMBOQV MI>@BELIABO PRMMLOQBA FK 2MOFKD 7,+ 5IF QSPQFSUZ QMBDFIPMEFST JT BMTP TVQQPSUFE JO NBOZ PG UIF $BNFM 4QSJOH 9.- UBHT TVDI BT <package>, <packageScan>, <contextScan>, <jmxAgent>, <endpoint>, <routeBuilder>, <proxy> BOE UIF PUIFST. 5IF FYBNQMF CFMPX IBT QSPQFSUZ QMBDFIPMEFS JO UIF <KNY"HFOU> UBH:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="org/apache/camel/spring/ jmx.properties"/> <!-- we can use propery placeholders when we define the JMX agent --> <jmxAgent id="agent" registryPort="{{myjmx.port}}" disabled="{{myjmx.disabled}}" usePlatformMBeanServer="{{myjmx.usePlatform}}" createConnector="true" statisticsLevel="RoutesOnly"/> <route id="foo" autoStartup="false"> <from uri="seda:start"/> <to uri="mock:result"/> </route> </camelContext>

:PV DBO BMTP EFGJOF QSPQFSUZ QMBDFIPMEFST JO UIF WBSJPVT BUUSJCVUFT PO UIF <DBNFM$POUFYU> UBH TVDI BT trace BT TIPXO IFSF:
<camelContext trace="{{foo.trace}}" xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="org/apache/camel/spring/processor/ myprop.properties"/> <template id="camelTemplate" defaultEndpoint="{{foo.cool}}"/> <route> <from uri="direct:start"/> <setHeader headerName="{{foo.header}}"> <simple>${in.body} World!</simple> </setHeader> <to uri="mock:result"/> </route> </camelContext>

.SBOOFAFKD > MOLMBOQV PBQQFKD RPFKD > )5, 2VPQBJ /OLMBOQV S>FI>?IB >P LC ">JBI 2.5 *U JT QPTTJCMF UP PWFSSJEF B QSPQFSUZ WBMVF BU SVOUJNF VTJOH B +7. 4ZTUFN QSPQFSUZ XJUIPVU UIF OFFE UP SFTUBSU UIF BQQMJDBUJPO UP QJDL VQ UIF DIBOHF. 5IJT NBZ BMTP CF BDDPNQMJTIFE GSPN UIF DPNNBOE MJOF CZ DSFBUJOH B +7. 4ZTUFN QSPQFSUZ PG UIF TBNF OBNF BT UIF QSPQFSUZ JU SFQMBDFT XJUI B OFX WBMVF. "O FYBNQMF PG UIJT JT HJWFO CFMPX

878

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class); pc.setCache(false); System.setProperty("cool.end", "mock:override"); System.setProperty("cool.result", "override"); context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:start").to("properties:cool.end"); from("direct:foo").to("properties:mock:{{cool.result}}"); } }); context.start(); getMockEndpoint("mock:override").expectedMessageCount(2); template.sendBody("direct:start", "Hello World"); template.sendBody("direct:foo", "Hello Foo"); System.clearProperty("cool.end"); System.clearProperty("cool.result"); assertMockEndpointsSatisfied();

4PFKD MOLMBOQV MI>@BELIABOP CLO >KV HFKA LC >QQOF?RQB FK QEB 7,+ #2+ S>FI>?IB >P LC ">JBI 2.7 1SFWJPVTMZ JU XBT POMZ UIF xs:string UZQF BUUSJCVUFT JO UIF 9.- %4- UIBU TVQQPSU QMBDFIPMEFST. 'PS FYBNQMF PGUFO B UJNFPVU BUUSJCVUF XPVME CF B xs:int UZQF BOE UIVT ZPV DBOOPU TFU B TUSJOH WBMVF BT UIF QMBDFIPMEFS LFZ. 5IJT JT OPX QPTTJCMF GSPN $BNFM 2.7 POXBSET VTJOH B TQFDJBM QMBDFIPMEFS OBNFTQBDF. *O UIF FYBNQMF CFMPX XF VTF UIF prop QSFGJY GPS UIF OBNFTQBDF http://camel.apache.org/schema/placeholder CZ XIJDI XF DBO VTF UIF prop QSFGJY JO UIF BUUSJCVUFT JO UIF 9.- %4-T. /PUJDF IPX XF VTF UIBU JO UIF .VMUJDBTU UP JOEJDBUF UIBU UIF PQUJPO stopOnException TIPVME CF UIF WBMVF PG UIF QMBDFIPMEFS XJUI UIF LFZ "TUPQ".
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:prop="http://camel.apache.org/schema/placeholder" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd ">

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

879

<!-- Notice in the declaration above, we have defined the prop prefix as the Camel placeholder namespace --> <bean id="damn" class="java.lang.IllegalArgumentException"> <constructor-arg index="0" value="Damn"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <propertyPlaceholder id="properties" location="classpath:org/apache/camel/component/properties/ myprop.properties" xmlns="http://camel.apache.org/schema/spring"/> <route> <from uri="direct:start"/> <!-- use prop namespace, to define a property placeholder, which maps to option stopOnException={{stop}} --> <multicast prop:stopOnException="stop"> <to uri="mock:a"/> <throwException ref="damn"/> <to uri="mock:b"/> </multicast> </route> </camelContext> </beans>

*O PVS QSPQFSUJFT GJMF XF IBWF UIF WBMVF EFGJOFE BT


stop=true

4PFKD MOLMBOQV MI>@BELIABO FK QEB )>S> #2+ S>FI>?IB >P LC ">JBI 2.7 -JLFXJTF XF IBWF BEEFE TVQQPSU GPS EFGJOJOH QMBDFIPMEFST JO UIF +BWB %4- VTJOH UIF OFX placeholder %4- BT TIPXO JO UIF GPMMPXJOH FRVJWBMFOU FYBNQMF:
from("direct:start") // use a property placeholder for the option stopOnException on the Multicast EIP // which should have the value of {{stop}} key being looked up in the properties file .multicast().placeholder("stopOnException", "stop") .to("mock:a").throwException(new IllegalAccessException("Damn")).to("mock:b");

880

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD !IRBMOFKQ MOLMBOQV MI>@BELIABO TFQE ">JBI OLRQBP S>FI>?IB >P LC ">JBI 2.7 $BNFM TVQQPSUT #MVFQSJOU XIJDI BMTP PGGFST B QSPQFSUZ QMBDFIPMEFS TFSWJDF. $BNFM TVQQPSUT DPOWFOUJPO PWFS DPOGJHVSBUJPO, TP BMM ZPV IBWF UP EP JT UP EFGJOF UIF 04(J #MVFQSJOU QSPQFSUZ QMBDFIPMEFS JO UIF 9.- GJMF BT TIPXO CFMPX:
Listing 1. Using OSGi blueprint property placeholders in Camel routes
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/ blueprint/v1.0.0/blueprint.xsd"> <!-- OSGI blueprint property placeholder --> <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint"> <!-- list some properties for this test --> <cm:default-properties> <cm:property name="result" value="mock:result"/> </cm:default-properties> </cm:property-placeholder> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <!-- in the route we can use {{ }} placeholders which will lookup in blueprint as Camel will auto detect the OSGi blueprint property placeholder and use it --> <route> <from uri="direct:start"/> <to uri="mock:foo"/> <to uri="{{result}}"/> </route> </camelContext> </blueprint>

#Z EFGBVMU $BNFM EFUFDUT BOE VTFT 04(J CMVFQSJOU QSPQFSUZ QMBDFIPMEFS TFSWJDF. :PV DBO EJTBCMF UIJT CZ TFUUJOH UIF BUUSJCVUF useBlueprintPropertyResolver UP GBMTF PO UIF <camelContext> EFGJOJUJPO. :PV DBO BMTP FYQMJDJU SFGFS UP B TQFDJGJD 04(J CMVFQSJOU QSPQFSUZ QMBDFIPMEFS CZ JUT JE. 'PS UIBU ZPV OFFE UP VTF UIF $BNFM'T <QSPQFSUZ1MBDFIPMEFS> BT TIPXO JO UIF FYBNQMF CFMPX:
Listing 1. Explicit referring to a OSGi blueprint placeholder in Camel
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xsi:schemaLocation=" http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

881

?LRQ MI>@BELIABO PVKQ>UBP /PUJDF IPX XF DBO VTF UIF $BNFM TZOUBY GPS QMBDFIPMEFST \\ ^^ JO UIF $BNFM SPVUF, XIJDI XJMM MPPLVQ UIF WBMVF GSPN 04(J CMVFQSJOU. 5IF CMVFQSJOU TZOUBY GPS QMBDFIPMEFST JT $\ ^. 4P PVUTJEF UIF <DBNFM$POUFYU> ZPV NVTU VTF UIF $\ ^ TZOUBY. 8IFSF BT JOTJEF <DBNFM$POUFYU> ZPV NVTU VTF \\ ^^ TZOUBY. 04(J CMVFQSJOU BMMPXT ZPV UP DPOGJHVSF UIF TZOUBY, TP ZPV DBO BDUVBMMZ BMJHO UIPTF JG ZPV XBOU.

blueprint/v1.0.0/blueprint.xsd"> <!-- OSGI blueprint property placeholder --> <cm:property-placeholder id="myblueprint.placeholder" persistent-id="camel.blueprint"> <!-- list some properties for this test --> <cm:default-properties> <cm:property name="prefix.result" value="mock:result"/> </cm:default-properties> </cm:property-placeholder> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <!-- using Camel properties component and refer to the blueprint property placeholder by its id --> <propertyPlaceholder id="properties" location="blueprint:myblueprint.placeholder" prefixToken="[[" suffixToken="]]" propertyPrefix="prefix."/> <!-- in the route we can use {{ }} placeholders which will lookup in blueprint --> <route> <from uri="direct:start"/> <to uri="mock:foo"/> <to uri="[[result]]"/> </route> </camelContext> </blueprint>

/PUJDF IPX XF VTF UIF blueprint TDIFNF UP SFGFS UP UIF 04(J CMVFQSJOU QMBDFIPMEFS CZ JUT JE. 5IJT BMMPXT ZPV UP NJY BOE NBUDI, GPS FYBNQMF ZPV DBO BMTP IBWF BEEJUJPOBM TDIFNFT JO UIF MPDBUJPO. 'PS FYBNQMF UP MPBE B GJMF GSPN UIF DMBTTQBUI ZPV DBO EP:
location="blueprint:myblueprint.placeholder,classpath:myproperties.properties"

882

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

&BDI MPDBUJPO JT TFQBSBUFE CZ DPNNB.

.SBOOFAFKD !IRBMOFKQ MOLMBOQV MI>@BELIABOP LRQPFAB ">JBI"LKQBUQ


S>FI>?IB >P LC ">JBI 2.10.4 8IFO VTJOH #MVFQSJOU QSPQFSUZ QMBDFIPMEFS JO UIF #MVFQSJOU 9.- GJMF, ZPV DBO EFDMBSF UIF QSPQFSUJFT EJSFDUMZ JO UIF 9.- GJMF BT TIPXO CFMPX:
<!-- blueprint property placeholders --> <cm:property-placeholder persistent-id="my-placeholders"> <cm:default-properties> <cm:property name="greeting" value="Hello"/> <cm:property name="destination" value="mock:result"/> </cm:default-properties> </cm:property-placeholder> <!-- a bean that uses a blueprint property placeholder --> <bean id="myCoolBean" class="org.apache.camel.test.blueprint.MyCoolBean"> <property name="say" value="${greeting}"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="direct:start"/> <bean ref="myCoolBean" method="saySomething"/> <to uri="{{destination}}"/> </route> </camelContext>

/PUJDF UIBU XF IBWF B <CFBO> XIJDI SFGFST UP POF PG UIF QSPQFSUJFT. "OE JO UIF $BNFM SPVUF XF SFGFS UP UIF PUIFS VTJOH UIF \\ ^^ OPUBUJPO. /PX JG ZPV XBOU UP PWFSSJEF UIFTF #MVFQSJOU QSPQFSUJFT GSPN BO VOJU UFTU, ZPV DBO EP UIJT BT TIPXO CFMPX:
@Override protected String useOverridePropertiesWithConfigAdmin(Dictionary props) { // add the properties we want to override props.put("greeting", "Bye"); // return the PID of the config-admin we are using in the blueprint xml file return "my-placeholders"; }

5P EP UIJT XF PWFSSJEF BOE JNQMFNFOU UIF useOverridePropertiesWithConfigAdmin NFUIPE. 8F DBO UIFO QVU UIF QSPQFSUJFT

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

883

XF XBOU UP PWFSSJEF PO UIF HJWFO QSPQT QBSBNFUFS. "OE UIF SFUVSO WBMVF JRPQ CF UIF QFSTJTUFODF-JE PG UIF <DN:QSPQFSUZ-QMBDFIPMEFS> UBH, XIJDI ZPV EFGJOF JO UIF CMVFQSJOU 9.GJMF.

4PFKD .@CD LO .MOLMBOQFBP CFIB CLO !IRBMOFKQ MOLMBOQV MI>@BELIABOP


S>FI>?IB >P LC ">JBI 2.10.4 8IFO VTJOH #MVFQSJOU QSPQFSUZ QMBDFIPMEFS JO UIF #MVFQSJOU 9.- GJMF, ZPV DBO EFDMBSF UIF QSPQFSUJFT JO B .QSPQFSUJFT PS .DGH GJMF. *G ZPV VTF "QBDIF 4FSWJF.JY / ,BSBG UIFO UIJT DPOUBJOFS IBT B DPOWFOUJPO UIBU JU MPBET UIF QSPQFSUJFT GSPN B GJMF JO UIF FUD EJSFDUPSZ XJUI UIF OBNJOH FUD/QJE.DGH, XIFSF QJE JT UIF QFSTJTUFODF-JE. 'PS FYBNQMF JO UIF CMVFQSJOU 9.- GJMF XF IBWF UIF QFSTJTUFODF-JE="TUVGG", XIJDI NFBO JU XJMM MPBE UIF DPOGJHVSBUJPO GJMF BT FUD/TUVGG.DGH.
<!-- blueprint property placeholders, that will use etc/stuff.cfg as the properties file --> <cm:property-placeholder persistent-id="stuff"/> <!-- a bean that uses a blueprint property placeholder --> <bean id="myCoolBean" class="org.apache.camel.test.blueprint.MyCoolBean"> <property name="say" value="${greeting}"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="direct:start"/> <bean ref="myCoolBean" method="saySomething"/> <to uri="mock:result"/> </route> </camelContext>

/PX JG ZPV XBOU UP VOJU UFTU UIJT CMVFQSJOU 9.- GJMF, UIFO ZPV DBO PWFSSJEF UIF loadConfigAdminConfigurationFile BOE UFMM $BNFM XIJDI GJMF UP MPBE BT TIPXO CFMPX:
@Override protected String[] loadConfigAdminConfigurationFile() { // String[0] = tell Camel the path of the .cfg file to use for OSGi ConfigAdmin in the blueprint XML file // String[1] = tell Camel the persistence-id of the cm:property-placeholder in the blueprint XML file return new String[]{"src/test/resources/etc/stuff.cfg", "stuff"}; }

884

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

/PUJDF UIBU UIJT NFUIPE SFRVJSFT UP SFUVSO B 4USJOH<> XJUI 2 WBMVFT. 5IF 1TU WBMVF JT UIF QBUI GPS UIF DPOGJHVSBUJPO GJMF UP MPBE. 5IF 2OE WBMVF JT UIF QFSTJTUFODF-JE PG UIF <DN:QSPQFSUZ-QMBDFIPMEFS> UBH. 5IF TUVGG.DGH GJMF JT KVTU B QMBJO QSPQFSUJFT GJMF XJUI UIF QSPQFSUZ QMBDFIPMEFST TVDI BT:
## this is a comment greeting=Bye

4PFKD .@CD CFIB >KA LSBOOFAFKD MOLMBOQFBP CLO !IRBMOFKQ MOLMBOQV MI>@BELIABOP
:PV DBO EP CPUI BT XFMM. )FSF JT B DPNQMFUF FYBNQMF. 'JSTU XF IBWF UIF #MVFQSJOU 9.- GJMF:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0" xsi:schemaLocation=" http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0 http://aries.apache.org/schemas/blueprint-cm/blueprint-cm-1.0.0.xsd http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/ blueprint/v1.0.0/blueprint.xsd"> <!-- blueprint property placeholders, that will use etc/stuff.cfg as the properties file --> <cm:property-placeholder persistent-id="stuff"/> <!-- a bean that uses a blueprint property placeholder --> <bean id="myCoolBean" class="org.apache.camel.test.blueprint.MyCoolBean"> <property name="say" value="${greeting}"/> <property name="echo" value="${echo}"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/blueprint"> <route> <from uri="direct:start"/> <bean ref="myCoolBean" method="saySomething"/> <to uri="{{destination}}"/> <bean ref="myCoolBean" method="echoSomething"/> <to uri="{{destination}}"/> </route> </camelContext> </blueprint>

"OE JO UIF VOJU UFTU DMBTT XF EP BT GPMMPXT:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

885

/** * This example will load a Blueprint .cfdg file, and also override its property placeholders from this unit test * source code directly. */ public class ConfigAdminLoadConfigurationFileAndOverrideTest extends CamelBlueprintTestSupport { @Override protected String getBlueprintDescriptor() { // which blueprint XML file to use for this test return "org/apache/camel/test/blueprint/configadmin-loadfileoverride.xml"; } @Override protected String[] loadConfigAdminConfigurationFile() { // which .cfg file to use, and the name of the persistence-id return new String[]{"src/test/resources/etc/stuff.cfg", "stuff"}; } @Override protected String useOverridePropertiesWithConfigAdmin(Dictionary props) throws Exception { // override / add extra properties props.put("destination", "mock:extra"); // return the persistence-id to use return "stuff"; } @Test public void testConfigAdmin() throws Exception { // regular unit test method getMockEndpoint("mock:extra").expectedBodiesReceived("Bye World", "Yay Bye WorldYay Bye World"); template.sendBody("direct:start", "World"); assertMockEndpointsSatisfied(); } }

"OE UIF etc/stuff.cfg DPOGJHVSBUJPO GJMF DPOUBJOT


greeting=Bye echo=Yay destination=mock:result

886

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

!OFADFKD 2MOFKD >KA ">JBI MOLMBOQV MI>@BELIABOP S>FI>?IB >P LC ">JBI 2.10 5IF 4QSJOH 'SBNFXPSL EPFT OPU BMMPX 3SE QBSUZ GSBNFXPSLT TVDI BT "QBDIF $BNFM UP TFBNMFTT IPPL JOUP UIF 4QSJOH QSPQFSUZ QMBDFIPMEFS NFDIBOJTN. )PXFWFS ZPV DBO FBTJMZ CSJEHF 4QSJOH BOE $BNFM CZ EFDMBSJOH B 4QSJOH CFBO XJUI UIF UZQF org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer, XIJDI JT B 4QSJOH org.springframework.beans.factory.config.PropertyPlaceholderConfigurer UZQF. 5P CSJEHF 4QSJOH BOE $BNFM ZPV NVTU EFGJOF B TJOHMF CFBO BT TIPXO CFMPX:
Listing 1. Bridging Spring and Camel property placeholders
<!-- bridge spring property placeholder with Camel --> <!-- you must NOT use the <context:property-placeholder at the same time, only this bridge bean --> <bean id="bridgePropertyPlaceholder" class="org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer"> <property name="location" value="classpath:org/apache/camel/component/properties/ cheese.properties"/> </bean>

:PV JRPQ KLQ VTF UIF TQSJOH <DPOUFYU:QSPQFSUZ-QMBDFIPMEFS> OBNFTQBDF BU UIF TBNF UJNF; UIJT JT OPU QPTTJCMF. "GUFS EFDMBSJOH UIJT CFBO, ZPV DBO EFGJOF QSPQFSUZ QMBDFIPMEFST VTJOH CPUI UIF 4QSJOH TUZMF, BOE UIF $BNFM TUZMF XJUIJO UIF <DBNFM$POUFYU> UBH BT TIPXO CFMPX:
Listing 1. Using bridge property placeholders
<!-- a bean that uses Spring property placeholder --> <!-- the ${hi} is a spring property placeholder --> <bean id="hello" class="org.apache.camel.component.properties.HelloBean"> <property name="greeting" value="${hi}"/> </bean> <camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- in this route we use Camels property placeholder {{ }} style --> <route> <from uri="direct:{{cool.bar}}"/> <bean ref="hello"/> <to uri="{{cool.end}}"/> </route> </camelContext>

/PUJDF IPX UIF IFMMP CFBO JT VTJOH QVSF 4QSJOH QSPQFSUZ QMBDFIPMEFST VTJOH UIF $\ ^ OPUBUJPO. "OE JO UIF $BNFM SPVUFT XF VTF UIF $BNFM QMBDFIPMEFS OPUBUJPO XJUI \\ ^^.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

887

.SBOOFAFKD MOLMBOQFBP COLJ ">JBI QBPQ HFQ S>FI>?IB >P LC ">JBI 2.10 8IFO 5FTUJOH XJUI $BNFM BOE VTJOH UIF 1SPQFSUJFT DPNQPOFOU, ZPV NBZ XBOU UP CF BCMF UP QSPWJEF UIF QSPQFSUJFT UP CF VTFE GSPN EJSFDUMZ XJUIJO UIF VOJU UFTU TPVSDF DPEF. 5IJT JT OPX QPTTJCMF GSPN $BNFM 2.10 POXBSET, BT UIF $BNFM UFTU LJUT, FH CamelTestSupport DMBTT PGGFST UIF GPMMPXJOH NFUIPET VTF0WFSSJEF1SPQFSUJFT8JUI1SPQFSUJFT$PNQPOFOU JHOPSF.JTTJOH-PDBUJPO8JUI1SPQFSUJFT$PNQPOFOU 4P GPS FYBNQMF JO ZPVS VOJU UFTU DMBTTFT, ZPV DBO PWFSSJEF UIF useOverridePropertiesWithPropertiesComponent NFUIPE BOE SFUVSO B java.util.Properties UIBU DPOUBJOT UIF QSPQFSUJFT XIJDI TIPVME CF QSFGFSSFE UP CF VTFE.
Listing 1. Providing properties from within unit test source
// override this method to provide our custom properties we use in this unit test @Override protected Properties useOverridePropertiesWithPropertiesComponent() { Properties extra = new Properties(); extra.put("destination", "mock:extra"); extra.put("greeting", "Bye"); return extra; }

5IJT DBO CF EPOF GSPN BOZ PG UIF $BNFM 5FTU LJUT, TVDI BT DBNFM-UFTU, DBNFM-UFTU-TQSJOH, BOE DBNFM-UFTU-CMVFQSJOU. 5IF ignoreMissingLocationWithPropertiesComponent DBO CF VTFE UP JOTUSVDU $BNFM UP JHOPSF BOZ MPDBUJPOT XIJDI XBT OPU EJTDPWFSBCMF, GPS FYBNQMF JG ZPV SVO UIF VOJU UFTU, JO BO FOWJSPONFOU UIBU EPFT OPU IBWF BDDFTT UP UIF MPDBUJPO PG UIF QSPQFSUJFT. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE +BTZQU GPS VTJOH FODSZQUFE WBMVFT (FH QBTTXPSET) JO UIF QSPQFSUJFT

1$% ".,/.-$-3
5IF OBC: DPNQPOFOU JT VTFE GPS MPPLVQ PG FYJTUJOH FOEQPJOUT CPVOE JO UIF 3FHJTUSZ.

888

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( CLOJ>Q
ref:someName

8IFSF PLJB->JB JT UIF OBNF PG BO FOEQPJOU JO UIF 3FHJTUSZ (VTVBMMZ, CVU OPU BMXBZT, UIF 4QSJOH SFHJTUSZ). *G ZPV BSF VTJOH UIF 4QSJOH SFHJTUSZ, someName XPVME CF UIF CFBO *% PG BO FOEQPJOU JO UIF 4QSJOH SFHJTUSZ. 1RKQFJB ILLHRM 5IJT DPNQPOFOU DBO CF VTFE XIFO ZPV OFFE EZOBNJD EJTDPWFSZ PG FOEQPJOUT JO UIF 3FHJTUSZ XIFSF ZPV DBO DPNQVUF UIF 63* BU SVOUJNF. 5IFO ZPV DBO MPPL VQ UIF FOEQPJOU VTJOH UIF GPMMPXJOH DPEF:
// lookup the endpoint String myEndpointRef = "bigspenderOrder"; Endpoint endpoint = context.getEndpoint("ref:" + myEndpointRef); Producer producer = endpoint.createProducer(); Exchange exchange = producer.createExchange(); exchange.getIn().setBody(payloadToSend); // send the exchange producer.process(exchange); ...

"OE ZPV DPVME IBWF B MJTU PG FOEQPJOUT EFGJOFE JO UIF 3FHJTUSZ TVDI BT:
<camelContext id="camel" xmlns="http://activemq.apache.org/camel/schema/spring"> <endpoint id="normalOrder" uri="activemq:order.slow"/> <endpoint id="bigspenderOrder" uri="activemq:order.high"/> ... </camelContext>

2>JMIB *O UIF TBNQMF CFMPX XF VTF UIF ref: JO UIF 63* UP SFGFSFODF UIF FOEQPJOU XJUI UIF TQSJOH *%, endpoint2:
<bean id="mybean" class="org.apache.camel.spring.example.DummyBean"> <property name="endpoint" ref="endpoint1"/> </bean> <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <jmxAgent id="agent" disabled="true"/> <endpoint id="endpoint1" uri="direct:start"/> <endpoint id="endpoint2" uri="mock:end"/>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

889

<route> <from ref="endpoint1"/> <to uri="ref:endpoint2"/> </route> </camelContext>

:PV DPVME, PG DPVSTF, IBWF VTFE UIF ref BUUSJCVUF JOTUFBE:


<to ref="endpoint2"/>

8IJDI JT UIF NPSF DPNNPO XBZ UP XSJUF JU. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

1$23+$3 ".,/.-$-3
5IF 1BPQIBQ DPNQPOFOU QSPWJEFT 3FTUMFU CBTFE FOEQPJOUT GPS DPOTVNJOH BOE QSPEVDJOH 3&45GVM SFTPVSDFT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-restlet</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
restlet:restletUrl[?options]

'PSNBU PG SFTUMFU6SM:
protocol://hostname[:port][/resourcePattern]

890

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

3FTUMFU QSPNPUFT EFDPVQMJOH PG QSPUPDPM BOE BQQMJDBUJPO DPODFSOT. 5IF SFGFSFODF JNQMFNFOUBUJPO PG 3FTUMFU &OHJOF TVQQPSUT B OVNCFS PG QSPUPDPMT. )PXFWFS, XF IBWF UFTUFE UIF )551 QSPUPDPM POMZ. 5IF EFGBVMU QPSU JT QPSU 80. 8F EP OPU BVUPNBUJDBMMZ TXJUDI EFGBVMU QPSU CBTFE PO UIF QSPUPDPM ZFU. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
headerFilterStrategy=#refName

#BC>RIQ 5>IRB
"O JOTUBODF PG RestletHeaderFilterStrategy "O JOTUBODF PG DefaultRestletBinding GET

#BP@OFMQFLK
6TF UIF # OPUBUJPO (headerFilterStrategy=#refName) UP SFGFSFODF B IFBEFS GJMUFS TUSBUFHZ JO UIF $BNFM 3FHJTUSZ. 5IF TUSBUFHZ XJMM CF QMVHHFE JOUP UIF SFTUMFU CJOEJOH JG JU JT HeaderFilterStrategyAware. 5IF CFBO *% PG B RestletBinding PCKFDU JO UIF $BNFM 3FHJTUSZ. 0O B QSPEVDFS FOEQPJOU, TQFDJGJFT UIF SFRVFTU NFUIPE UP VTF. 0O B DPOTVNFS FOEQPJOU, TQFDJGJFT UIBU UIF FOEQPJOU DPOTVNFT POMZ restletMethod SFRVFTUT. 5IF TUSJOH WBMVF JT DPOWFSUFE UP PSH.SFTUMFU.EBUB..FUIPE CZ UIF Method.valueOf(String) NFUIPE. "LKPRJBO LKIV 4QFDJGZ POF PS NPSF NFUIPET TFQBSBUFE CZ DPNNBT (F.H. restletMethods=post,put) UP CF TFSWJDFE CZ B SFTUMFU DPOTVNFS FOEQPJOU. *G CPUI restletMethod BOE restletMethods PQUJPOT BSF TQFDJGJFE, UIF restletMethod TFUUJOH JT JHOPSFE. 5IF CFBO *% PG UIF 3FBMN .BQ JO UIF $BNFM 3FHJTUSZ. "LKPRJBO LKIV 4QFDJGZ POF PSF NPSF 63* UFNQMBUFT UP CF TFSWJDFE CZ B SFTUMFU DPOTVNFS FOEQPJOU, VTJOH UIF # OPUBUJPO UP SFGFSFODF B List<String> JO UIF $BNFM 3FHJTUSZ. *G B 63* QBUUFSO IBT CFFO EFGJOFE JO UIF FOEQPJOU 63*, CPUI UIF 63* QBUUFSO EFGJOFE JO UIF FOEQPJOU BOE UIF restletUriPatterns PQUJPO XJMM CF IPOPSFE. *1SPEVDFS POMZ * 5ISPXT FYDFQUJPO PO B QSPEVDFS GBJMVSF.

restletBinding=#refName

restletMethod

restletMethods

None

restletRealm=#refName

null

restletUriPatterns=#refName

None

throwExceptionOnFailure (2.6 LO I>QBO)

USVF

"LJMLKBKQ .MQFLKP 5IF 3FTUMFU DPNQPOFOU DBO CF DPOGJHVSFE XJUI UIF GPMMPXJOH PQUJPOT
->JB
controllerDaemon controllerSleepTimeMs inboundBufferSize minThreads maxThreads maxConnectionsPerHost maxTotalConnections outboundBufferSize persistingConnections pipeliningConnections threadMaxIdleTimeMs

#BC>RIQ 5>IRB
true 100 8192 1 10 -1 -1 8192 true false 60000

#BP@OFMQFLK
">JBI 2.10: *OEJDBUFT JG UIF DPOUSPMMFS UISFBE TIPVME CF B EBFNPO (OPU CMPDLJOH +7. FYJU). ">JBI 2.10: 5JNF GPS UIF DPOUSPMMFS UISFBE UP TMFFQ CFUXFFO FBDI DPOUSPM. ">JBI 2.10: 5IF TJ[F PG UIF CVGGFS XIFO SFBEJOH NFTTBHFT. ">JBI 2.10: .JOJNVN UISFBET XBJUJOH UP TFSWJDF SFRVFTUT. ">JBI 2.10: .BYJNVN UISFBET UIBU XJMM TFSWJDF SFRVFTUT. ">JBI 2.10: .BYJNVN OVNCFS PG DPODVSSFOU DPOOFDUJPOT QFS IPTU (*1 BEESFTT). ">JBI 2.10: .BYJNVN OVNCFS PG DPODVSSFOU DPOOFDUJPOT JO UPUBM. ">JBI 2.10: 5IF TJ[F PG UIF CVGGFS XIFO XSJUJOH NFTTBHFT. ">JBI 2.10: *OEJDBUFT JG DPOOFDUJPOT TIPVME CF LFQU BMJWF BGUFS B DBMM. ">JBI 2.10: *OEJDBUFT JG QJQFMJOJOH DPOOFDUJPOT BSF TVQQPSUFE. ">JBI 2.10: 5JNF GPS BO JEMF UISFBE UP XBJU GPS BO PQFSBUJPO CFGPSF CFJOH DPMMFDUFE. ">JBI 2.10: -PPLVQ UIF "9-'PSXBSEFE-'PS" IFBEFS TVQQPSUFE CZ QPQVMBS QSPYJFT BOE DBDIFT BOE VTFT JU UP QPQVMBUF UIF 3FRVFTU.HFU$MJFOU"EESFTTFT() NFUIPE SFTVMU. 5IJT JOGPSNBUJPO JT POMZ TBGF GPS JOUFSNFEJBSZ DPNQPOFOUT XJUIJO ZPVS MPDBM OFUXPSL. 0UIFS BEESFTTFT DPVME FBTJMZ CF DIBOHFE CZ TFUUJOH B GBLF IFBEFS BOE TIPVME OPU CF USVTUFE GPS TFSJPVT TFDVSJUZ DIFDLT.

useForwardedForHeader

false

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

891

,BPP>DB 'B>ABOP
->JB 3VMB #BP@OFMQFLK
4QFDJGJFT UIF DPOUFOU UZQF, XIJDI DBO CF TFU PO UIF 065 NFTTBHF CZ UIF BQQMJDBUJPO/QSPDFTTPS. 5IF WBMVF JT UIF content-type PG UIF SFTQPOTF NFTTBHF. *G UIJT IFBEFS JT OPU TFU, UIF DPOUFOU UZQF JT CBTFE PO UIF PCKFDU UZQF PG UIF 065 NFTTBHF CPEZ. *O $BNFM 2.3 POXBSE, JG UIF $POUFOU-5ZQF IFBEFS JT TQFDJGJFE JO UIF $BNFM */ NFTTBHF, UIF WBMVF PG UIF IFBEFS EFUFSNJOF UIF DPOUFOU UZQF GPS UIF 3FTUMFU SFRVFTU NFTTBHF.cc 0UIFSXJTF, JU JT EFGBVMUFE UP "BQQMJDBUJPO/Y-XXX-GPSN-VSMFODPEFE'. 1SJPS UP SFMFBTF 2.3, JU JT OPU QPTTJCMF UP DIBOHF UIF SFRVFTU DPOUFOU UZQF EFGBVMU. 2FK@B ">JBI 2.9.3, 2.10.0: 5IF )551 "DDFQU SFRVFTU IFBEFS. 5IF )551 SFRVFTU NFUIPE. 5IJT JT TFU JO UIF */ NFTTBHF IFBEFS. 5IF RVFSZ TUSJOH PG UIF SFRVFTU 63*. *U JT TFU PO UIF */ NFTTBHF CZ DefaultRestletBinding XIFO UIF SFTUMFU DPNQPOFOU SFDFJWFT B SFRVFTU. 5IF SFTQPOTF DPEF DBO CF TFU PO UIF 065 NFTTBHF CZ UIF BQQMJDBUJPO/QSPDFTTPS. 5IF WBMVF JT UIF SFTQPOTF DPEF PG UIF SFTQPOTF NFTTBHF. *G UIJT IFBEFS JT OPU TFU, UIF SFTQPOTF DPEF JT TFU CZ UIF SFTUMFU SVOUJNF FOHJOF. 5IF )551 SFRVFTU 63*. 5IJT JT TFU JO UIF */ NFTTBHF IFBEFS. -PHJO OBNF GPS CBTJD BVUIFOUJDBUJPO. *U JT TFU PO UIF */ NFTTBHF CZ UIF BQQMJDBUJPO BOE HFUT GJMUFSFE CFGPSF UIF SFTUMFU SFRVFTU IFBEFS CZ $BNFM. 1BTTXPSE OBNF GPS CBTJD BVUIFOUJDBUJPO. *U JT TFU PO UIF */ NFTTBHF CZ UIF BQQMJDBUJPO BOE HFUT GJMUFSFE CFGPSF UIF SFTUMFU SFRVFTU IFBEFS CZ $BNFM. ">JBI 2.8: 5IF org.restlet.Request PCKFDU XIJDI IPMET BMM SFRVFTU EFUBJMT. ">JBI 2.8: 5IF org.restlet.Response PCKFDU. :PV DBO VTF UIJT UP DSFBUF SFTQPOTFT VTJOH UIF "1* GSPN 3FTUMFU. 4FF FYBNQMFT CFMPX. "UUSJCVUFT PG B 3FTUMFU NFTTBHF UIBU HFU QSPQBHBUFE UP $BNFM */ IFBEFST. ">JBI 2.11: 6TFS DBO TFU UIF DBDIF-DPOUSPM XJUI UIF 4USJOH WBMVF PS UIF -JTU PG $BDIF%JSFDUJWF PG 3FTUMFU GSPN UIF DBNFM NFTTBHF IFBEFS.

Content-Type

String

CamelAcceptContentType CamelHttpMethod CamelHttpQuery CamelHttpResponseCode CamelHttpUri CamelRestletLogin CamelRestletPassword CamelRestletRequest CamelRestletResponse org.restlet.* cache-control

String String String String PS Integer String String String Request Response c String PS List<CacheDirective>

,BPP>DB !LAV $BNFM XJMM TUPSF UIF SFTUMFU SFTQPOTF GSPN UIF FYUFSOBM TFSWFS PO UIF 065 CPEZ. "MM IFBEFST GSPN UIF */ NFTTBHF XJMM CF DPQJFE UP UIF 065 NFTTBHF, TP UIBU IFBEFST BSF QSFTFSWFE EVSJOH SPVUJOH. 2>JMIBP

1BPQIBQ $KAMLFKQ TFQE

RQEBKQF@>QFLK

5IF GPMMPXJOH SPVUF TUBSUT B restlet DPOTVNFS FOEQPJOU UIBU MJTUFOT GPS POST SFRVFTUT PO IUUQ://MPDBMIPTU:8080. 5IF QSPDFTTPS DSFBUFT B SFTQPOTF UIBU FDIPFT UIF SFRVFTU CPEZ BOE UIF WBMVF PG UIF id IFBEFS.
from("restlet:http://localhost:" + port + "/securedOrders?restletMethod=post&restletRealm=#realm").process(new Processor() { public void process(Exchange exchange) throws Exception { exchange.getOut().setBody( "received [" + exchange.getIn().getBody() + "] as an order id = " + exchange.getIn().getHeader("id")); } });

892

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

5IF restletRealm TFUUJOH JO UIF 63* RVFSZ JT VTFE UP MPPL VQ B 3FBMN .BQ JO UIF SFHJTUSZ. *G UIJT PQUJPO JT TQFDJGJFE, UIF SFTUMFU DPOTVNFS VTFT UIF JOGPSNBUJPO UP BVUIFOUJDBUF VTFS MPHJOT. 0OMZ authenticated SFRVFTUT DBO BDDFTT UIF SFTPVSDFT. *O UIJT TBNQMF, XF DSFBUF B 4QSJOH BQQMJDBUJPO DPOUFYU UIBU TFSWFT BT B SFHJTUSZ. 5IF CFBO *% PG UIF 3FBMN .BQ TIPVME NBUDI UIF restletRealmRef.
<util:map id="realm"> <entry key="admin" value="foo" /> <entry key="bar" value="foo" /> </util:map>

5IF GPMMPXJOH TBNQMF TUBSUT B direct FOEQPJOU UIBU TFOET SFRVFTUT UP UIF TFSWFS PO IUUQ://MPDBMIPTU:8080 (UIBU JT, PVS SFTUMFU DPOTVNFS FOEQPJOU).
// Note: restletMethod and restletRealmRef are stripped // from the query before a request is sent as they are // only processed by Camel. from("direct:start-auth").to("restlet:http://localhost:" + port + "/securedOrders?restletMethod=post");

5IBU JT BMM XF OFFE. 8F BSF SFBEZ UP TFOE B SFRVFTU BOE USZ PVU UIF SFTUMFU DPNQPOFOU:
final String id = "89531"; Map<String, Object> headers = new HashMap<String, Object>(); headers.put(RestletConstants.RESTLET_LOGIN, "admin"); headers.put(RestletConstants.RESTLET_PASSWORD, "foo"); headers.put("id", id); String response = (String)template.requestBodyAndHeaders( "direct:start-auth", "<order foo='1'/>", headers);

5IF TBNQMF DMJFOU TFOET B SFRVFTU UP UIF direct:start-auth FOEQPJOU XJUI UIF GPMMPXJOH IFBEFST: ` CamelRestletLogin (VTFE JOUFSOBMMZ CZ $BNFM) ` CamelRestletPassword (VTFE JOUFSOBMMZ CZ $BNFM) ` id (BQQMJDBUJPO IFBEFS) 5IF TBNQMF DMJFOU HFUT B SFTQPOTF MJLF UIF GPMMPXJOH:
received [<order foo='1'/>] as an order id = 89531

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

893

-LQB org.apache.camel.restlet.auth.login BOE org.apache.camel.restlet.auth.password XJMM OPU CF QSPQBHBUFE BT 3FTUMFU IFBEFS.

2FKDIB OBPQIBQ BKAMLFKQ QL PBOSF@B JRIQFMIB JBQELAP >KA 41( QBJMI>QBP


*U JT QPTTJCMF UP DSFBUF B TJOHMF SPVUF UP TFSWJDF NVMUJQMF )551 NFUIPET VTJOH UIF restletMethods PQUJPO. 5IJT TOJQQFU BMTP TIPXT IPX UP SFUSJFWF UIF SFRVFTU NFUIPE GSPN UIF IFBEFS:
from("restlet:http://localhost:" + portNum + "/users/{username}?restletMethods=post,get,put") .process(new Processor() { public void process(Exchange exchange) throws Exception { // echo the method exchange.getOut().setBody(exchange.getIn().getHeader(Exchange.HTTP_METHOD, String.class)); } });

*O BEEJUJPO UP TFSWJDJOH NVMUJQMF NFUIPET, UIF OFYU TOJQQFU TIPXT IPX UP DSFBUF BO FOEQPJOU UIBU TVQQPSUT NVMUJQMF 63* UFNQMBUFT VTJOH UIF restletUriPatterns PQUJPO. 5IF SFRVFTU 63* JT BWBJMBCMF JO UIF IFBEFS PG UIF */ NFTTBHF BT XFMM. *G B 63* QBUUFSO IBT CFFO EFGJOFE JO UIF FOEQPJOU 63* (XIJDI JT OPU UIF DBTF JO UIJT TBNQMF), CPUI UIF 63* QBUUFSO EFGJOFE JO UIF FOEQPJOU BOE UIF restletUriPatterns PQUJPO XJMM CF IPOPSFE.
from("restlet:http://localhost:" + portNum + "?restletMethods=post,get&restletUriPatterns=#uriTemplates") .process(new Processor() { public void process(Exchange exchange) throws Exception { // echo the method String uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class); String out = exchange.getIn().getHeader(Exchange.HTTP_METHOD, String.class); if (("http://localhost:" + portNum + "/users/homer").equals(uri)) { exchange.getOut().setBody(out + " " + exchange.getIn().getHeader("username", String.class)); } else if (("http://localhost:" + portNum + "/atom/collection/foo/ component/bar").equals(uri)) { exchange.getOut().setBody(out + " " + exchange.getIn().getHeader("id", String.class) + " " + exchange.getIn().getHeader("cid", String.class)); }

894

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

} });

5IF restletUriPatterns=#uriTemplates PQUJPO SFGFSFODFT UIF List<String> CFBO EFGJOFE JO UIF 4QSJOH 9.- DPOGJHVSBUJPO.
<util:list id="uriTemplates"> <value>/users/{username}</value> <value>/atom/collection/{id}/component/{cid}</value> </util:list>

4PFKD 1BPQIBQ

/( QL MLMRI>QB OBPMLKPB

S>FI>?IB >P LC ">JBI 2.8 :PV NBZ XBOU UP VTF UIF org.restlet.Response "1* UP QPQVMBUF UIF SFTQPOTF. 5IJT HJWFT ZPV GVMM BDDFTT UP UIF 3FTUMFU "1* BOE GJOF HSBJOFE DPOUSPM PG UIF SFTQPOTF. 4FF UIF SPVUF TOJQQFU CFMPX XIFSF XF HFOFSBUF UIF SFTQPOTF GSPN BO JOMJOFE $BNFM 1SPDFTTPS:
Listing 1. Generating response using Restlet Response API
from("restlet:http://localhost:" + portNum + "/users/{id}/like/{beer}") .process(new Processor() { public void process(Exchange exchange) throws Exception { // the Restlet request should be available if neeeded Request request = exchange.getIn().getHeader(RestletConstants.RESTLET_REQUEST, Request.class); assertNotNull("Restlet Request", request); // use Restlet API to create the response Response response = exchange.getIn().getHeader(RestletConstants.RESTLET_RESPONSE, Response.class); assertNotNull("Restlet Response", response); response.setStatus(Status.SUCCESS_OK); response.setEntity("<response>Beer is Good</response>", MediaType.TEXT_XML); exchange.getOut().setBody(response); } });

4PFKD QEB 1BPQIBQ PBOSIBQ TFQEFK > TB?>MM


S>FI>?IB >P LC ">JBI 2.8 5IFSF BSF UISFF QPTTJCMF XBZT UP DPOGJHVSF B 3FTUMFU BQQMJDBUJPO XJUIJO B TFSWMFU DPOUBJOFS BOE VTJOH UIF TVCDMBTTFE 4QSJOH4FSWFS4FSWMFU FOBCMFT DPOGJHVSBUJPO XJUIJO $BNFM CZ JOKFDUJOH UIF 3FTUMFU $PNQPOFOU.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

895

6TF PG UIF 3FTUMFU TFSWMFU XJUIJO B TFSWMFU DPOUBJOFS FOBCMFT SPVUFT UP CF DPOGJHVSFE XJUI SFMBUJWF QBUIT JO 63*T (SFNPWJOH UIF SFTUSJDUJPOT PG IBSE-DPEFE BCTPMVUF 63*T) BOE GPS UIF IPTUJOH TFSWMFU DPOUBJOFS UP IBOEMF JODPNJOH SFRVFTUT (SBUIFS UIBO IBWF UP TQBXO B TFQBSBUF TFSWFS QSPDFTT PO B OFX QPSU). 5P DPOGJHVSF, BEE UIF GPMMPXJOH UP ZPVS DBNFM-DPOUFYU.YNM;
<camelContext> <route id="RS_RestletDemo"> <from uri="restlet:/demo/{id}" /> <transform> <simple>Request type : ${header.CamelHttpMethod} and ID : ${header.id}</simple> </transform> </route> </camelContext> <bean id="RestletComponent" class="org.restlet.Component" /> <bean id="RestletComponentService" class="org.apache.camel.component.restlet.RestletComponent"> <constructor-arg index="0"> <ref bean="RestletComponent" /> </constructor-arg> </bean>

"OE BEE UIJT UP ZPVS XFC.YNM;


<!-- Restlet Servlet --> <servlet> <servlet-name>RestletServlet</servlet-name> <servlet-class>org.restlet.ext.spring.SpringServerServlet</servlet-class> <init-param> <param-name>org.restlet.component</param-name> <param-value>RestletComponent</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>RestletServlet</servlet-name> <url-pattern>/rs/*</url-pattern> </servlet-mapping>

:PV XJMM UIFO CF BCMF UP BDDFTT UIF EFQMPZFE SPVUF BU IUUQ://MPDBMIPTU:8080/NZXFCBQQ/ST/EFNP/ 1234 XIFSF; MPDBMIPTU:8080 JT UIF TFSWFS BOE QPSU PG ZPVS TFSWMFU DPOUBJOFS NZXFCBQQ JT UIF OBNF PG ZPVS EFQMPZFE XFCBQQ :PVS CSPXTFS XJMM UIFO TIPX UIF GPMMPXJOH DPOUFOU;
"Request type : GET and ID : 1234"

896

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV XJMM OFFE UP BEE EFQFOEFODZ PO UIF 4QSJOH FYUFOTJPO UP SFTUMFU XIJDI ZPV DBO EP JO ZPVS .BWFO QPN.YNM GJMF:
<dependency> <groupId>org.restlet.jee</groupId> <artifactId>org.restlet.ext.spring</artifactId> <version>${restlet-version}</version> </dependency>

"OE ZPV XPVME OFFE UP BEE EFQFOEFODZ PO UIF SFTUMFU NBWFO SFQPTJUPSZ BT XFMM:
<repository> <id>maven-restlet</id> <name>Public online Restlet repository</name> <url>http://maven.restlet.org</url> </repository>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

1,( ".,/.-$-3
5IF OJF: DPNQPOFOU CJOET 1PKP&YDIBOHFT UP UIF 3.* QSPUPDPM (+3.1). 4JODF UIJT CJOEJOH JT KVTU VTJOH 3.*, OPSNBM 3.* SVMFT TUJMM BQQMZ SFHBSEJOH XIBU NFUIPET DBO CF JOWPLFE. 5IJT DPNQPOFOU TVQQPSUT POMZ 1PKP&YDIBOHFT UIBU DBSSZ B NFUIPE JOWPDBUJPO GSPN BO JOUFSGBDF UIBU FYUFOET UIF 3FNPUF JOUFSGBDF. "MM QBSBNFUFST JO UIF NFUIPE TIPVME CF FJUIFS 4FSJBMJ[BCMF PS Remote PCKFDUT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-rmi</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

897

41( CLOJ>Q
rmi://rmi-regisitry-host:rmi-registry-port/registry-path[?options]

'PS FYBNQMF:
rmi://localhost:1099/path/to/service

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
method remoteInterfaces

#BC>RIQ 5>IRB
null null

#BP@OFMQFLK
:PV DBO TFU UIF OBNF PG UIF NFUIPE UP JOWPLF. *UT OPX QPTTJCMF UP VTF UIJT PQUJPO GSPN ">JBI 2.7: JO UIF 9.- %4-. *U DBO CF B MJTU PG JOUFSGBDF OBNFT TFQBSBUFE CZ DPNNB.

4PFKD 5P DBMM PVU UP BO FYJTUJOH 3.* TFSWJDF SFHJTUFSFE JO BO 3.* SFHJTUSZ, DSFBUF B SPVUF TJNJMBS UP UIF GPMMPXJOH:
from("pojo:foo").to("rmi://localhost:1099/foo");

5P CJOE BO FYJTUJOH DBNFM QSPDFTTPS PS TFSWJDF JO BO 3.* SFHJTUSZ, EFGJOF BO 3.* FOEQPJOU BT GPMMPXT:
RmiEndpoint endpoint= (RmiEndpoint) endpoint("rmi://localhost:1099/bar"); endpoint.setRemoteInterfaces(ISay.class); from(endpoint).to("pojo:bar");

/PUF UIBU XIFO CJOEJOH BO 3.* DPOTVNFS FOEQPJOU, ZPV NVTU TQFDJGZ UIF Remote JOUFSGBDFT FYQPTFE. *O 9.- %4- ZPV DBO EP BT GPMMPXT GSPN ">JBI 2.7 POXBSET:
<camel:route> <from uri="rmi://localhost:37541/ helloServiceBean?remoteInterfaces=org.apache.camel.example.osgi.HelloService"/> <to uri="bean:helloServiceBean"/> </camel:route>

898

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

122 ".,/.-$-3
5IF OPP: DPNQPOFOU JT VTFE GPS QPMMJOH 344 GFFET. $BNFM XJMM EFGBVMU QPMM UIF GFFE FWFSZ 60UI TFDPOET. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-rss</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

-LQB: 5IF DPNQPOFOU DVSSFOUMZ POMZ TVQQPSUT QPMMJOH (DPOTVNJOH) GFFET. 41( CLOJ>Q
rss:rssUri

8IFSF rssUri JT UIF 63* UP UIF 344 GFFE UP QPMM. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
/OLMBOQV
splitEntries

#BC>RIQ
true

#BP@OFMQFLK
*G true, $BNFM TQMJUT B GFFE JOUP JUT JOEJWJEVBM FOUSJFT BOE SFUVSOT FBDI FOUSZ, QPMM CZ QPMM. 'PS FYBNQMF, JG B GFFE DPOUBJOT TFWFO FOUSJFT, $BNFM SFUVSOT UIF GJSTU FOUSZ PO UIF GJSTU QPMM, UIF TFDPOE FOUSZ PO UIF TFDPOE QPMM, BOE TP PO. 8IFO OP NPSF FOUSJFT BSF MFGU JO UIF GFFE, $BNFM DPOUBDUT UIF SFNPUF 344 63* UP PCUBJO B OFX GFFE. *G false, $BNFM PCUBJOT B GSFTI GFFE PO FWFSZ QPMM BOE SFUVSOT BMM PG UIF GFFE'T FOUSJFT. 6TF JO DPNCJOBUJPO XJUI UIF splitEntries PQUJPO JO PSEFS UP GJMUFS SFUVSOFE FOUSJFT. #Z EFGBVMU, $BNFM BQQMJFT UIF UpdateDateFilter GJMUFS, XIJDI SFUVSOT POMZ OFX FOUSJFT GSPN UIF GFFE, FOTVSJOH UIBU UIF DPOTVNFS FOEQPJOU OFWFS SFDFJWFT BO FOUSZ NPSF UIBO PODF. 5IF GJMUFS PSEFST UIF FOUSJFT DISPOPMPHJDBMMZ, XJUI UIF OFXFTU SFUVSOFE MBTU. ">JBI 2.5: 4FUT XIFUIFS BMM FOUSJFT JEFOUJGJFE JO B TJOHMF GFFE QPMM TIPVME CF EFMJWFSFE JNNFEJBUFMZ. *G USVF, POMZ POF FOUSZ JT QSPDFTTFE QFS DPOTVNFS.EFMBZ. 0OMZ BQQMJDBCMF XIFO TQMJU&OUSJFT JT TFU UP USVF. 6TF JO DPNCJOBUJPO XJUI UIF filter PQUJPO UP CMPDL FOUSJFT FBSMJFS UIBO B TQFDJGJD EBUF/UJNF (VTFT UIF entry.updated UJNFTUBNQ). 5IF GPSNBU JT: yyyy-MM-ddTHH:MM:ss. &YBNQMF: 2007-12-24T17:45:59. 4QFDJGJFT XIFUIFS UP BEE UIF 30.& SyndFeed PCKFDU BT B IFBEFS. *G splitEntries JT true, UIJT TQFDJGJFT XIFUIFS UP TPSU UIF FOUSJFT CZ VQEBUFE EBUF.

filter

true

throttleEntries lastUpdate feedHeader sortEntries

true null true false

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

899

$BNFM-STT JOUFSOBMMZ VTFT B QBUDIFE WFSTJPO PG 30.& IPTUFE PO 4FSWJDF.JY UP TPMWF TPNF 04(J DMBTT MPBEJOH JTTVFT.
consumer.delay consumer.initialDelay consumer.userFixedDelay 60000 1000 false %FMBZ JO NJMMJTFDPOET CFUXFFO FBDI QPMM. .JMMJTFDPOET CFGPSF QPMMJOH TUBSUT. 4FU UP true UP VTF GJYFE EFMBZ CFUXFFO QPPMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT.

$U@E>KDB A>Q> QVMBP $BNFM JOJUJBMJ[FT UIF *O CPEZ PO UIF &YDIBOHF XJUI B 30.& SyndFeed. %FQFOEJOH PO UIF WBMVF PG UIF splitEntries GMBH, $BNFM SFUVSOT FJUIFS B SyndFeed XJUI POF SyndEntry PS B java.util.List PG SyndEntrys.
.MQFLK
splitEntries splitEntries

5>IRB
true false

!BE>SFLO
" TJOHMF FOUSZ GSPN UIF DVSSFOU GFFE JT TFU JO UIF FYDIBOHF. 5IF FOUJSF MJTU PG FOUSJFT GSPN UIF DVSSFOU GFFE JT TFU JO UIF FYDIBOHF.

,BPP>DB 'B>ABOP
'B>ABO
CamelRssFeed

#BP@OFMQFLK
5IF FOUJSF SyncFeed PCKFDU.

122 #>Q>CLOJ>Q 5IF 344 DPNQPOFOU TIJQT XJUI BO 344 EBUBGPSNBU UIBU DBO CF VTFE UP DPOWFSU CFUXFFO 4USJOH (BT 9.-) BOE 30.& 344 NPEFM PCKFDUT. ` NBSTIBM = GSPN 30.& SyndFeed UP 9.- String ` VONBSTIBM = GSPN 9.- String UP 30.& SyndFeed " SPVUF VTJOH UIJT XPVME MPPL TPNFUIJOH MJLF UIJT:
from("rss:file:src/test/data/ rss20.xml?splitEntries=false&consumer.delay=1000").marshal().rss().to("mock:marshal");

5IF QVSQPTF PG UIJT GFBUVSF JT UP NBLF JU QPTTJCMF UP VTF $BNFM'T MPWFMZ CVJMU-JO FYQSFTTJPOT GPS NBOJQVMBUJOH 344 NFTTBHFT. "T TIPXO CFMPX, BO 91BUI FYQSFTTJPO DBO CF VTFE UP GJMUFS UIF 344 NFTTBHF:
// only entries with Camel in the title will get through the filter from("rss:file:src/test/data/rss20.xml?splitEntries=true&consumer.delay=100") .marshal().rss().filter().xpath("//item/ title[contains(.,'Camel')]").to("mock:result");

900

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

0RBOV M>O>JBQBOP *G UIF 63- GPS UIF 344 GFFE VTFT RVFSZ QBSBNFUFST, UIJT DPNQPOFOU XJMM VOEFSTUBOE UIFN BT XFMM, GPS FYBNQMF JG UIF GFFE VTFT alt=rss, UIFO ZPV DBO GPS FYBNQMF EP from("rss:http://someserver.com/feeds/posts/ default?alt=rss&splitEntries=false&consumer.delay=1000").to("bean:rss" %FIQBOFKD BKQOFBP :PV DBO GJMUFS PVU FOUSJFT RVJUF FBTJMZ VTJOH 91BUI, BT TIPXO JO UIF EBUB GPSNBU TFDUJPO BCPWF. :PV DBO BMTP FYQMPJU $BNFM'T #FBO *OUFHSBUJPO UP JNQMFNFOU ZPVS PXO DPOEJUJPOT. 'PS JOTUBODF, B GJMUFS FRVJWBMFOU UP UIF 91BUI FYBNQMF BCPWF XPVME CF:
// only entries with Camel in the title will get through the filter from("rss:file:src/test/data/rss20.xml?splitEntries=true&consumer.delay=100"). filter().method("myFilterBean", "titleContainsCamel").to("mock:result");

5IF DVTUPN CFBO GPS UIJT XPVME CF:


public static class FilterBean { public boolean titleContainsCamel(@Body SyndFeed feed) { SyndEntry firstEntry = (SyndEntry) feed.getEntries().get(0); return firstEntry.getTitle().contains("Camel"); } }

2BB

IPL

` $POGJHVSJOH $BNFM ` $PNQPOFOU ` &OEQPJOU ` (FUUJOH 4UBSUFE "UPN 6OBCMF UP SFOEFS \JODMVEF^ $PVMEO'U GJOE B QBHF UP JODMVEF DBMMFE: 4DBMBUF

2$#

".,/.-$-3

5IF PBA>: DPNQPOFOU QSPWJEFT BTZODISPOPVT 4&%" CFIBWJPS, TP UIBU NFTTBHFT BSF FYDIBOHFE PO B #MPDLJOH2VFVF BOE DPOTVNFST BSF JOWPLFE JO B TFQBSBUF UISFBE GSPN UIF QSPEVDFS. /PUF UIBU RVFVFT BSF POMZ WJTJCMF XJUIJO B single $BNFM$POUFYU. *G ZPV XBOU UP DPNNVOJDBUF BDSPTT CamelContext JOTUBODFT (GPS FYBNQMF, DPNNVOJDBUJOH CFUXFFO 8FC BQQMJDBUJPOT), TFF UIF 7. DPNQPOFOU.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

901

5IJT DPNQPOFOU EPFT OPU JNQMFNFOU BOZ LJOE PG QFSTJTUFODF PS SFDPWFSZ, JG UIF 7. UFSNJOBUFT XIJMF NFTTBHFT BSF ZFU UP CF QSPDFTTFE. *G ZPV OFFE QFSTJTUFODF, SFMJBCJMJUZ PS EJTUSJCVUFE 4&%", USZ VTJOH FJUIFS +.4 PS "DUJWF.2. 41( CLOJ>Q
seda:someName[?options]

8IFSF PLJB->JB DBO CF BOZ TUSJOH UIBU VOJRVFMZ JEFOUJGJFT UIF FOEQPJOU XJUIJO UIF DVSSFOU $BNFM$POUFYU. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU: ?option=value&option=value& .MQFLKP
->JB 2FK@B #BC>RIQ #BP@OFMQFLK
5IF NBYJNVN DBQBDJUZ PG UIF 4&%" RVFVF (J.F., UIF OVNCFS PG NFTTBHFT JU DBO IPME). 5IF EFGBVMU WBMVF JO $BNFM 2.2 PS PMEFS JT 1000. 'SPN $BNFM 2.3 POXBSET, UIF TJ[F JT VOCPVOEFE CZ EFGBVMU. -LQF@B: .JOE JG ZPV VTF UIJT PQUJPO, UIFO JUT UIF GJSTU FOEQPJOU CFJOH DSFBUFE XJUI UIF RVFVF OBNF, UIBU EFUFSNJOFT UIF TJ[F. 5P NBLF TVSF BMM FOEQPJOUT VTF TBNF TJ[F, UIFO DPOGJHVSF UIF TJ[F PQUJPO PO BMM PG UIFN, PS UIF GJSTU FOEQPJOU CFJOH DSFBUFE. 'SPN ">JBI 2.11 POXBSET, B WBMJEBUJPO JT UBLFO QMBDF UP FOTVSF JG VTJOH NJYFE RVFVF TJ[FT GPS UIF TBNF RVFVF OBNF, $BNFM XPVME EFUFDU UIJT BOE GBJM DSFBUJOH UIF FOEQPJOU. /VNCFS PG DPODVSSFOU UISFBET QSPDFTTJOH FYDIBOHFT. 0QUJPO UP TQFDJGZ XIFUIFS UIF DBMMFS TIPVME XBJU GPS UIF BTZOD UBTL UP DPNQMFUF PS OPU CFGPSF DPOUJOVJOH. 5IF GPMMPXJOH UISFF PQUJPOT BSF TVQQPSUFE: Always, Never PS IfReplyExpected. 5IF GJSTU UXP WBMVFT BSF TFMG-FYQMBOBUPSZ. 5IF MBTU WBMVF, IfReplyExpected, XJMM POMZ XBJU JG UIF NFTTBHF JT 3FRVFTU 3FQMZ CBTFE. 5IF EFGBVMU PQUJPO JT IfReplyExpected. 4FF NPSF JOGPSNBUJPO BCPVU "TZOD NFTTBHJOH. 5JNFPVU (JO NJMMJTFDPOET) CFGPSF B 4&%" QSPEVDFS XJMM TUPQ XBJUJOH GPS BO BTZODISPOPVT UBTL UP DPNQMFUF. 4FF waitForTaskToComplete BOE "TZOD GPS NPSF EFUBJMT. *O ">JBI 2.2 ZPV DBO OPX EJTBCMF UJNFPVU CZ VTJOH 0 PS B OFHBUJWF WBMVF. 4QFDJGJFT XIFUIFS NVMUJQMF DPOTVNFST BSF BMMPXFE. *G FOBCMFE, ZPV DBO VTF 4&%" GPS 1VCMJTI4VCTDSJCF NFTTBHJOH. 5IBU JT, ZPV DBO TFOE B NFTTBHF UP UIF 4&%" RVFVF BOE IBWF FBDI DPOTVNFS SFDFJWF B DPQZ PG UIF NFTTBHF. 8IFO FOBCMFE, UIJT PQUJPO TIPVME CF TQFDJGJFE PO FWFSZ DPOTVNFS FOEQPJOU. 8IFUIFS UP MJNJU UIF OVNCFS PG concurrentConsumers UP UIF NBYJNVN PG 500. #Z EFGBVMU, BO FYDFQUJPO XJMM CF UISPXO JG B 4&%" FOEQPJOU JT DPOGJHVSFE XJUI B HSFBUFS OVNCFS. :PV DBO EJTBCMF UIBU DIFDL CZ UVSOJOH UIJT PQUJPO PGG. 8IFUIFS B UISFBE UIBU TFOET NFTTBHFT UP B GVMM 4&%" RVFVF XJMM CMPDL VOUJM UIF RVFVF'T DBQBDJUZ JT OP MPOHFS FYIBVTUFE. #Z EFGBVMU, BO FYDFQUJPO XJMM CF UISPXO TUBUJOH UIBU UIF RVFVF JT GVMM. #Z FOBCMJOH UIJT PQUJPO, UIF DBMMJOH UISFBE XJMM JOTUFBE CMPDL BOE XBJU VOUJM UIF NFTTBHF DBO CF BDDFQUFE. "LJMLKBKQ LKIV: 5IF NBYJNVN EFGBVMU TJ[F (DBQBDJUZ PG UIF OVNCFS PG NFTTBHFT JU DBO IPME) PG UIF 4&%" RVFVF. 5IJT PQUJPO JT VTFE JG size JT OPU JO VTF. Consumer only f 5IF UJNFPVU VTFE XIFO QPMMJOH. 8IFO B UJNFPVU PDDVST, UIF DPOTVNFS DBO DIFDL XIFUIFS JU JT BMMPXFE UP DPOUJOVF SVOOJOH. 4FUUJOH B MPXFS WBMVF BMMPXT UIF DPOTVNFS UP SFBDU NPSF RVJDLMZ VQPO TIVUEPXO.

size

concurrentConsumers

waitForTaskToComplete

IfReplyExpected

timeout

30000

multipleConsumers

2.2

false

limitConcurrentConsumers

2.3

true

blockWhenFull

2.9

false

queueSize

2.9

pollTimeout

2.9.3

1000

4PB LC 1BNRBPQ 1BMIV 5IF 4&%" DPNQPOFOU TVQQPSUT VTJOH 3FRVFTU 3FQMZ, XIFSF UIF DBMMFS XJMM XBJU GPS UIF "TZOD SPVUF UP DPNQMFUF. 'PS JOTUBODF:

902

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2VK@EOLKLRP 5IF %JSFDU DPNQPOFOU QSPWJEFT TZODISPOPVT JOWPDBUJPO PG BOZ DPOTVNFST XIFO B QSPEVDFS TFOET B NFTTBHF FYDIBOHF.

from("mina:tcp://0.0.0.0:9876?textline=true&sync=true").to("seda:input"); from("seda:input").to("bean:processInput").to("bean:createResponse");

*O UIF SPVUF BCPWF, XF IBWF B 5$1 MJTUFOFS PO QPSU 9876 UIBU BDDFQUT JODPNJOH SFRVFTUT. 5IF SFRVFTU JT SPVUFE UP UIF seda:input RVFVF. "T JU JT B 3FRVFTU 3FQMZ NFTTBHF, XF XBJU GPS UIF SFTQPOTF. 8IFO UIF DPOTVNFS PO UIF seda:input RVFVF JT DPNQMFUF, JU DPQJFT UIF SFTQPOTF UP UIF PSJHJOBM NFTTBHF SFTQPOTF. "LK@ROOBKQ @LKPRJBOP #Z EFGBVMU, UIF 4&%" FOEQPJOU VTFT B TJOHMF DPOTVNFS UISFBE, CVU ZPV DBO DPOGJHVSF JU UP VTF DPODVSSFOU DPOTVNFS UISFBET. 4P JOTUFBE PG UISFBE QPPMT ZPV DBO VTF:
from("seda:stageName?concurrentConsumers=5").process(...)

"T GPS UIF EJGGFSFODF CFUXFFO UIF UXP, OPUF B thread pool DBO JODSFBTF/TISJOL EZOBNJDBMMZ BU SVOUJNF EFQFOEJOH PO MPBE, XIFSFBT UIF OVNCFS PG DPODVSSFOU DPOTVNFST JT BMXBZT GJYFE. 3EOB>A MLLIP #F BXBSF UIBU BEEJOH B UISFBE QPPM UP B 4&%" FOEQPJOU CZ EPJOH TPNFUIJOH MJLF:
from("seda:stageName").thread(5).process(...)

$BO XJOE VQ XJUI UXP BlockQueues: POF GSPN UIF 4&%" FOEQPJOU, BOE POF GSPN UIF XPSLRVFVF PG UIF UISFBE QPPM, XIJDI NBZ OPU CF XIBU ZPV XBOU. *OTUFBE, ZPV NJHIU XJTI UP DPOGJHVSF B %JSFDU FOEQPJOU XJUI B UISFBE QPPM, XIJDI DBO QSPDFTT NFTTBHFT CPUI TZODISPOPVTMZ BOE BTZODISPOPVTMZ. 'PS FYBNQMF:
from("direct:stageName").thread(5).process(...)

:PV DBO BMTP EJSFDUMZ DPOGJHVSF OVNCFS PG UISFBET UIBU QSPDFTT NFTTBHFT PO B 4&%" FOEQPJOU VTJOH UIF concurrentConsumers PQUJPO.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

903

RKQFI 2.2: 6LOHP LKIV TFQE 2 BKAMLFKQP 6TJOH 3FRVFTU 3FQMZ PWFS 4&%" PS 7. POMZ XPSLT XJUI 2 FOEQPJOUT. :PV @>KKLQ DIBJO FOEQPJOUT CZ TFOEJOH UP " -> # -> $ FUD. 0OMZ CFUXFFO " -> #. 5IF SFBTPO JT UIF JNQMFNFOUBUJPO MPHJD JT GBJSMZ TJNQMF. 5P TVQQPSU 3+ FOEQPJOUT NBLFT UIF MPHJD NVDI NPSF DPNQMFY UP IBOEMF PSEFSJOH BOE OPUJGJDBUJPO CFUXFFO UIF XBJUJOH UISFBET QSPQFSMZ.
5IJT IBT CFFO JNQSPWFE JO ">JBI 2.3 POXBSET, XIJDI BMMPXT ZPV UP DIBJO BT NBOZ FOEQPJOUT BT ZPV MJLF.

2>JMIB *O UIF SPVUF CFMPX XF VTF UIF 4&%" RVFVF UP TFOE UIF SFRVFTU UP UIJT BTZOD RVFVF UP CF BCMF UP TFOE B GJSF-BOE-GPSHFU NFTTBHF GPS GVSUIFS QSPDFTTJOH JO BOPUIFS UISFBE, BOE SFUVSO B DPOTUBOU SFQMZ JO UIJT UISFBE UP UIF PSJHJOBM DBMMFS.
public void configure() throws Exception { from("direct:start") // send it to the seda queue that is async .to("seda:next") // return a constant response .transform(constant("OK")); from("seda:next").to("mock:result"); }

)FSF XF TFOE B )FMMP 8PSME NFTTBHF BOE FYQFDUT UIF SFQMZ UP CF 0,.
Object out = template.requestBody("direct:start", "Hello World"); assertEquals("OK", out);

5IF ")FMMP 8PSME" NFTTBHF XJMM CF DPOTVNFE GSPN UIF 4&%" RVFVF GSPN BOPUIFS UISFBE GPS GVSUIFS QSPDFTTJOH. 4JODF UIJT JT GSPN B VOJU UFTU, JU XJMM CF TFOU UP B mock FOEQPJOU XIFSF XF DBO EP BTTFSUJPOT JO UIF VOJU UFTU. 4PFKD JRIQFMIB"LKPRJBOP S>FI>?IB >P LC ">JBI 2.2 *O UIJT FYBNQMF XF IBWF EFGJOFE UXP DPOTVNFST BOE SFHJTUFSFE UIFN BT TQSJOH CFBOT.
<!-- define the consumers as spring beans --> <bean id="consumer1" class="org.apache.camel.spring.example.FooEventConsumer"/> <bean id="consumer2" class="org.apache.camel.spring.example.AnotherFooEventConsumer"/>

904

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- define a shared endpoint which the consumers can refer to instead of using url --> <endpoint id="foo" uri="seda:foo?multipleConsumers=true"/> </camelContext>

4JODF XF IBWF TQFDJGJFE JRIQFMIB"LKPRJBOP=QORB PO UIF TFEB GPP FOEQPJOU XF DBO IBWF UIPTF UXP DPOTVNFST SFDFJWF UIFJS PXO DPQZ PG UIF NFTTBHF BT B LJOE PG QVC-TVC TUZMF NFTTBHJOH. "T UIF CFBOT BSF QBSU PG BO VOJU UFTU UIFZ TJNQMZ TFOE UIF NFTTBHF UP B NPDL FOEQPJOU, CVU OPUJDF IPX XF DBO VTF !$POTVNF UP DPOTVNF GSPN UIF TFEB RVFVF.
public class FooEventConsumer { @EndpointInject(uri = "mock:result") private ProducerTemplate destination; @Consume(ref = "foo") public void doSomething(String body) { destination.sendBody("foo" + body); } }

$UQO>@QFKD NRBRB FKCLOJ>QFLK. *G OFFEFE, JOGPSNBUJPO TVDI BT RVFVF TJ[F, FUD. DBO CF PCUBJOFE XJUIPVU VTJOH +.9 JO UIJT GBTIJPO:
SedaEndpoint seda = context.getEndpoint("seda:xxxx"); int size = seda.getExchanges().size();

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 7. %JSFDU "TZOD

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

905

2$15+$3 ".,/.-$-3
5IF PBOSIBQ: DPNQPOFOU QSPWJEFT )551 CBTFE FOEQPJOUT GPS DPOTVNJOH )551 SFRVFTUT UIBU BSSJWF BU B )551 FOEQPJOU UIBU JT CPVOE UP B QVCMJTIFE 4FSWMFU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-servlet</artifactId> <version>x.x.x</version> <\!-\- use the same version as your Camel core version \--> </dependency>

41( CLOJ>Q
servlet://relative_path[?options]

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
httpBindingRef matchOnUriPrefix servletName

#BC>RIQ 5>IRB
null false CamelServlet

#BP@OFMQFLK
3FGFSFODF UP BO org.apache.camel.component.http.HttpBinding JO UIF 3FHJTUSZ. " HttpBinding JNQMFNFOUBUJPO DBO CF VTFE UP DVTUPNJ[F IPX UP XSJUF B SFTQPOTF. 8IFUIFS PS OPU UIF CamelServlet TIPVME USZ UP GJOE B UBSHFU DPOTVNFS CZ NBUDIJOH UIF 63* QSFGJY, JG OP FYBDU NBUDI JT GPVOE. 4QFDJGJFT UIF TFSWMFU OBNF UIBU UIF TFSWMFU FOEQPJOU XJMM CJOE UP. 5IJT OBNF TIPVME NBUDI UIF OBNF ZPV EFGJOF JO web.xml GJMF.

,BPP>DB 'B>ABOP $BNFM XJMM BQQMZ UIF TBNF .FTTBHF )FBEFST BT UIF )551 DPNQPOFOU. $BNFM XJMM BMTP QPQVMBUF >II request.parameter BOE request.headers. 'PS FYBNQMF, JG B DMJFOU SFRVFTU IBT UIF 63-, http://myserver/myserver?orderid=123, UIF FYDIBOHF XJMM DPOUBJO B IFBEFS OBNFE orderid XJUI UIF WBMVF 123. 4P>DB :PV DBO DPOTVNF POMZ GSPN FOEQPJOUT HFOFSBUFE CZ UIF 4FSWMFU DPNQPOFOU. 5IFSFGPSF, JU TIPVME CF VTFE POMZ BT JOQVU JOUP ZPVS $BNFM SPVUFT. 5P JTTVF )551 SFRVFTUT BHBJOTU PUIFS )551 FOEQPJOUT, VTF UIF )551 $PNQPOFOU

906

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

2QOB>J 4FSWMFU JT TUSFBN CBTFE, XIJDI NFBOT UIF JOQVU JU SFDFJWFT JT TVCNJUUFE UP $BNFM BT B TUSFBN. 5IBU NFBOT ZPV XJMM POMZ CF BCMF UP SFBE UIF DPOUFOU PG UIF TUSFBN LK@B. *G ZPV GJOE B TJUVBUJPO XIFSF UIF NFTTBHF CPEZ BQQFBST UP CF FNQUZ PS ZPV OFFE UP BDDFTT UIF EBUB NVMUJQMF UJNFT (FH: EPJOH NVMUJDBTUJOH, PS SFEFMJWFSZ FSSPS IBOEMJOH) ZPV TIPVME VTF 4USFBN DBDIJOH PS DPOWFSU UIF NFTTBHF CPEZ UP B String XIJDI JT TBGF UP CF SFBE NVMUJQMF UJNFT. /RQQFKD ">JBI ) 1P FK QEB >MM PBOSBO ?LLQ @I>PPM>QE *G ZPV QVU UIF $BNFM +"3T TVDI BT camel-core, camel-servlet, FUD. JO UIF CPPU DMBTTQBUI PG ZPVS BQQMJDBUJPO TFSWFS (FH VTVBMMZ JO JUT MJC EJSFDUPSZ), UIFO NJOE UIBU UIF TFSWMFU NBQQJOH MJTU JT OPX TIBSFE CFUXFFO NVMUJQMF EFQMPZFE $BNFM BQQMJDBUJPO JO UIF BQQ TFSWFS. .JOE UIBU QVUUJOH $BNFM +"3T JO UIF CPPU DMBTTQBUI PG UIF BQQMJDBUJPO TFSWFS JT HFOFSBMMZ OPU CFTU QSBDUJDF! 4P JO UIPTF TJUVBUJPOT ZPV JRPQ EFGJOF B DVTUPN BOE VOJRVF TFSWMFU OBNF JO FBDI PG ZPVS $BNFM BQQMJDBUJPO, FH JO UIF web.xml EFGJOF:
<servlet> <servlet-name>MySerlvet</servlet-name> <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>

"OE JO ZPVS $BNFM FOEQPJOUT UIFO JODMVEF UIF TFSWMFU OBNF BT XFMM
<route> <from uri="servlet://foo?servletName=MyServlet"/> ... </route>

'SPN ">JBI 2.11 POXBSET $BNFM XJMM EFUFDU UIJT EVQMJDBUF BOE GBJM UP TUBSU UIF BQQMJDBUJPO. :PV DBO DPOUSPM UP JHOPSF UIJT EVQMJDBUF CZ TFUUJOH UIF TFSWMFU JOJU-QBSBNFUFS JHOPSF%VQMJDBUF4FSWMFU/BNF UP USVF BT GPMMPXT:
<servlet> <servlet-name>CamelServlet</servlet-name> <display-name>Camel Http Transport Servlet</display-name>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

907

<servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class> <init-param> <param-name>ignoreDuplicateServletName</param-name> <param-value>true</param-value> </init-param> </servlet>

#VU JUT PQOLKDIV >ASFPBA UP VTF VOJRVF TFSWMFU-OBNF GPS FBDI $BNFM BQQMJDBUJPO UP BWPJE UIJT EVQMJDBUJPO DMBTI, BT XFMM BOZ VOGPSFTFFO TJEF-FGGFDUT. 2>JMIB *O UIJT TBNQMF, XF EFGJOF B SPVUF UIBU FYQPTFT B )551 TFSWJDF BU http://localhost:8080/camel/services/hello. 'JSTU, ZPV OFFE UP QVCMJTI UIF $BNFM)UUQ5SBOTQPSU4FSWMFU UISPVHI UIF OPSNBM 8FC $POUBJOFS, PS 04(J 4FSWJDF. 6TF UIF Web.xml GJMF UP QVCMJTI UIF $BNFM)UUQ5SBOTQPSU4FSWMFU BT GPMMPXT:
<web-app> <servlet> <servlet-name>CamelServlet</servlet-name> <display-name>Camel Http Transport Servlet</display-name> <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CamelServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> </web-app>

5IFO ZPV DBO EFGJOF ZPVS SPVUF BT GPMMPXT:


from("servlet:///hello?matchOnUriPrefix=true").process(new Processor() { public void process(Exchange exchange) throws Exception { String contentType = exchange.getIn().getHeader(Exchange.CONTENT_TYPE, String.class); String path = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class); path = path.substring(path.lastIndexOf("/")); assertEquals("Get a wrong content type", CONTENT_TYPE, contentType); // assert camel http header String charsetEncoding = exchange.getIn().getHeader(Exchange.HTTP_CHARACTER_ENCODING, String.class);

908

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

'SPN $BNFM 2.7 POXBSET JU'T FBTJFS UP VTF 4FSWMFU JO 4QSJOH XFC BQQMJDBUJPOT. 4FF 4FSWMFU 5PNDBU &YBNQMF GPS EFUBJMT.

assertEquals("Get a wrong charset name from the message heaer", "UTF-8", charsetEncoding); // assert exchange charset assertEquals("Get a wrong charset naem from the exchange property", "UTF-8", exchange.getProperty(Exchange.CHARSET_NAME)); exchange.getOut().setHeader(Exchange.CONTENT_TYPE, contentType + "; charset=UTF-8"); exchange.getOut().setHeader("PATH", path); exchange.getOut().setBody("<b>Hello World</b>"); } });

2>JMIB TEBK RPFKD 2MOFKD 3.U


4FF 4FSWMFU 5PNDBU &YBNQMF

2>JMIB TEBK RPFKD 2MOFKD 2.U


8IFO VTJOH UIF 4FSWMFU DPNQPOFOU JO B $BNFM/4QSJOH BQQMJDBUJPO JU'T PGUFO SFRVJSFE UP MPBE UIF 4QSJOH "QQMJDBUJPO$POUFYU after UIF 4FSWMFU DPNQPOFOU IBT TUBSUFE. 5IJT DBO CF BDDPNQMJTIFE CZ VTJOH 4QSJOH'T ContextLoaderServlet JOTUFBE PG ContextLoaderListener. *O UIBU DBTF ZPV'MM OFFE UP TUBSU ContextLoaderServlet BGUFS $BNFM)UUQ5SBOTQPSU4FSWMFU MJLF UIJT:

<web-app> <servlet> <servlet-name>CamelServlet</servlet-name> <servlet-class> org.apache.camel.component.servlet.CamelHttpTransportServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>SpringApplicationContext</servlet-name> <servlet-class> org.springframework.web.context.ContextLoaderServlet </servlet-class> <load-on-startup>2</load-on-startup>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

909

2MB@FCV QEB OBI>QFSB M>QE CLO @>JBI-PBOSIBQ BKAMLFKQ 4JODF XF BSF CJOEJOH UIF )UUQ USBOTQPSU XJUI B QVCMJTIFE TFSWMFU, BOE XF EPO'U LOPX UIF TFSWMFU'T BQQMJDBUJPO DPOUFYU QBUI, UIF camel-servlet FOEQPJOU VTFT UIF SFMBUJWF QBUI UP TQFDJGZ UIF FOEQPJOU'T 63-. " DMJFOU DBO BDDFTT UIF camelservlet FOEQPJOU UISPVHI UIF TFSWMFU QVCMJTI BEESFTT: ("http://localhost:8080/camel/services") + RELATIVE_PATH("/hello").

</servlet> <web-app>

2>JMIB TEBK RPFKD .2&F


'SPN ">JBI 2.6.0, ZPV DBO QVCMJTI UIF $BNFM)UUQ5SBOTQPSU4FSWMFU BT BO 04(J TFSWJDF XJUI IFMQ PG 4QSJOH%. MJLF UIJT.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/ schema/osgi/spring-osgi.xsd"> <bean id="camelServlet" class="org.apache.camel.component.servlet.CamelHttpTransportServlet"> </bean> <!-Enlist it in OSGi service registry This will cause two things: 1) As the pax web whiteboard extender is running the CamelServlet will be registered with the OSGi HTTP Service 2) It will trigger the HttpRegistry in other bundles so the servlet is made known there too --> <osgi:service ref="camelServlet"> <osgi:interfaces> <value>javax.servlet.Servlet</value> <value>org.apache.camel.component.http.CamelServlet</value> </osgi:interfaces> <osgi:service-properties> <entry key="alias" value="/camel/services" />

910

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<entry key="matchOnUriPrefix" value="true" /> <entry key="servlet-name" value="CamelServlet"/> </osgi:service-properties> </osgi:service> </beans>

5IFO VTF UIJT TFSWJDF JO ZPVS DBNFM SPVUF MJLF UIJT:


<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/ schema/osgi/spring-osgi.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd"> <osgi:reference id="servletref" interface="org.apache.camel.component.http.CamelServlet"> <osgi:listener bind-method="register" unbind-method="unregister"> <ref bean="httpRegistry"/> </osgi:listener> </osgi:reference> <bean id="httpRegistry" class="org.apache.camel.component.servlet.DefaultHttpRegistry"/> <bean id="servlet" class="org.apache.camel.component.servlet.ServletComponent"> <property name="httpRegistry" ref="httpRegistry" /> </bean> <bean id="servletProcessor" class="org.apache.camel.itest.osgi.servlet.ServletProcessor" /> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <!-- notice how we can use the servlet scheme which is that osgi:reference above --> <from uri="servlet:///hello"/> <process ref="servletProcessor"/> </route> </camelContext> </beans>

'PS WFSTJPOT QSJPS UP $BNFM 2.6 ZPV DBO VTF BO Activator UP QVCMJTI UIF $BNFM)UUQ5SBOTQPSU4FSWMFU PO UIF 04(J QMBUGPSN

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

911

import java.util.Dictionary; import java.util.Hashtable; import import import import import import import import import org.apache.camel.component.servlet.CamelHttpTransportServlet; org.osgi.framework.BundleActivator; org.osgi.framework.BundleContext; org.osgi.framework.ServiceReference; org.osgi.service.http.HttpContext; org.osgi.service.http.HttpService; org.slf4j.Logger; org.slf4j.LoggerFactory; org.springframework.osgi.context.BundleContextAware;

public final class ServletActivator implements BundleActivator, BundleContextAware { private static final transient Logger LOG = LoggerFactory.getLogger(ServletActivator.class); private static boolean registerService; /** * HttpService reference. */ private ServiceReference httpServiceRef; /** * Called when the OSGi framework starts our bundle */ public void start(BundleContext bc) throws Exception { registerServlet(bc); } /** * Called when the OSGi framework stops our bundle */ public void stop(BundleContext bc) throws Exception { if (httpServiceRef != null) { bc.ungetService(httpServiceRef); httpServiceRef = null; } } protected void registerServlet(BundleContext bundleContext) throws Exception { httpServiceRef = bundleContext.getServiceReference(HttpService.class.getName()); if (httpServiceRef != null && !registerService) { LOG.info("Register the servlet service"); final HttpService httpService = (HttpService)bundleContext.getService(httpServiceRef); if (httpService != null) { // create a default context to share between registrations final HttpContext httpContext = httpService.createDefaultHttpContext(); // register the hello world servlet final Dictionary<String, String> initParams = new Hashtable<String, String>();

912

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

initParams.put("matchOnUriPrefix", "false"); initParams.put("servlet-name", "CamelServlet"); httpService.registerServlet("/camel/services", // alias new CamelHttpTransportServlet(), // register servlet initParams, // init params httpContext // http context ); registerService = true; } } } public void setBundleContext(BundleContext bc) { try { registerServlet(bc); } catch (Exception e) { LOG.error("Cannot register the servlet, the reason is " + e); } } }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4FSWMFU 5PNDBU &YBNQMF 4FSWMFU 5PNDBU /P 4QSJOH &YBNQMF )551 +FUUZ

2'(1. 2$"41(38 ".,/.-$-3


S>FI>?IB >P LC ">JBI 2.5 5IF PEFOL-PB@ROFQV DPNQPOFOU JO $BNFM JT B TFDVSJUZ GPDVTFE DPNQPOFOU, CBTFE PO UIF "QBDIF 4IJSP TFDVSJUZ QSPKFDU. "QBDIF 4IJSP JT B QPXFSGVM BOE GMFYJCMF PQFO-TPVSDF TFDVSJUZ GSBNFXPSL UIBU DMFBOMZ IBOEMFT BVUIFOUJDBUJPO, BVUIPSJ[BUJPO, FOUFSQSJTF TFTTJPO NBOBHFNFOU BOE DSZQUPHSBQIZ. 5IF PCKFDUJWF PG UIF "QBDIF 4IJSP QSPKFDU JT UP QSPWJEF UIF NPTU SPCVTU BOE DPNQSFIFOTJWF BQQMJDBUJPO TFDVSJUZ GSBNFXPSL BWBJMBCMF XIJMF BMTP CFJOH WFSZ FBTZ UP VOEFSTUBOE BOE FYUSFNFMZ TJNQMF UP VTF. 5IJT DBNFM TIJSP-TFDVSJUZ DPNQPOFOU BMMPXT BVUIFOUJDBUJPO BOE BVUIPSJ[BUJPO TVQQPSU UP CF BQQMJFE UP EJGGFSFOU TFHNFOUT PG B DBNFM SPVUF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

913

4IJSP TFDVSJUZ JT BQQMJFE PO B SPVUF VTJOH B $BNFM 1PMJDZ. " 1PMJDZ JO $BNFM VUJMJ[FT B TUSBUFHZ QBUUFSO GPS BQQMZJOH JOUFSDFQUPST PO $BNFM 1SPDFTTPST. *U PGGFSJOH UIF BCJMJUZ UP BQQMZ DSPTTDVUUJOH DPODFSOT (GPS FYBNQMF. TFDVSJUZ, USBOTBDUJPOT FUD) PO TFDUJPOT/TFHNFOUT PG B DBNFM SPVUF. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-shiro</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

2EFOL 2B@ROFQV !>PF@P 5P FNQMPZ 4IJSP TFDVSJUZ PO B DBNFM SPVUF, B 4IJSP4FDVSJUZ1PMJDZ PCKFDU NVTU CF JOTUBOUJBUFE XJUI TFDVSJUZ DPOGJHVSBUJPO EFUBJMT (JODMVEJOH VTFST, QBTTXPSET, SPMFT FUD). 5IJT PCKFDU NVTU UIFO CF BQQMJFE UP B DBNFM SPVUF. 5IJT 4IJSP4FDVSJUZ1PMJDZ 0CKFDU NBZ BMTP CF SFHJTUFSFE JO UIF $BNFM SFHJTUSZ (+/%* PS "QQMJDBUJPO$POUFYU3FHJTUSZ) BOE UIFO VUJMJ[FE PO PUIFS SPVUFT JO UIF $BNFM $POUFYU. $POGJHVSBUJPO EFUBJMT BSF QSPWJEFE UP UIF 4IJSP4FDVSJUZ1PMJDZ VTJOH BO *OJ GJMF (QSPQFSUJFT GJMF) PS BO *OJ PCKFDU. 5IF *OJ GJMF JT B TUBOEBSE 4IJSP DPOGJHVSBUJPO GJMF DPOUBJOJOH VTFS/SPMF EFUBJMT BT TIPXO CFMPX
[users] # user 'ringo' with password 'starr' and the 'sec-level1' role ringo = starr, sec-level1 george = harrison, sec-level2 john = lennon, sec-level3 paul = mccartney, sec-level3 [roles] # 'sec-level3' role has all permissions, indicated by the # wildcard '*' sec-level3 = * # The 'sec-level2' role can do anything with access of permission # readonly (*) to help sec-level2 = zone1:* # The 'sec-level1' role can do anything with access of permission # readonly sec-level1 = zone1:readonly:*

914

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

(KPQ>KQF>QFKD > 2EFOL2B@ROFQV/LIF@V .?GB@Q " 4IJSP4FDVSJUZ1PMJDZ PCKFDU JT JOTUBOUJBUFE BT GPMMPXT


private final String iniResourcePath = "classpath:shiro.ini"; private final byte[] passPhrase = { (byte) 0x08, (byte) 0x09, (byte) 0x0A, (byte) 0x0B, (byte) 0x0C, (byte) 0x0D, (byte) 0x0E, (byte) 0x0F, (byte) 0x10, (byte) 0x11, (byte) 0x12, (byte) 0x13, (byte) 0x14, (byte) 0x15, (byte) 0x16, (byte) 0x17}; List<permission> permissionsList = new ArrayList<permission>(); Permission permission = new WildcardPermission("zone1:readwrite:*"); permissionsList.add(permission); final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy(iniResourcePath, passPhrase, true, permissionsList);

2EFOL2B@ROFQV/LIF@V .MQFLKP
->JB
iniResourcePath or ini

#BC>RIQ 5>IRB
none

3VMB
3FTPVSDF 4USJOH PS *OJ 0CKFDU

#BP@OFMQFLK
" NBOEBUPSZ 3FTPVSDF 4USJOH GPS UIF JOJ3FTPVSDF1BUI PS BO JOTUBODF PG BO *OJ PCKFDU NVTU CF QBTTFE UP UIF TFDVSJUZ QPMJDZ. 3FTPVSDFT DBO CF BDRVJSFE GSPN UIF GJMF TZTUFN, DMBTTQBUI, PS 63-T XIFO QSFGJYFE XJUI "GJMF:, DMBTTQBUI:, PS VSM:" SFTQFDUJWFMZ. 'PS F.H "DMBTTQBUI:TIJSP.JOJ" " QBTT1ISBTF UP EFDSZQU 4IJSP4FDVSJUZ5PLFO(T) TFOU BMPOH XJUI .FTTBHF &YDIBOHFT 4FUUJOH UP FOTVSF SF-BVUIFOUJDBUJPO PO FWFSZ JOEJWJEVBM SFRVFTU. *G TFU UP GBMTF, UIF VTFS JT BVUIFOUJDBUFE BOE MPDLFE TVDI UIBO POMZ SFRVFTUT GSPN UIF TBNF VTFS HPJOH GPSXBSE BSF BVUIFOUJDBUFE. " -JTU PG QFSNJTTJPOT SFRVJSFE JO PSEFS GPS BO BVUIFOUJDBUFE VTFS UP CF BVUIPSJ[FE UP QFSGPSN GVSUIFS BDUJPO J.F DPOUJOVF GVSUIFS PO UIF SPVUF. *G OP 1FSNJTTJPOT MJTU JT QSPWJEFE UP UIF 4IJSP4FDVSJUZ1PMJDZ PCKFDU, UIFO BVUIPSJ[BUJPO JT EFFNFE BT OPU SFRVJSFE 4IJSP TIJQT XJUI "&4 & #MPXGJTI CBTFE $JQIFS4FSWJDFT. :PV NBZ VTF POF UIFTF PS QBTT JO ZPVS PXO $JQIFS JNQMFNFOUBUJPO

passPhrase

An AES 128 based key true

CZUF<>

alwaysReauthenticate

CPPMFBO

permissionsList

none

-JTU<1FSNJTTJPO>

cipherService

AES

PSH.BQBDIF.TIJSP.DSZQUP.$JQIFS4FSWJDF

MMIVFKD 2EFOL

RQEBKQF@>QFLK LK > ">JBI 1LRQB

5IF 4IJSP4FDVSJUZ1PMJDZ, UFTUT BOE QFSNJUT JODPNJOH NFTTBHF FYDIBOHFT DPOUBJOJOH B FODSZQUFE 4FDVSJUZ5PLFO JO UIF .FTTBHF )FBEFS UP QSPDFFE GVSUIFS GPMMPXJOH QSPQFS BVUIFOUJDBUJPO. 5IF 4FDVSJUZ5PLFO PCKFDU DPOUBJOT B 6TFSOBNF/1BTTXPSE EFUBJMT UIBU BSF VTFE UP EFUFSNJOF XIFSF UIF VTFS JT B WBMJE VTFS.
protected RouteBuilder createRouteBuilder() throws Exception { final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy("classpath:shiro.ini", passPhrase); return new RouteBuilder() { public void configure() { onException(UnknownAccountException.class).

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

915

to("mock:authenticationException"); onException(IncorrectCredentialsException.class). to("mock:authenticationException"); onException(LockedAccountException.class). to("mock:authenticationException"); onException(AuthenticationException.class). to("mock:authenticationException"); from("direct:secureEndpoint"). to("log:incoming payload"). policy(securityPolicy). to("mock:success"); } }; }

MMIVFKD 2EFOL

RQELOFW>QFLK LK > ">JBI 1LRQB

"VUIPSJ[BUJPO DBO CF BQQMJFE PO B DBNFM SPVUF CZ BTTPDJBUJOH B 1FSNJTTJPOT -JTU XJUI UIF 4IJSP4FDVSJUZ1PMJDZ. 5IF 1FSNJTTJPOT -JTU TQFDJGJFT UIF QFSNJTTJPOT OFDFTTBSZ GPS UIF VTFS UP QSPDFFE XJUI UIF FYFDVUJPO PG UIF SPVUF TFHNFOU. *G UIF VTFS EPFT OPU IBWF UIF QSPQFS QFSNJTTJPO TFU, UIF SFRVFTU JT OPU BVUIPSJ[FE UP DPOUJOVF BOZ GVSUIFS.
protected RouteBuilder createRouteBuilder() throws Exception { final ShiroSecurityPolicy securityPolicy = new ShiroSecurityPolicy("./src/test/resources/securityconfig.ini", passPhrase); return new RouteBuilder() { public void configure() { onException(UnknownAccountException.class). to("mock:authenticationException"); onException(IncorrectCredentialsException.class). to("mock:authenticationException"); onException(LockedAccountException.class). to("mock:authenticationException"); onException(AuthenticationException.class). to("mock:authenticationException"); from("direct:secureEndpoint"). to("log:incoming payload"). policy(securityPolicy). to("mock:success"); } }; }

916

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

"OB>QFKD > 2EFOL2B@ROFQV3LHBK >KA FKGB@QFKD FQ FKQL > ,BPP>DB $U@E>KDB " 4IJSP4FDVSJUZ5PLFO PCKFDU NBZ CF DSFBUFE BOE JOKFDUFE JOUP B .FTTBHF &YDIBOHF VTJOH B 4IJSP 1SPDFTTPS DBMMFE 4IJSP4FDVSJUZ5PLFO*OKFDUPS. "O FYBNQMF PG JOKFDUJOH B 4IJSP4FDVSJUZ5PLFO VTJOH B 4IJSP4FDVSJUZ5PLFO*OKFDUPS JO UIF DMJFOU JT TIPXO CFMPX
ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("ringo", "starr"); ShiroSecurityTokenInjector shiroSecurityTokenInjector = new ShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); from("direct:client"). process(shiroSecurityTokenInjector). to("direct:secureEndpoint");

2BKAFKD ,BPP>DBP QL OLRQBP PB@ROBA ?V > 2EFOL2B@ROFQV/LIF@V .FTTBHFT BOE .FTTBHF &YDIBOHFT TFOU BMPOH UIF DBNFM SPVUF XIFSF UIF TFDVSJUZ QPMJDZ JT BQQMJFE OFFE UP CF BDDPNQBOJFE CZ B 4FDVSJUZ5PLFO JO UIF &YDIBOHF )FBEFS. 5IF 4FDVSJUZ5PLFO JT BO FODSZQUFE PCKFDU UIBU IPMET B 6TFSOBNF BOE 1BTTXPSE. 5IF 4FDVSJUZ5PLFO JT FODSZQUFE VTJOH "&4 128 CJU TFDVSJUZ CZ EFGBVMU BOE DBO CF DIBOHFE UP BOZ DJQIFS PG ZPVS DIPJDF. (JWFO CFMPX JT BO FYBNQMF PG IPX B SFRVFTU NBZ CF TFOU VTJOH B 1SPEVDFS5FNQMBUF JO $BNFM BMPOH XJUI B 4FDVSJUZ5PLFO

@Test public void testSuccessfulShiroAuthenticationWithNoAuthorization() throws Exception { //Incorrect password ShiroSecurityToken shiroSecurityToken = new ShiroSecurityToken("ringo", "stirr"); // TestShiroSecurityTokenInjector extends ShiroSecurityTokenInjector TestShiroSecurityTokenInjector shiroSecurityTokenInjector = new TestShiroSecurityTokenInjector(shiroSecurityToken, passPhrase); successEndpoint.expectedMessageCount(1); failureEndpoint.expectedMessageCount(0); template.send("direct:secureEndpoint", shiroSecurityTokenInjector); successEndpoint.assertIsSatisfied(); failureEndpoint.assertIsSatisfied(); }

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

917

2(/ ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.5 5IF PFM DPNQPOFOU JO $BNFM JT B DPNNVOJDBUJPO DPNQPOFOU, CBTFE PO UIF +BJO 4*1 JNQMFNFOUBUJPO (BWBJMBCMF VOEFS UIF +$1 MJDFOTF). 4FTTJPO *OJUJBUJPO 1SPUPDPM (4*1) JT BO *&5'-EFGJOFE TJHOBMJOH QSPUPDPM, XJEFMZ VTFE GPS DPOUSPMMJOH NVMUJNFEJB DPNNVOJDBUJPO TFTTJPOT TVDI BT WPJDF BOE WJEFP DBMMT PWFS *OUFSOFU 1SPUPDPM (*1).5IF 4*1 QSPUPDPM JT BO "QQMJDBUJPO -BZFS QSPUPDPM EFTJHOFE UP CF JOEFQFOEFOU PG UIF VOEFSMZJOH USBOTQPSU MBZFS; JU DBO SVO PO 5SBOTNJTTJPO $POUSPM 1SPUPDPM (5$1), 6TFS %BUBHSBN 1SPUPDPM (6%1) PS 4USFBN $POUSPM 5SBOTNJTTJPO 1SPUPDPM (4$51). 5IF +BJO 4*1 JNQMFNFOUBUJPO TVQQPSUT 5$1 BOE 6%1 POMZ. 5IF $BNFM 4*1 DPNQPOFOU LKIV TVQQPSUT UIF 4*1 1VCMJTI BOE 4VCTDSJCF DBQBCJMJUZ BT EFTDSJCFE JO UIF 3'$3903 - 4FTTJPO *OJUJBUJPO 1SPUPDPM (4*1) &YUFOTJPO GPS &WFOU 5IJT DBNFM DPNQPOFOU TVQQPSUT CPUI QSPEVDFS BOE DPOTVNFS FOEQPJOUT. $BNFM 4*1 1SPEVDFST (&WFOU 1VCMJTIFST) BOE 4*1 $POTVNFST (&WFOU 4VCTDSJCFST) DPNNVOJDBUF FWFOU & TUBUF JOGPSNBUJPO UP FBDI PUIFS VTJOH BO JOUFSNFEJBSZ FOUJUZ DBMMFE B 4*1 1SFTFODF "HFOU (B TUBUFGVM CSPLFSJOH FOUJUZ). 'PS 4*1 CBTFE DPNNVOJDBUJPO, B 4*1 4UBDL XJUI B MJTUFOFS JRPQ CF JOTUBOUJBUFE PO CPUI UIF 4*1 1SPEVDFS BOE $POTVNFS (VTJOH TFQBSBUF QPSUT JG VTJOH MPDBMIPTU). 5IJT JT OFDFTTBSZ JO PSEFS UP TVQQPSU UIF IBOETIBLFT & BDLOPXMFEHFNFOUT FYDIBOHFE CFUXFFO UIF 4*1 4UBDLT EVSJOH DPNNVOJDBUJPO. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-sip</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q 5IF 63* TDIFNF GPS B TJQ FOEQPJOU JT BT GPMMPXT:


sip://johndoe@localhost:99999[?options] sips://johndoe@localhost:99999/[?options]

5IJT DPNQPOFOU TVQQPSUT QSPEVDFS BOE DPOTVNFS FOEQPJOUT GPS CPUI 5$1 BOE 6%1. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&...

918

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.MQFLKP 5IF 4*1 $PNQPOFOU PGGFST BO FYUFOTJWF TFU PG DPOGJHVSBUJPO PQUJPOT & DBQBCJMJUZ UP DSFBUF DVTUPN TUBUFGVM IFBEFST OFFEFE UP QSPQBHBUF TUBUF WJB UIF 4*1 QSPUPDPM.
->JB
stackName transport fromUser fromHost fromPort toUser toHost toPort maxforwards eventId eventHeaderName maxMessageSize cacheConnections consumer automaticDialogSupport contentType contentSubType receiveTimeoutMillis useRouterForAllUris msgExpiration presenceAgent

#BC>RIQ 5>IRB
NAME_NOT_SET tcp c c c c c c 0 c c 1048576 false false off text xml 10000 false 3600 false

#BP@OFMQFLK
/BNF PG UIF 4*1 4UBDL JOTUBODF BTTPDJBUFE XJUI BO 4*1 &OEQPJOU. 4FUUJOH GPS DIPJDF PG USBOTQPSU QPUPDPM. 7BMJE DIPJDFT BSF "UDQ" PS "VEQ". 6TFSOBNF PG UIF NFTTBHF PSJHJOBUPS. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA @RPQLJ %OLJ'B>ABO FP PMB@FCFBA. )PTUOBNF PG UIF NFTTBHF PSJHJOBUPS. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA %OLJ'B>ABO FP PMB@FCFBA 1PSU PG UIF NFTTBHF PSJHJOBUPS. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA %OLJ'B>ABO FP PMB@FCFBA 6TFSOBNF PG UIF NFTTBHF SFDFJWFS. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA @RPQLJ 3L'B>ABO FP PMB@FCFBA. )PTUOBNF PG UIF NFTTBHF SFDFJWFS. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA 3L'B>ABO FP PMB@FCFBA 1PSUOBNF PG UIF NFTTBHF SFDFJWFS. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA 3L'B>ABO FP PMB@FCFBA UIF OVNCFS PG JOUFSNFEJBSJFT UIBU NBZ GPSXBSE UIF NFTTBHF UP UIF NFTTBHF SFDFJWFS. .MQFLK>I PBQQFKD. ,>V >IQBOK>QFSBIV ?B PBQ RPFKD >P OBDFPQOV ?>PBA ,>U%LOT>OAP'B>ABO 4FUUJOH GPS B 4USJOH CBTFE FWFOU *E. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA %OLJ'B>ABO FP PMB@FCFBA 4FUUJOH GPS B 4USJOH CBTFE FWFOU *E. ,>KA>QLOV PBQQFKD RKIBPP > OBDFPQOV ?>PBA %OLJ'B>ABO FP PMB@FCFBA 4FUUJOH GPS NBYJNVN BMMPXFE .FTTBHF TJ[F JO CZUFT. 4IPVME DPOOFDUJPOT CF DBDIFE CZ UIF 4JQ4UBDL UP SFEVDF DPTU PG DPOOFDUJPO DSFBUJPO. 5IJT JT VTFGVM JG UIF DPOOFDUJPO JT VTFE GPS MPOH SVOOJOH DPOWFSTBUJPOT. 5IJT TFUUJOH JT VTFE UP EFUFSNJOF XIFUIFS UIF LJOE PG IFBEFS ('SPN)FBEFS,5P)FBEFS FUD) UIBU OFFET UP CF DSFBUFE GPS UIJT FOEQPJOU 4FUUJOH UP TQFDJGZ XIFUIFS FWFSZ DPNNVOJDBUJPO TIPVME CF BTTPDJBUFE XJUI B EJBMPH. 4FUUJOH GPS DPOUFOU5ZQF DBO CF TFU UP BOZ WBMJE .JNF5ZQF. 4FUUJOH GPS DPOUFOU4VC5ZQF DBO CF TFU UP BOZ WBMJE .JNF4VC5ZQF. 4FUUJOH GPS TQFDJGZJOH BNPVOU PG UJNF UP XBJU GPS B 3FTQPOTF BOE/PS "DLOPXMFEHFNFOU DBO CF SFDFJWFE GSPN BOPUIFS 4*1 TUBDL 5IJT TFUUJOH JT VTFE XIFO SFRVFTUT BSF TFOU UP UIF 1SFTFODF "HFOU WJB B QSPYZ. 5IF BNPVOU PG UJNF B NFTTBHF SFDFJWFE BU BO FOEQPJOU JT DPOTJEFSFE WBMJE 5IJT TFUUJOH JT VTFE UP EJTUJOHJTI CFUXFFO B 1SFTFODF "HFOU & B DPOTVNFS. 5IJT JT EVF UP UIF GBDU UIBU UIF 4*1 $BNFM DPNQPOFOU TIJQT XJUI B CBTJD 1SFTFODF "HFOU (GPS UFTUJOH QVSQPTFT POMZ). $POTVNFST IBWF UP TFU UIJT GMBH UP USVF.

1BDFPQOV ?>PBA .MQFLKP 4*1 SFRVJSFT B OVNCFS PG IFBEFST UP CF TFOU/SFDFJWFE BT QBSU PG B SFRVFTU. 5IFTF 4*1 IFBEFS DBO CF FOMJTUFE JO UIF 3FHJTUSZ, TVDI BT JO UIF 4QSJOH 9.- GJMF. 5IF WBMVFT UIBU DPVME CF QBTTFE JO, BSF UIF GPMMPXJOH:
->JB
fromHeader toHeader viaHeaders contentTypeHeader callIdHeader maxForwardsHeader eventHeader

#BP@OFMQFLK
B DVTUPN )FBEFS PCKFDU DPOUBJOJOH NFTTBHF PSJHJOBUPS TFUUJOHT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.'SPN)FBEFS B DVTUPN )FBEFS PCKFDU DPOUBJOJOH NFTTBHF SFDFJWFS TFUUJOHT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.5P)FBEFS -JTU PG DVTUPN )FBEFS PCKFDUT PG UIF UZQF KBWBY.TJQ.IFBEFS.7JB)FBEFS. &BDI 7JB)FBEFS DPOUBJOJOH B QSPYZ BEESFTT GPS SFRVFTU GPSXBSEJOH. (/PUF UIJT IFBEFS JT BVUPNBUJDBMMZ VQEBUFE CZ FBDI QSPYZ XIFO UIF SFRVFTU BSSJWFT BU JUT MJTUFOFS) B DVTUPN )FBEFS PCKFDU DPOUBJOJOH NFTTBHF DPOUFOU EFUBJMT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.$POUFOU5ZQF)FBEFS B DVTUPN )FBEFS PCKFDU DPOUBJOJOH DBMM EFUBJMT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.$BMM*E)FBEFS B DVTUPN )FBEFS PCKFDU DPOUBJOJOH EFUBJMT PO NBYJNVN QSPYZ GPSXBSET. 5IJT IFBEFS QMBDFT B MJNJU PO UIF WJB)FBEFST QPTTJCMF. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS..BY'PSXBSET)FBEFS B DVTUPN )FBEFS PCKFDU DPOUBJOJOH FWFOU EFUBJMT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.&WFOU)FBEFS

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

919

contactHeader expiresHeader extensionHeader

BO PQUJPOBM DVTUPN )FBEFS PCKFDU DPOUBJOJOH WFSCPTF DPOUBDU EFUBJMT (FNBJM, QIPOF OVNCFS FUD). .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.$POUBDU)FBEFS B DVTUPN )FBEFS PCKFDU DPOUBJOJOH NFTTBHF FYQJSBUJPO EFUBJMT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.&YQJSFT)FBEFS B DVTUPN )FBEFS PCKFDU DPOUBJOJOH VTFS/BQQMJDBUJPO TQFDJGJD EFUBJMT. .VTU JNQMFNFOU UIF UZQF KBWBY.TJQ.IFBEFS.&YUFOTJPO)FBEFS

2BKAFKD ,BPP>DBP QL/COLJ > 2(/ BKAMLFKQ

"OB>QFKD > ">JBI 2(/ /R?IFPEBO


*O UIF FYBNQMF CFMPX, B 4*1 1VCMJTIFS JT DSFBUFE UP TFOE 4*1 &WFOU QVCMJDBUJPOT UP B VTFS "BHFOU!MPDBMIPTU:5152". 5IJT JT UIF BEESFTT PG UIF 4*1 1SFTFODF "HFOU XIJDI BDUT BT B CSPLFS CFUXFFO UIF 4*1 1VCMJTIFS BOE 4VCTDSJCFS ` VTJOH B 4*1 4UBDL OBNFE DMJFOU ` VTJOH B SFHJTUSZ CBTFE FWFOU)FBEFS DBMMFE FWU)ES/BNF ` VTJOH B SFHJTUSZ CBTFE FWFOU*E DBMMFE FWU*E ` GSPN B 4*1 4UBDL XJUI -JTUFOFS TFU VQ BT VTFS2!MPDBMIPTU:3534 ` 5IF &WFOU CFJOH QVCMJTIFE JT &7&/5@" ` " .BOEBUPSZ )FBEFS DBMMFE 3&26&45@.&5)0% JT TFU UP 3FRVFTU.1VCMJTI UIFSFCZ TFUUJOH VQ UIF FOEQPJOU BT B &WFOU QVCMJTIFS"
producerTemplate.sendBodyAndHeader(

"sip://agent@localhost:5152?stackName=client&eventHeaderName=evtHdrName&eventId=evtid&fromUser=user2&f "EVENT_A", "REQUEST_METHOD", Request.PUBLISH);

"OB>QFKD > ">JBI 2(/ 2R?P@OF?BO


*O UIF FYBNQMF CFMPX, B 4*1 4VCTDSJCFS JT DSFBUFE UP SFDFJWF 4*1 &WFOU QVCMJDBUJPOT TFOU UP B VTFS "KPIOEPF!MPDBMIPTU:5154" ` VTJOH B 4*1 4UBDL OBNFE 4VCTDSJCFS ` SFHJTUFSJOH XJUI B 1SFTFODF "HFOU VTFS DBMMFE BHFOU!MPDBMIPTU:5152 ` VTJOH B SFHJTUSZ CBTFE FWFOU)FBEFS DBMMFE FWU)ES/BNF. 5IF FWU)ES/BNF DPOUBJOT UIF &WFOU XIJDI JT TF UP "&WFOU@"" ` VTJOH B SFHJTUSZ CBTFE FWFOU*E DBMMFE FWU*E
@Override protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { @Override public void configure() throws Exception { // Create PresenceAgent

920

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("sip://agent@localhost:5152?stackName=PresenceAgent&presenceAgent=true&eventHeaderName=evtHdrName .to("mock:neverland"); // Create Sip Consumer(Event Subscriber)

from("sip://johndoe@localhost:5154?stackName=Subscriber&toUser=agent&toHost=localhost&toPort=5152&even .to("log:ReceivedEvent?level=DEBUG") .to("mock:notification"); } }; }

3EB ">JBI 2(/ @LJMLKBKQ >IPL PEFMP TFQE > /OBPBK@B DBKQ QE>Q FP JB>KQ QL ?B RPBA CLO 3BPQFKD >KA #BJL MROMLPBP LKIV. "O FYBNQMF PG JOTUBOUJBUJOH B 1SFTFODF "HFOU JT HJWFO BCPWF. /PUF UIBU UIF 1SFTFODF "HFOU JT TFU VQ BT B VTFS BHFOU!MPDBMIPTU:5152 BOE JT DBQBCMF PG DPNNVOJDBUJOH XJUI CPUI 1VCMJTIFS BT XFMM BT 4VCTDSJCFS. *U IBT B TFQBSBUF 4*1 TUBDL/BNF EJTUJODU GSPN 1VCMJTIFS BT XFMM BT 4VCTDSJCFS. 8IJMF JU JT TFU VQ BT B $BNFM $POTVNFS, JU EPFT OPU BDUVBMMZ TFOE BOZ NFTTBHFT BMPOH UIF SPVUF UP UIF FOEQPJOU "NPDL:OFWFSMBOE".

2,// ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.2 5IJT DPNQPOFOU QSPWJEFT BDDFTT UP BO 4.4$ (4IPSU .FTTBHF 4FSWJDF $FOUFS) PWFS UIF 4.11 QSPUPDPM UP TFOE BOE SFDFJWF 4.4. 5IF +4.11 JT VTFE. 2Q>OQFKD TFQE ">JBI 2.9, ZPV BSF BMTP BCMF UP FYFDVUF 3FQMBDF4N, 2VFSZ4N, 4VCNJU.VMUJ, $BODFM4N BOE %BUB4N. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-smpp</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
smpp://[username@]hostname[:port][?options] smpps://[username@]hostname[:port][?options]

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

921

*G OP RPBOK>JB JT QSPWJEFE, UIFO $BNFM XJMM QSPWJEF UIF EFGBVMU WBMVF smppclient. *G OP MLOQ OVNCFS JT QSPWJEFE, UIFO $BNFM XJMM QSPWJEF UIF EFGBVMU WBMVF 2775. ">JBI 2.3: *G UIF QSPUPDPM OBNF JT "TNQQT", DBNFM-TNQQ XJUI USZ UP VTF 44-4PDLFU UP JOJU B DPOOFDUJPO UP UIF TFSWFS. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... 41( .MQFLKP
->JB
password systemType

#BC>RIQ 5>IRB
password cp

#BP@OFMQFLK
4QFDJGJFT UIF QBTTXPSE UP VTF UP MPH JO UP UIF 4.4$. 5IJT QBSBNFUFS JT VTFE UP DBUFHPSJ[F UIF UZQF PG &4.& (&YUFSOBM 4IPSU .FTTBHF &OUJUZ) UIBU JT CJOEJOH UP UIF 4.4$ (NBY. 13 DIBSBDUFST). ">JBI 2.11 %FGJOFT UIF EBUB DPEJOH BDDPSEJOH UIF 4.11 3.4 TQFDJGJDBUJPO, TFDUJPO 5.2.19. (1SJPS UP ">JBI 2.9, UIJT PQUJPO JT BMTP TVQQPSUFE.) &YBNQMF EBUB FODPEJOHT BSF: 0: 4.4$ %FGBVMU "MQIBCFU 3: -BUJO 1 (*40-8859-1) 4: 0DUFU VOTQFDJGJFE (8-CJU CJOBSZ) 8: 6$42 (*40/*&$-10646) 13: &YUFOEFE ,BOKJ +*4(9 0212-1990) ">JBI 2.5 %FGJOFT FODPEJOH PG EBUB BDDPSEJOH UIF 4.11 3.4 TQFDJGJDBUJPO, TFDUJPO 5.2.19. 5IJT PQUJPO JT NBQQFE UP Alphabet.java BOE VTFE UP DSFBUF UIF byte[] XIJDI JT TFOE UP UIF 4.4$. &YBNQMF BMQIBCFUT BSF: 0: 4.4$ %FGBVMU "MQIBCFU 4: 8 CJU "MQIBCFU 8: 6$42 "MQIBCFU LKIV CLO 2R?JFQ2J, 1BMI>@B2J >KA 2R?JFQ,RIQF %FGJOFT UIF FODPEJOH TDIFNF PG UIF TIPSU NFTTBHF VTFS EBUB. %FGJOFT UIF JOUFSWBM JO NJMMJTFDPOET CFUXFFO UIF DPOGJEFODF DIFDLT. 5IF DPOGJEFODF DIFDL JT VTFE UP UFTU UIF DPNNVOJDBUJPO QBUI CFUXFFO BO &4.& BOE BO 4.4$. %FGJOFT UIF NBYJNVN QFSJPE PG JOBDUJWJUZ BMMPXFE BGUFS B USBOTBDUJPO, BGUFS XIJDI BO 4.11 FOUJUZ NBZ BTTVNF UIBU UIF TFTTJPO JT OP MPOHFS BDUJWF. 5IJT UJNFS NBZ CF BDUJWF PO FJUIFS DPNNVOJDBUJOH 4.11 FOUJUZ (J.F. 4.4$ PS &4.&). %FGJOFT UIF JOJUJBM EFMBZ JO NJMMJTFDPOET BGUFS UIF DPOTVNFS/QSPEVDFS USJFT UP SFDPOOFDU UP UIF 4.4$, BGUFS UIF DPOOFDUJPO XBT MPTU. %FGJOFT UIF JOUFSWBM JO NJMMJTFDPOET CFUXFFO UIF SFDPOOFDU BUUFNQUT, JG UIF DPOOFDUJPO UP UIF 4.4$ XBT MPTU BOE UIF QSFWJPVT XBT OPU TVDDFFE. LKIV CLO 2R?JFQ2J, 1BMI>@B2J, 2R?JFQ,RIQF >KA #>Q>2J *T VTFE UP SFRVFTU BO 4.4$ EFMJWFSZ SFDFJQU BOE/PS 4.& PSJHJOBUFE BDLOPXMFEHFNFOUT. 5IF GPMMPXJOH WBMVFT BSF EFGJOFE: 0: /P 4.4$ EFMJWFSZ SFDFJQU SFRVFTUFE. 1: 4.4$ EFMJWFSZ SFDFJQU SFRVFTUFE XIFSF GJOBM EFMJWFSZ PVUDPNF JT TVDDFTT PS GBJMVSF. 2: 4.4$ EFMJWFSZ SFDFJQU SFRVFTUFE XIFSF UIF GJOBM EFMJWFSZ PVUDPNF JT EFMJWFSZ GBJMVSF. 5IF TFSWJDF UZQF QBSBNFUFS DBO CF VTFE UP JOEJDBUF UIF 4.4 "QQMJDBUJPO TFSWJDF BTTPDJBUFE XJUI UIF NFTTBHF. 5IF GPMMPXJOH HFOFSJD TFSWJDF@UZQFT BSF EFGJOFE: CMT: $FMMVMBS .FTTBHJOH CPT: $FMMVMBS 1BHJOH VMN: 7PJDF .BJM /PUJGJDBUJPO VMA: 7PJDF .BJM "MFSUJOH WAP: 8JSFMFTT "QQMJDBUJPO 1SPUPDPM USSD: 6OTUSVDUVSFE 4VQQMFNFOUBSZ 4FSWJDFT %BUB %FGJOFT UIF BEESFTT PG 4.& (4IPSU .FTTBHF &OUJUZ) XIJDI PSJHJOBUFE UIJT NFTTBHF. LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF, ">K@BI2J >KA #>Q>2J %FGJOFT UIF EFTUJOBUJPO 4.& BEESFTT. 'PS NPCJMF UFSNJOBUFE NFTTBHFT, UIJT JT UIF EJSFDUPSZ OVNCFS PG UIF SFDJQJFOU .4. %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF 4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 5IF GPMMPXJOH 50/ WBMVFT BSF EFGJOFE: 0: 6OLOPXO 1: *OUFSOBUJPOBM 2: /BUJPOBM 3: /FUXPSL 4QFDJGJD 4: 4VCTDSJCFS /VNCFS 5: "MQIBOVNFSJD 6: "CCSFWJBUFE

dataCoding

alphabet

encoding enquireLinkTimer transactionTimer initialReconnectDelay reconnectDelay

ISO-8859-1 5000 10000 5000 5000

registeredDelivery

serviceType

CMT

sourceAddr destAddr

1616 1717

sourceAddrTon

922

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

destAddrTon

LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF, ">K@BI2J >KA #>Q>2J %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF 4.& EFTUJOBUJPO BEESFTT QBSBNFUFST. 4BNF BT UIF sourceAddrTon WBMVFT EFGJOFE BCPWF. %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF 4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 5IF GPMMPXJOH /1* WBMVFT BSF EFGJOFE: 0: 6OLOPXO 1: *4%/ (&163/&164) 2: %BUB (9.121) 3: 5FMFY ('.69) 6: -BOE .PCJMF (&.212) 8: /BUJPOBM 9: 1SJWBUF 10: &3.&4 13: *OUFSOFU (*1) 18: 8"1 $MJFOU *E (UP CF EFGJOFE CZ 8"1 'PSVN) LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF, ">K@BI2J >KA #>Q>2J %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF 4.& EFTUJOBUJPO BEESFTT QBSBNFUFST. 4BNF BT UIF sourceAddrNpi WBMVFT EFGJOFE BCPWF. LKIV CLO 2R?JFQ2J >KA 2R?JFQ,RIQF "MMPXT UIF PSJHJOBUJOH 4.& UP BTTJHO B QSJPSJUZ MFWFM UP UIF TIPSU NFTTBHF. 'PVS 1SJPSJUZ -FWFMT BSF TVQQPSUFE: 0: -FWFM 0 (MPXFTU) QSJPSJUZ 1: -FWFM 1 QSJPSJUZ 2: -FWFM 2 QSJPSJUZ 3: -FWFM 3 (IJHIFTU) QSJPSJUZ LKIV CLO 2R?JFQ2J >KA 2R?JFQ,RIQF 6TFE UP SFRVFTU UIF 4.4$ UP SFQMBDF B QSFWJPVTMZ TVCNJUUFE NFTTBHF, UIBU JT TUJMM QFOEJOH EFMJWFSZ. 5IF 4.4$ XJMM SFQMBDF BO FYJTUJOH NFTTBHF QSPWJEFE UIBU UIF TPVSDF BEESFTT, EFTUJOBUJPO BEESFTT BOE TFSWJDF UZQF NBUDI UIF TBNF GJFMET JO UIF OFX NFTTBHF. 5IF GPMMPXJOH SFQMBDF JG QSFTFOU GMBH WBMVFT BSF EFGJOFE: 0: %PO'U SFQMBDF 1: 3FQMBDF %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF 4.&. 6TF UIF sourceAddrTon WBMVFT EFGJOFE BCPWF. %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF 4.&. 6TF UIF sourceAddrNpi WBMVFT EFGJOFE BCPWF. ">JBI 2.8 LKT>OAP 4FTTJPOT DBO CF MB[JMZ DSFBUFE UP BWPJE FYDFQUJPOT, JG UIF 4.4$ JT OPU BWBJMBCMF XIFO UIF $BNFM QSPEVDFS JT TUBSUFE. ">JBI 2.11 LKT>OAP $BNFM XJMM DIFDL UIF JO NFTTBHF IFBEFST '$BNFM4NQQ4ZTUFN*E' BOE '$BNFM4NQQ1BTTXPSE' PG UIF GJSTU FYDIBOHF. *G UIFZ BSF QSFTFOU, $BNFM XJMM VTF UIFTF EBUB UP DPOOFDU UP UIF 4.4$. ">JBI 2.9.1: *G ZPV OFFE UP UVOOFM 4.11 UISPVHI B )551 QSPYZ, TFU UIJT BUUSJCVUF UP UIF IPTUOBNF PS JQ BEESFTT PG ZPVS )551 QSPYZ. ">JBI 2.9.1: *G ZPV OFFE UP UVOOFM 4.11 UISPVHI B )551 QSPYZ, TFU UIJT BUUSJCVUF UP UIF QPSU PG ZPVS )551 QSPYZ. ">JBI 2.9.1: *G ZPVS )551 QSPYZ SFRVJSFT CBTJD BVUIFOUJDBUJPO, TFU UIJT BUUSJCVUF UP UIF VTFSOBNF SFRVJSFE GPS ZPVS )551 QSPYZ. ">JBI 2.9.1: *G ZPVS )551 QSPYZ SFRVJSFT CBTJD BVUIFOUJDBUJPO, TFU UIJT BUUSJCVUF UP UIF QBTTXPSE SFRVJSFE GPS ZPVS )551 QSPYZ. ">JBI 2.9.3: :PV DBO SFGFS UP B org.jsmpp.session.SessionStateListener JO UIF Registry UP SFDFJWF DBMMCBDLT XIFO UIF TFTTJPO TUBUF DIBOHFE. ">JBI 2.11: :PV DBO TQFDJGZ UIF BEESFTT SBOHF GPS UIF SmppConsumer BT EFGJOFE JO TFDUJPO 5.2.7 PG UIF 4.11 3.4 TQFDJGJDBUJPO. 5IF SmppConsumer XJMM SFDFJWF NFTTBHFT POMZ GSPN 4.4$'T XIJDI UBSHFU BO BEESFTT (.4*4%/ PS *1 BEESFTT) XJUIJO UIJT SBOHF.

sourceAddrNpi

destAddrNpi

priorityFlag

replaceIfPresentFlag

typeOfNumber numberingPlanIndicator

0 0

lazySessionCreation

false

httpProxyHost httpProxyPort httpProxyUsername httpProxyPassword sessionStateListener

null 3128 null null null

addressRange

""

:PV DBO IBWF BT NBOZ PG UIFTF PQUJPOT BT ZPV MJLF.

smpp://smppclient@localhost:2775?password=password&enquireLinkTimer=3000&transactionTimer=5000&systemT

/OLAR@BO ,BPP>DB 'B>ABOP 5IF GPMMPXJOH NFTTBHF IFBEFST DBO CF VTFE UP BGGFDU UIF CFIBWJPS PG UIF 4.11 QSPEVDFS
'B>ABO
CamelSmppDestAddr

3VMB
List/String

#BP@OFMQFLK
LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF, ">K@BI2J >KA #>Q>2J %FGJOFT UIF EFTUJOBUJPO 4.& BEESFTT(FT). 'PS NPCJMF UFSNJOBUFE NFTTBHFT, UIJT JT UIF EJSFDUPSZ OVNCFS PG UIF SFDJQJFOU .4. *T NVTU CF B List<String> GPS 4VCNJU.VMUJ BOE B String PUIFSXJTF. LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF, ">K@BI2J >KA #>Q>2J %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF 4.& EFTUJOBUJPO BEESFTT QBSBNFUFST. 6TF UIF sourceAddrTon 63* PQUJPO WBMVFT EFGJOFE BCPWF. LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF, ">K@BI2J >KA #>Q>2J %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF 4.& EFTUJOBUJPO BEESFTT QBSBNFUFST. 6TF UIF 63* PQUJPO sourceAddrNpi WBMVFT EFGJOFE BCPWF.

CamelSmppDestAddrTon CamelSmppDestAddrNpi

Byte Byte

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

923

CamelSmppSourceAddr CamelSmppSourceAddrTon CamelSmppSourceAddrNpi CamelSmppServiceType CamelSmppRegisteredDelivery CamelSmppPriorityFlag

String Byte Byte String Byte Byte

%FGJOFT UIF BEESFTT PG 4.& (4IPSU .FTTBHF &OUJUZ) XIJDI PSJHJOBUFE UIJT NFTTBHF. %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF 4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 6TF UIF sourceAddrTon 63* PQUJPO WBMVFT EFGJOFE BCPWF. %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF 4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 6TF UIF 63* PQUJPO sourceAddrNpi WBMVFT EFGJOFE BCPWF. 5IF TFSWJDF UZQF QBSBNFUFS DBO CF VTFE UP JOEJDBUF UIF 4.4 "QQMJDBUJPO TFSWJDF BTTPDJBUFE XJUI UIF NFTTBHF. 6TF UIF 63* PQUJPO serviceType TFUUJOHT BCPWF. LKIV CLO 2R?JFQ2J, 1BMI>@B2J, 2R?JFQ,RIQF >KA #>Q>2J *T VTFE UP SFRVFTU BO 4.4$ EFMJWFSZ SFDFJQU BOE/PS 4.& PSJHJOBUFE BDLOPXMFEHFNFOUT. 6TF UIF 63* PQUJPO registeredDelivery TFUUJOHT BCPWF. LKIV CLO 2R?JFQ2J >KA 2R?JFQ,RIQF "MMPXT UIF PSJHJOBUJOH 4.& UP BTTJHO B QSJPSJUZ MFWFM UP UIF TIPSU NFTTBHF. 6TF UIF 63* PQUJPO priorityFlag TFUUJOHT BCPWF. LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF >KA 1BMI>@B2J 5IJT QBSBNFUFS TQFDJGJFT UIF TDIFEVMFE UJNF BU XIJDI UIF NFTTBHF EFMJWFSZ TIPVME CF GJSTU BUUFNQUFE. *U EFGJOFT FJUIFS UIF BCTPMVUF EBUF BOE UJNF PS SFMBUJWF UJNF GSPN UIF DVSSFOU 4.4$ UJNF BU XIJDI EFMJWFSZ PG UIJT NFTTBHF XJMM CF BUUFNQUFE CZ UIF 4.4$. *U DBO CF TQFDJGJFE JO FJUIFS BCTPMVUF UJNF GPSNBU PS SFMBUJWF UJNF GPSNBU. 5IF FODPEJOH PG B UJNF GPSNBU JT TQFDJGJFE JO DIBQUFS 7.1.1. JO UIF TNQQ TQFDJGJDBUJPO W3.4. LKIV CLO 2R?JFQ2J, 2R?JFQ,RIQF >KA 1BMI>@B2J 5IF WBMJEJUZ QFSJPE QBSBNFUFS JOEJDBUFT UIF 4.4$ FYQJSBUJPO UJNF, BGUFS XIJDI UIF NFTTBHF TIPVME CF EJTDBSEFE JG OPU EFMJWFSFE UP UIF EFTUJOBUJPO. *G JU'T QSPWJEFE BT Date, JU'T JOUFSQSFUFE BT BCTPMVUF UJNF. ">JBI 2.9.1 LKT>OAP: *U DBO CF EFGJOFE JO BCTPMVUF UJNF GPSNBU PS SFMBUJWF UJNF GPSNBU JG ZPV QSPWJEF JU BT String BT TQFDJGJFE JO DIBQUFS 7.1.1 JO UIF TNQQ TQFDJGJDBUJPO W3.4. LKIV CLO 2R?JFQ2J >KA 2R?JFQ,RIQF 5IF SFQMBDF JG QSFTFOU GMBH QBSBNFUFS JT VTFE UP SFRVFTU UIF 4.4$ UP SFQMBDF B QSFWJPVTMZ TVCNJUUFE NFTTBHF, UIBU JT TUJMM QFOEJOH EFMJWFSZ. 5IF 4.4$ XJMM SFQMBDF BO FYJTUJOH NFTTBHF QSPWJEFE UIBU UIF TPVSDF BEESFTT, EFTUJOBUJPO BEESFTT BOE TFSWJDF UZQF NBUDI UIF TBNF GJFMET JO UIF OFX NFTTBHF. 5IF GPMMPXJOH WBMVFT BSF EFGJOFE: 0: %PO'U SFQMBDF 1: 3FQMBDF ">JBI 2.5 %LO 2R?JFQ2J, 2R?JFQ,RIQF >KA 1BMI>@B2J (1SJPS UP ">JBI 2.9 VTF CamelSmppDataCoding JOTUFBE PG CamelSmppAlphabet.) 5IF EBUB DPEJOH BDDPSEJOH UP UIF 4.11 3.4 TQFDJGJDBUJPO, TFDUJPO 5.2.19. 6TF UIF 63* PQUJPO alphabet TFUUJOHT BCPWF.

CamelSmppScheduleDeliveryTime

Date

CamelSmppValidityPeriod

String/Date

CamelSmppReplaceIfPresentFlag

Byte

CamelSmppAlphabet / CamelSmppDataCoding

Byte

5IF GPMMPXJOH NFTTBHF IFBEFST BSF VTFE CZ UIF 4.11 QSPEVDFS UP TFU UIF SFTQPOTF GSPN UIF 4.4$ JO UIF NFTTBHF IFBEFS
'B>ABO
CamelSmppId

3VMB
List<String>/String

#BP@OFMQFLK
5IF JE UP JEFOUJGZ UIF TVCNJUUFE TIPSU NFTTBHF(T) GPS MBUFS VTF. %OLJ ">JBI 2.9.0: *O DBTF PG B 3FQMBDF4N, 2VFSZ4N, $BODFM4N BOE %BUB4N UIJT IFBEFS WBVMF JT B String. *O DBTF PG B 4VCNJU4N PS 4VCNJU.VMUJ4N UIJT IFBEFS WBVMF JT B List<String>. %OLJ ">JBI 2.9 LKT>OAP LKIV CLO 2R?JFQ2J >KA 2R?JFQ,RIQF2J 5IF UPUBM OVNCFS PG NFTTBHFT XIJDI IBT CFFO TFOU. %OLJ ">JBI 2.9 LKT>OAP LKIV CLO 2R?JFQ,RIQF2J 5IF FSSPST XIJDI PDDVSSFE CZ TFOEJOH UIF TIPSU NFTTBHF(T) UIF GPSN Map<String, List<Map<String, Object>>> (NFTTBHF*% : (EFTU"EES : BEESFTT, FSSPS : FSSPS$PEF)).

CamelSmppSentMessageCount

Integer Map<String, List<Map<String, Object>>>

CamelSmppError

"LKPRJBO ,BPP>DB 'B>ABOP 5IF GPMMPXJOH NFTTBHF IFBEFST BSF VTFE CZ UIF 4.11 DPOTVNFS UP TFU UIF SFRVFTU EBUB GSPN UIF 4.4$ JO UIF NFTTBHF IFBEFS
'B>ABO
CamelSmppSequenceNumber

3VMB
Integer

#BP@OFMQFLK
LKIV CLO IBOQ-LQFCF@>QFLK, #BIFSBO2J >KA #>Q>2J " TFRVFODF OVNCFS BMMPXT B SFTQPOTF 1%6 UP CF DPSSFMBUFE XJUI B SFRVFTU 1%6. 5IF BTTPDJBUFE 4.11 SFTQPOTF 1%6 NVTU QSFTFSWF UIJT GJFME. LKIV CLO IBOQ-LQFCF@>QFLK, #BIFSBO2J >KA #>Q>2J 5IF DPNNBOE JE GJFME JEFOUJGJFT UIF QBSUJDVMBS 4.11 1%6. 'PS UIF DPNQMFUF MJTU PG EFGJOFE WBMVFT TFF DIBQUFS 5.1.2.1 JO UIF TNQQ TQFDJGJDBUJPO W3.4. LKIV CLO IBOQ-LQFCF@>QFLK, #BIFSBO2J >KA #>Q>2J %FGJOFT UIF BEESFTT PG 4.& (4IPSU .FTTBHF &OUJUZ) XIJDI PSJHJOBUFE UIJT NFTTBHF. LKIV CLO IBOQ-LQFCF@>QFLK >KA #>Q>2J %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF 4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 6TF UIF 63* PQUJPO sourceAddrNpi WBMVFT EFGJOFE BCPWF. LKIV CLO IBOQ-LQFCF@>QFLK >KA #>Q>2J %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF 4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 6TF UIF sourceAddrTon 63* PQUJPO WBMVFT EFGJOFE BCPWF.

CamelSmppCommandId

Integer

CamelSmppSourceAddr

String

CamelSmppSourceAddrNpi

Byte

CamelSmppSourceAddrTon

Byte

924

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

CamelSmppEsmeAddr CamelSmppEsmeAddrNpi CamelSmppEsmeAddrTon CamelSmppId

String Byte Byte String

LKIV CLO IBOQ-LQFCF@>QFLK %FGJOFT UIF EFTUJOBUJPO &4.& BEESFTT. 'PS NPCJMF UFSNJOBUFE NFTTBHFT, UIJT JT UIF EJSFDUPSZ OVNCFS PG UIF SFDJQJFOU .4. LKIV CLO IBOQ-LQFCF@>QFLK %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) UP CF VTFE JO UIF &4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 6TF UIF 63* PQUJPO sourceAddrNpi WBMVFT EFGJOFE BCPWF. LKIV CLO IBOQ-LQFCF@>QFLK %FGJOFT UIF UZQF PG OVNCFS (50/) UP CF VTFE JO UIF &4.& PSJHJOBUPS BEESFTT QBSBNFUFST. 6TF UIF sourceAddrTon 63* PQUJPO WBMVFT EFGJOFE BCPWF. LKIV CLO PJP@ #BIFSBOV1B@BFMQ >KA #>Q>2J 5IF NFTTBHF *% BMMPDBUFE UP UIF NFTTBHF CZ UIF 4.4$ XIFO PSJHJOBMMZ TVCNJUUFE. LKIV CLO PJP@ #BIFSBOV1B@BFMQ /VNCFS PG TIPSU NFTTBHFT EFMJWFSFE. 5IJT JT POMZ SFMFWBOU XIFSF UIF PSJHJOBM NFTTBHF XBT TVCNJUUFE UP B EJTUSJCVUJPO MJTU.5IF WBMVF JT QBEEFE XJUI MFBEJOH [FSPT JG OFDFTTBSZ. LKIV CLO PJP@ #BIFSBOV1B@BFMQ 5IF UJNF BOE EBUF BU XIJDI UIF TIPSU NFTTBHF SFBDIFE JU'T GJOBM TUBUF. 5IF GPSNBU JT BT GPMMPXT: ::..%%IINN. LKIV CLO PJP@ #BIFSBOV1B@BFMQ: 5IF GJOBM TUBUVT PG UIF NFTTBHF. 5IF GPMMPXJOH WBMVFT BSF EFGJOFE: DELIVRD: .FTTBHF JT EFMJWFSFE UP EFTUJOBUJPO EXPIRED: .FTTBHF WBMJEJUZ QFSJPE IBT FYQJSFE. DELETED: .FTTBHF IBT CFFO EFMFUFE. UNDELIV: .FTTBHF JT VOEFMJWFSBCMF ACCEPTD: .FTTBHF JT JO BDDFQUFE TUBUF (J.F. IBT CFFO NBOVBMMZ SFBE PO CFIBMG PG UIF TVCTDSJCFS CZ DVTUPNFS TFSWJDF) UNKNOWN: .FTTBHF JT JO JOWBMJE TUBUF REJECTD: .FTTBHF JT JO B SFKFDUFE TUBUF LKIV CLO #>Q>2J 5IF $PNNBOE TUBUVT PG UIF NFTTBHF. LKIV CLO PJP@ #BIFSBOV1B@BFMQ 8IFSF BQQSPQSJBUF UIJT NBZ IPME B /FUXPSL TQFDJGJD FSSPS DPEF PS BO 4.4$ FSSPS DPEF GPS UIF BUUFNQUFE EFMJWFSZ PG UIF NFTTBHF. 5IFTF FSSPST BSF /FUXPSL PS 4.4$ TQFDJGJD BOE BSF OPU JODMVEFE IFSF. LKIV CLO PJP@ #BIFSBOV1B@BFMQ 5IF UJNF BOE EBUF BU XIJDI UIF TIPSU NFTTBHF XBT TVCNJUUFE. *O UIF DBTF PG B NFTTBHF XIJDI IBT CFFO SFQMBDFE, UIJT JT UIF EBUF UIBU UIF PSJHJOBM NFTTBHF XBT SFQMBDFE. 5IF GPSNBU JT BT GPMMPXT: ::..%%IINN. LKIV CLO PJP@ #BIFSBOV1B@BFMQ /VNCFS PG TIPSU NFTTBHFT PSJHJOBMMZ TVCNJUUFE. 5IJT JT POMZ SFMFWBOU XIFO UIF PSJHJOBM NFTTBHF XBT TVCNJUUFE UP B EJTUSJCVUJPO MJTU.5IF WBMVF JT QBEEFE XJUI MFBEJOH [FSPT JG OFDFTTBSZ. LKIV CLO #BIFSBO2J >KA #>Q>2J: %FGJOFT UIF EFTUJOBUJPO 4.& BEESFTT. 'PS NPCJMF UFSNJOBUFE NFTTBHFT, UIJT JT UIF EJSFDUPSZ OVNCFS PG UIF SFDJQJFOU .4. LKIV CLO #BIFSBO2J: 5IJT QBSBNFUFS TQFDJGJFT UIF TDIFEVMFE UJNF BU XIJDI UIF NFTTBHF EFMJWFSZ TIPVME CF GJSTU BUUFNQUFE. *U EFGJOFT FJUIFS UIF BCTPMVUF EBUF BOE UJNF PS SFMBUJWF UJNF GSPN UIF DVSSFOU 4.4$ UJNF BU XIJDI EFMJWFSZ PG UIJT NFTTBHF XJMM CF BUUFNQUFE CZ UIF 4.4$. *U DBO CF TQFDJGJFE JO FJUIFS BCTPMVUF UJNF GPSNBU PS SFMBUJWF UJNF GPSNBU. 5IF FODPEJOH PG B UJNF GPSNBU JT TQFDJGJFE JO 4FDUJPO 7.1.1. JO UIF TNQQ TQFDJGJDBUJPO W3.4. LKIV CLO #BIFSBO2J 5IF WBMJEJUZ QFSJPE QBSBNFUFS JOEJDBUFT UIF 4.4$ FYQJSBUJPO UJNF, BGUFS XIJDI UIF NFTTBHF TIPVME CF EJTDBSEFE JG OPU EFMJWFSFE UP UIF EFTUJOBUJPO. *U DBO CF EFGJOFE JO BCTPMVUF UJNF GPSNBU PS SFMBUJWF UJNF GPSNBU. 5IF FODPEJOH PG BCTPMVUF BOE SFMBUJWF UJNF GPSNBU JT TQFDJGJFE JO 4FDUJPO 7.1.1 JO UIF TNQQ TQFDJGJDBUJPO W3.4. LKIV CLO #BIFSBO2J >KA #>Q>2J 5IF TFSWJDF UZQF QBSBNFUFS JOEJDBUFT UIF 4.4 "QQMJDBUJPO TFSWJDF BTTPDJBUFE XJUI UIF NFTTBHF. LKIV CLO #>Q>2J *T VTFE UP SFRVFTU BO EFMJWFSZ SFDFJQU BOE/PS 4.& PSJHJOBUFE BDLOPXMFEHFNFOUT. 4BNF WBMVFT BT JO 1SPEVDFS IFBEFS MJTU BCPWF. LKIV CLO #>Q>2J %FGJOFT UIF OVNFSJD QMBO JOEJDBUPS (/1*) JO UIF EFTUJOBUJPO BEESFTT QBSBNFUFST. 6TF UIF 63* PQUJPO sourceAddrNpi WBMVFT EFGJOFE BCPWF. LKIV CLO #>Q>2J %FGJOFT UIF UZQF PG OVNCFS (50/) JO UIF EFTUJOBUJPO BEESFTT QBSBNFUFST. 6TF UIF sourceAddrTon 63* PQUJPO WBMVFT EFGJOFE BCPWF. ">JBI 2.6 LKT>OAP: *EFOUJGJFT UIF UZQF PG BO JODPNJOH NFTTBHF: AlertNotification: BO 4.4$ BMFSU OPUJGJDBUJPO DataSm: BO 4.4$ EBUB TIPSU NFTTBHF DeliveryReceipt: BO 4.4$ EFMJWFSZ SFDFJQU DeliverSm: BO 4.4$ EFMJWFS TIPSU NFTTBHF ">JBI 2.10.5 LKT>OAP >KA LKIV CLO #BIFSBO2J 5IF PQUJPOBM QBSBNFUFST TFOE CBDL CZ UIF 4.4$.

CamelSmppDelivered

Integer

CamelSmppDoneDate

Date

CamelSmppFinalStatus

DeliveryReceiptState

CamelSmppCommandStatus CamelSmppError

Integer String

CamelSmppSubmitDate

Date

CamelSmppSubmitted

Integer

CamelSmppDestAddr

String

CamelSmppScheduleDeliveryTime

String

CamelSmppValidityPeriod

String

CamelSmppServiceType CamelSmppRegisteredDelivery CamelSmppDestAddrNpi CamelSmppDestAddrTon

String Byte Byte Byte

CamelSmppMessageType

String

CamelSmppOptionalParameters

Map<String, Object>

$U@BMQFLK E>KAIFKD 5IJT DPNQPOFOU TVQQPSUT UIF HFOFSBM $BNFM FYDFQUJPO IBOEMJOH DBQBCJMJUJFT. ">JBI 2.8 LKT>OAP: 8IFO UIF 4.11 DPOTVNFS SFDFJWFT B DeliverSm PS DataSm TIPSU

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

925

)2,// IF?O>OV 4FF UIF EPDVNFOUBUJPO PG UIF +4.11 -JCSBSZ GPS NPSF EFUBJMT BCPVU UIF VOEFSMZJOH MJCSBSZ. NFTTBHF BOE UIF QSPDFTTJOH PG UIFTF NFTTBHFT GBJMT, ZPV DBO BMTP UISPX B ProcessRequestException JOTUFBE PG IBOEMF UIF GBJMVSF. *O UIJT DBTF, UIJT FYDFQUJPO JT GPSXBSEFE UP UIF VOEFSMZJOH +4.11 MJCSBSZ XIJDI XJMM SFUVSO UIF JODMVEFE FSSPS DPEF UP UIF 4.4$. 5IJT GFBUVSF JT VTFGVM UP F.H. JOTUSVDU UIF 4.4$ UP SFTFOE UIF TIPSU NFTTBHF BU B MBUFS UJNF. 5IJT DPVME CF EPOF XJUI UIF GPMMPXJOH MJOFT PG DPEF:

from("smpp://smppclient@localhost:2775?password=password&enquireLinkTimer=3000&transactionTimer=5000&s .doTry() .to("bean:dao?method=updateSmsState") .doCatch(Exception.class) .throwException(new ProcessRequestException("update of sms state failed", 100)) .end();

1MFBTF SFGFS UP UIF 4.11 TQFDJGJDBUJPO GPS UIF DPNQMFUF MJTU PG FSSPS DPEFT BOE UIFJS NFBOJOHT. 2>JMIBP " SPVUF XIJDI TFOET BO 4.4 VTJOH UIF +BWB %4-:
from("direct:start") .to("smpp://smppclient@localhost:2775? password=password&enquireLinkTimer=3000&transactionTimer=5000&systemType=producer");

" SPVUF XIJDI TFOET BO 4.4 VTJOH UIF 4QSJOH 9.- %4-:
<route> <from uri="direct:start"/> <to uri="smpp://smppclient@localhost:2775? password=password&amp;enquireLinkTimer=3000&amp;transactionTimer=5000&amp;systemType=producer"/> </route>

" SPVUF XIJDI SFDFJWFT BO 4.4 VTJOH UIF +BWB %4-:

from("smpp://smppclient@localhost:2775?password=password&enquireLinkTimer=3000&transactionTimer=5000&s .to("bean:foo");

" SPVUF XIJDI SFDFJWFT BO 4.4 VTJOH UIF 4QSJOH 9.- %4-:

926

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<route> <from uri="smpp://smppclient@localhost:2775? password=password&amp;enquireLinkTimer=3000&amp;transactionTimer=5000&amp;systemType=consumer"/> <to uri="bean:foo"/> </route>

#B?RD ILDDFKD 5IJT DPNQPOFOU IBT MPH MFWFM #$!4&, XIJDI DBO CF IFMQGVM JO EFCVHHJOH QSPCMFNT. *G ZPV VTF MPH4K, ZPV DBO BEE UIF GPMMPXJOH MJOF UP ZPVS DPOGJHVSBUJPO:
log4j.logger.org.apache.camel.component.smpp=DEBUG

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

2-,/ ".,/.-$-3
S>FI>?IB >P LC ">JBI 2.1 5IF PKJM: DPNQPOFOU HJWFT ZPV UIF BCJMJUZ UP QPMM 4/.1 DBQBCMF EFWJDFT PS SFDFJWJOH USBQT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-snmp</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
snmp://hostname[:port][?Options]

5IF DPNQPOFOU TVQQPSUT QPMMJOH 0*% WBMVFT GSPN BO 4/.1 FOBCMFE EFWJDF BOE SFDFJWJOH USBQT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

927

2,2" PFJRI>QLO *G ZPV OFFE BO 4.4$ TJNVMBUPS GPS ZPVS UFTU, ZPV DBO VTF UIF TJNVMBUPS QSPWJEFE CZ -PHJDB. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
type protocol retries timeout snmpVersion snmpCommunity delay oids

#BC>RIQ 5>IRB
OPOF udp 2 1500 0 (XIJDI NFBOT 4/.1W1) public 60 TFDPOET OPOF

#BP@OFMQFLK
5IF UZQF PG BDUJPO ZPV XBOU UP QFSGPSN. "DUVBMMZ ZPV DBO FOUFS IFSF POLL PS TRAP. 5IF WBMVF POLL XJMM JOTUSVDU UIF FOEQPJOU UP QPMM B HJWFO IPTU GPS UIF TVQQMJFE 0*% LFZT. *G ZPV QVU JO TRAP ZPV XJMM TFUVQ B MJTUFOFS GPS 4/.1 5SBQ &WFOUT. )FSF ZPV DBO TFMFDU XIJDI QSPUPDPM UP VTF. :PV DBO VTF FJUIFS udp PS tcp. %FGJOFT IPX PGUFO B SFUSZ JT NBEF CFGPSF DBODFMJOH UIF SFRVFTU. 4FUT UIF UJNFPVU WBMVF GPS UIF SFRVFTU JO NJMMJT. 4FUT UIF TONQ WFSTJPO GPS UIF SFRVFTU. 4FUT UIF DPNNVOJUZ PDUFU TUSJOH GPS UIF TONQ SFRVFTU. %FGJOFT UIF EFMBZ JO TFDPOET CFUXFFO UP QPMM DZDMFT. %FGJOFT XIJDI WBMVFT ZPV BSF JOUFSFTUFE JO. 1MFBTF IBWF B MPPL BU UIF 8JLJQFEJB UP HFU B CFUUFS VOEFSTUBOEJOH. :PV NBZ QSPWJEF B TJOHMF 0*% PS B DPNB TFQBSBUFE MJTU PG 0*%T. &YBNQMF: PJET="1.3.6.1.2.1.1.3.0,1.3.6.1.2.1.25.3.2.1.5.1,1.3.6.1.2.1.25.3.5.1.1.1,1.3.6.1.2.1.43.5.1.1.11.1"

3EB OBPRIQ LC > MLII (JWFO UIF TJUVBUJPO, UIBU * QPMM GPS UIF GPMMPXJOH 0*%T:
Listing 1. OIDs
1.3.6.1.2.1.1.3.0 1.3.6.1.2.1.25.3.2.1.5.1 1.3.6.1.2.1.25.3.5.1.1.1 1.3.6.1.2.1.43.5.1.1.11.1

5IF SFTVMU XJMM CF UIF GPMMPXJOH:


Listing 1. Result of toString conversion
<?xml version="1.0" encoding="UTF-8"?> <snmp> <entry> <oid>1.3.6.1.2.1.1.3.0</oid> <value>6 days, 21:14:28.00</value> </entry> <entry> <oid>1.3.6.1.2.1.25.3.2.1.5.1</oid> <value>2</value>

928

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

</entry> <entry> <oid>1.3.6.1.2.1.25.3.5.1.1.1</oid> <value>3</value> </entry> <entry> <oid>1.3.6.1.2.1.43.5.1.1.11.1</oid> <value>6</value> </entry> <entry> <oid>1.3.6.1.2.1.1.1.0</oid> <value>My Very Special Printer Of Brand Unknown</value> </entry> </snmp>

"T ZPV NBZCF SFDPHOJ[FE UIFSF JT POF NPSF SFTVMU UIBO SFRVFTUFE....1.3.6.1.2.1.1.1.0. 5IJT POF JT GJMMFE JO CZ UIF EFWJDF BVUPNBUJDBMMZ JO UIJT TQFDJBM DBTF. 4P JU NBZ BCTPMVUFMZ IBQQFO, UIBU ZPV SFDFJWF NPSF UIBO ZPV SFRVFTUFE...CF QSFQBSFE. $U>JMIBP 1PMMJOH B SFNPUF EFWJDF:
snmp:192.168.178.23:161?protocol=udp&type=POLL&oids=1.3.6.1.2.1.1.5.0

4FUUJOH VQ B USBQ SFDFJWFS (-LQB QE>Q KL .(# FKCL FP KBBABA EBOB!):


snmp:127.0.0.1:162?protocol=udp&type=TRAP

%OLJ ">JBI 2.10.0, ZPV DBO HFU UIF DPNNVOJUZ PG 4/.1 53"1 XJUI NFTTBHF IFBEFS 'TFDVSJUZ/BNF', QFFS BEESFTT PG UIF 4/.1 53"1 XJUI NFTTBHF IFBEFS 'QFFS"EESFTT'. 3PVUJOH FYBNQMF JO +BWB: (DPOWFSUT UIF 4/.1 1%6 UP 9.- 4USJOH)
from("snmp:192.168.178.23:161?protocol=udp&type=POLL&oids=1.3.6.1.2.1.1.5.0"). convertBodyTo(String.class). to("activemq:snmp.states");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

929

2/1(-& (-3$&1 3(.- ".,/.-$-3


5IF PMOFKD-FKQBDO>QFLK: DPNQPOFOU QSPWJEFT B CSJEHF GPS $BNFM DPNQPOFOUT UP UBML UP TQSJOH JOUFHSBUJPO FOEQPJOUT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-integration</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
spring-integration:defaultChannelName[?options]

8IFSF ABC>RIQ"E>KKBI->JB SFQSFTFOUT UIF EFGBVMU DIBOOFM OBNF XIJDI JT VTFE CZ UIF 4QSJOH *OUFHSBUJPO 4QSJOH DPOUFYU. *U XJMM FRVBM UP UIF inputChannel OBNF GPS UIF 4QSJOH *OUFHSBUJPO DPOTVNFS BOE UIF outputChannel OBNF GPS UIF 4QSJOH *OUFHSBUJPO QSPWJEFS. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
inputChannel outputChannel inOut

3VMB
4USJOH 4USJOH 4USJOH

#BP@OFMQFLK
5IF 4QSJOH JOUFHSBUJPO JOQVU DIBOOFM OBNF UIBU UIJT FOEQPJOU XBOUT UP DPOTVNF GSPN, XIFSF UIF TQFDJGJFE DIBOOFM OBNF JT EFGJOFE JO UIF 4QSJOH DPOUFYU. 5IF 4QSJOH JOUFHSBUJPO PVUQVU DIBOOFM OBNF UIBU JT VTFE UP TFOE NFTTBHFT UP UIF 4QSJOH JOUFHSBUJPO DPOUFYU. 5IF FYDIBOHF QBUUFSO UIBU UIF 4QSJOH JOUFHSBUJPO FOEQPJOU TIPVME VTF. *G inOut=true UIFO B SFQMZ DIBOOFM JT FYQFDUFE, FJUIFS GSPN UIF 4QSJOH *OUFHSBUJPO .FTTBHF IFBEFS PS DPOGJHVSFE PO UIF FOEQPJOU.

4P>DB 5IF 4QSJOH JOUFHSBUJPO DPNQPOFOU JT B CSJEHF UIBU DPOOFDUT $BNFM FOEQPJOUT XJUI 4QSJOH JOUFHSBUJPO FOEQPJOUT UISPVHI UIF 4QSJOH JOUFHSBUJPO'T JOQVU DIBOOFMT BOE PVUQVU DIBOOFMT. 6TJOH UIJT DPNQPOFOU, XF DBO TFOE $BNFM NFTTBHFT UP 4QSJOH *OUFHSBUJPO FOEQPJOUT PS SFDFJWF NFTTBHFT GSPN 4QSJOH JOUFHSBUJPO FOEQPJOUT JO B $BNFM SPVUJOH DPOUFYU.

930

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

$U>JMIBP

4PFKD QEB 2MOFKD FKQBDO>QFLK BKAMLFKQ


:PV DBO TFU VQ B 4QSJOH JOUFHSBUJPO FOEQPJOU VTJOH B 63*, BT GPMMPXT:
<beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/ spring/camel-spring.xsd"> <!-- spring integration channels --> <channel id="inputChannel"/> <channel id="outputChannel"/> <channel id="onewayChannel"/> <!-- spring integration service activators --> <service-activator input-channel="inputChannel" ref="helloService" method="sayHello"/> <service-activator input-channel="onewayChannel" ref="helloService" method="greet"/> <!-- custom bean --> <beans:bean id="helloService" class="org.apache.camel.component.spring.integration.HelloWorldService"/> <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:twowayMessage"/> <to uri="spring-integration:inputChannel?inOut=true&amp;inputChannel=outputChannel"/> </route> <route> <from uri="direct:onewayMessage"/> <to uri="spring-integration:onewayChannel?inOut=false"/> </route> </camelContext>

<!-- spring integration channels --> <channel id="requestChannel"/> <channel id="responseChannel"/> <!-- cusom Camel processor --> <beans:bean id="myProcessor" class="org.apache.camel.component.spring.integration.MyProcessor"/>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

931

<!-- Camel route --> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="spring-integration://requestChannel?outputChannel=responseChannel&amp;inOut=true"/> <process ref="myProcessor"/> </route> </camelContext>

0S EJSFDUMZ VTJOH B 4QSJOH JOUFHSBUJPO DIBOOFM OBNF:


<beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/ spring/camel-spring.xsd"> <!-- spring integration channel --> <channel id="outputChannel"/> <camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="outputChannel"/> <to uri="mock:result"/> </route> </camelContext>

3EB 2LRO@B >KA 3>ODBQ >A>MQBO


4QSJOH JOUFHSBUJPO BMTP QSPWJEFT UIF 4QSJOH JOUFHSBUJPO'T TPVSDF BOE UBSHFU BEBQUFST, XIJDI DBO SPVUF NFTTBHFT GSPN B 4QSJOH JOUFHSBUJPO DIBOOFM UP B $BNFM FOEQPJOU PS GSPN B $BNFM FOEQPJOU UP B 4QSJOH JOUFHSBUJPO DIBOOFM. 5IJT FYBNQMF VTFT UIF GPMMPXJOH OBNFTQBDFT:
<beans:beans xmlns="http://www.springframework.org/schema/integration" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel-si="http://camel.apache.org/schema/spring/integration" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/ schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration

932

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

http://www.springframework.org/schema/integration/spring-integration.xsd http://camel.apache.org/schema/spring/integration http://camel.apache.org/ schema/spring/integration/camel-spring-integration.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/ camel-spring.xsd ">

:PV DBO CJOE ZPVS TPVSDF PS UBSHFU UP B $BNFM FOEQPJOU BT GPMMPXT:


<!-- Create the camel context here --> <camelContext id="camelTargetContext" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:EndpointA" /> <to uri="mock:result" /> </route> <route> <from uri="direct:EndpointC"/> <process ref="myProcessor"/> </route> </camelContext> <!-- We can bind the camelTarget to the camel context's endpoint by specifying the camelEndpointUri attribute --> <camel-si:camelTarget id="camelTargetA" camelEndpointUri="direct:EndpointA" expectReply="false"> <camel-si:camelContextRef>camelTargetContext</camel-si:camelContextRef> </camel-si:camelTarget> <camel-si:camelTarget id="camelTargetB" camelEndpointUri="direct:EndpointC" replyChannel="channelC" expectReply="true"> <camel-si:camelContextRef>camelTargetContext</camel-si:camelContextRef> </camel-si:camelTarget> <camel-si:camelTarget id="camelTargetD" camelEndpointUri="direct:EndpointC" expectReply="true"> <camel-si:camelContextRef>camelTargetContext</camel-si:camelContextRef> </camel-si:camelTarget> <beans:bean id="myProcessor" class="org.apache.camel.component.spring.integration.MyProcessor"/>

<!-- spring integration channels --> <channel id="channelA"/> <channel id="channelB"/> <channel id="channelC"/> <!-- spring integration service activator --> <service-activator input-channel="channelB" output-channel="channelC" ref="helloService" method="sayHello"/> <!-- custom bean -->

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

933

<beans:bean id="helloService" class="org.apache.camel.component.spring.integration.HelloWorldService"/> <camelContext id="camelSourceContext" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:OneWay"/> <to uri="direct:EndpointB"/> </route> <route> <from uri="direct:TwoWay"/> <to uri="direct:EndpointC"/> </route> </camelContext> <!-- camelSource will redirect the message coming for direct:EndpointB to the spring requestChannel channelA --> <camel-si:camelSource id="camelSourceA" camelEndpointUri="direct:EndpointB" requestChannel="channelA" expectReply="false"> <camel-si:camelContextRef>camelSourceContext</camel-si:camelContextRef> </camel-si:camelSource> <!-- camelSource will redirect the message coming for direct:EndpointC to the spring requestChannel channelB then it will pull the response from channelC and put the response message back to direct:EndpointC --> <camel-si:camelSource id="camelSourceB" camelEndpointUri="direct:EndpointC" requestChannel="channelB" replyChannel="channelC" expectReply="true"> <camel-si:camelContextRef>camelSourceContext</camel-si:camelContextRef> </camel-si:camelSource>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

2/1(-& +# / ".,/.-$-3
S>FI>?IB PFK@B ">JBI 2.11 5IF PMOFKD-IA>M: DPNQPOFOU QSPWJEFT B $BNFM XSBQQFS GPS 4QSJOH -%"1. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:

934

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-ldap</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
spring-ldap:springLdapTemplate[?options]

8IFSF PMOFKD+A>M3BJMI>QB JT UIF OBNF PG UIF 4QSJOH -%"1 5FNQMBUF CFBO. *O UIJT CFBO, ZPV DPOGJHVSF UIF 63- BOE UIF DSFEFOUJBMT GPS ZPVS -%"1 BDDFTT. .MQFLKP
->JB
operation scope

3VMB
4USJOH 4USJOH

#BP@OFMQFLK
5IF -%"1 PQFSBUJPO UP CF QFSGPSNFE. .VTU CF POF PG search, bind, PS unbind. 5IF TDPQF PG UIF TFBSDI PQFSBUJPO. .VTU CF POF PG object, onelevel, PS subtree, TFF BMTP IUUQ://FO.XJLJQFEJB.PSH/XJLJ/ -JHIUXFJHIU@%JSFDUPSZ@"DDFTT@1SPUPDPM#4FBSDI@BOE@$PNQBSF

*G BO VOTVQQPSUFE WBMVF JT TQFDJGJFE GPS TPNF PQUJPO, UIF DPNQPOFOU UISPXT BO UnsupportedOperationException. 4P>DB

5IF DPNQPOFOU TVQQPSUT QSPEVDFS FOEQPJOU POMZ. "O BUUFNQU UP DSFBUF B DPOTVNFS FOEQPJOU XJMM SFTVMU JO BO UnsupportedOperationException. 5IF CPEZ PG UIF NFTTBHF NVTU CF B NBQ (BO JOTUBODF PG java.util.Map). 5IJT NBQ NVTU DPOUBJO BU MFBTU BO FOUSZ XJUI UIF LFZ dn UIBU TQFDJGJFT UIF SPPU OPEF GPS UIF -%"1 PQFSBUJPO UP CF QFSGPSNFE. 0UIFS FOUSJFT PG UIF NBQ BSF PQFSBUJPO-TQFDJGJD (TFF CFMPX). 5IF CPEZ PG UIF NFTTBHF SFNBJOT VODIBOHFE GPS UIF bind BOE unbind PQFSBUJPOT. 'PS UIF search PQFSBUJPO, UIF CPEZ JT TFU UP UIF SFTVMU PG UIF TFBSDI, TFF IUUQ://TUBUJD.TQSJOHTPVSDF.PSH/TQSJOH-MEBQ/TJUF/BQJEPDT/PSH/TQSJOHGSBNFXPSL/MEBQ/DPSF/ -EBQ5FNQMBUF.IUNM#TFBSDI%28KBWB.MBOH.4USJOH,%20KBWB.MBOH.4USJOH,%20JOU,%20PSH.TQSJOHGSBNFXPSL.MEBQ.DPSF."U

2B>O@E
5IF NFTTBHF CPEZ NVTU IBWF BO FOUSZ XJUI UIF LFZ filter. 5IF WBMVF NVTU CF B 4USJOH SFQSFTFOUJOH B WBMJE -%"1 GJMUFS, TFF IUUQ://FO.XJLJQFEJB.PSH/XJLJ/ -JHIUXFJHIU@%JSFDUPSZ@"DDFTT@1SPUPDPM#4FBSDI@BOE@$PNQBSF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

935

!FKA
5IF NFTTBHF CPEZ NVTU IBWF BO FOUSZ XJUI UIF LFZ attributes. 5IF WBMVF NVTU CF BO JOTUBODF PG KBWBY.OBNJOH.EJSFDUPSZ."UUSJCVUFT 5IJT FOUSZ TQFDJGJFT UIF -%"1 OPEF UP CF DSFBUFE.

4K?FKA
/P GVSUIFS FOUSJFT OFDFTTBSZ, UIF OPEF XJUI UIF TQFDJGJFE dn JT EFMFUFE. *BV ABCFKFQFLKP *O PSEFS UP BWPJE TQFMMJOH FSSPST, UIF GPMMPXJOH DPOTUBOUT BSF EFGJOFE JO org.apache.camel.springldap.SpringLdapProducer: ` QVCMJD TUBUJD GJOBM 4USJOH %/ = "EO" ` QVCMJD TUBUJD GJOBM 4USJOH '*-5&3 = "GJMUFS" ` QVCMJD TUBUJD GJOBM 4USJOH "553*#65&4 = "BUUSJCVUFT"

2/1(-& 6$! 2$15("$2 ".,/.-$-3


S>FI>?IB >P LC ">JBI 2.6 5IF PMOFKD-TP: DPNQPOFOU BMMPXT ZPV UP JOUFHSBUF XJUI 4QSJOH 8FC 4FSWJDFT. *U PGGFST CPUI client-TJEF TVQQPSU, GPS BDDFTTJOH XFC TFSWJDFT, BOE server-TJEF TVQQPSU GPS DSFBUJOH ZPVS PXO DPOUSBDU-GJSTU XFC TFSWJDFT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-ws</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q 5IF 63* TDIFNF GPS UIJT DPNQPOFOU JT BT GPMMPXT


spring-ws:[mapping-type:]address[?options]

5P FYQPTF B XFC TFSWJDF J>MMFKD-QVMB OFFET UP CF TFU UP BOZ PG UIF GPMMPXJOH:


,>MMFKD QVMB
rootqname soapaction

#BP@OFMQFLK
0GGFST UIF PQUJPO UP NBQ XFC TFSWJDF SFRVFTUT CBTFE PO UIF RVBMJGJFE OBNF PG UIF SPPU FMFNFOU DPOUBJOFE JO UIF NFTTBHF. 6TFE UP NBQ XFC TFSWJDF SFRVFTUT CBTFE PO UIF 40"1 BDUJPO TQFDJGJFE JO UIF IFBEFS PG UIF NFTTBHF.

936

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

#BMBKABK@FBP "T PG $BNFM 2.8 UIJT DPNQPOFOU TIJQT XJUI 4QSJOH-84 2.0.Y XIJDI (MJLF UIF SFTU PG $BNFM) SFRVJSFT 4QSJOH 3.0.Y.
&BSMJFS $BNFM WFSTJPOT TIJQQFE 4QSJOH-84 1.5.9 XIJDI JT DPNQBUJCMF XJUI 4QSJOH 2.5.Y BOE 3.0.Y. *O PSEFS UP SVO FBSMJFS WFSTJPOT PG camel-spring-ws PO 4QSJOH 2.5.Y ZPV OFFE UP BEE UIF spring-webmvc NPEVMF GSPN 4QSJOH 2.5.Y. *O PSEFS UP SVO 4QSJOH-84 1.5.9 PO 4QSJOH 3.0.Y ZPV OFFE UP FYDMVEF UIF 09. NPEVMF GSPN 4QSJOH 3.0.Y BT UIJT NPEVMF JT BMTP JODMVEFE JO 4QSJOH-84 1.5.9 (TFF UIJT QPTU)

uri xpathresult beanname

*O PSEFS UP NBQ XFC TFSWJDF SFRVFTUT UIBU UBSHFU B TQFDJGJD 63*. 6TFE UP NBQ XFC TFSWJDF SFRVFTUT CBTFE PO UIF FWBMVBUJPO PG BO 91BUI expression BHBJOTU UIF JODPNJOH NFTTBHF. 5IF SFTVMU PG UIF FWBMVBUJPO TIPVME NBUDI UIF 91BUI SFTVMU TQFDJGJFE JO UIF FOEQPJOU 63*. "MMPXT ZPV UP SFGFSFODF BO org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher PCKFDU JO PSEFS UP JOUFHSBUF XJUI FYJTUJOH (MFHBDZ) FOEQPJOU NBQQJOHT MJLF PayloadRootQNameEndpointMapping, SoapActionEndpointMapping, FUD

"T B DPOTVNFS UIF >AAOBPP TIPVME DPOUBJO B WBMVF SFMFWBOU UP UIF TQFDJGJFE NBQQJOH-UZQF (F.H. B 40"1 BDUJPO, 91BUI FYQSFTTJPO). "T B QSPEVDFS UIF BEESFTT TIPVME CF TFU UP UIF 63* PG UIF XFC TFSWJDF ZPVS DBMMJOH VQPO. :PV DBO BQQFOE RVFSZ LMQFLKP UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
soapAction wsAddressingAction

1BNRFOBA?
/P /P 0OMZ XIFO mappingtype JT xpathresult

#BP@OFMQFLK
40"1 BDUJPO UP JODMVEF JOTJEF B 40"1 SFRVFTU XIFO BDDFTTJOH SFNPUF XFC TFSWJDFT 84-"EESFTTJOH 1.0 BDUJPO IFBEFS UP JODMVEF XIFO BDDFTTJOH XFC TFSWJDFT. 5IF To IFBEFS JT TFU UP UIF address PG UIF XFC TFSWJDF BT TQFDJGJFE JO UIF FOEQPJOU 63* (EFGBVMU 4QSJOH-84 CFIBWJPS). 91BUI FYQSFTTJPO UP VTF JO UIF QSPDFTT PG NBQQJOH XFC TFSWJDF SFRVFTUT, TIPVME NBUDI UIF SFTVMU TQFDJGJFE CZ xpathresult ">JBI 2.10: 4FUT UIF TPDLFU SFBE UJNFPVU (JO NJMMJTFDPOET) XIJMF JOWPLJOH B XFCTFSWJDF VTJOH UIF QSPEVDFS, TFF 63-$POOFDUJPO.TFU3FBE5JNFPVU() BOE $PNNPOT)UUQ.FTTBHF4FOEFS.TFU3FBE5JNFPVU(). c5IJT PQUJPO XPSLT XIFO VTJOH UIF CVJMU-JO NFTTBHF TFOEFS JNQMFNFOUBUJPOT:cCommonsHttpMessageSendercBOEcHttpUrlConnectionMessageSender. c0OF PG UIFTF JNQMFNFOUBUJPOT XJMM CF VTFE CZ EFGBVMU GPS )551 CBTFE TFSWJDFT VOMFTT ZPV DVTUPNJ[F UIF 4QSJOH 84 DPOGJHVSBUJPO PQUJPOT TVQQMJFE UP UIF DPNQPOFOU. c*G ZPV BSF VTJOH B OPO-TUBOEBSE TFOEFS, JU JT BTTVNFE UIBU ZPV XJMM IBOEMF ZPVS PXO UJNFPVU DPOGJHVSBUJPO. ">JBI 2.10:c3FGFSFODF UP BOcorg.apache.camel.util.jsse.SSLContextParameters JOcUIFc3FHJTUSZ. c4FFc6TJOH UIF +44& $POGJHVSBUJPO 6UJMJUZ. c5IJT PQUJPO XPSLT XIFO VTJOH UIF CVJMU-JO NFTTBHF TFOEFS JNQMFNFOUBUJPOT:cCommonsHttpMessageSendercBOEcHttpUrlConnectionMessageSender. c0OF PG UIFTF JNQMFNFOUBUJPOT XJMM CF VTFE CZ EFGBVMU GPS )551 CBTFE TFSWJDFT VOMFTT ZPV DVTUPNJ[F UIF 4QSJOH 84 DPOGJHVSBUJPO PQUJPOT TVQQMJFE UP UIF DPNQPOFOU. c*G ZPV BSF VTJOH B OPO-TUBOEBSE TFOEFS, JU JT BTTVNFE UIBU ZPV XJMM IBOEMF ZPVS PXO 5-4 DPOGJHVSBUJPO.

expression

timeout

/P

sslContextParameters

/P

1BDFPQOV ?>PBA LMQFLKP


5IF GPMMPXJOH PQUJPOT DBO CF TQFDJGJFE JO UIF SFHJTUSZ (NPTU MJLFMZ B 4QSJOH "QQMJDBUJPO$POUFYU) BOE SFGFSFODFE GSPN UIF FOEQPJOU 63* VTJOH UIF # OPUBUJPO.
->JB 1BNRFOBA? #BP@OFMQFLK

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

937

webServiceTemplate messageSender messageFactory transformerFactory

/P /P /P /P 0OMZ XIFO mappingtype JT rootqname, soapaction, uri PS xpathresult /P

0QUJPO UP QSPWJEF B DVTUPN 8FC4FSWJDF5FNQMBUF. 5IJT BMMPXT GPS GVMM DPOUSPM PWFS DMJFOU-TJEF XFC TFSWJDFT IBOEMJOH; MJLF BEEJOH B DVTUPN JOUFSDFQUPS PS TQFDJGZJOH B GBVMU SFTPMWFS, NFTTBHF TFOEFS PS NFTTBHF GBDUPSZ. 0QUJPO UP QSPWJEF B DVTUPN 8FC4FSWJDF.FTTBHF4FOEFS. 'PS FYBNQMF UP QFSGPSN BVUIFOUJDBUJPO PS VTF BMUFSOBUJWF USBOTQPSUT 0QUJPO UP QSPWJEF B DVTUPN 8FC4FSWJDF.FTTBHF'BDUPSZ. 'PS FYBNQMF XIFO ZPV XBOU "QBDIF "YJPN UP IBOEMF XFC TFSWJDF NFTTBHFT JOTUFBE PG 4""+ 0QUJPO UP PWFSSJEF EFGBVMU 5SBOTGPSNFS'BDUPSZ. 5IF QSPWJEFE USBOTGPSNFS GBDUPSZ NVTU CF PG UZQF javax.xml.transform.TransformerFactory 3FGFSFODF UP BO JOTUBODF PG org.apache.camel.component.spring.ws.bean.CamelEndpointMapping JO UIF 3FHJTUSZ/"QQMJDBUJPO$POUFYU. 0OMZ POF CFBO JT SFRVJSFE JO UIF SFHJTUSZ UP TFSWF BMM $BNFM/4QSJOH-84 FOEQPJOUT. 5IJT CFBO JT BVUP-EJTDPWFSFE CZ UIF .FTTBHF%JTQBUDIFS BOE VTFE UP NBQ SFRVFTUT UP $BNFM FOEQPJOUT CBTFE PO DIBSBDUFSJTUJDT TQFDJGJFE PO UIF FOEQPJOU (MJLF SPPU 2/BNF, 40"1 BDUJPO, FUD) 0QUJPO UP QSPWJEF B DVTUPN .FTTBHF'JMUFS TJODF 2.10.3. 'PS FYBNQMF XIFO ZPV XBOU UP QSPDFTT ZPVS IFBEFST PS BUUBDINFOUT CZ ZPVS PXO.

endpointMapping

messageFilter

,BPP>DB EB>ABOP
->JB
CamelSpringWebserviceEndpointUri CamelSpringWebserviceSoapAction CamelSpringWebserviceAddressingAction

3VMB
4USJOH 4USJOH 63*

#BP@OFMQFLK
63* PG UIF XFC TFSWJDF ZPVS BDDFTTJOH BT B DMJFOU, PWFSSJEFT address QBSU PG UIF FOEQPJOU 63* )FBEFS UP TQFDJGZ UIF 40"1 BDUJPO PG UIF NFTTBHF, PWFSSJEFT soapAction PQUJPO JG QSFTFOU 6TF UIJT IFBEFS UP TQFDJGZ UIF 84-"EESFTTJOH BDUJPO PG UIF NFTTBHF, PWFSSJEFT wsAddressingAction PQUJPO JG QSFTFOU

""$22(-& 6$! 2$15("$2


5P DBMM B XFC TFSWJDF BU http://foo.com/bar TJNQMZ EFGJOF B SPVUF:
from("direct:example").to("spring-ws:http://foo.com/bar")

"OE TFOU B NFTTBHF:


template.requestBody("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>");

3FNFNCFS JG JU'T B 40"1 TFSWJDF ZPV'SF DBMMJOH ZPV EPO'U IBWF UP JODMVEF 40"1 UBHT. 4QSJOH-84 XJMM QFSGPSN UIF 9.--UP-40"1 NBSTIBMJOH. 2BKAFKD 2. / >KA 62- AAOBPPFKD >@QFLK EB>ABOP 8IFO B SFNPUF XFC TFSWJDF SFRVJSFT B 40"1 BDUJPO PS VTF PG UIF 84-"EESFTTJOH TUBOEBSE ZPV EFGJOF ZPVS SPVUF BT:
from("direct:example") .to("spring-ws:http://foo.com/ bar?soapAction=http://foo.com&wsAddressingAction=http://bar.com")

0QUJPOBMMZ ZPV DBO PWFSSJEF UIF FOEQPJOU PQUJPOT XJUI IFBEFS WBMVFT:

938

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

template.requestBodyAndHeader("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>", SpringWebserviceConstants.SPRING_WS_SOAP_ACTION, "http://baz.com");

3EB EB>ABO >KA >QQ>@EJBKQ MOLM>D>QFLK 4QSJOH 84 $BNFM TVQQPSUT QSPQBHBUJPO PG UIF IFBEFST BOE BUUBDINFOUT JOUP 4QSJOH-84 8FC4FSWJDF.FTTBHF SFTQPOTF TJODF WFSTJPO 2.10.3. 5IF FOEQPJOU XJMM VTF TP DBMMFE "IPPL" UIF .FTTBHF'JMUFS (EFGBVMU JNQMFNFOUBUJPO JT QSPWJEFE CZ #BTJD.FTTBHF'JMUFS) UP QSPQBHBUF UIF FYDIBOHF IFBEFST BOE BUUBDINFOUT JOUP 8FC4ESWJDF.FTTBHF SFTQPOTF. /PX ZPV DBO VTF
exchange.getOut().getHeaders().put("myCustom","myHeaderValue") exchange.getIn().addAttachment("myAttachment", new DataHandler(...))

/PUF: *G UIF FYDIBOHF IFBEFS JO UIF QJQFMJOF DPOUBJOT UFYU, JU HFOFSBUFT 2OBNF(LFZ)=WBMVF BUUSJCVUF JO UIF TPBQ IFBEFS. 3FDPNNFOEFE JT UP DSFBUF B 2/BNF DMBTT EJSFDUMZ BOE QVU JOUP BOZ LFZ JOUP IFBEFS. 'LT QL RPB ,3., >QQ>@EJBKQP 5IF #BTJD.FTTBHF'JMUFS QSPWJEFT BMM SFRVJSFE JOGPSNBUJPO GPS "QBDIF "YJPN JO PSEFS UP QSPEVDF .50. NFTTBHF. *G ZPV XBOU UP VTF "QBDIF $BNFM 4QSJOH 84 XJUIJO "QBDIF "YJPN, IFSF JT BO FYBNQMF: 1. 4JNQMZ EFGJOF UIF NFTTBHF'BDUPSZ BT JT CFMMPX BOE TQSJOH-XT XJMM VTF .50. TUSBUFHZ UP QPQVMBUF ZPVS 40"1 NFTTBHF XJUI PQUJNJ[FE BUUBDINFOUT.
<bean id="axiomMessageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory"> <property name="payloadCaching" value="false" /> <property name="attachmentCaching" value="true" /> <property name="attachmentCacheThreshold" value="1024" /> </bean>

2. "EE JOUP ZPVS QPN.YNM UIF GPMMPXJOH EFQFOEFODJFT


<dependency> <groupId>org.apache.ws.commons.axiom</groupId> <artifactId>axiom-api</artifactId> <version>1.2.13</version> </dependency> <dependency> <groupId>org.apache.ws.commons.axiom</groupId>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

939

<artifactId>axiom-impl</artifactId> <version>1.2.13</version> <scope>runtime</scope> </dependency>

3. "EE ZPVS BUUBDINFOU JOUP UIF QJQFMJOF, GPS FYBNQMF VTJOH B 1SPDFTTPS JNQMFNFOUBUJPO.
private class Attachement implements Processor { public void process(Exchange exchange) throws Exception { exchange.getOut().copyFrom(exchange.getIn()); File file = new File("testAttachment.txt"); exchange.getOut().addAttachment("test", new DataHandler(new FileDataSource(file))); } }

4. %FGJOF FOEQPJOU (QSPEVDFS) BT VTTVBM, GPS FYBNQMF MJLF UIJT:


from("direct:send") .process(new Attachement()) .to("spring-ws:http://localhost:8089/ mySoapService?soapAction=mySoap&messageFactory=axiomMessageFactory");

5. /PX, ZPVS QSPEVDFS XJMM HFOFSBUF .50. NFTTBHF XJUI PUQNJ[FE BUUBDINFOUT. 3EB @RPQLJ EB>ABO >KA >QQ>@EJBKQ CFIQBOFKD *G ZPV OFFE UP QSPWJEF ZPVS DVTUPNF QSPDFTTJOH PG FJUIFS IFBEFST PS BUUBDINFOUT, FYUFOE FYJTUJOH #BTJD.FTTBHF'JMUFS BOE PWFSSJEF UIF BQQSPDIJBUF NFUIPET PS XSJUF B CSBOE OFX JNQMFNFOUBUJPO PG UIF .FTTBHF'JMUFS JOUFSGBDF. 5P VTF ZPVS DVTUPN GJMUFS, BEE UIJT JOUP ZPVS TQSJOH DPOUFYU: :PV DBO TQFDJGZ FJUIFS B HMPCBM B PS B MPDBM NFTTBHF GJMUFS BT GPMMPXT: B) UIF HMPCBM DVTUPNF GJMUFS UIBU QSPWJEFT UIF HMPCBM DPOGJHVSBUJPO GPS BMM TQSJOH-XT FOEQPJOUT

<bean id="messageFilter" class="your.domain.myMessageFiler" scope="singleton" />

PS C) UIF MPDBM NFTTBHF'JMUFS EJSFDUMZ PO UIF FOEQPJOU BT GPMMPXT:


to("spring-ws:http://yourdomain.com?messageFilter=#myEndpointSpecificMessageFilter");

'PS NPSF JOGPSNBUJPO TFF $".&--5724 *G ZPV XBOU UP DSFBUF ZPVS PXO .FTTBHF'JMUFS, DPOTJEFS PWFSSJEFJOH UIF GPMMPXJOH NFUIPET JO UIF EFGBVMU JNQMFNFOUBUJPO PG .FTTBHF'JMUFS JO DMBTT #BTJD.FTTBHF'JMUFS:

940

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

protected void doProcessSoapHeader(Message inOrOut, SoapMessage soapMessage) {your code /*no need to call super*/ } protected void doProcessSoapAttachements(Message inOrOut, SoapMessage response) { your code /*no need to call super*/ }

4PFKD > @RPQLJ ,BPP>DB2BKABO >KA ,BPP>DB%>@QLOV " DVTUPN NFTTBHF TFOEFS PS GBDUPSZ JO UIF SFHJTUSZ DBO CF SFGFSFODFE MJLF UIJT:
from("direct:example") .to("spring-ws:http://foo.com/ bar?messageFactory=#messageFactory&messageSender=#messageSender")

4QSJOH DPOGJHVSBUJPO:
<!-- authenticate using HTTP Basic Authentication --> <bean id="messageSender" class="org.springframework.ws.transport.http.CommonsHttpMessageSender"> <property name="credentials"> <bean class="org.apache.commons.httpclient.UsernamePasswordCredentials"> <constructor-arg index="0" value="admin"/> <constructor-arg index="1" value="secret"/> </bean> </property> </bean> <!-- force use of Sun SAAJ implementation, http://static.springsource.org/spring-ws/ sites/1.5/faq.html#saaj-jboss --> <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"> <property name="messageFactory"> <bean class="com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"></bean> </property> </bean>

$7/.2(-& 6$! 2$15("$2


*O PSEFS UP FYQPTF B XFC TFSWJDF VTJOH UIJT DPNQPOFOU ZPV GJSTU OFFE UP TFU-VQ B .FTTBHF%JTQBUDIFS UP MPPL GPS FOEQPJOU NBQQJOHT JO B 4QSJOH 9.- GJMF. *G ZPV QMBO PO SVOOJOH JOTJEF B TFSWMFU DPOUBJOFS ZPV QSPCBCMZ XBOU UP VTF B MessageDispatcherServlet DPOGJHVSFE JO web.xml. #Z EFGBVMU UIF MessageDispatcherServlet XJMM MPPL GPS B 4QSJOH 9.- OBNFE /WEBINF/spring-ws-servlet.xml. 5P VTF $BNFM XJUI 4QSJOH-84 UIF POMZ NBOEBUPSZ CFBO

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

941

JO UIBU 9.- GJMF JT CamelEndpointMapping. 5IJT CFBO BMMPXT UIF MessageDispatcher UP EJTQBUDI XFC TFSWJDF SFRVFTUT UP ZPVS SPVUFT. web.xml
<web-app> <servlet> <servlet-name>spring-ws</servlet-name> <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring-ws</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>

spring-ws-servlet.xml
<bean id="endpointMapping" class="org.apache.camel.component.spring.ws.bean.CamelEndpointMapping" /> <bean id="wsdl" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition"> <property name="schema"> <bean class="org.springframework.xml.xsd.SimpleXsdSchema"> <property name="xsd" value="/WEB-INF/foobar.xsd"/> </bean> </property> <property name="portTypeName" value="FooBar"/> <property name="locationUri" value="/"/> <property name="targetNamespace" value="http://example.com/"/> </bean>

.PSF JOGPSNBUJPO PO TFUUJOH VQ 4QSJOH-84 DBO CF GPVOE JO 8SJUJOH $POUSBDU-'JSTU 8FC 4FSWJDFT. #BTJDBMMZ QBSBHSBQI 3.6 "*NQMFNFOUJOH UIF &OEQPJOU" JT IBOEMFE CZ UIJT DPNQPOFOU (TQFDJGJDBMMZ QBSBHSBQI 3.6.2 "3PVUJOH UIF .FTTBHF UP UIF &OEQPJOU" JT XIFSF CamelEndpointMapping DPNFT JO). "MTP EPO'U GPSHFU UP DIFDL PVU UIF 4QSJOH 8FC 4FSWJDFT &YBNQMF JODMVEFE JO UIF $BNFM EJTUSJCVUJPO. $KAMLFKQ J>MMFKD FK OLRQBP 8JUI UIF 9.- DPOGJHVSBUJPO JO-QMBDF ZPV DBO OPX VTF $BNFM'T %4- UP EFGJOF XIBU XFC TFSWJDF SFRVFTUT BSF IBOEMFE CZ ZPVS FOEQPJOU: 5IF GPMMPXJOH SPVUF XJMM SFDFJWF BMM XFC TFSWJDF SFRVFTUT UIBU IBWF B SPPU FMFNFOU OBNFE "(FU'PP" XJUIJO UIF http://example.com/ OBNFTQBDF.

942

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)

5IF GPMMPXJOH SPVUF XJMM SFDFJWF XFC TFSWJDF SFRVFTUT DPOUBJOJOH UIF http://example.com/GetFoo 40"1 BDUJPO.
from("spring-ws:soapaction:http://example.com/GetFoo?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)

5IF GPMMPXJOH SPVUF XJMM SFDFJWF BMM SFRVFTUT TFOU UP http://example.com/foobar.


from("spring-ws:uri:http://example.com/foobar?endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)

5IF SPVUF CFMPX XJMM SFDFJWF SFRVFTUT UIBU DPOUBJO UIF FMFNFOU <foobar>abc</foobar> BOZXIFSF JOTJEF UIF NFTTBHF (BOE UIF EFGBVMU OBNFTQBDF).
from("spring-ws:xpathresult:abc?expression=//foobar&endpointMapping=#endpointMapping") .convertBodyTo(String.class).to(mock:example)

IQBOK>QFSB @LKCFDRO>QFLK, RPFKD BUFPQFKD BKAMLFKQ J>MMFKDP 'PS FWFSZ FOEQPJOU XJUI NBQQJOH-UZQF beanname POF CFBO PG UZQF CamelEndpointDispatcher XJUI B DPSSFTQPOEJOH OBNF JT SFRVJSFE JO UIF 3FHJTUSZ/ "QQMJDBUJPO$POUFYU. 5IJT CFBO BDUT BT B CSJEHF CFUXFFO UIF $BNFM FOEQPJOU BOE BO FYJTUJOH FOEQPJOU NBQQJOH MJLF PayloadRootQNameEndpointMapping. "O FYBNQMF PG B SPVUF VTJOH beanname:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="spring-ws:beanname:QuoteEndpointDispatcher" /> <to uri="mock:example" /> </route> </camelContext> <bean id="legacyEndpointMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping"> <property name="mappings"> <props> <prop key="{http://example.com/}GetFuture">FutureEndpointDispatcher</prop> <prop key="{http://example.com/}GetQuote">QuoteEndpointDispatcher</prop> </props> </property> </bean>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

943

5IF VTF PG UIF beanname NBQQJOH-UZQF JT QSJNBSJMZ NFBOU GPS (MFHBDZ) TJUVBUJPOT XIFSF ZPV'SF BMSFBEZ VTJOH 4QSJOH-84 BOE IBWF FOEQPJOU NBQQJOHT EFGJOFE JO B 4QSJOH 9.- GJMF. 5IF beanname NBQQJOH-UZQF BMMPXT ZPV UP XJSF ZPVS $BNFM SPVUF JOUP BO FYJTUJOH FOEQPJOU NBQQJOH. 8IFO ZPV'SF TUBSUJOH GSPN TDSBUDI JU'T SFDPNNFOEFE UP EFGJOF ZPVS FOEQPJOU NBQQJOHT BT $BNFM 63*'T (BT JMMVTUSBUFE BCPWF XJUI endpointMapping) TJODF JU SFRVJSFT MFTT DPOGJHVSBUJPO BOE JT NPSF FYQSFTTJWF. "MUFSOBUJWFMZ ZPV DPVME VTF WBOJMMB 4QSJOH-84 XJUI UIF IFMQ PG BOOPUBUJPOT.

<bean id="QuoteEndpointDispatcher" class="org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher" /> <bean id="FutureEndpointDispatcher" class="org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher" />

/.). (4-), 12' ++(-&


$BNFM'T QMVHHBCMF EBUB GPSNBUT PGGFS TVQQPSU GPS QPKP/YNM NBSTIBMMJOH VTJOH MJCSBSJFT TVDI BT +"9#, 94USFBN, +JC9, $BTUPS BOE 9.-#FBOT. :PV DBO VTF UIFTF EBUB GPSNBUT JO ZPVS SPVUF UP TFOU BOE SFDFJWF QPKP'T, UP BOE GSPN XFC TFSWJDFT. 8IFO accessing XFC TFSWJDFT ZPV DBO NBSTIBM UIF SFRVFTU BOE VONBSTIBM UIF SFTQPOTF NFTTBHF:
JaxbDataFormat jaxb = new JaxbDataFormat(false); jaxb.setContextPath("com.example.model"); from("direct:example").marshal(jaxb).to("spring-ws:http://foo.com/ bar").unmarshal(jaxb);

4JNJMBSMZ XIFO providing XFC TFSWJDFT, ZPV DBO VONBSTIBM 9.- SFRVFTUT UP 10+0'T BOE NBSTIBM UIF SFTQPOTF NFTTBHF CBDL UP 9.-:

from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping").unmarshal(jax .to("mock:example").marshal(jaxb);

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

944

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

231$ , ".,/.-$-3
5IF PQOB>J: DPNQPOFOU QSPWJEFT BDDFTT UP UIF System.in, System.out BOE System.err TUSFBNT BT XFMM BT BMMPXJOH TUSFBNJOH PG GJMF BOE 63-. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-stream</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
stream:in[?options] stream:out[?options] stream:err[?options] stream:header[?options]

*O BEEJUJPO, UIF file BOE url FOEQPJOU 63*T BSF TVQQPSUFE:


stream:file?fileName=/foo/bar.txt stream:url[?options]

*G UIF stream:header 63* JT TQFDJGJFE, UIF stream IFBEFS JT VTFE UP GJOE UIF TUSFBN UP XSJUF UP. 5IJT PQUJPO JT BWBJMBCMF POMZ GPS TUSFBN QSPEVDFST (UIBU JT, JU DBOOPU BQQFBS JO from()). :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
delay encoding promptMessage promptDelay initialPromptDelay fileName

#BC>RIQ 5>IRB
0 JVM Default null 0 2000 null

#BP@OFMQFLK
*OJUJBM EFMBZ JO NJMMJTFDPOET CFGPSF DPOTVNJOH PS QSPEVDJOH UIF TUSFBN. :PV DBO DPOGJHVSF UIF FODPEJOH (JT B DIBSTFU OBNF) UP VTF UFYU-CBTFE TUSFBNT (GPS FYBNQMF, NFTTBHF CPEZ JT B String PCKFDU). *G OPU QSPWJEFE, $BNFM VTFT UIF +7. EFGBVMU $IBSTFU. .FTTBHF QSPNQU UP VTF XIFO SFBEJOH GSPN stream:in; GPS FYBNQMF, ZPV DPVME TFU UIJT UP Enter a command: 0QUJPOBM EFMBZ JO NJMMJTFDPOET CFGPSF TIPXJOH UIF NFTTBHF QSPNQU. *OJUJBM EFMBZ JO NJMMJTFDPOET CFGPSF TIPXJOH UIF NFTTBHF QSPNQU. 5IJT EFMBZ PDDVST POMZ PODF. $BO CF VTFE EVSJOH TZTUFN TUBSUVQ UP BWPJE NFTTBHF QSPNQUT CFJOH XSJUUFO XIJMF PUIFS MPHHJOH JT EPOF UP UIF TZTUFN PVU. 8IFO VTJOH UIF stream:file 63* GPSNBU, UIJT PQUJPO TQFDJGJFT UIF GJMFOBNF UP TUSFBN UP/GSPN.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

945

url scanStream retry scanStreamDelay groupLines

null false false 0 0

8IFO VTJOH UIF stream:url 63* GPSNBU, UIJT PQUJPO TQFDJGJFT UIF 63- UP TUSFBN UP/GSPN. 5IF JOQVU/PVUQVU TUSFBN XJMM CF PQFOFE VTJOH UIF +%, 63-$POOFDUJPO GBDJMJUZ. 5P CF VTFE GPS DPOUJOVPVTMZ SFBEJOH B TUSFBN TVDI BT UIF VOJY tail DPNNBOE. ">JBI 2.4 QL ">JBI 2.6: XJMM SFUSZ PQFOJOH UIF GJMF JG JU JT PWFSXSJUUFO, TPNFXIBU MJLF tail --retry ">JBI 2.7: XJMM SFUSZ PQFOJOH UIF GJMF JG JU'T PWFSXSJUUFO, TPNFXIBU MJLF tail --retry %FMBZ JO NJMMJTFDPOET CFUXFFO SFBE BUUFNQUT XIFO VTJOH scanStream. ">JBI 2.5: 5P HSPVQ 9 OVNCFS PG MJOFT JO UIF DPOTVNFS. 'PS FYBNQMF UP HSPVQ 10 MJOFT BOE UIFSFGPSF POMZ TQJU PVU BO &YDIBOHF XJUI 10 MJOFT, JOTUFBE PG 1 &YDIBOHF QFS MJOF. ">JBI 2.10.0: (2.9.3 BOE 2.8.6) /VNCFS PG NFTTBHFT UP QSPDFTT CFGPSF DMPTJOH TUSFBN PO 1SPEVDFS TJEF. /FWFS DMPTF TUSFBN CZ EFGBVMU (POMZ XIFO 1SPEVDFS JT TUPQQFE). *G NPSF NFTTBHFT BSF TFOU, UIF TUSFBN JT SFPQFOFE GPS BOPUIFS autoCloseCount CBUDI. ">JBI 2.11.0: *G JU JT USVF BOE TUSFBN JT CBTFE PO GJMF, UIF QSPEVDFS XJMM DMPTF UIF TUSFBN PODF JU TBX UIF GMBH PG TQMJU DPNQMJU.

autoCloseCount closeOnDone

0 false

,BPP>DB @LKQBKQ 5IF PQOB>J: DPNQPOFOU TVQQPSUT FJUIFS String PS byte[] GPS XSJUJOH UP TUSFBNT. +VTU BEE FJUIFS String PS byte[] DPOUFOU UP UIF message.in.body. .FTTBHFT TFOU UP UIF PQOB>J: QSPEVDFS JO CJOBSZ NPEF BSF OPU GPMMPXFE CZ UIF OFXMJOF DIBSBDUFS (BT PQQPTFE UP UIF String NFTTBHFT). .FTTBHF XJUI null CPEZ XJMM OPU CF BQQFOEFE UP UIF PVUQVU TUSFBN. 5IF TQFDJBM stream:header 63* JT VTFE GPS DVTUPN PVUQVU TUSFBNT. +VTU BEE B java.io.OutputStream PCKFDU UP message.in.header JO UIF LFZ header. 4FF TBNQMFT GPS BO FYBNQMF. 2>JMIBP *O UIF GPMMPXJOH TBNQMF XF SPVUF NFTTBHFT GSPN UIF direct:in FOEQPJOU UP UIF System.out TUSFBN:
// Route messages to the standard output. from("direct:in").to("stream:out"); // Send String payload to the standard output. // Message will be followed by the newline. template.sendBody("direct:in", "Hello Text World"); // Send byte[] payload to the standard output. // No newline will be added after the message. template.sendBody("direct:in", "Hello Bytes World".getBytes());

5IF GPMMPXJOH TBNQMF EFNPOTUSBUFT IPX UIF IFBEFS UZQF DBO CF VTFE UP EFUFSNJOF XIJDI TUSFBN UP VTF. *O UIF TBNQMF XF VTF PVS PXO PVUQVU TUSFBN, MyOutputStream.
private OutputStream mystream = new MyOutputStream(); private StringBuilder sb = new StringBuilder(); @Test public void testStringContent() { template.sendBody("direct:in", "Hello");

946

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

// StreamProducer appends \n in text mode assertEquals("Hello\n", sb.toString()); } @Test public void testBinaryContent() { template.sendBody("direct:in", "Hello".getBytes()); // StreamProducer is in binary mode so no \n is appended assertEquals("Hello", sb.toString()); } protected RouteBuilder createRouteBuilder() { return new RouteBuilder() { public void configure() { from("direct:in").setHeader("stream", constant(mystream)). to("stream:header"); } }; } private class MyOutputStream extends OutputStream { public void write(int b) throws IOException { sb.append((char)b); } }

5IF GPMMPXJOH TBNQMF EFNPOTUSBUFT IPX UP DPOUJOVPVTMZ SFBE B GJMF TUSFBN (BOBMPHPVT UP UIF 6/*9 tail DPNNBOE):
from("stream:file?fileName=/server/logs/ server.log&scanStream=true&scanStreamDelay=1000").to("bean:logService?method=parseLogLine");

0OF HPUDIB XJUI TDBO4USFBN (QSF $BNFM 2.7) PS TDBO4USFBN + SFUSZ JT UIF GJMF XJMM CF SF-PQFOFE BOE TDBOOFE XJUI FBDI JUFSBUJPO PG TDBO4USFBN%FMBZ. 6OUJM /*02 JT BWBJMBCMF XF DBOOPU SFMJBCMZ EFUFDU XIFO B GJMF JT EFMFUFE/SFDSFBUFE. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

231(-& 3$,/+ 3$
5IF PQOFKD-QBJMI>QB: DPNQPOFOU BMMPXT ZPV UP QSPDFTT B NFTTBHF VTJOH B 4USJOH 5FNQMBUF. 5IJT DBO CF JEFBM XIFO VTJOH 5FNQMBUJOH UP HFOFSBUF SFTQPOTFT GPS SFRVFTUT.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

947

.BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-stringtemplate</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
string-template:templateName[?options]

8IFSF QBJMI>QB->JB JT UIF DMBTTQBUI-MPDBM 63* PG UIF UFNQMBUF UP JOWPLF; PS UIF DPNQMFUF 63- PG UIF SFNPUF UFNQMBUF. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
contentCache

#BC>RIQ
false

#BP@OFMQFLK
$BDIF GPS UIF SFTPVSDF DPOUFOU XIFO JUT MPBEFE. /PUF : BT PG ">JBI 2.9 DBDIFE SFTPVSDF DPOUFOU DBO CF DMFBSFE WJB +.9 VTJOH UIF FOEQPJOU'T clearContentCache PQFSBUJPO.

'B>ABOP $BNFM XJMM TUPSF B SFGFSFODF UP UIF SFTPVSDF JO UIF NFTTBHF IFBEFS XJUI LFZ, org.apache.camel.stringtemplate.resource. 5IF 3FTPVSDF JT BO org.springframework.core.io.Resource PCKFDU. 'LQ OBIL>AFKD 5IF TUSJOH UFNQMBUF SFTPVSDF JT CZ EFGBVMU IPU-SFMPBEBCMF GPS CPUI GJMF BOE DMBTTQBUI SFTPVSDFT (FYQBOEFE KBS). *G ZPV TFU contentCache=true, $BNFM MPBET UIF SFTPVSDF POMZ PODF BOE IPU-SFMPBEJOH JT OPU QPTTJCMF. 5IJT TDFOBSJP DBO CF VTFE JO QSPEVDUJPO XIFO UIF SFTPVSDF OFWFS DIBOHFT. 2QOFKD3BJMI>QB QQOF?RQBP

$BNFM XJMM QSPWJEF FYDIBOHF JOGPSNBUJPO BT BUUSJCVUFT (KVTU B java.util.Map) UP UIF TUSJOH UFNQMBUF. 5IF &YDIBOHF JT USBOTGFSFE BT:

948

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

HBV
exchange headers camelContext request in body out response

S>IRB
5IF &YDIBOHF JUTFMG. 5IF IFBEFST PG UIF *O NFTTBHF. 5IF $BNFM $POUFYU. 5IF *O NFTTBHF. 5IF *O NFTTBHF. 5IF *O NFTTBHF CPEZ. 5IF 0VU NFTTBHF (POMZ GPS *O0VU NFTTBHF FYDIBOHF QBUUFSO). 5IF 0VU NFTTBHF (POMZ GPS *O0VU NFTTBHF FYDIBOHF QBUUFSO).

2>JMIBP 'PS FYBNQMF ZPV DPVME VTF B TUSJOH UFNQMBUF BT GPMMPXT JO PSEFS UP GPSNVMBUF B SFTQPOTF UP B NFTTBHF:
from("activemq:My.Queue"). to("string-template:com/acme/MyResponse.tm");

3EB $J>FI 2>JMIB *O UIJT TBNQMF XF XBOU UP VTF B TUSJOH UFNQMBUF UP TFOE BO PSEFS DPOGJSNBUJPO FNBJM. 5IF FNBJM UFNQMBUF JT MBJE PVU JO StringTemplate BT:
Dear $headers.lastName$, $headers.firstName$ Thanks for the order of $headers.item$. Regards Camel Riders Bookstore $body$

"OE UIF KBWB DPEF JT BT GPMMPXT:


private Exchange createLetter() { Exchange exchange = context.getEndpoint("direct:a").createExchange(); Message msg = exchange.getIn(); msg.setHeader("firstName", "Claus"); msg.setHeader("lastName", "Ibsen"); msg.setHeader("item", "Camel in Action"); msg.setBody("PS: Next beer is on me, James"); return exchange; } @Test public void testVelocityLetter() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedMessageCount(1); mock.expectedBodiesReceived("Dear Ibsen, Claus! Thanks for the order of Camel in

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

949

Action. Regards Camel Riders Bookstore PS: Next beer is on me, James"); template.send("direct:a", createLetter()); mock.assertIsSatisfied(); } protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { from("direct:a").to("string-template:org/apache/camel/component/ stringtemplate/letter.tm").to("mock:result"); } }; }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

20+ ".,/.-$-3
5IF PNI: DPNQPOFOU BMMPXT ZPV UP XPSL XJUI EBUBCBTFT VTJOH +%#$ RVFSJFT. 5IF EJGGFSFODF CFUXFFO UIJT DPNQPOFOU BOE +%#$ DPNQPOFOU JT UIBU JO DBTF PG 42- UIF RVFSZ JT B QSPQFSUZ PG UIF FOEQPJOU BOE JU VTFT NFTTBHF QBZMPBE BT QBSBNFUFST QBTTFE UP UIF RVFSZ. 5IJT DPNQPOFOU VTFT spring-jdbc CFIJOE UIF TDFOFT GPS UIF BDUVBM 42- IBOEMJOH. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-sql</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

5IF 42- DPNQPOFOU BMTP TVQQPSUT: B +%#$ CBTFE SFQPTJUPSZ GPS UIF *EFNQPUFOU $POTVNFS &*1 QBUUFSO. 4FF GVSUIFS CFMPX. B +%#$ CBTFE SFQPTJUPSZ GPS UIF "HHSFHBUPS &*1 QBUUFSO. 4FF GVSUIFS CFMPX.

950

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

41( CLOJ>Q 5IF 42- DPNQPOFOU VTFT UIF GPMMPXJOH FOEQPJOU 63* OPUBUJPO:
sql:select * from table where id=# order by name[?options]

'SPN $BNFM 2.11 POXBSET ZPV DBO VTF OBNFE QBSBNFUFST CZ VTJOH #:name TUZMF BT TIPXO:
sql:select * from table where id=:#myId order by name[?options]

8IFO VTJOH OBNFE QBSBNFUFST, $BNFM XJMM MPPLVQ UIF OBNFT GSPN, JO UIF HJWFO QSFDFEFODF: 1. GSPN NFTTBHF CPEZ JG JUT B java.util.Map 2. GSPN NFTTBHF IFBEFST *G B OBNFE QBSBNFUFS DBOOPU CF SFTPMWFE, UIFO BO FYDFQUJPO JT UISPXO. /PUJDF UIBU UIF TUBOEBSE ? TZNCPM UIBU EFOPUFT UIF QBSBNFUFST UP BO 42- RVFSZ JT TVCTUJUVUFE XJUI UIF # TZNCPM, CFDBVTF UIF ? TZNCPM JT VTFE UP TQFDJGZ PQUJPOT GPS UIF FOEQPJOU. 5IF ? TZNCPM SFQMBDFNFOU DBO CF DPOGJHVSFE PO FOEQPJOU CBTJT. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
batch dataSourceRef dataSource

3VMB
boolean String String

#BC>RIQ
false null null

#BP@OFMQFLK
">JBI 2.7.5, 2.8.4 >KA 2.9: &YFDVUF 42- CBUDI VQEBUF TUBUFNFOUT. 4FF OPUFT CFMPX PO IPX UIF USFBUNFOU PG UIF JOCPVOE NFTTBHF CPEZ DIBOHFT JG UIJT JT TFU UP true. #BMOB@>QBA >KA TFII ?B OBJLSBA FK ">JBI 3.0: 3FGFSFODF UP B DataSource UP MPPL VQ JO UIF SFHJTUSZ. ">JBI 2.11: 3FGFSFODF UP B DataSource UP MPPL VQ JO UIF SFHJTUSZ. ">JBI 2.4: 4QFDJGJFT B DIBSBDUFS UIBU XJMM CF SFQMBDFE UP ? JO 42- RVFSZ. /PUJDF, UIBU JU JT TJNQMF String.replaceAll() PQFSBUJPO BOE OP 42- QBSTJOH JT JOWPMWFE (RVPUFE TUSJOHT XJMM BMTP DIBOHF). 5IJT SFQMBDFNFOU JT LKIV IBQQFOJOH JG UIF FOEQPJOU JT DSFBUFE VTJOH UIF SqlComponent. *G ZPV NBOVBMMZ DSFBUF UIF FOEQPJOU, UIFO VTF UIF FYQFDUFE ? TJHO JOTUFBE. 4FUT BEEJUJPOBM PQUJPOT PO UIF 4QSJOH JdbcTemplate UIBU JT VTFE CFIJOE UIF TDFOFT UP FYFDVUF UIF RVFSJFT. 'PS JOTUBODF, template.maxRows=10. 'PS EFUBJMFE EPDVNFOUBUJPO, TFF UIF +ECD5FNQMBUF KBWBEPD EPDVNFOUBUJPO. ">JBI 2.11: 8IFUIFS UP BMMPX VTJOH OBNFE QBSBNFUFST JO UIF RVFSJFT. ">JBI 2.11: 20+ @LKPRJBO LKIV: "MMPXT UP QMVHJO UP VTF B DVTUPN org.apache.camel.component.sql.SqlProcessingStrategy UP FYFDVUF RVFSJFT XIFO UIF DPOTVNFS IBT QSPDFTTFE UIF SPXT/CBUDI. ">JBI 2.11: "MMPXT UP QMVHJO UP VTF B DVTUPN org.apache.camel.component.sql.SqlPrepareStatementStrategy UP DPOUSPM QSFQBSBUJPO PG UIF RVFSZ BOE QSFQBSFE TUBUFNFOU. ">JBI 2.11: 20+ @LKPRJBO LKIV: %FMBZ JO NJMMJTFDPOET CFUXFFO FBDI QPMM. ">JBI 2.11: 20+ @LKPRJBO LKIV: .JMMJTFDPOET CFGPSF QPMMJOH TUBSUT. ">JBI 2.11: 20+ @LKPRJBO LKIV: 4FU UP true UP VTF GJYFE EFMBZ CFUXFFO QPMMT, PUIFSXJTF GJYFE SBUF JT VTFE. 4FF 4DIFEVMFE&YFDVUPS4FSWJDF JO +%, GPS EFUBJMT. ">JBI 2.11: 20+ @LKPRJBO LKIV: "O JOUFHFS WBMVF UP EFGJOF UIF NBYJNVN OVNCFS PG NFTTBHFT UP HBUIFS QFS QPMM. #Z EFGBVMU, OP NBYJNVN JT TFU. ">JBI 2.11: 20+ @LKPRJBO LKIV: *G true FBDI SPX SFUVSOFE XIFO QPMMJOH XJMM CF QSPDFTTFE JOEJWJEVBMMZ. *G false UIF FOUJSF java.util.List PG EBUB JT TFU BT UIF */ CPEZ.

placeholder

String

template.<xxx> allowNamedParameters processingStrategy

c boolean c

null true c

prepareStatementStrategy consumer.delay consumer.initialDelay consumer.useFixedDelay maxMessagesPerPoll consumer.useIterator

c long long boolean int boolean

c 500 1000 false 0 true

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

951

*O $BNFM 2.10 PS PMEFS UIF 42- DPNQPOFOU DBO POMZ CF VTFE BT QSPEVDFS. 'SPN $BNFM 2.11 POXBSET UIJT DPNQPOFOU DBO BMTP CF B DPOTVNFS, FH from().

5IJT DPNQPOFOU DBO CF VTFE BT B 5SBOTBDUJPOBM $MJFOU.


">JBI 2.11: 20+ @LKPRJBO LKIV: 8IFUIFS UP SPVUF B TJOHMF FNQUZ &YDIBOHF JG UIFSF XBT OP EBUB UP QPMM. ">JBI 2.11: 20+ @LKPRJBO LKIV: "GUFS QSPDFTTJOH FBDI SPX UIFO UIJT RVFSZ DBO CF FYFDVUFE, JG UIF &YDIBOHF XBT QSPDFTTFE TVDDFTTGVMMZ, GPS FYBNQMF UP NBSL UIF SPX BT QSPDFTTFE. 5IF RVFSZ DBO IBWF QBSBNFUFS. ">JBI 2.11: 20+ @LKPRJBO LKIV: "GUFS QSPDFTTJOH FBDI SPX UIFO UIJT RVFSZ DBO CF FYFDVUFE, JG UIF &YDIBOHF GBJMFE, GPS FYBNQMF UP NBSL UIF SPX BT GBJMFE. 5IF RVFSZ DBO IBWF QBSBNFUFS. ">JBI 2.11: 20+ @LKPRJBO LKIV: "GUFS QSPDFTTJOH UIF FOUJSF CBUDI, UIJT RVFSZ DBO CF FYFDVUFE UP CVML VQEBUF SPXT FUD. 5IF RVFSZ DBOOPU IBWF QBSBNFUFST. ">JBI 2.11: 20+ @LKPRJBO LKIV: *G VTJOH consumer.onConsume UIFO UIJT PQUJPO DBO CF VTFE UP TFU BO FYQFDUFE OVNCFS PG SPXT CFJOH VQEBUFE. 5ZQJDBMMZ ZPV NBZ TFU UIJT UP 1 UP FYQFDU POF SPX UP CF VQEBUFE. ">JBI 2.11: 20+ @LKPRJBO LKIV: *G VTJOH consumer.onConsume BOE JU GBJMT, UIFO UIJT PQUJPO DPOUSPMT XIFUIFS UP CSFBL PVU PG UIF CBUDI PS DPOUJOVF QSPDFTTJOH UIF OFYU SPX GSPN UIF CBUDI. ">JBI 2.11: 20+ MOLAR@BO LKIV: *G FOBCMFE UIFO UIF populateStatement NFUIPE GSPN org.apache.camel.component.sql.SqlPrepareStatementStrategy JT BMXBZT JOWPLFE, BMTP JG UIFSF JT OP FYQFDUFE QBSBNFUFST UP CF QSFQBSFE. 8IFO UIJT JT false UIFO UIF populateStatement JT POMZ JOWPLFE JG UIFSF JT 1 PS NPSF FYQFDUFE QBSBNFUFST UP CF TFU; GPS FYBNQMF UIJT BWPJET SFBEJOH UIF NFTTBHF CPEZ/IFBEFST GPS 42- RVFSJFT XJUI OP QBSBNFUFST.

consumer.routeEmptyResultSet

boolean

false

consumer.onConsume

String

null

consumer.onConsumeFailed

String

null

consumer.onConsumeBatchComplete

String

null

consumer.expectedUpdateCount

int

-1

consumer.breakBatchOnConsumeFail

boolean

false

alwaysPopulateStatement

boolean

false

3OB>QJBKQ LC QEB JBPP>DB ?LAV 5IF 42- DPNQPOFOU USJFT UP DPOWFSU UIF NFTTBHF CPEZ UP BO PCKFDU PG java.util.Iterator UZQF BOE UIFO VTFT UIJT JUFSBUPS UP GJMM UIF RVFSZ QBSBNFUFST (XIFSF FBDI RVFSZ QBSBNFUFS JT SFQSFTFOUFE CZ B # TZNCPM (PS DPOGJHVSFE QMBDFIPMEFS) JO UIF FOEQPJOU 63*). *G UIF NFTTBHF CPEZ JT OPU BO BSSBZ PS DPMMFDUJPO, UIF DPOWFSTJPO SFTVMUT JO BO JUFSBUPS UIBU JUFSBUFT PWFS POMZ POF PCKFDU, XIJDI JT UIF CPEZ JUTFMG. 'PS FYBNQMF, JG UIF NFTTBHF CPEZ JT BO JOTUBODF PG java.util.List, UIF GJSTU JUFN JO UIF MJTU JT TVCTUJUVUFE JOUP UIF GJSTU PDDVSSFODF PG # JO UIF 42- RVFSZ, UIF TFDPOE JUFN JO UIF MJTU JT TVCTUJUVUFE JOUP UIF TFDPOE PDDVSSFODF PG #, BOE TP PO. *G batch JT TFU UP true, UIFO UIF JOUFSQSFUBUJPO PG UIF JOCPVOE NFTTBHF CPEZ DIBOHFT TMJHIUMZ f JOTUFBE PG BO JUFSBUPS PG QBSBNFUFST, UIF DPNQPOFOU FYQFDUT BO JUFSBUPS UIBU DPOUBJOT UIF QBSBNFUFS JUFSBUPST; UIF TJ[F PG UIF PVUFS JUFSBUPS EFUFSNJOFT UIF CBUDI TJ[F.

952

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

1BPRIQ LC QEB NRBOV 'PS select PQFSBUJPOT, UIF SFTVMU JT BO JOTUBODF PG List<Map<String, Object>> UZQF, BT SFUVSOFE CZ UIF +ECD5FNQMBUF.RVFSZ'PS-JTU() NFUIPE. 'PS update PQFSBUJPOT, UIF SFTVMU JT UIF OVNCFS PG VQEBUFE SPXT, SFUVSOFE BT BO Integer. 'B>ABO S>IRBP 8IFO QFSGPSNJOH update PQFSBUJPOT, UIF 42- $PNQPOFOU TUPSFT UIF VQEBUF DPVOU JO UIF GPMMPXJOH NFTTBHF IFBEFST: 'B>ABO CamelSqlUpdateCount CamelSqlRowCount #BP@OFMQFLK 5IF OVNCFS PG SPXT VQEBUFE GPS update PQFSBUJPOT, SFUVSOFE BT BO Integer PCKFDU. 5IF OVNCFS PG SPXT SFUVSOFE GPS select PQFSBUJPOT, SFUVSOFE BT BO Integer PCKFDU. ">JBI 2.8: 2VFSZ UP FYFDVUF. 5IJT RVFSZ UBLFT QSFDFEFODF PWFS UIF RVFSZ TQFDJGJFE JO UIF FOEQPJOU 63*. /PUF UIBU RVFSZ QBSBNFUFST JO UIF IFBEFS are SFQSFTFOUFE CZ B ? JOTUFBE PG B # TZNCPM

CamelSqlQuery

"LKCFDRO>QFLK :PV DBO OPX TFU B SFGFSFODF UP B DataSource JO UIF 63* EJSFDUMZ:
sql:select * from table where id=# order by name?dataSourceRef=myDS

2>JMIB *O UIF TBNQMF CFMPX XF FYFDVUF B RVFSZ BOE SFUSJFWF UIF SFTVMU BT B List PG SPXT, XIFSF FBDI SPX JT B Map<String, Object BOE UIF LFZ JT UIF DPMVNO OBNF. 'JSTU, XF TFU VQ B UBCMF UP VTF GPS PVS TBNQMF. "T UIJT JT CBTFE PO BO VOJU UFTU, XF EP JU JO KBWB:
// this is the database we create with some initial data for our unit test db = new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.DERBY).addScript("sql/ createAndPopulateDatabase.sql").build();

5IF 42- TDSJQU createAndPopulateDatabase.sql XF FYFDVUF MPPLT MJLF BT EFTDSJCFE CFMPX:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

953

create table projects (id integer primary key, project varchar(10), license varchar(5)); insert into projects values (1, 'Camel', 'ASF'); insert into projects values (2, 'AMQ', 'ASF'); insert into projects values (3, 'Linux', 'XXX');

5IFO XF DPOGJHVSF PVS SPVUF BOE PVS sql DPNQPOFOU. /PUJDF UIBU XF VTF B direct FOEQPJOU JO GSPOU PG UIF sql FOEQPJOU. 5IJT BMMPXT VT UP TFOE BO FYDIBOHF UP UIF direct FOEQPJOU XJUI UIF 63*, direct:simple, XIJDI JT NVDI FBTJFS GPS UIF DMJFOU UP VTF UIBO UIF MPOH sql: 63*. /PUF UIBU UIF DataSource JT MPPLFE VQ VQ JO UIF SFHJTUSZ, TP XF DBO VTF TUBOEBSE 4QSJOH 9.- UP DPOGJHVSF PVS DataSource.
from("direct:simple") .to("sql:select * from projects where license = # order by id?dataSourceRef=jdbc/ myDataSource") .to("mock:result");

"OE UIFO XF GJSF UIF NFTTBHF JOUP UIF direct FOEQPJOU UIBU XJMM SPVUF JU UP PVS sql DPNQPOFOU UIBU RVFSJFT UIF EBUBCBTF.
MockEndpoint mock = getMockEndpoint("mock:result"); mock.expectedMessageCount(1); // send the query to direct that will route it to the sql where we will execute the query // and bind the parameters with the data from the body. The body only contains one value // in this case (XXX) but if we should use multi values then the body will be iterated // so we could supply a List<String> instead containing each binding value. template.sendBody("direct:simple", "XXX"); mock.assertIsSatisfied(); // the result is a List List<?> received = assertIsInstanceOf(List.class, mock.getReceivedExchanges().get(0).getIn().getBody()); // and each row in the list is a Map Map<?, ?> row = assertIsInstanceOf(Map.class, received.get(0)); // and we should be able the get the project from the map that should be Linux assertEquals("Linux", row.get("PROJECT"));

8F DPVME DPOGJHVSF UIF DataSource JO 4QSJOH 9.- BT GPMMPXT:


<jee:jndi-lookup id="myDS" jndi-name="jdbc/myDataSource"/>

954

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD K>JBA M>O>JBQBOP


S>FI>?IB >P LC ">JBI 2.11 *O UIF HJWFO SPVUF CFMPX, XF XBOU UP HFU BMM UIF QSPKFDUT GSPN UIF QSPKFDUT UBCMF. /PUJDF UIF 42- RVFSZ IBT 2 OBNFE QBSBNFUFST, :#MJD BOE :#NJO. $BNFM XJMM UIFO MPPLVQ GPS UIFTF QBSBNFUFST GSPN UIF NFTTBHF CPEZ PS NFTTBHF IFBEFST. /PUJDF JO UIF FYBNQMF BCPWF XF TFU UXP IFBEFST XJUI DPOTUBOU WBMVF GPS UIF OBNFE QBSBNFUFST:
from("direct:projects") .setHeader("lic", constant("ASF")) .setHeader("min", constant(123)) .to("sql:select * from projects where license = :#lic and id > :#min order by id")

5IPVHI JG UIF NFTTBHF CPEZ JT B java.util.Map UIFO UIF OBNFE QBSBNFUFST XJMM CF UBLFO GSPN UIF CPEZ.
from("direct:projects") .to("sql:select * from projects where license = :#lic and id > :#min order by id")

4PFKD QEB )#!" ?>PBA FABJMLQBKQ OBMLPFQLOV S>FI>?IB >P LC ">JBI 2.7: *O UIJT TFDUJPO XF XJMM VTF UIF +%#$ CBTFE JEFNQPUFOU SFQPTJUPSZ. 'JSTU XF IBWF UP DSFBUF UIF EBUBCBTF UBCMF XIJDI XJMM CF VTFE CZ UIF JEFNQPUFOU SFQPTJUPSZ. 'PS ">JBI 2.7, XF VTF UIF GPMMPXJOH TDIFNB:
CREATE TABLE CAMEL_MESSAGEPROCESSED ( processorName VARCHAR(255), messageId VARCHAR(100) )

*O ">JBI 2.8, XF BEEFE UIF DSFBUFE"U DPMVNO:


CREATE TABLE CAMEL_MESSAGEPROCESSED ( processorName VARCHAR(255), messageId VARCHAR(100), createdAt TIMESTAMP )

8F SFDPNNFOE UP IBWF B VOJRVF DPOTUSBJOU PO UIF DPMVNOT QSPDFTTPS/BNF BOE NFTTBHF*E. #FDBVTF UIF TZOUBY GPS UIJT DPOTUSBJOU EJGGFST GPS EBUBCBTF UP EBUBCBTF, XF EP OPU TIPX JU IFSF. 4FDPOE XF OFFE UP TFUVQ B javax.sql.DataSource JO UIF TQSJOH 9.- GJMF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

955

?PQO>@Q @I>PP 'SPN $BNFM 2.9 POXBSET UIFSF JT BO BCTUSBDU DMBTT org.apache.camel.processor.idempotent.jdbc.AbstractJdbcMessageIdReposi ZPV DBO FYUFOE UP CVJME DVTUPN +%#$ JEFNQPUFOU SFQPTJUPSZ.

<jdbc:embedded-database id="dataSource" type="DERBY" />

"OE GJOBMMZ XF DBO DSFBUF PVS +%#$ JEFNQPUFOU SFQPTJUPSZ JO UIF TQSJOH 9.- GJMF BT XFMM:
<bean id="messageIdRepository" class="org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository"> <constructor-arg ref="dataSource" /> <constructor-arg value="myProcessorName" /> </bean> <camel:camelContext> <camel:errorHandler id="deadLetterChannel" type="DeadLetterChannel" deadLetterUri="mock:error"> <camel:redeliveryPolicy maximumRedeliveries="0" maximumRedeliveryDelay="0" logStackTrace="false" /> </camel:errorHandler> <camel:route id="JdbcMessageIdRepositoryTest" errorHandlerRef="deadLetterChannel"> <camel:from uri="direct:start" /> <camel:idempotentConsumer messageIdRepositoryRef="messageIdRepository"> <camel:header>messageId</camel:header> <camel:to uri="mock:result" /> </camel:idempotentConsumer> </camel:route> </camel:camelContext>

"RPQLJFWB QEB )A?@,BPP>DB(A1BMLPFQLOV


4UBSUJOH XJUI ">JBI 2.9.1 ZPV IBWF B GFX PQUJPOT UP UVOF UIF org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository GPS ZPVS OFFET: />O>JBQBO DSFBUF5BCMF*G/PU&YJTUT #BC>RIQ 5>IRB USVF #BP@OFMQFLK %FGJOFT XIFUIFS PS OPU $BNFM TIPVME USZ UP DSFBUF UIF UBCMF JG JU EPFTO'U FYJTU.

956

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

UBCMF&YJTUT4USJOH

4&-&$5 1 '30. $".&-@.&44"(&130$&44&% 8)&3& 1 = 0 $3&"5& 5"#-& $".&-@.&44"(&130$&44&% (QSPDFTTPS/BNF 7"3$)"3(255), NFTTBHF*E 7"3$)"3(100), DSFBUFE"U 5*.&45".1)

5IJT RVFSZ JT VTFE UP GJHVSF PVU XIFUIFS UIF UBCMF BMSFBEZ FYJTUT PS OPU. *U NVTU UISPX BO FYDFQUJPO UP JOEJDBUF UIF UBCMF EPFTO'U FYJTU.

DSFBUF4USJOH

5IF TUBUFNFOU XIJDI JT VTFE UP DSFBUF UIF UBCMF.

RVFSZ4USJOH

4&-&$5 $06/5(*) '30. $".&-@.&44"(&130$&44&% 8)&3& QSPDFTTPS/BNF = "/% NFTTBHF*E =

5IF RVFSZ XIJDI JT VTFE UP GJHVSF PVU XIFUIFS UIF NFTTBHF BMSFBEZ FYJTUT JO UIF SFQPTJUPSZ (UIF SFTVMU JT OPU FRVBMT UP '0'). *U UBLFT UXP QBSBNFUFST. 5IJT GJSTU POF JT UIF QSPDFTTPS OBNF (String) BOE UIF TFDPOE POF JT UIF NFTTBHF JE (String). 5IF TUBUFNFOU XIJDI JT VTFE UP BEE UIF FOUSZ JOUP UIF UBCMF. *U UBLFT UISFF QBSBNFUFS. 5IF GJSTU POF JT UIF QSPDFTTPS OBNF (String), UIF TFDPOE POF JT UIF NFTTBHF JE (String) BOE UIF UIJSE POF JT UIF UJNFTUBNQ (java.sql.Timestamp) XIFO UIJT FOUSZ XBT BEEFE UP UIF SFQPTJUPSZ. 5IF TUBUFNFOU XIJDI JT VTFE UP EFMFUF UIF FOUSZ GSPN UIF EBUBCBTF. *U UBLFT UXP QBSBNFUFS. 5IJT GJSTU POF JT UIF QSPDFTTPS OBNF (String) BOE UIF TFDPOE POF JT UIF NFTTBHF JE (String).

JOTFSU4USJOH

*/4&35 */50 $".&-@.&44"(&130$&44&% (QSPDFTTPS/BNF, NFTTBHF*E, DSFBUFE"U) 7"-6&4 ( , , )

EFMFUF4USJOH

%&-&5& '30. $".&-@.&44"(&130$&44&% 8)&3& QSPDFTTPS/BNF = "/% NFTTBHF*E =

" DVTUPNJ[FE org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository DPVME MPPL MJLF:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

957

<bean id="messageIdRepository" class="org.apache.camel.processor.idempotent.jdbc.JdbcMessageIdRepository"> <constructor-arg ref="dataSource" /> <constructor-arg value="myProcessorName" /> <property name="tableExistsString" value="SELECT 1 FROM CUSTOMIZED_MESSAGE_REPOSITORY WHERE 1 = 0" /> <property name="createString" value="CREATE TABLE CUSTOMIZED_MESSAGE_REPOSITORY (processorName VARCHAR(255), messageId VARCHAR(100), createdAt TIMESTAMP)" /> <property name="queryString" value="SELECT COUNT(*) FROM CUSTOMIZED_MESSAGE_REPOSITORY WHERE processorName = ? AND messageId = ?" /> <property name="insertString" value="INSERT INTO CUSTOMIZED_MESSAGE_REPOSITORY (processorName, messageId, createdAt) VALUES (?, ?, ?)" /> <property name="deleteString" value="DELETE FROM CUSTOMIZED_MESSAGE_REPOSITORY WHERE processorName = ? AND messageId = ?" /> </bean>

4PFKD QEB )#!" ?>PBA >DDOBD>QFLK OBMLPFQLOV S>FI>?IB >P LC ">JBI 2.6 JdbcAggregationRepository JT BO AggregationRepository XIJDI PO UIF GMZ QFSTJTUT UIF BHHSFHBUFE NFTTBHFT. 5IJT FOTVSFT UIBU ZPV XJMM OPU MPPTF NFTTBHFT, BT UIF EFGBVMU BHHSFHBUPS XJMM VTF BO JO NFNPSZ POMZ AggregationRepository. 5IF JdbcAggregationRepository BMMPXT UPHFUIFS XJUI $BNFM UP QSPWJEF QFSTJTUFOU TVQQPSU GPS UIF "HHSFHBUPS. *U IBT UIF GPMMPXJOH PQUJPOT: .MQFLK dataSource repositoryName 3VMB DataSource String #BP@OFMQFLK

,>KA>QLOV: 5IF javax.sql.DataSource ,>KA>QLOV: 5IF OBNF PG UIF SFQPTJUPSZ.

transactionManager

TransactionManager

,>KA>QLOV: 5IF org.springframework.transaction.P UP NBOHF USBOTBDUJPOT GPS UIF EBUBCBTF. 5IF 5SB TVQQPSU EBUBCBTFT.

lobHandler

LobHandler

" org.springframework.jdbc.suppor -PC UZQFT JO UIF EBUBCBTF. 6TF UIJT PQUJPO UP VTF FYBNQMF XIFO VTJOH 0SBDMF.

returnOldExchange

CPPMFBO

8IFUIFS UIF HFU PQFSBUJPO TIPVME SFUVSO UIF PM EFGBVMU UIJT PQUJPO JT false UP PQUJNJ[F BT XF E BHHSFHBUJOH.

958

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

4PFKD )A?@ DDOBD>QFLK1BMLPFQLOV FK ">JBI 2.6 *O $BNFM 2.6, UIF +ECD"HHSFHBUJPO3FQPTJUPSZ JT QSPWJEFE JO UIF camel-jdbcaggregator DPNQPOFOU. 'SPN $BNFM 2.7 POXBSET, UIF JdbcAggregationRepository JT QSPWJEFE JO UIF camel-sql DPNQPOFOU.

useRecovery

CPPMFBO

8IFUIFS PS OPU SFDPWFSZ JT FOBCMFE. 5IJT PQUJPO UIF $BNFM "HHSFHBUPS BVUPNBUJD SFDPWFS GBJMFE B SFTVCNJUUFE.

recoveryInterval

MPOH

*G SFDPWFSZ JT FOBCMFE UIFO B CBDLHSPVOE UBTL JT FYDIBOHFT UP SFDPWFS BOE SFTVCNJU. #Z EFGBVMU UI

maximumRedeliveries

JOU

"MMPXT ZPV UP MJNJU UIF NBYJNVN OVNCFS PG SFE FYDIBOHF. *G FOBCMFE UIFO UIF &YDIBOHF XJMM CF N SFEFMJWFSZ BUUFNQUT GBJMFE. #Z EFGBVMU UIJT PQUJPO UIF deadLetterUri PQUJPO NVTU BMTP CF QSPW

deadLetterUri

4USJOH

"O FOEQPJOU VSJ GPS B %FBE -FUUFS $IBOOFM XIFS XJMM CF NPWFE. *G UIJT PQUJPO JT VTFE UIFO UIF ma NVTU BMTP CF QSPWJEFE.

storeBodyAsText headersToStoreAsText

CPPMFBO List<String>

">JBI 2.11: 8IFUIFS UP TUPSF UIF NFTTBHF CP SFBEBCMF. #Z EFGBVMU UIJT PQUJPO JT false TUPSJOH

">JBI 2.11: "MMPXT UP TUPSF IFBEFST BT 4USJOH UIJT PQUJPO JT EJTBCMFE, TUPSJOH UIF IFBEFST JO CJO

6E>Q FP MOBPBOSBA TEBK MBOPFPQFKD


JdbcAggregationRepository XJMM POMZ QSFTFSWF BOZ Serializable DPNQBUJCMF EBUB UZQFT. *G B EBUB UZQF JT OPU TVDI B UZQF JUT ESPQQFE BOE B WARN JT MPHHFE. "OE JU POMZ QFSTJTUT UIF Message CPEZ BOE UIF Message IFBEFST. 5IF Exchange QSPQFSUJFT BSF KLQ QFSTJTUFE. 'SPN $BNFM 2.11 POXBSET ZPV DBO TUPSF UIF NFTTBHF CPEZ BOE TFMFDU(FE) IFBEFST BT 4USJOH JO TFQBSBUF DPMVNOT.

1B@LSBOV
5IF JdbcAggregationRepository XJMM CZ EFGBVMU SFDPWFS BOZ GBJMFE &YDIBOHF. *U EPFT UIJT CZ IBWJOH B CBDLHSPVOE UBTLT UIBU TDBOT GPS GBJMFE &YDIBOHFT JO UIF QFSTJTUFOU TUPSF. :PV DBO VTF UIF checkInterval PQUJPO UP TFU IPX PGUFO UIJT UBTL SVOT. 5IF SFDPWFSZ XPSLT BT USBOTBDUJPOBM XIJDI FOTVSFT UIBU $BNFM XJMM USZ UP SFDPWFS BOE SFEFMJWFS UIF GBJMFE &YDIBOHF.

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

959

"OZ &YDIBOHF XIJDI XBT GPVOE UP CF SFDPWFSFE XJMM CF SFTUPSFE GSPN UIF QFSTJTUFOU TUPSF BOE SFTVCNJUUFE BOE TFOE PVU BHBJO. 5IF GPMMPXJOH IFBEFST JT TFU XIFO BO &YDIBOHF JT CFJOH SFDPWFSFE/SFEFMJWFSFE: 'B>ABO Exchange.REDELIVERED Exchange.REDELIVERY_COUNTER 3VMB #PPMFBO *OUFHFS #BP@OFMQFLK *T TFU UP USVF UP JOEJDBUF UIF &YDIBOHF JT CFJOH SFEFMJWFSFE. 5IF SFEFMJWFSZ BUUFNQU, TUBSUJOH GSPN 1.

0OMZ XIFO BO &YDIBOHF IBT CFFO TVDDFTTGVMMZ QSPDFTTFE JU XJMM CF NBSLFE BT DPNQMFUF XIJDI IBQQFOT XIFO UIF confirm NFUIPE JT JOWPLFE PO UIF AggregationRepository. 5IJT NFBOT JG UIF TBNF &YDIBOHF GBJMT BHBJO JU XJMM CF LFQU SFUSJFE VOUJM JU TVDDFTT. :PV DBO VTF PQUJPO maximumRedeliveries UP MJNJU UIF NBYJNVN OVNCFS PG SFEFMJWFSZ BUUFNQUT GPS B HJWFO SFDPWFSFE &YDIBOHF. :PV NVTU BMTP TFU UIF deadLetterUri PQUJPO TP $BNFM LOPXT XIFSF UP TFOE UIF &YDIBOHF XIFO UIF maximumRedeliveries XBT IJU. :PV DBO TFF TPNF FYBNQMFT JO UIF VOJU UFTUT PG DBNFM-TRM, GPS FYBNQMF UIJT UFTU.

#>Q>?>PB
5P CF PQFSBUJPOBM, FBDI BHHSFHBUPS VTFT UXP UBCMF: UIF BHHSFHBUJPO BOE DPNQMFUFE POF. #Z DPOWFOUJPO UIF DPNQMFUFE IBT UIF TBNF OBNF BT UIF BHHSFHBUJPO POF TVGGJYFE XJUI "_COMPLETED". 5IF OBNF NVTU CF DPOGJHVSFE JO UIF 4QSJOH CFBO XJUI UIF RepositoryName QSPQFSUZ. *O UIF GPMMPXJOH FYBNQMF BHHSFHBUJPO XJMM CF VTFE. 5IF UBCMF TUSVDUVSF EFGJOJUJPO PG CPUI UBCMF BSF JEFOUJDBM: JO CPUI DBTF B 4USJOH WBMVF JT VTFE BT LFZ (FA) XIFSFBT B #MPC DPOUBJOT UIF FYDIBOHF TFSJBMJ[FE JO CZUF BSSBZ. )PXFWFS POF EJGGFSFODF TIPVME CF SFNFNCFSFE: UIF FA GJFME EPFT OPU IBWF UIF TBNF DPOUFOU EFQFOEJOH PO UIF UBCMF. *O UIF BHHSFHBUJPO UBCMF FA IPMET UIF DPSSFMBUJPO *E VTFE CZ UIF DPNQPOFOU UP BHHSFHBUF UIF NFTTBHFT. *O UIF DPNQMFUFE UBCMF, FA IPMET UIF JE PG UIF FYDIBOHF TUPSFE JO DPSSFTQPOEJOH UIF CMPC GJFME. )FSF JT UIF 42- RVFSZ VTFE UP DSFBUF UIF UBCMFT, KVTU SFQMBDF "aggregation" XJUI ZPVS BHHSFHBUPS SFQPTJUPSZ OBNF.
CREATE TABLE aggregation ( id varchar(255) NOT NULL, exchange blob NOT NULL, constraint aggregation_pk PRIMARY KEY (id) ); CREATE TABLE aggregation_completed ( id varchar(255) NOT NULL, exchange blob NOT NULL,

960

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

constraint aggregation_completed_pk PRIMARY KEY (id) );

2QLOFKD ?LAV >KA EB>ABOP >P QBUQ


S>FI>?IB >P LC ">JBI 2.11 :PV DBO DPOGJHVSF UIF JdbcAggregationRepository UP TUPSF NFTTBHF CPEZ BOE TFMFDU(FE) IFBEFST BT 4USJOH JO TFQBSBUF DPMVNOT. 'PS FYBNQMF UP TUPSF UIF CPEZ, BOE UIF GPMMPXJOH UXP IFBEFST companyName BOE accountName VTF UIF GPMMPXJOH 42-:
CREATE TABLE aggregationRepo3 ( id varchar(255) NOT NULL, exchange blob NOT NULL, body varchar(1000), companyName varchar(1000), accountName varchar(1000), constraint aggregationRepo3_pk PRIMARY KEY (id) ); CREATE TABLE aggregationRepo3_completed ( id varchar(255) NOT NULL, exchange blob NOT NULL, body varchar(1000), companyName varchar(1000), accountName varchar(1000), constraint aggregationRepo3_completed_pk PRIMARY KEY (id) );

"OE UIFO DPOGJHVSF UIF SFQPTJUPSZ UP FOBCMF UIJT CFIBWJPS BT TIPXO CFMPX:
<bean id="repo3" class="org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository"> <property name="repositoryName" value="aggregationRepo3"/> <property name="transactionManager" ref="txManager3"/> <property name="dataSource" ref="dataSource3"/> <!-- configure to store the message body and following headers as text in the repo --> <property name="storeBodyAsText" value="true"/> <property name="headersToStoreAsText"> <list> <value>companyName</value> <value>accountName</value> </list> </property> </bean>

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

961

"LAB@ (2BOF>IFW>QFLK)
4JODF UIFZ DBO DPOUBJO BOZ UZQF PG QBZMPBE, &YDIBOHFT BSF OPU TFSJBMJ[BCMF CZ EFTJHO. *U JT DPOWFSUFE JOUP B CZUF BSSBZ UP CF TUPSFE JO B EBUBCBTF #-0# GJFME. "MM UIPTF DPOWFSTJPOT BSF IBOEMFE CZ UIF JdbcCodec DMBTT. 0OF EFUBJM PG UIF DPEF SFRVJSFT ZPVS BUUFOUJPO: UIF ClassLoadingAwareObjectInputStream. 5IF ClassLoadingAwareObjectInputStream IBT CFFO SFVTFE GSPN UIF "QBDIF "DUJWF.2 QSPKFDU. *U XSBQT BO ObjectInputStream BOE VTF JU XJUI UIF ContextClassLoader SBUIFS UIBO UIF currentThread POF. 5IF CFOFGJU JT UP CF BCMF UP MPBE DMBTTFT FYQPTFE CZ PUIFS CVOEMFT. 5IJT BMMPXT UIF FYDIBOHF CPEZ BOE IFBEFST UP IBWF DVTUPN UZQFT PCKFDU SFGFSFODFT.

3O>KP>@QFLK
" 4QSJOH PlatformTransactionManager JT SFRVJSFE UP PSDIFTUSBUF USBOTBDUJPO.

2BOSF@B (2Q>OQ/2QLM)
5IF start NFUIPE WFSJGZ UIF DPOOFDUJPO PG UIF EBUBCBTF BOE UIF QSFTFODF PG UIF SFRVJSFE UBCMFT. *G BOZUIJOH JT XSPOH JU XJMM GBJM EVSJOH TUBSUJOH.

DDOBD>QLO @LKCFDRO>QFLK
%FQFOEJOH PO UIF UBSHFUFE FOWJSPONFOU, UIF BHHSFHBUPS NJHIU OFFE TPNF DPOGJHVSBUJPO. "T ZPV BMSFBEZ LOPX, FBDI BHHSFHBUPS TIPVME IBWF JUT PXO SFQPTJUPSZ (XJUI UIF DPSSFTQPOEJOH QBJS PG UBCMF DSFBUFE JO UIF EBUBCBTF) BOE B EBUB TPVSDF. *G UIF EFGBVMU MPC)BOEMFS JT OPU BEBQUFE UP ZPVS EBUBCBTF TZTUFN, JU DBO CF JOKFDUFE XJUI UIF lobHandler QSPQFSUZ. )FSF JT UIF EFDMBSBUJPO GPS 0SBDMF:
<bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"> <property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/> </bean> <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"/> <bean id="repo" class="org.apache.camel.processor.aggregate.jdbc.JdbcAggregationRepository"> <property name="transactionManager" ref="transactionManager"/> <property name="repositoryName" value="aggregation"/> <property name="dataSource" ref="dataSource"/> <!-- Only with Oracle, else use default -->

962

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

<property name="lobHandler" ref="lobHandler"/> </bean>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE +%#$

3$23 ".,/.-$-3
5FTUJOH PG EJTUSJCVUFE BOE BTZODISPOPVT QSPDFTTJOH JT OPUPSJPVTMZ EJGGJDVMU. 5IF .PDL, 5FTU BOE %BUB4FU FOEQPJOUT XPSL HSFBU XJUI UIF $BNFM 5FTUJOH 'SBNFXPSL UP TJNQMJGZ ZPVS VOJU BOE JOUFHSBUJPO UFTUJOH VTJOH &OUFSQSJTF *OUFHSBUJPO 1BUUFSOT BOE $BNFM'T MBSHF SBOHF PG $PNQPOFOUT UPHFUIFS XJUI UIF QPXFSGVM #FBO *OUFHSBUJPO. 5IF QBPQ DPNQPOFOU FYUFOET UIF .PDL DPNQPOFOU UP TVQQPSU QVMMJOH NFTTBHFT GSPN BOPUIFS FOEQPJOU PO TUBSUVQ UP TFU UIF FYQFDUFE NFTTBHF CPEJFT PO UIF VOEFSMZJOH .PDL FOEQPJOU. 5IBU JT, ZPV VTF UIF UFTU FOEQPJOU JO B SPVUF BOE NFTTBHFT BSSJWJOH PO JU XJMM CF JNQMJDJUMZ DPNQBSFE UP TPNF FYQFDUFE NFTTBHFT FYUSBDUFE GSPN TPNF PUIFS MPDBUJPO. 4P ZPV DBO VTF, GPS FYBNQMF, BO FYQFDUFE TFU PG NFTTBHF CPEJFT BT GJMFT. 5IJT XJMM UIFO TFU VQ B QSPQFSMZ DPOGJHVSFE .PDL FOEQPJOU, XIJDI JT POMZ WBMJE JG UIF SFDFJWFE NFTTBHFT NBUDI UIF OVNCFS PG FYQFDUFE NFTTBHFT BOE UIFJS NFTTBHF QBZMPBET BSF FRVBM. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU XIFO VTJOH ">JBI 2.8 PS PMEFS:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

'SPN $BNFM 2.9 POXBSET UIF 5FTU DPNQPOFOU JT QSPWJEFE EJSFDUMZ JO UIF DBNFM-DPSF. 41( CLOJ>Q
test:expectedMessagesEndpointUri

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

963

8IFSF BUMB@QBA,BPP>DBP$KAMLFKQ4OF SFGFST UP TPNF PUIFS $PNQPOFOU 63* UIBU UIF FYQFDUFE NFTTBHF CPEJFT BSF QVMMFE GSPN CFGPSF TUBSUJOH UIF UFTU. $U>JMIB 'PS FYBNQMF, ZPV DPVME XSJUF B UFTU DBTF BT GPMMPXT:
from("seda:someEndpoint"). to("test:file://data/expectedOutput?noop=true");

*G ZPVS UFTU UIFO JOWPLFT UIF .PDL&OEQPJOU.BTTFSU*T4BUJTGJFE(DBNFM$POUFYU) NFUIPE, ZPVS UFTU DBTF XJMM QFSGPSN UIF OFDFTTBSZ BTTFSUJPOT. 5P TFF IPX ZPV DBO TFU PUIFS FYQFDUBUJPOT PO UIF UFTU FOEQPJOU, TFF UIF .PDL DPNQPOFOU. 2BB IPL ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 4QSJOH 5FTUJOH

3(,$1 ".,/.-$-3
5IF QFJBO: DPNQPOFOU JT VTFE UP HFOFSBUF NFTTBHF FYDIBOHFT XIFO B UJNFS GJSFT :PV DBO POMZ DPOTVNF FWFOUT GSPN UIJT FOEQPJOU. 41( CLOJ>Q
timer:name[?options]

8IFSF name JT UIF OBNF PG UIF Timer PCKFDU, XIJDI JT DSFBUFE BOE TIBSFE BDSPTT FOEQPJOUT. 4P JG ZPV VTF UIF TBNF OBNF GPS BMM ZPVS UJNFS FOEQPJOUT, POMZ POF Timer PCKFDU BOE UISFBE XJMM CF VTFE. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... -LQB: 5IF */ CPEZ PG UIF HFOFSBUFE FYDIBOHF JT null. 4P exchange.getIn().getBody() SFUVSOT null.

964

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

AS>K@BA 2@EBARIBO 4FF BMTP UIF 2VBSU[ DPNQPOFOU UIBU TVQQPSUT NVDI NPSF BEWBODFE TDIFEVMJOH.

2MB@FCV QFJB FK ERJ>K COFBKAIV CLOJ>Q *O ">JBI 2.3 POXBSET ZPV DBO TQFDJGZ UIF UJNF JO IVNBO GSJFOEMZ TZOUBY. .MQFLKP
->JB
time pattern period delay fixedRate daemon repeatCount

#BC>RIQ 5>IRB
null null 1000 0 / 1000 false true 0

#BP@OFMQFLK
" java.util.Date UIF CFOPQ FWFOU TIPVME CF HFOFSBUFE. *G VTJOH UIF 63*, UIF QBUUFSO FYQFDUFE JT: yyyy-MM-dd HH:mm:ss PS yyyy-MM-dd'T'HH:mm:ss. "MMPXT ZPV UP TQFDJGZ B DVTUPN Date QBUUFSO UP VTF GPS TFUUJOH UIF UJNF PQUJPO VTJOH 63* TZOUBY. *G HSFBUFS UIBO 0, HFOFSBUF QFSJPEJD FWFOUT FWFSZ period NJMMJTFDPOET. 5IF OVNCFS PG NJMMJTFDPOET UP XBJU CFGPSF UIF GJSTU FWFOU JT HFOFSBUFE. 4IPVME OPU CF VTFE JO DPOKVODUJPO XJUI UIF time PQUJPO. 5IF EFGBVMU WBMVF IBT CFFO DIBOHFE UP 1000 GSPN ">JBI 2.11 POXBSET. *O PMEFS SFMFBTFT UIF EFGBVMU WBMVF JT 0. &WFOUT UBLF QMBDF BU BQQSPYJNBUFMZ SFHVMBS JOUFSWBMT, TFQBSBUFE CZ UIF TQFDJGJFE QFSJPE. 4QFDJGJFT XIFUIFS PS OPU UIF UISFBE BTTPDJBUFE XJUI UIF UJNFS FOEQPJOU SVOT BT B EBFNPO. ">JBI 2.8: 4QFDJGJFT B NBYJNVN MJNJU PG OVNCFS PG GJSFT. 4P JG ZPV TFU JU UP 1, UIF UJNFS XJMM POMZ GJSF PODF. *G ZPV TFU JU UP 5, JU XJMM POMZ GJSF GJWF UJNFT. " WBMVF PG [FSP PS OFHBUJWF NFBOT GJSF GPSFWFS.

$U@E>KDB /OLMBOQFBP 8IFO UIF UJNFS JT GJSFE, JU BEET UIF GPMMPXJOH JOGPSNBUJPO BT QSPQFSUJFT UP UIF Exchange:
->JB
Exchange.TIMER_NAME Exchange.TIMER_TIME Exchange.TIMER_PERIOD Exchange.TIMER_FIRED_TIME Exchange.TIMER_COUNTER

3VMB
String Date long Date Long

#BP@OFMQFLK
5IF WBMVF PG UIF name PQUJPO. 5IF WBMVF PG UIF time PQUJPO. 5IF WBMVF PG UIF period PQUJPO. 5IF UJNF XIFO UIF DPOTVNFS GJSFE. ">JBI 2.8: 5IF DVSSFOU GJSF DPVOUFS. 4UBSUT GSPN 1.

,BPP>DB 'B>ABOP 8IFO UIF UJNFS JT GJSFE, JU BEET UIF GPMMPXJOH JOGPSNBUJPO BT IFBEFST UP UIF */ NFTTBHF
->JB
Exchange.TIMER_FIRED_TIME

3VMB
java.util.Date

#BP@OFMQFLK
5IF UJNF XIFO UIF DPOTVNFS GJSFE

2>JMIB 5P TFU VQ B SPVUF UIBU HFOFSBUFT BO FWFOU FWFSZ 60 TFDPOET:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

965

from("timer://foo?fixedRate=true&period=60000").to("bean:myBean?method=someMethodName");

5IF BCPWF SPVUF XJMM HFOFSBUF BO FWFOU BOE UIFO JOWPLF UIF someMethodName NFUIPE PO UIF CFBO DBMMFE myBean JO UIF 3FHJTUSZ TVDI BT +/%* PS 4QSJOH. "OE UIF SPVUF JO 4QSJOH %4-:
<route> <from uri="timer://foo?fixedRate=true&amp;period=60000"/> <to uri="bean:myBean?method=someMethodName"/> </route>

%FOFKD LKIV LK@B


S>FI>?IB >P LC ">JBI 2.8 :PV NBZ XBOU UP GJSF B NFTTBHF JO B $BNFM SPVUF POMZ PODF, TVDI BT XIFO TUBSUJOH UIF SPVUF. 5P EP UIBU ZPV VTF UIF SFQFBU$PVOU PQUJPO BT TIPXO:
<route> <from uri="timer://foo?repeatCount=1"/> <to uri="bean:myBean?method=someMethodName"/> </route>

2BB

IPL ` ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE 2VBSU[

5 +(# 3(.- ".,/.-$-3


5IF 7BMJEBUJPO DPNQPOFOU QFSGPSNT 9.- WBMJEBUJPO PG UIF NFTTBHF CPEZ VTJOH UIF +"91 7BMJEBUJPO "1* BOE CBTFE PO BOZ PG UIF TVQQPSUFE 9.- TDIFNB MBOHVBHFT, XIJDI EFGBVMUT UP 9.- 4DIFNB /PUF UIBU UIF +JOH DPNQPOFOU BMTP TVQQPSUT UIF GPMMPXJOH VTFGVM TDIFNB MBOHVBHFT: ` 3FMBY/( $PNQBDU 4ZOUBY ` 3FMBY/( 9.- 4ZOUBY 5IF .47 DPNQPOFOU BMTP TVQQPSUT 3FMBY/( 9.- 4ZOUBY.

966

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*OTUFBE PG 60000 ZPV DBO VTF QFSJPE=60T XIJDI JT NPSF GSJFOEMZ UP SFBE. 41( CLOJ>Q
validator:someLocalOrRemoteResource

8IFSF PLJB+L@>I.O1BJLQB1BPLRO@B JT TPNF 63- UP B MPDBM SFTPVSDF PO UIF DMBTTQBUI PS B GVMM 63- UP B SFNPUF SFTPVSDF PS SFTPVSDF PO UIF GJMF TZTUFN XIJDI DPOUBJOT UIF 94% UP WBMJEBUF BHBJOTU. 'PS FYBNQMF: ` msv:org/foo/bar.xsd ` msv:file:../foo/bar.xsd ` msv:http://acme.com/cheese.xsd ` validator:com/mypackage/myschema.xsd .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU XIFO VTJOH ">JBI 2.8 PS PMEFS:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

'SPN $BNFM 2.9 POXBSET UIF 7BMJEBUJPO DPNQPOFOU JT QSPWJEFE EJSFDUMZ JO UIF DBNFM-DPSF. .MQFLKP
.MQFLK
resourceResolver useDom useSharedSchema failOnNullBody headerName failOnNullHeader

#BC>RIQ
null false true true null true

#BP@OFMQFLK
">JBI 2.9: 3FGFSFODF UP B org.w3c.dom.ls.LSResourceResolver JO UIF 3FHJTUSZ. 8IFUIFS DOMSource/DOMResult PS SaxSource/SaxResult TIPVME CF VTFE CZ UIF WBMJEBUPS. ">JBI 2.3: 8IFUIFS UIF Schema JOTUBODF TIPVME CF TIBSFE PS OPU. 5IJT PQUJPO JT JOUSPEVDFE UP XPSL BSPVOE B +%, 1.6.Y CVH. 9FSDFT TIPVME OPU IBWF UIJT JTTVF. ">JBI 2.9.5/2.10.3: 8IFUIFS UP GBJM JG OP CPEZ FYJTUT. ">JBI 2.11: 5P WBMJEBUF BHBJOTU B IFBEFS JOTUFBE PG UIF NFTTBHF CPEZ. ">JBI 2.11: 8IFUIFS UP GBJM JG OP IFBEFS FYJTUT XIFO WBMJEBUJOH BHBJOTU B IFBEFS.

$U>JMIB 5IF GPMMPXJOH FYBNQMF TIPXT IPX UP DPOGJHVSF B SPVUF GSPN FOEQPJOU AFOB@Q:PQ>OQ XIJDI UIFO HPFT UP POF PG UXP FOEQPJOUT, FJUIFS JL@H:S>IFA PS JL@H:FKS>IFA CBTFE PO XIFUIFS PS OPU UIF 9.- NBUDIFT UIF HJWFO TDIFNB (XIJDI JT TVQQMJFE PO UIF DMBTTQBUI).

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

967

<route> <from uri="direct:start"/> <doTry> <to uri="validator:org/apache/camel/component/validator/schema.xsd"/> <to uri="mock:valid"/> <doCatch> <exception>org.apache.camel.ValidationException</exception> <to uri="mock:invalid"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route>

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

5$+."(38
5IF SBIL@FQV: DPNQPOFOU BMMPXT ZPV UP QSPDFTT B NFTTBHF VTJOH BO "QBDIF 7FMPDJUZ UFNQMBUF. 5IJT DBO CF JEFBM XIFO VTJOH 5FNQMBUJOH UP HFOFSBUF SFTQPOTFT GPS SFRVFTUT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-velocity</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
velocity:templateName[?options]

8IFSF QBJMI>QB->JB JT UIF DMBTTQBUI-MPDBM 63* PG UIF UFNQMBUF UP JOWPLF; PS UIF DPNQMFUF 63- PG UIF SFNPUF UFNQMBUF (FH: GJMF://GPMEFS/NZGJMF.WN).

968

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

:PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
.MQFLK
loaderCache contentCache encoding propertiesFile

#BC>RIQ
true true null null

#BP@OFMQFLK
7FMPDJUZ CBTFE GJMF MPBEFS DBDIF. $BDIF GPS UIF SFTPVSDF DPOUFOU XIFO JU JT MPBEFE. /PUF : BT PG $BNFM 2.9 DBDIFE SFTPVSDF DPOUFOU DBO CF DMFBSFE WJB +.9 VTJOH UIF FOEQPJOU'T clearContentCache PQFSBUJPO. $IBSBDUFS FODPEJOH PG UIF SFTPVSDF DPOUFOU. /FX PQUJPO JO $BNFM 2.1: 5IF 63* PG UIF QSPQFSUJFT GJMF XIJDI JT VTFE GPS 7FMPDJUZ&OHJOF JOJUJBMJ[BUJPO.

,BPP>DB 'B>ABOP 5IF WFMPDJUZ DPNQPOFOU TFUT B DPVQMF IFBEFST PO UIF NFTTBHF (ZPV DBO'U TFU UIFTF ZPVSTFMG BOE GSPN $BNFM 2.1 WFMPDJUZ DPNQPOFOU XJMM OPU TFU UIFTF IFBEFST XIJDI XJMM DBVTF TPNF TJEF FGGFDU PO UIF EZOBNJD UFNQMBUF TVQQPSU):
'B>ABO
CamelVelocityResourceUri

#BP@OFMQFLK
5IF QBJMI>QB->JB BT B String PCKFDU.

)FBEFST TFU EVSJOH UIF 7FMPDJUZ FWBMVBUJPO BSF SFUVSOFE UP UIF NFTTBHF BOE BEEFE BT IFBEFST. 5IFO JUT LJOEB QPTTJCMF UP SFUVSO WBMVFT GSPN 7FMPDJUZ UP UIF .FTTBHF. 'PS FYBNQMF, UP TFU UIF IFBEFS WBMVF PG fruit JO UIF 7FMPDJUZ UFNQMBUF .tm:
$in.setHeader('fruit', 'Apple')

5IF fruit IFBEFS JT OPX BDDFTTJCMF GSPN UIF message.out.headers. 5BIL@FQV "LKQBUQ $BNFM XJMM QSPWJEF FYDIBOHF JOGPSNBUJPO JO UIF 7FMPDJUZ DPOUFYU (KVTU B Map). 5IF Exchange JT USBOTGFSFE BT:
HBV
exchange exchange.properties headers camelContext request in body out response

S>IRB
5IF Exchange JUTFMG. 5IF Exchange QSPQFSUJFT. 5IF IFBEFST PG UIF *O NFTTBHF. 5IF $BNFM $POUFYU JOUBODF. 5IF *O NFTTBHF. 5IF *O NFTTBHF. 5IF *O NFTTBHF CPEZ. 5IF 0VU NFTTBHF (POMZ GPS *O0VU NFTTBHF FYDIBOHF QBUUFSO). 5IF 0VU NFTTBHF (POMZ GPS *O0VU NFTTBHF FYDIBOHF QBUUFSO).

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

969

'LQ OBIL>AFKD 5IF 7FMPDJUZ UFNQMBUF SFTPVSDF JT, CZ EFGBVMU, IPU SFMPBEBCMF GPS CPUI GJMF BOE DMBTTQBUI SFTPVSDFT (FYQBOEFE KBS). *G ZPV TFU contentCache=true, $BNFM XJMM POMZ MPBE UIF SFTPVSDF PODF, BOE UIVT IPU SFMPBEJOH JT OPU QPTTJCMF. 5IJT TDFOBSJP DBO CF VTFE JO QSPEVDUJPO, XIFO UIF SFTPVSDF OFWFS DIBOHFT. #VK>JF@ QBJMI>QBP S>FI>?IB >P LC ">JBI 2.1 $BNFM QSPWJEFT UXP IFBEFST CZ XIJDI ZPV DBO EFGJOF B EJGGFSFOU SFTPVSDF MPDBUJPO GPS B UFNQMBUF PS UIF UFNQMBUF DPOUFOU JUTFMG. *G BOZ PG UIFTF IFBEFST JT TFU UIFO $BNFM VTFT UIJT PWFS UIF FOEQPJOU DPOGJHVSFE SFTPVSDF. 5IJT BMMPXT ZPV UP QSPWJEF B EZOBNJD UFNQMBUF BU SVOUJNF.
'B>ABO
$BNFM7FMPDJUZ3FTPVSDF6SJ $BNFM7FMPDJUZ5FNQMBUF

3VMB
4USJOH 4USJOH

#BP@OFMQFLK
">JBI 2.1: " 63* GPS UIF UFNQMBUF SFTPVSDF UP VTF JOTUFBE PG UIF FOEQPJOU DPOGJHVSFE. ">JBI 2.1: 5IF UFNQMBUF UP VTF JOTUFBE PG UIF FOEQPJOU DPOGJHVSFE.

2>JMIBP 'PS FYBNQMF ZPV DPVME VTF TPNFUIJOH MJLF


from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm");

5P VTF B 7FMPDJUZ UFNQMBUF UP GPSNVMBUF B SFTQPOTF UP B NFTTBHF GPS *O0VU NFTTBHF FYDIBOHFT (XIFSF UIFSF JT B JMSReplyTo IFBEFS). *G ZPV XBOU UP VTF *O0OMZ BOE DPOTVNF UIF NFTTBHF BOE TFOE JU UP BOPUIFS EFTUJOBUJPO, ZPV DPVME VTF UIF GPMMPXJOH SPVUF:
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm"). to("activemq:Another.Queue");

"OE UP VTF UIF DPOUFOU DBDIF, F.H. GPS VTF JO QSPEVDUJPO, XIFSF UIF .vm UFNQMBUF OFWFS DIBOHFT:
from("activemq:My.Queue"). to("velocity:com/acme/MyResponse.vm?contentCache=true"). to("activemq:Another.Queue");

"OE B GJMF CBTFE SFTPVSDF:

970

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

from("activemq:My.Queue"). to("velocity:file://myfolder/MyResponse.vm?contentCache=true"). to("activemq:Another.Queue");

*O ">JBI 2.1 JU'T QPTTJCMF UP TQFDJGZ XIBU UFNQMBUF UIF DPNQPOFOU TIPVME VTF EZOBNJDBMMZ WJB B IFBEFS, TP GPS FYBNQMF:
from("direct:in"). setHeader("CamelVelocityResourceUri").constant("path/to/my/template.vm"). to("velocity:dummy");

*O ">JBI 2.1 JU'T QPTTJCMF UP TQFDJGZ B UFNQMBUF EJSFDUMZ BT B IFBEFS UIF DPNQPOFOU TIPVME VTF EZOBNJDBMMZ WJB B IFBEFS, TP GPS FYBNQMF:
from("direct:in"). setHeader("CamelVelocityTemplate").constant("Hi this is a velocity template that can do templating ${body}"). to("velocity:dummy");

3EB $J>FI 2>JMIB *O UIJT TBNQMF XF XBOU UP VTF 7FMPDJUZ UFNQMBUJOH GPS BO PSEFS DPOGJSNBUJPO FNBJM. 5IF FNBJM UFNQMBUF JT MBJE PVU JO 7FMPDJUZ BT:
Dear ${headers.lastName}, ${headers.firstName} Thanks for the order of ${headers.item}. Regards Camel Riders Bookstore ${body}

"OE UIF KBWB DPEF:


private Exchange createLetter() { Exchange exchange = context.getEndpoint("direct:a").createExchange(); Message msg = exchange.getIn(); msg.setHeader("firstName", "Claus"); msg.setHeader("lastName", "Ibsen"); msg.setHeader("item", "Camel in Action"); msg.setBody("PS: Next beer is on me, James"); return exchange; } @Test public void testVelocityLetter() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result");

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

971

mock.expectedMessageCount(1); mock.expectedBodiesReceived("Dear Ibsen, Claus\n\nThanks for the order of Camel in Action.\n\nRegards Camel Riders Bookstore\nPS: Next beer is on me, James"); template.send("direct:a", createLetter()); mock.assertIsSatisfied(); } protected RouteBuilder createRouteBuilder() throws Exception { return new RouteBuilder() { public void configure() throws Exception { from("direct:a").to("velocity:org/apache/camel/component/velocity/ letter.vm").to("mock:result"); } }; }

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

5, ".,/.-$-3
5IF SJ: DPNQPOFOU QSPWJEFT BTZODISPOPVT 4&%" CFIBWJPS, FYDIBOHJOH NFTTBHFT PO B #MPDLJOH2VFVF BOE JOWPLJOH DPOTVNFST JO B TFQBSBUF UISFBE QPPM. 5IJT DPNQPOFOU EJGGFST GSPN UIF 4&%" DPNQPOFOU JO UIBU 7. TVQQPSUT DPNNVOJDBUJPO BDSPTT $BNFM$POUFYU JOTUBODFT - TP ZPV DBO VTF UIJT NFDIBOJTN UP DPNNVOJDBUF BDSPTT XFC BQQMJDBUJPOT (QSPWJEFE UIBU camel-core.jar JT PO UIF system/boot DMBTTQBUI). 7. JT BO FYUFOTJPO UP UIF 4&%" DPNQPOFOU. 41( CLOJ>Q
vm:queueName[?options]

8IFSF queueName DBO CF BOZ TUSJOH UP VOJRVFMZ JEFOUJGZ UIF FOEQPJOU XJUIJO UIF +7. (PS BU MFBTU XJUIJO UIF DMBTTMPBEFS UIBU MPBEFE DBNFM-DPSF.KBS) :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU: ?option=value&option=value&...

972

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

!BCLOB ">JBI 2.3 - 2>JB 41( JRPQ ?B RPBA CLO ?LQE MOLAR@BO >KA @LKPRJBO "O FYBDUMZ JEFOUJDBM 7. FOEQPJOU 63* JRPQ CF VTFE GPS CPUI UIF QSPEVDFS BOE UIF DPOTVNFS FOEQPJOU. 0UIFSXJTF, $BNFM XJMM DSFBUF B TFDPOE 7. FOEQPJOU EFTQJUF UIBU UIF queueName QPSUJPO PG UIF 63* JT JEFOUJDBM. 'PS FYBNQMF:
from("direct:foo").to("vm:bar?concurrentConsumers=5"); from("vm:bar?concurrentConsumers=5").to("file://output");

/PUJDF UIBU XF IBWF UP VTF UIF GVMM 63*, JODMVEJOH PQUJPOT JO CPUI UIF QSPEVDFS BOE DPOTVNFS. *O $BNFM 2.4 UIJT IBT CFFO GJYFE TP UIBU POMZ UIF RVFVF OBNF NVTU NBUDI. 6TJOH UIF RVFVF OBNF bar, XF DPVME SFXSJUF UIF QSFWJPVT FYNQMF BT GPMMPXT:
from("direct:foo").to("vm:bar"); from("vm:bar?concurrentConsumers=5").to("file://output");

.MQFLKP 4FF UIF 4&%" DPNQPOFOU GPS PQUJPOT BOE PUIFS JNQPSUBOU VTBHF EFUBJMT BT UIF TBNF SVMFT BQQMZ UP UIF 7. DPNQPOFOU. 2>JMIBP *O UIF SPVUF CFMPX XF TFOE FYDIBOHFT BDSPTT $BNFM$POUFYU JOTUBODFT UP B 7. RVFVF OBNFE order.email:
from("direct:in").bean(MyOrderBean.class).to("vm:order.email");

"OE UIFO XF SFDFJWF FYDIBOHFT JO TPNF PUIFS $BNFM DPOUFYU (TVDI BT EFQMPZFE JO BOPUIFS .war BQQMJDBUJPO):
from("vm:order.email").bean(MyOrderEmailSender.class);

2BB

IPL ` $POGJHVSJOH $BNFM ` $PNQPOFOU


$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9 973

` &OEQPJOU ` (FUUJOH 4UBSUFE 4&%"

7,// ".,/.-$-3
5IF UJMM: DPNQPOFOU JNQMFNFOUT BO 9.11 (+BCCFS) USBOTQPSU. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-xmpp</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
xmpp://[login@]hostname[:port][/participant][?Options]

5IF DPNQPOFOU TVQQPSUT CPUI SPPN CBTFE BOE QSJWBUF QFSTPO-QFSTPO DPOWFSTBUJPOT. 5IF DPNQPOFOU TVQQPSUT CPUI QSPEVDFS BOE DPOTVNFS (ZPV DBO HFU NFTTBHFT GSPN 9.11 PS TFOE NFTTBHFT UP 9.11). $POTVNFS NPEF TVQQPSUT SPPNT TUBSUJOH. :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... .MQFLKP
->JB
room

#BP@OFMQFLK
*G UIJT PQUJPO JT TQFDJGJFE, UIF DPNQPOFOU XJMM DPOOFDU UP .6$ (.VMUJ 6TFS $IBU). 6TVBMMZ, UIF EPNBJO OBNF GPS .6$ JT EJGGFSFOU GSPN UIF MPHJO EPNBJO. 'PS FYBNQMF, JG ZPV BSF superman@jabber.org BOE XBOU UP KPJO UIF krypton SPPN, UIFO UIF SPPN 63- JT krypton@conference.jabber.org. /PUF UIF conference QBSU. *U JT OPU B SFRVJSFNFOU UP QSPWJEF UIF GVMM SPPN +*%. *G UIF room QBSBNFUFS EPFT OPU DPOUBJO UIF @ TZNCPM, UIF EPNBJO QBSU XJMM CF EJTDPWFSFE BOE BEEFE CZ $BNFM 6TFS OBNF (XJUIPVU TFSWFS OBNF). *G OPU TQFDJGJFE, BOPOZNPVT MPHJO XJMM CF BUUFNQUFE. 1BTTXPSE. 9.11 SFTPVSDF. 5IF EFGBVMU JT Camel. *G true, BO BUUFNQU UP DSFBUF BO BDDPVOU XJMM CF NBEF. %FGBVMU JT false. +*% (+BCCFS *%) PG QFSTPO UP SFDFJWF NFTTBHFT. room QBSBNFUFS IBT QSFDFEFODF PWFS participant. 6TF OJDLOBNF XIFO KPJOJOH SPPN. *G SPPN JT TQFDJGJFE BOE OJDLOBNF JT OPU, user XJMM CF VTFE GPS UIF OJDLOBNF. 5IF OBNF PG UIF TFSWJDF ZPV BSF DPOOFDUJOH UP. 'PS (PPHMF 5BML, UIJT XPVME CF gmail.com. ">JBI 2.11 4QFDJGJFT XIFUIFS UP UFTU UIF DPOOFDUJPO PO TUBSUVQ. 5IJT JT VTFE UP FOTVSF UIBU UIF 9.11 DMJFOU IBT B WBMJE DPOOFDUJPO UP UIF 9.11 TFSWFS XIFO UIF SPVUF TUBSUT. $BNFM UISPXT BO FYDFQUJPO PO TUBSUVQ JG B DPOOFDUJPO DBOOPU CF FTUBCMJTIFE. 8IFO UIJT PQUJPO JT TFU UP GBMTF, $BNFM XJMM BUUFNQU UP FTUBCMJTI B "MB[Z" DPOOFDUJPO XIFO OFFEFE CZ B QSPEVDFS, BOE XJMM QPMM GPS B DPOTVNFS DPOOFDUJPO VOUJM UIF DPOOFDUJPO JT FTUBCMJTIFE. %FGBVMU JT true.

user password resource createAccount participant nickname serviceName

testConnectionOnStartup

974

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

connectionPollDelay

">JBI 2.11 5IF BNPVOU PG UJNF JO TFDPOET CFUXFFO QPMMT UP WFSJGZ UIF IFBMUI PG UIF 9.11 DPOOFDUJPO, PS CFUXFFO BUUFNQUT UP FTUBCMJTI BO JOJUJBM DPOTVNFS DPOOFDUJPO. $BNFM XJMM USZ UP SF-FTUBCMJTI B DPOOFDUJPO JG JU IBT CFDPNF JOBDUJWF. %FGBVMU JT 10 seconds.

'B>ABOP >KA PBQQFKD 2R?GB@Q LO +>KDR>DB $BNFM TFUT UIF NFTTBHF */ IFBEFST BT QSPQFSUJFT PO UIF 9.11 NFTTBHF. :PV DBO DPOGJHVSF B HeaderFilterStategy JG ZPV OFFE DVTUPN GJMUFSJOH PG IFBEFST. 5IF 2R?GB@Q BOE +>KDR>DB PG UIF 9.11 NFTTBHF BSF BMTP TFU JG UIFZ BSF QSPWJEFE BT */ IFBEFST. $U>JMIBP 6TFS superman UP KPJO SPPN krypton BU jabber TFSWFS XJUI QBTTXPSE, secret:
xmpp://superman@jabber.org/?room=krypton@conference.jabber.org&password=secret

6TFS superman UP TFOE NFTTBHFT UP joker:


xmpp://superman@jabber.org/joker@jabber.org?password=secret

3PVUJOH FYBNQMF JO +BWB:


from("timer://kickoff?period=10000"). setBody(constant("I will win!\n Your Superman.")). to("xmpp://superman@jabber.org/joker@jabber.org?password=secret");

$POTVNFS DPOGJHVSBUJPO, XIJDI XSJUFT BMM NFTTBHFT GSPN joker JOUP UIF RVFVF, evil.talk.
from("xmpp://superman@jabber.org/joker@jabber.org?password=secret"). to("activemq:evil.talk");

$POTVNFS DPOGJHVSBUJPO, XIJDI MJTUFOT UP SPPN NFTTBHFT:


from("xmpp://superman@jabber.org/?password=secret&room=krypton@conference.jabber.org"). to("activemq:krypton.talk");

3PPN JO TIPSU OPUBUJPO (OP EPNBJO QBSU):


from("xmpp://superman@jabber.org/?password=secret&room=krypton"). to("activemq:krypton.talk");

8IFO DPOOFDUJOH UP UIF (PPHMF $IBU TFSWJDF, ZPV'MM OFFE UP TQFDJGZ UIF serviceName BT XFMM BT ZPVS DSFEFOUJBMT:

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

975

// send a message from fromuser@gmail.com to touser@gmail.com from("direct:start"). to("xmpp://talk.google.com:5222/ touser@gmail.com?serviceName=gmail.com&user=fromuser&password=secret"). to("mock:result");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

704$18
5IF UNRBOV: DPNQPOFOU BMMPXT ZPV UP QSPDFTT B NFTTBHF VTJOH BO 92VFSZ UFNQMBUF. 5IJT DBO CF JEFBM XIFO VTJOH 5FNQMBUJOH UP HFOFSBUF SFTQPQOTFT GPS SFRVFTUT. .BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-saxon</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

41( CLOJ>Q
xquery:templateName

8IFSF QBJMI>QB->JB JT UIF DMBTTQBUI-MPDBM 63* PG UIF UFNQMBUF UP JOWPLF; PS UIF DPNQMFUF 63- PG UIF SFNPUF UFNQMBUF. 'PS FYBNQMF ZPV DPVME VTF TPNFUIJOH MJLF UIJT:
from("activemq:My.Queue"). to("xquery:com/acme/mytransform.xquery");

5P VTF BO 92VFSZ UFNQMBUF UP GPSNVMBUF B SFTQPOTF UP B NFTTBHF GPS *O0VU NFTTBHF FYDIBOHFT (XIFSF UIFSF JT B JMSReplyTo IFBEFS).

976

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

*G ZPV XBOU UP VTF *O0OMZ, DPOTVNF UIF NFTTBHF, BOE TFOE JU UP BOPUIFS EFTUJOBUJPO, ZPV DPVME VTF UIF GPMMPXJOH SPVUF:
from("activemq:My.Queue"). to("xquery:com/acme/mytransform.xquery"). to("activemq:Another.Queue");

2BB

IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

72+3
5IF UPIQ: DPNQPOFOU BMMPXT ZPV UP QSPDFTT B NFTTBHF VTJOH BO 94-5 UFNQMBUF. 5IJT DBO CF JEFBM XIFO VTJOH 5FNQMBUJOH UP HFOFSBUF SFTQPQOTFT GPS SFRVFTUT. 41( CLOJ>Q
xslt:templateName[?options]

8IFSF QBJMI>QB->JB JT UIF DMBTTQBUI-MPDBM 63* PG UIF UFNQMBUF UP JOWPLF; PS UIF DPNQMFUF 63- PG UIF SFNPUF UFNQMBUF. 3FGFS UP UIF 4QSJOH %PDVNFOUBUJPO GPS NPSF EFUBJM PG UIF 63* TZOUBY :PV DBO BQQFOE RVFSZ PQUJPOT UP UIF 63* JO UIF GPMMPXJOH GPSNBU, ?option=value&option=value&... )FSF BSF TPNF FYBNQMF 63*T
41( #BP@OFMQFLK

xslt:com/acme/mytransform.xsl

SFGFST UP UIF GJMF DPN/BDNF/NZUSBOTGPSN.YTM PO UIF DMBTTQBUI

xslt:file:///foo/bar.xsl

SFGFST UP UIF GJMF /GPP/CBS.YTM

xslt:http://acme.com/cheese/foo.xsl

SFGFST UP UIF SFNPUF IUUQ SFTPVSDF

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

977

.BWFO VTFST XJMM OFFE UP BEE UIF GPMMPXJOH EFQFOEFODZ UP UIFJS pom.xml GPS UIJT DPNQPOFOU XIFO VTJOH ">JBI 2.8 PS PMEFS:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>

'SPN $BNFM 2.9 POXBSET UIF 94-5 DPNQPOFOU JT QSPWJEFE EJSFDUMZ JO UIF DBNFM-DPSF. .MQFLKP
->JB
converter transformerFactory transformerFactoryClass

#BC>RIQ 5>IRB
null null null

#BP@OFMQFLK
0QUJPO UP PWFSSJEF EFGBVMU 9NM$POWFSUFS. 8JMM MPPLVQ GPS UIF DPOWFSUFS JO UIF 3FHJTUSZ. 5IF QSPWJEFE DPOWFSUFE NVTU CF PG UZQF PSH.BQBDIF.DBNFM.DPOWFSUFS.KBYQ.9NM$POWFSUFS. 0QUJPO UP PWFSSJEF EFGBVMU 5SBOTGPSNFS'BDUPSZ. 8JMM MPPLVQ GPS UIF USBOTGPSNFS'BDUPSZ JO UIF 3FHJTUSZ. 5IF QSPWJEFE USBOTGPSNFS GBDUPSZ NVTU CF PG UZQF KBWBY.YNM.USBOTGPSN.5SBOTGPSNFS'BDUPSZ. 0QUJPO UP PWFSSJEF EFGBVMU 5SBOTGPSNFS'BDUPSZ. 8JMM DSFBUF B 5SBOTGPSNFS'BDUPSZ$MBTT JOTUBODF BOE TFU JU UP UIF DPOWFSUFS. ">JBI 2.3: "MMPXT ZPV UP VTF B DVTUPN javax.xml.transformation.URIResolver. $BNFM XJMM CZ EFGBVMU VTF JUT PXO JNQMFNFOUBUJPO org.apache.camel.builder.xml.XsltUriResolver XIJDI JT DBQBCMF PG MPBEJOH GSPN DMBTTQBUI. ">JBI 2.3: "MMPXT ZPV UP VTF B DVTUPN org.apache.camel.builder.xml.ResultHandlerFactory XIJDI JT DBQBCMF PG VTJOH DVTUPN org.apache.camel.builder.xml.ResultHandler UZQFT. ">JBI 2.3: 8IFUIFS PS OPU UP UISPX BO FYDFQUJPO JG UIF JOQVU CPEZ JT OVMM. ">JBI 2.6: *G ZPV IBWF output=file UIFO UIJT PQUJPO EJDUBUFT XIFUIFS PS OPU UIF PVUQVU GJMF TIPVME CF EFMFUFE XIFO UIF &YDIBOHF JT EPOF QSPDFTTJOH. 'PS FYBNQMF TVQQPTF UIF PVUQVU GJMF JT B UFNQPSBSZ GJMF, UIFO JU DBO CF B HPPE JEFB UP EFMFUF JU BGUFS VTF. ">JBI 2.3: 0QUJPO UP TQFDJGZ XIJDI PVUQVU UZQF UP VTF. 1PTTJCMF WBMVFT BSF: string, bytes, DOM, file. 5IF GJSTU UISFF PQUJPOT BSF BMM JO NFNPSZ CBTFE, XIFSF BT file JT TUSFBNFE EJSFDUMZ UP B java.io.File. 'PS file ZPV JRPQ TQFDJGZ UIF GJMFOBNF JO UIF */ IFBEFS XJUI UIF LFZ Exchange.XSLT_FILE_NAME XIJDI JT BMTP CamelXsltFileName. "MTP BOZ QBUIT MFBEJOH UP UIF GJMFOBNF NVTU CF DSFBUFE CFGPSFIBOE, PUIFSXJTF BO FYDFQUJPO JT UISPXO BU SVOUJNF. ">JBI 2.6: $BDIF GPS UIF SFTPVSDF DPOUFOU (UIF TUZMFTIFFU GJMF) XIFO JU JT MPBEFE. *G TFU UP false $BNFM XJMM SFMPBE UIF TUZMFTIFFU GJMF PO FBDI NFTTBHF QSPDFTTJOH. 5IJT JT HPPE GPS EFWFMPQNFOU. /PUF: GSPN ">JBI 2.9 B DBDIFE TUZMFTIFFU DBO CF GPSDFE UP SFMPBE BU SVOUJNF WJB +.9 VTJOH UIF clearCachedStylesheet PQFSBUJPO. ">JBI 2.8.3/2.9: 8IFUIFS UP BMMPX VTJOH 4U"9 BT UIF javax.xml.transform.Source. ">JBI 2.9.3/2.10.1: 5IF OVNCFS PG javax.xml.transform.Transformer PCKFDU UIBU BSF DBDIFE GPS SFVTF UP BWPJE DBMMT UP Template.newTransformer(). ">JBI 2.11: 8IFUIFS UP VTF 4BYPO BT UIF transformerFactoryClass. *G FOBCMFE UIFO UIF DMBTT net.sf.saxon.TransformerFactoryImpl. :PV XPVME OFFE UP BEE 4BYPO UP UIF DMBTTQBUI.

uriResolver

null

resultHandlerFactory failOnNullBody deleteOutputFile

null true false

output

string

contentCache

true

allowStAX transformerCacheSize saxon

false 0 false

4PFKD 72+3 BKAMLFKQP 'PS FYBNQMF ZPV DPVME VTF TPNFUIJOH MJLF
from("activemq:My.Queue"). to("xslt:com/acme/mytransform.xsl");

978

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

5P VTF BO 94-5 UFNQMBUF UP GPSNVMBUF B SFTQPOTF GPS B NFTTBHF GPS *O0VU NFTTBHF FYDIBOHFT (XIFSF UIFSF JT B JMSReplyTo IFBEFS). *G ZPV XBOU UP VTF *O0OMZ BOE DPOTVNF UIF NFTTBHF BOE TFOE JU UP BOPUIFS EFTUJOBUJPO ZPV DPVME VTF UIF GPMMPXJOH SPVUF:
from("activemq:My.Queue"). to("xslt:com/acme/mytransform.xsl"). to("activemq:Another.Queue");

&BQQFKD />O>JBQBOP FKQL QEB 72+3 QL TLOH TFQE #Z EFGBVMU, BMM IFBEFST BSF BEEFE BT QBSBNFUFST XIJDI BSF BWBJMBCMF JO UIF 94-5. 5P EP UIJT ZPV XJMM OFFE UP EFDMBSF UIF QBSBNFUFS TP JU JT UIFO useable.
<setHeader headerName="myParam"><constant>42</constant></setHeader> <to uri="xslt:MyTransform.xsl"/>

"OE UIF 94-5 KVTU OFFET UP EFDMBSF JU BU UIF UPQ MFWFM GPS JU UP CF BWBJMBCMF:
<xsl: ...... > <xsl:param name="myParam"/> <xsl:template ...>

2MOFKD 7,+ SBOPFLKP 5P VTF UIF BCPWF FYBNQMFT JO 4QSJOH 9.- ZPV XPVME VTF TPNFUIJOH MJLF
<camelContext xmlns="http://activemq.apache.org/camel/schema/spring"> <route> <from uri="activemq:My.Queue"/> <to uri="xslt:org/apache/camel/spring/processor/example.xsl"/> <to uri="activemq:Another.Queue"/> </route> </camelContext>

5IFSF JT B UFTU DBTF BMPOH XJUI JUT 4QSJOH 9.- JG ZPV XBOU B DPODSFUF FYBNQMF. 4PFKD UPI:FK@IRAB ">JBI 2.2 LO LIABO *G ZPV VTF YTM:JODMVEF JO ZPVS 94- GJMFT UIFO JO $BNFM 2.2 PS PMEFS JU VTFT UIF EFGBVMU

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

979

javax.xml.transform.URIResolver XIJDI NFBOT JU DBO POMZ MPPLVQ GJMFT GSPN GJMF TZTUFN, BOE JUT EPFT UIBU SFMBUJWF GSPN UIF +7. TUBSUJOH GPMEFS. 'PS FYBNQMF UIJT JODMVEF:
<xsl:include href="staff_template.xsl"/>

8JMM MPPLVQ UIF staff_tempkalte.xsl GJMF GSPN UIF TUBSUJOH GPMEFS XIFSF UIF BQQMJDBUJPO XBT TUBSUFE. ">JBI 2.3 LO KBTBO /PX $BNFM QSPWJEFT JUT PXO JNQMFNFOUBUJPO PG URIResolver XIJDI BMMPXT $BNFM UP MPBE JODMVEFE GJMFT GSPN UIF DMBTTQBUI BOE NPSF JOUFMMJHFOU UIBO CFGPSF. 'PS FYBNQMF UIJT JODMVEF:
<xsl:include href="staff_template.xsl"/>

8JMM OPX CF MPDBUFE SFMBUJWF GSPN UIF TUBSUJOH FOEQPJOU, XIJDI GPS FYBNQMF DPVME CF:
.to("xslt:org/apache/camel/component/xslt/staff_include_relative.xsl")

8IJDI NFBOT $BNFM XJMM MPDBUF UIF GJMF JO UIF @I>PPM>QE BT org/apache/camel/ component/xslt/staff_template.xsl. 5IJT BMMPXT ZPV UP VTF YTM JODMVEF BOE IBWF YTM GJMFT MPDBUFE JO UIF TBNF GPMEFS TVDI BT XF EP JO UIF FYBNQMF org/apache/camel/component/xslt. :PV DBO VTF UIF GPMMPXJOH UXP QSFGJYFT classpath: PS file: UP JOTUSVDU $BNFM UP MPPL FJUIFS JO DMBTTQBUI PS GJMF TZTUFN. *G ZPV PNJU UIF QSFGJY UIFO $BNFM VTFT UIF QSFGJY GSPN UIF FOEQPJOU DPOGJHVSBUJPO. *G UIBU OFJUIFS IBT POF, UIFO DMBTTQBUI JT BTTVNFE. :PV DBO BMTP SFGFS CBDL JO UIF QBUIT TVDI BT
<xsl:include href="../staff_other_template.xsl"/>

8IJDI UIFO XJMM SFTPMWF UIF YTM GJMF VOEFS org/apache/camel/component.

4PFKD UPI:FK@IRAB >KA ABC>RIQ MOBCFU


8IFO VTJOH YTM:JODMVEF TVDI BT:
<xsl:include href="staff_template.xsl"/>

5IFO JO $BNFM 2.10.3 BOE PMEFS, UIFO $BNFM XJMM VTF "DMBTTQBUI:" BT UIF EFGBVMU QSFGJY, BOE MPBE UIF SFTPVSDF GSPN UIF DMBTTQBUI. 5IJT XPSLT GPS NPTU DBTFT, CVU JG ZPV DPOGJHVSF UIF TUBSUJOH SFTPVSDF UP MPBE GSPN GJMF,

980

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

.to("xslt:file:etc/xslt/staff_include_relative.xsl")

.. UIFO ZPV XPVME IBWF UP QSFGJY BMM ZPVS JODMVEFT XJUI "GJMF:" BT XFMM.
<xsl:include href="file:staff_template.xsl"/>

'SPN $BNFM 2.10.4 POXBSET XF IBWF NBEF UIJT FBTJFS BT $BNFM XJMM VTF UIF QSFGJY GSPN UIF FOEQPJOU DPOGJHVSBUJPO BT UIF EFGBVMU QSFGJY. 4P GSPN $BNFM 2.10.4 POXBSET ZPV DBO EP:
<xsl:include href="staff_template.xsl"/>

8IJDI XJMM MPBE UIF TUBGG@UFNQMBUF.YTM SFTPVSDF GSPN UIF GJMF TZTUFN, BT UIF FOEQPJOU XBT DPOGJHVSFE XJUI "GJMF:" BT QSFGJY. :PV DBO TUJMM UIPVHI FYQMJDJU DPOGJHVSF B QSFGJY, BOE UIFO NJY BOE NBUDI. "OE IBWF CPUI GJMF BOE DMBTTQBUI MPBEJOH. #VU UIBU XPVME CF VOVTVBM, BT NPTU QFPQMF FJUIFS VTF GJMF PS DMBTTQBUI CBTFE SFTPVSDFT. #VK>JF@ PQVIBPEBBQP S>FI>?IB >P LC ">JBI 2.9 $BNFM QSPWJEFT UIF CamelXsltResourceUri IFBEFS XIJDI ZPV DBO VTF UP EFGJOF B TUZMFTIFFU UP VTF JOTUFBE PG XIBU JT DPOGJHVSFE PO UIF FOEQPJOU 63*. 5IJT BMMPXT ZPV UP QSPWJEF B EZOBNJD TUZMFTIFFU BU SVOUJNF. -LQBP LK RPFKD 72+3 >KA )>S> 5BOPFLKP )FSF BSF TPNF PCTFSWBUJPOT GSPN 4BNFFS, B $BNFM VTFS, XIJDI IF LJOEMZ TIBSFE XJUI VT: *O DBTF BOZCPEZ GBDFT JTTVFT XJUI UIF 94-5 FOEQPJOU QMFBTF SFWJFX UIFTF QPJOUT. * XBT USZJOH UP VTF BO YTMU FOEQPJOU GPS B TJNQMF USBOTGPSNBUJPO GSPN POF YNM UP BOPUIFS VTJOH B TJNQMF YTM. 5IF PVUQVU YNM LFQU BQQFBSJOH (BGUFS UIF YTMU QSPDFTTPS JO UIF SPVUF) XJUI PVUFSNPTU YNM UBH XJUI OP DPOUFOU XJUIJO. /P FYQMBOBUJPOT TIPX VQ JO UIF %&#6( MPHT. 0O UIF 53"$& MPHT IPXFWFS * EJE GJOE TPNF FSSPS/XBSOJOH JOEJDBUJOH UIBU UIF 9.-$POWFSUFS CFBO DPVME OP CF JOJUJBMJ[FE. "GUFS B GFX IPVST PG DSBOLJOH NZ NJOE, * IBE UP EP UIF GPMMPXJOH UP HFU JU UP XPSL (UIBOLT UP TPNF QPTUT PO UIF VTFST GPSVN UIBU HBWF TPNF DMVF): 1. 6TF UIF USBOTGPSNFS'BDUPSZ PQUJPO JO UIF SPVUF ("xslt:mytransformer.xsl?transformerFactory=tFactory") XJUI UIF tFactory CFBO IBWJOH CFBO EFGJOFE JO UIF TQSJOH DPOUFYU GPS

$) "15 &3 11 - $0 . 10 / &/ 5 "11&/ %*9

981

class="org.apache.xalan.xsltc.trax.TransformerFactoryImpl". 2. "EEFE UIF 9BMBO KBS JOUP NZ NBWFO QPN. .Z HVFTT JT UIBU UIF EFGBVMU YNM QBSTJOH NFDIBOJTN TVQQMJFE XJUIJO UIF +%, (* BN VTJOH 1.6.0@03) EPFT OPU XPSL SJHIU JO UIJT DPOUFYU BOE EPFT OPU UISPX VQ BOZ FSSPS FJUIFS. 8IFO * TXJUDIFE UP 9BMBO UIJT XBZ JU XPSLT. 5IJT JT OPU B $BNFM JTTVF, CVU NJHIU OFFE B NFOUJPO PO UIF YTMU DPNQPOFOU QBHF. "OPUIFS OPUF, KEL 1.6.0@03 TIJQT XJUI +"9# 2.0 XIJMF $BNFM OFFET 2.1. 0OF XPSLBSPVOE JT UP BEE UIF 2.1 KBS UP UIF jre/lib/endorsed EJSFDUPSZ GPS UIF KWN PS BT TQFDJGJFE CZ UIF DPOUBJOFS. )PQF UIJT QPTU TBWFT OFXCJF $BNFM SJEFST TPNF UJNF. 2BB IPL ` ` ` ` $POGJHVSJOH $BNFM $PNQPOFOU &OEQPJOU (FUUJOH 4UBSUFE

982

$) " 15& 3 1 1 - $ 0.1 0/& /5 " 1 1 & /% * 9

You might also like