Fuse ESB

EIP Component Reference

Version 4.4.1

Sept. 2011
Trademark Disclaimer
Third Party Acknowledgements

Updated: 06 Jun 2013

Table of Contents

1. Components Overview
List of Components
2. ActiveMQ
3. ActiveMQ Journal
4. AHC
5. AMQP
6. APNS
7. AWS
Introduction to the AWS Components
AWS-S3
AWS-SNS
AWS-SQS
8. Atom
9. Bean
10. Bean Validation
11. Browse
12. Cache
13. Class
14. Cometd
15. Context
16. Crypto (Digital Signatures)
17. CXF Bean Component
18. CXF
19. CXFRS
20. DataSet
21. Db4o
22. Direct
23. DNS
24. EJB
25. Esper
26. Event
27. EventAdmin
28. Exec
29. File2
30. FIX
31. Flatpack
32. FreeMarker
33. FTP2
34. GAE
Introduction to the GAE Components
gauth
ghttp
glogin
gmail
gsec
gtask
35. HawtDB
36. Hazelcast Component
37. HDFS
38. Hibernate
39. HL7
40. HTTP
41. HTTP4
42. iBATIS
43. IRC
44. Jasypt
45. JavaSpace
46. JBI
47. JCR
48. JDBC
49. Jetty
50. Jing
51. JMS
52. JMX
53. JPA
54. JT400
55. Language
56. LDAP
57. List
58. Log
59. Lucene
60. Mail
61. MINA
62. Mock
63. MSV
64. MyBatis
65. Nagios
66. Netty
67. NMR
68. Pojo
69. Printer
70. Pax-Logging
71. Properties
72. Quartz
73. Queue
74. Quickfix
75. Ref
76. Restlet
77. RMI
78. Routebox
79. RSS
80. Scalate
81. SEDA
82. SERVLET
83. Shiro Security
84. Sip
85. Smooks
86. SMPP
87. SNMP
88. SpringIntegration
89. Spring Security
90. Spring Web Services
91. SQL Component
92. Stream
93. StringTemplate
94. Test
95. Timer
96. Validation
97. Velocity
98. VM
99. XMPP
100. XQuery Endpoint
101. XSLT
Index

List of Tables

1.1. Fuse Mediation Router Components

List of Examples

34.1. web.xml with authorization constraint

The following components are available for use with Fuse Mediation Router.

Table 1.1. Fuse Mediation Router Components

ComponentEndpoint URIArtifact IDDescription
ActiveMQactivemq:[queue:|topic:]DestinationNameactivemq-coreFor JMS Messaging with Apache ActiveMQ.
ActiveMQ Journalactivemq.journal:DirectoryName[?Options]activemq-coreUses ActiveMQ's fast disk journaling implementation to store message bodies in a rolling log file.
AHCahc:http[s]://Hostname[:Port][/ResourceUri]camel-ahcTo call external HTTP services using Async Http Client
AMQPamqp:[queue:|topic:]DestinationName[?Options]]camel-amqpFor messaging with the AMQP protocol.
APNS
apns:notify[?Options]
apns:consumer[?Options]
camel-apnsFor sending notifications to Apple iOS devices.
Atomatom://AtomUri[?Options]camel-atomWorking with Apache Abdera for atom integration, such as consuming an atom feed.
AWS-S3aws-s3://BucketName[?Options]camel-awsFor working with Amazon's Simple Storage Service (S3).
AWS-SNSaws-sns://TopicName[?Options]camel-awsFor Messaging with Amazon's Simple Notification Service (SNS).
AWS-SQSaws-sqs://QueueName[?Options]camel-awsFor Messaging with Amazon's Simple Queue Service (SQS).
Beanbean:BeanID[?methodName=Method]camel-coreUses the Bean Binding to bind message exchanges to beans in the Registry. Is also used for exposing and invoking POJO (Plain Old Java Objects).
Bean Validation
bean-validator:Something[?Options]
camel-bean-validatorValidates the payload of a message using the Java Validation API (JSR 303 and JAXP Validation) and its reference implementation Hibernate Validator.
Browsebrowse:Name camel-coreProvdes a simple BrowsableEndpoint which can be useful for testing, visualisation tools or debugging. The exchanges sent to the endpoint are all available to be browsed.
Cachecache://CacheName[?Options]camel-cacheThe cache component enables you to perform caching operations using EHCache as the Cache Implementation.
Classclass:ClassName[?method=MethodName]camel-coreUses the Bean binding to bind message exchanges to beans in the registry. Is also used for exposing and invoking POJOs (Plain Old Java Objects).
Cometdcometd://Hostname[:Port]/ChannelName[?Options]camel-cometdA transport for working with the jetty implementation of the cometd/bayeux protocol.
Contextcontext:CamelContextId:LocalEndpointNamecamel-contextRefers to an endpoint in a different CamelContext.
Crypto
crypto:sign:Name[?Options]
crypto:verify:Name[?Options]
camel-cryptoSign and verify exchanges using the Signature Service of the Java Cryptographic Extension.
CXFcxf://Address[?Options]camel-cxfWorking with Apache CXF for web services integration.
CXF Beancxf:BeanNamecamel-cxfProceess the exchange using a JAX WS or JAX RS annotated bean from the registry.
CXFRScxfrs:bean:RsEndpoint[?Options]camel-cxfProvides integration with Apache CXF for connecting to JAX-RS services hosted in CXF.
DataSetdataset:Name[?Options]camel-coreFor load & soak testing the DataSet provides a way to create huge numbers of messages for sending to Components or asserting that they are consumed correctly.
Db4odb4o:ClassNamecamel-db4oTo use a db4o datastore as a queue, through the db4o library.
Directdirect:EndpointID[?Options]camel-coreDirect invocation of the consumer from the producer so that single threaded (non-SEDA) in VM invocation is performed.
DNSdns:Operationcamel-dnsLook up domain information and run DNS queries using DNSJava
EJBejb:EjbName[?method=MethodName]camel-ejbUses the Bean binding to bind message exchanges to EJBs. It works like the Bean component, but just for accessing EJBs. Supports EJB 3.0 onwards.
Esperesper:namecamel-esperWorking with the Esper Library for Event Stream Processing.
Eventevent://dummycamel-springWorking with Spring ApplicationEvents.
EventAdmineventadmin:topiccamel-eventadmin 
Execexec://Executable[?Options]camel-execExecute system command.
File2file://DirectoryName[?Options]camel-coreSending messages to a file or polling a file or directory.
FIXfix://ConfigurationResourcecamel-fixSends or receives messages using the FIX protocol.
Flatpackflatpack:[fixed|delim]:ConfigFilecamel-flatpackProcessing fixed width or delimited files or messages using the FlatPack library
Freemarkerfreemarker:TemplateResource camel-freemarkerGenerates a response using a Freemarker template.
FTP2ftp://[Username@]Hostname[:Port]/Directoryname[?Options]camel-ftpSending and receiving files over FTP.
GAuthgauth://Name[?Options]camel-gaeUsed by web applications to implement a Google-specific OAuth consumer
GHTTP
ghttp:///Path[?Options]
ghttp://Hostname[:Port]/Path[?Options]
ghttps://Hostname[:Port]/Path[?Options]
camel-gaeProvides connectivity to the GAE URL fetch service and can also be used to receive messages from servlets.
GLoginglogin://Hostname[:Port][?Options]camel-gaeUsed by Camel applications outside Google App Engine (GAE) for programmatic login to GAE applications.
GMail
gmail://Username@gmail.com[?Options]
gmail://Username@googlemail.com[?Options]
camel-gaeSupports sending of emails via the GAE mail service.
GTaskgtask://QueueNamecamel-gaeSupports asynchronous message processing on GAE using the task queueing service as a message queue.
Hazelcasthazelcast://StoreType:CacheName[?Options]camel-hazelcastHazelcast is a data grid entirely implemented in Java (single JAR). This component supports map, multimap, seda, queue, set, atomic number and simple cluster.
HDFShdfs://Path[?Options]camel-hdfsFor reading/writing from/to an HDFS filesystem.
Hibernatehibernate://EntityName camel-hibernate (Camel Extra)For using a database as a queue via the Hibernate library.
HL7mina:tcp://Host[:Port]camel-hl7For working with the HL7 MLLP protocol and the HL7 model using the HAPI library.
HTTPhttp://Hostname[:Port][/ResourceUri]camel-httpFor calling out to external HTTP servers, using Apache HTTP Client 3.x.
HTTP4http://Hostname[:Port][/ResourceUri]camel-http4For calling out to external HTTP servers, using Apache HTTP Client 4.x.
iBATISibatis:OperationName[?Options]camel-ibatisPerforms a query, poll, insert, update or delete in a relational database using Apache iBATIS.
IMapimap://[UserName@]Host[:Port][?Options]camel-mailReceiving email using IMap.
IRCirc:Host[:Port]/#Roomcamel-ircFor IRC communication.
JavaSpacejavaspace:jini://Host[?Options]camel-javaspaceSending and receiving messages through JavaSpace.
JBI
jbi:service:serviceNamespace[sep]serviceName
jbi:endpoint:serviceNamespace[sep]serviceName[sep]endpointName
jbi:name:endpointName
camel-jbiFor JBI integration such as working with Apache ServiceMix.
JCRjcr://UserName:Password@Repository/path/to/nodecamel-jcrStoring a message in a JCR (JSR-170) compliant repository like Apache Jackrabbit.
JDBCjdbc:DataSourceName[?Options]camel-jdbcFor performing JDBC queries and operations.
JDBC-AggregationRepository camel-jdbc-aggregator 
Jettyjetty:http://Host[:Port][/ResourceUri]camel-jettyFor exposing services over HTTP.
Jing
rng:LocalOrRemoteResource
rnc:LocalOrRemoteResource
camel-jingValidates the payload of a message using RelaxNG or RelaxNG compact syntax.
JMSjms:[temp:][queue:|topic:]DestinationName[?Options]camel-jmsWorking with JMS providers.
JMXjmx://Platform[?Options]camel-jmxFor working with JMX notification listeners.
JPAjpa:[EntityClassName][?Options]camel-jpaFor using a database as a queue via the JPA specification for working with OpenJPA, Hibernate or TopLink.
JT400jt400://User:Pwd@System/PathToDTAQcamel-jt400For integrating with data queues on an AS/400 (aka System i, IBM i, i5, ...) system.
Languagelanguage://LanguageName[:Script][?Options]camel-coreExecutes language scripts.
LDAPldap:Host[:Port]?base=...[&scope=Scope]camel-ldapPerforming searches on LDAP servers (Scope must be one of object|onelevel|subtree).
Listlist:ListIDcamel-coreProvides a simple BrowsableEndpoint which can be useful for testing, visualisation tools or debugging. The exchanges sent to the endpoint are all available to be browsed.
Loglog:LoggingCategory[?level=LoggingLevel]camel-coreUses Jakarta Commons Logging to log the message exchange to some underlying logging system like log4j.
Lucene
lucene:SearcherName:insert[?analyzer=Analyzer]
lucene:SearcherName:query[?analyzer=Analyzer]
camel-luceneUses Apache Lucene to perform Java-based indexing and full text based searches using advanced analysis/tokenization capabilities.
MINA
mina:tcp://Hostname[:Port][?Options]
mina:udp://Hostname[:Port][?Options]
mina:multicast://Hostname[:Port][?Options]
mina:vm://Hostname[:Port][?Options]
camel-minaWorking with Apache MINA.
Mockmock:EndpointIDcamel-coreFor testing routes and mediation rules using mocks.
MSMQmsmq:MsmqQueueName[?Options]camel-msmqSending and receiving messages with Microsoft Message Queuing.
MSVmsv:LocalOrRemoteResourcecamel-msvValidates the payload of a message using the MSV Library.
MyBatismybatis:StatementNamecamel-mybatisPerforms a query, poll, insert, update or delete in a relational database using MyBatis.
Nagiosnagios://Host[:Port][?Options]camel-nagiosSending passive checks to Nagios using JSendNSCA.
Netty
netty:tcp://localhost:99999[?Options]
netty:udp://Remotehost:99999/[?Options]
camel-nettyWorking with TCP and UDP protocols using Java NIO based capabilities offered by the JBoss Netty community project.
NMRnmr:serviceMixURIservicemix-camelFor OSGi integration when working with Fuse ESB. Enables you to specify the URI of a ServiceMix endpoint.
Pax-Loggingpaxlogging:Appendercamel-paxlogging 
POPpop3://[UserName@]Host[:Port][?Options]camel-mailReceiving email using POP3 and JavaMail.
Printer
lpr://localhost[:Port]/default[?Options]
lpr://RemoteHost[:Port]/path/to/printer[?Options]
camel-printerProvides a way to direct payloads on a route to a printer.
Propertiesproperties://Key[?Options] camel-propertiesFacilitates using property placeholders directly in endpoint URI definitions.
Quartz
quartz://[GroupName/]TimerName[?Options]
quartz://GroupName/TimerName/CronExpression
camel-quartzProvides a scheduled delivery of messages using the Quartz scheduler.
Quickfix
quickfix-server:ConfigFile
quickfix-client:ConfigFile
camel-quickfixImplementation of the QuickFix for Java engine which allow to send/receive FIX messages.
Refref:EndpointIDcamel-coreComponent for lookup of existing endpoints bound in the Registry.
Restletrestlet:RestletUrl[?Options]camel-restletComponent for consuming and producing Restful resources using Restlet.
RMIrmi://RmiRegistryHost:RmiRegistryPort/RegistryPathcamel-rmiWorking with RMI.
Routeboxroutebox:routeboxName[?Options] camel-routebox 
RSSrss:Uricamel-rssWorking with ROME for RSS integration, such as consuming an RSS feed.
RNCrnc:LocalOrRemoteResourcecamel-jingValidates the payload of a message using RelaxNG Compact Syntax.
RNGrng:LocalOrRemoteResourcecamel-jingValidates the payload of a message using RelaxNG.
Scalatescalate:TemplateName[?Options]org.fusesource.scalate/scalate-camelUses the given Scalate template to transform the message.
SEDAseda:EndpointIDcamel-coreUsed to deliver messages to a java.util.concurrent.BlockingQueue, useful when creating SEDA style processing pipelines within the same CamelContext.
SERVLETservlet://RelativePath[?Options]camel-servletProvides HTTP based endpoints for consuming HTTP requests that arrive at a HTTP endpoint and this endpoint is bound to a published Servlet.
SFTPsftp://[Username@]Hostname[:Port]/Directoryname[?Options]camel-ftpSending and receiving files over SFTP.
Sip
sip://User@Hostname[:Port][?Options]
sips://User@Hostname[:Port][?Options]
camel-sipPublish/subscribe communication capability using the telecom SIP protocol. RFC3903 - Session Initiation Protocol (SIP) Extension for Event
Smooks  For working with EDI parsing using the Smooks library.
SMPPsmpp://UserInfo@Host[:Port][?Options]camel-smppTo send and receive SMS using Short Messaging Service Center using the JSMPP library.
SMTPsmtp://[UserName@]Host[:Port][?Options]camel-mailSending email using SMTP and JavaMail.
SNMPsnmp://Hostname[:Port][?Options]camel-snmpGives you the ability to poll SNMP capable devices or receive traps.
Spring Integrationspring-integration:DefaultChannelName[?Options]camel-spring-integrationThe bridge component of Camel and Spring Integration.
Spring Web Servicesspring-ws:[MappingType:]Address[?Options]camel-spring-wsClient-side support for accessing web services, and server-side support for creating your own contract-first web services using Spring Web Services.
SQLsql:SqlQueryString[?Options]camel-sqlPerforming SQL queries using JDBC.
Streamstream:[in|out|err|header][?Options]camel-streamRead or write to an input/output/error/file stream rather like Unix pipes.
String Templatestring-template:TemplateURI[?Options]camel-stringtemplateGenerates a response using a String Template.
Testtest:RouterEndpointUricamel-springCreates a Mock endpoint which expects to receive all the message bodies that could be polled from the given underlying endpoint.
Timertimer:EndpointID[?Options]camel-coreA timer endpoint.
Validationvalidator:LocalOrRemoteResourcecamel-springValidates the payload of a message using XML Schema and JAXP Validation.
Velocityvelocity:TemplateURI[?Options]camel-velocityGenerates a response using an Apache Velocity template.
VMvm:EndpointIDcamel-coreUsed to deliver messages to a java.util.concurrent.BlockingQueue, useful when creating SEDA style processing pipelines within the same JVM.
XMPPxmpp:Hostname[:Port][/Room]camel-xmppWorking with XMPP and Jabber.
XQueryxquery:TemplateURIcamel-saxonGenerates a response using an XQuery template.
XSLTxslt:TemplateURI[?Options]camel-springxquery:someXQueryResource.

The ActiveMQ component allows messages to be sent to a JMS Queue or Topic; or messages to be consumed from a JMS Queue or Topic using Apache ActiveMQ.

This component is based on the JMS Component and uses Spring's JMS support for declarative transactions, using Spring's JmsTemplate for sending and a MessageListenerContainer for consuming. All the options from the JMS component also apply for this component.

To use this component, make sure you have the activemq.jar or activemq-core.jar on your classpath along with any Fuse Mediation Router dependencies such as camel-core.jar, camel-spring.jar and camel-jms.jar.

See Options on the JMS component as all these options also apply for this component.

The following test case shows how to add an ActiveMQComponent to the CamelContext using the activeMQComponent() method while specifying the brokerURL used to connect to ActiveMQ.

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

When sending to an ActiveMQ broker using Camel it's recommended to use a pooled connection factory to handle efficient pooling of JMS connections, sessions and producers. This is documented in the page ActiveMQ Spring Support.

You can grab Jencks AMQ pool with Maven:

    <dependency>
      <groupId>org.apache.activemq</groupId>
      <artifactId>activemq-pool</artifactId>
      <version>5.3.2</version>
    </dependency>

And then setup the activemq component as follows:

     <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">
        <property name="maxConnections" value="8" />
        <property name="maximumActive" value="500" />
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>


    <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="pooledConnectionFactory"/>
        <property name="transacted" value="false"/>
        <property name="concurrentConsumers" value="10"/>
    </bean>

    <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
        <property name="configuration" ref="jmsConfig"/>
    </bean>

The ActiveMQ component also provides a helper Type Converter from a JMS MessageListener to a Processor. This means that the Bean component is capable of invoking any JMS MessageListener bean directly inside any route.

So for example you can create a MessageListener in JMS as follows:

public class MyListener implements MessageListener {
   public void onMessage(Message jmsMessage) {
       // ...
   }
}

Then use it in your route as follows

from("file://foo/bar").
  bean(MyListener.class);

That is, you can reuse any of the Fuse Mediation Router Components and easily integrate them into your JMS MessageListener POJO\!

ActiveMQ can generate Advisory messages which are put in topics that you can consume. Such messages can help you send alerts in case you detect slow consumers or to build statistics (number of messages/produced per day, etc.) The following Spring DSL example shows you how to read messages from a topic.

<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&ileName=advisoryConnection-${date:now:yyyyMMdd}.txt" />
</route>

If you consume a message on a queue, you should see the following files under data/activemq folder :

advisoryConnection-20100312.txt advisoryProducer-20100312.txt

and containing string:

      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}

You must have the camel-jms as dependency as ActiveMQ is an extension to the JMS component.

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-jms</artifactId>
  <version>1.6.0</version>
</dependency>

The ActiveMQ component is released with the ActiveMQ project itself. For Maven 2 users you just need to add the following dependency to your project.

For this version you must use the JMS component instead. Please be careful to use a pooling connection factory as described in the JmsTemplate Gotchas

Name Default Value Description
syncConsume false If set to true, when the journal is marked after a message is consumed, wait till the Operating System has verified the mark update is safely stored on disk.
syncProduce true If set to true, wait till the Operating System has verified the message is safely stored on disk.

The consumer of a Journal endpoint generates DefaultExchange objects with the In message set as follows:

  • journal header: set to the endpoint URI of the journal the message came from.

  • location header: set to a Location which identifies where the record was stored on disk.

  • Message body: set to ByteSequence, which contains the byte array data of the stored message.

The producer to a Journal endpoint expects an Exchange with an In message where the body can be converted to a ByteSequence or a byte[].

Available as of Camel 2.8

The ahc: component provides HTTP based endpoints for consuming external HTTP resources (as a client to call external servers using HTTP). The component uses the Async Http Client library.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-ahc</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>
Name Default Value Description
throwExceptionOnFailure true Option to disable throwing the AhcOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code.
bridgeEndpoint false If the option is true, then the Exchange.HTTP_URI header is ignored, and use the endpoint's URI for request. You may also set the throwExcpetionOnFailure to be false to let the AhcProducer send all the fault response back.
transferException false If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or Servlet Camel components). On the producer side the exception will be deserialized and thrown as is, instead of the AhcOperationFailedException. The caused exception is required to be serialized.
client null To use a custom com.ning.http.client.AsyncHttpClient.
clientConfig null To configure the AsyncHttpClients use a custom com.ning.http.client.AsyncHttpClientConfig.
binding null To use a custom org.apache.camel.component.ahc.AhcBinding.
sslContextParameters null Camel 2.9: Reference to a org.apache.camel.util.jsse.SSLContextParameters in the CAMEL:Registry. This reference overrides any configured SSLContextParameters at the component level. See Using the JSSE Configuration Utility. Note that configuring this option will override any SSL/TLS configuration options provided through the clientConfig option at the endpoint or component level.

Name Default Value Description
client null To use a custom com.ning.http.client.AsyncHttpClient.
clientConfig null To configure the AsyncHttpClients use a custom com.ning.http.client.AsyncHttpClientConfig.
binding null To use a custom org.apache.camel.component.ahc.AhcBinding.
sslContextParameters null Camel 2.9: To configure custom SSL/TLS configuration options at the component level. See Using the JSSE Configuration Utility for more details. Note that configuring this option will override any SSL/TLS configuration options provided through the clientConfig option at the endpoint or component level.

Notice that setting any of the options on the AhcComponent will propagate those options to AhcEndpoints being created. However the AhcEndpoint can also configure/override a custom option. Options set on endpoints will always take precedence over options from the AhcComponent.

Name Type Description
Exchange.HTTP_URI String URI to call. Will override existing URI set directly on the endpoint.
Exchange.HTTP_PATH String Request URI's path, the header will be used to build the request URI with the HTTP_URI. If the path is start with "/", http producer will try to find the relative path based on the Exchange.HTTP_BASE_URI header or the exchange.getFromEndpoint().getEndpointUri();
Exchange.HTTP_QUERY String URI parameters. Will override existing URI parameters set directly on the endpoint.
Exchange.HTTP_RESPONSE_CODE int The HTTP response code from the external server. Is 200 for OK.
Exchange.HTTP_CHARACTER_ENCODING String Character encoding.
Exchange.CONTENT_TYPE String The HTTP content type. Is set on both the IN and OUT message to provide a content type, such as text/html.
Exchange.CONTENT_ENCODING String The HTTP content encoding. Is set on both the IN and OUT message to provide a content encoding, such as gzip.

The AsyncHttpClient client uses a AsyncHttpClientConfig to configure the client. See the documentation at Async Http Client for more details.

The example below shows how to use a builder to create the AsyncHttpClientConfig which we configure on the AhcComponent.

// create a client config builder
AsyncHttpClientConfig.Builder builder = new AsyncHttpClientConfig.Builder();
// use the builder to set the options we want, in this case we want to follow redirects and try
// at most 3 retries to send a request to the host
AsyncHttpClientConfig config = builder.setFollowRedirects(true).setMaxRequestRetry(3).build();

// lookup AhcComponent
AhcComponent component = context.getComponent("ahc", AhcComponent.class);
// and set our custom client config to be used
component.setClientConfig(config);

The AsyncHttpClientConfig doesn't support getters/setters so its not easy to create/configure using a Spring bean style (eg the <bean> tag in the XML file).

As of Camel 2.9, the AHC component supports SSL/TLS configuration through the Camel JSSE Configuration Utility.  This utility greatly decreases the amount of component specific code you need to write and is configurable at the endpoint and component levels. The following examples demonstrate how to use the utility with the AHC component.

The AMQP component supports the AMQP protocol via the Qpid project.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-ampq</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

Available as of Camel 2.8

The apns component is used for sending notifications to iOS devices. The apns components use javapns library. The component supports sending notifications to Apple Push Notification Servers (APNS) and consuming feedback from the servers.

The consumer is configured with 3600 seconds for polling by default because it is a best practice to consume feedback stream from Apple Push Notification Servers only from time to time. For example: every 1 hour to avoid flooding the servers.

The feedback stream gives informations about inactive devices. You only need to get this informations every some hours if your mobile application is not a heavily used one.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-apns</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

Property Default Description
tokens Empty by default. Configure this property in case you want to statically declare tokens related to devices you want to notify. Tokens are separated by comma.

Property Default Description
delay 3600 Delay in seconds between each poll.
initialDelay 10 Seconds before polling starts.
timeUnit SECONDS Time Unit for polling.
userFixedDelay true If true, use fixed delay between pools, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.

You can append query options to the URI in the following format, ?option=value&option=value&...

Camel Apns uses these headers.

Property Default Description
CamelApnsTokens Empty by default.
CamelApnsMessageType STRING, PAYLOAD In case you choose PAYLOAD for the message type, then the message will be considered as a APNS payload and sent as is. In case you choose STRING, message will be converted as a APNS payload

<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">

	<!-- Replace by desired values -->
	<bean id="apnsServiceFactory" class="org.apache.camel.component.apns.factory.ApnsServiceFactory">

		<!-- Optional configuration of feedback host and port -->
		<!-- <property name="feedbackHost" value="localhost" /> -->
		<!-- <property name="feedbackPort" value="7843" /> -->

		<!-- Optional configuration of gateway host and port -->
		<!-- <property name="gatewayHost" value="localhost" /> -->
		<!-- <property name="gatewayPort" value="7654" /> -->

		<!-- Declaration of certificate used -->
		<property name="certificatePath" value="src/test/resources/certificate.p12" />
		<!-- In case you wants to load certificate from classpath: -->
		<!-- <property name="certificatePath" value="classpath:/certificate.p12" /> -->
		<property name="certificatePassword" value="MyCertPassword" />

		<!-- Optional connection strategy - By Default: No need to configure -->
		<!-- Possible options: NON_BLOCKING, QUEUE, POOL or Nothing -->
		<!-- <property name="connectionStrategy" value="POOL" /> -->
		<!-- Optional pool size -->
		<!-- <property name="poolSize" value="15" /> -->

		<!-- Optional connection strategy - By Default: No need to configure -->
		<!-- Possible options: EVERY_HALF_HOUR, EVERY_NOTIFICATION or Nothing (Corresponds to NEVER javapns option) -->
		<!-- <property name="reconnectionPolicy" value="EVERY_HALF_HOUR" /> -->
	</bean>

	<bean id="apnsService" factory-bean="apnsServiceFactory" factory-method="getApnsService" />

	<!-- Replace this declaration by wanted configuration -->
	<bean id="apns" class="org.apache.camel.component.apns.ApnsComponent">
		<property name="apnsService" ref="apnsService" />
	</bean>

	<camelContext id="camel-apns-test" xmlns="http://camel.apache.org/schema/spring">
        	<route id="apns-test">
                	<from uri="apns:consumer?initialDelay=10&elay=3600&imeUnit=SECONDS" />
        	        <to uri="log:org.apache.camel.component.apns?showAll=true&ultiline=true" />
                	<to uri="mock:result" />
        	</route>
	</camelContext>

</beans>

The Camel Components for Amazon Web Services provide connectivity to AWS services from Camel.

AWS service Camel component Camel Version Component description
Simple Queue Service (SQS) AWS-SQS 2.6 Supports sending and receiving messages using SQS
Simple Notification Service (SNS) AWS-SNS 2.8 Supports sending messages using SNS
Simple Storage Service (S3) AWS-S3 2.8 Supports storing and retrieving of objects using S3
SimpleDB not supported yet
Relational Database Service (RDS) not supported yet

Available as of Camel 2.8

The S3 component supports storing and retrieving objetcs from/to Amazon's S3 service.

Prerequisites

You must have a valid Amazon Web Services developer account, and be signed up to use Amazon S3. More information are available at Amazon S3.

Name Default Value Context Description
amazonS3Client null Shared Reference to a com.amazonaws.services.sqs.AmazonS3Client in the Registry.
accessKey null Shared Amazon AWS Access Key
secretKey null Shared Amazon AWS Secret Key
amazonS3Endpoint null Shared The region with which the AWS-S3 client wants to work with.
region null Producer The region who the bucket is located. This option is used in the com.amazonaws.services.s3.model.CreateBucketRequest.
deleteAfterRead true Consumer Delete objects from S3 after it has been retrieved.
maxMessagesPerPoll 10 Consumer The maximum number of objects which can be retrieved in one poll. Used in in the com.amazonaws.services.s3.model.ListObjectsRequest.

This component implements the Batch Consumer.

This allows you for instance to know how many messages exists in this batch and for instance let the Aggregator aggregate this number of messages.

Header Type Description
CamelAwsS3Key String The key under which this object will be stored.
CamelAwsS3ContentLength Long The content length of this object.
CamelAwsS3ContentType String The content type of this object.

Header Type Description
CamelAwsS3ETag String The ETag value for the newly uploaded object.
CamelAwsS3VersionId String The optional version ID of the newly uploaded object.

Header Type Description
CamelAwsS3Key String The key under which this object is stored.
CamelAwsS3BucketName String The name of the bucket in which this object is contained.
CamelAwsS3ETag String The hex encoded 128-bit MD5 digest of the associated object according to RFC 1864. This data is used as an integrity check to verify that the data received by the caller is the same data that was sent by Amazon S3.
CamelAwsS3LastModified Date The value of the Last-Modified header, indicating the date and time at which Amazon S3 last recorded a modification to the associated object.
CamelAwsS3VersionId String The version ID of the associated Amazon S3 object if available. Version IDs are only assigned to objects when an object is uploaded to an Amazon S3 bucket that has object versioning enabled.
CamelAwsS3ContentType String The Content-Type HTTP header, which indicates the type of content stored in the associated object. The value of this header is a standard MIME type.
CamelAwsS3ContentMD5 String The base64 encoded 128-bit MD5 digest of the associated object (content - not including headers) according to RFC 1864. This data is used as a message integrity check to verify that the data received by Amazon S3 is the same data that the caller sent.
CamelAwsS3ContentLength Long The Content-Length HTTP header indicating the size of the associated object in bytes.
CamelAwsS3ContentEncoding String The optional Content-Encoding HTTP header specifying what content encodings have been applied to the object and what decoding mechanisms must be applied in order to obtain the media-type referenced by the Content-Type field.
CamelAwsS3ContentDisposition String The optional Content-Disposition HTTP header, which specifies presentational information such as the recommended filename for the object to be saved as.
CamelAwsS3ContentControl String The optional Cache-Control HTTP header which allows the user to specify caching behavior along the HTTP request/reply chain.

Available as of Camel 2.8

The SNS component allows messages to be sent to an Amazon Simple Notification Topic. The implementation of the Amazon API is provided by the AWS SDK.

Prerequisites

You must have a valid Amazon Web Services developer account, and be signed up to use Amazon SNS. More information are available at Amazon SNS.

Name Default Value Context Description
amazonSNSClient null Producer Reference to a com.amazonaws.services.sqs.AmazonSNSClient in the Registry.
accessKey null Producer Amazon AWS Access Key
secretKey null Producer Amazon AWS Secret Key
subject null Producer The subject which is used if the message header 'CamelAwsSnsSubject' is not present.
amazonSNSEndpoint null Producer The region with which the AWS-SNS client wants to work with.

Header Type Description
CamelAwsSnsSubject String The Amazon SNS message subject. If not set, the subject from the SnsConfiguration is used.

Header Type Description
CamelAwsSnsMessageId String The Amazon SNS message ID.

If you need more control over the AmazonSNSClient configuration you can create your own instance and refer to it from the URI:

from("direct:start")
.to("aws-sns://MyTopic?amazonSNSClient=#amazonSNSClient");

The #amazonSNSClient refers to a AmazonSNSClient in the Registry.

For example if your Camel Application is running behind a firewall:

AWSCredentials awsCredentials = new BasicAWSCredentials("myAccessKey", "mySecretKey");
ClientConfiguration clientConfiguration = new ClientConfiguration();
clientConfiguration.setProxyHost("http://myProxyHost");
clientConfiguration.setProxyPort(8080);
AmazonSNSClient amazonSNSClient = new AmazonSNSClient(awsCredentials, clientConfiguration);

Available as of Camel 2.6

The sqs component supports sending and receiving messages to Amazon's SQS service.

Prerequisites

You must have a valid Amazon Web Services developer account, and be signed up to use Amazon SQS. More information are available at Amazon SQS.

Name Default Value Context Description
amazonSQSClient null Shared Reference to a com.amazonaws.services.sqs.AmazonSQSClient in the Registry.
accessKey null Shared Amazon AWS Access Key
secretKey null Shared Amazon AWS Secret Key
amazonSQSEndpoint null Shared The region with which the AWS-SQS client wants to work with.
attributeNames null Consumer A list of attributes to set in the com.amazonaws.services.sqs.model.ReceiveMessageRequest.
defaultVisibilityTimeout null Shared The visibility timeout (in seconds) to set in the com.amazonaws.services.sqs.model.CreateQueueRequest.
deleteAfterRead true Consumer Delete message from SQS after it has been read
maxMessagesPerPoll null Consumer The maximum number of messages which can be received in one poll to set in the com.amazonaws.services.sqs.model.ReceiveMessageRequest.
visibilityTimeout null Shared The duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request to set in the com.amazonaws.services.sqs.model.SetQueueAttributesRequest. This only make sense if its different from defaultVisibilityTimeout. It changes the queue visibility timeout attribute permanently.
messageVisibilityTimeout null Consumer Camel 2.8: The duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request to set in the com.amazonaws.services.sqs.model.ReceiveMessageRequest. It does NOT change the queue visibility timeout attribute permanently.
maximumMessageSize null Shared Camel 2.8: The maximumMessageSize (in bytes) an SQS message can contain for this queue, to set in the com.amazonaws.services.sqs.model.SetQueueAttributesRequest.
messageRetentionPeriod null Shared Camel 2.8: The messageRetentionPeriod (in seconds) a message will be retained by SQS for this queue, to set in the com.amazonaws.services.sqs.model.SetQueueAttributesRequest.
policy null Shared Camel 2.8: The policy for this queue to set in the com.amazonaws.services.sqs.model.SetQueueAttributesRequest.

This component implements the Batch Consumer.

This allows you for instance to know how many messages exists in this batch and for instance let the Aggregator aggregate this number of messages.

Header Type Description
CamelAwsSqsMD5OfBody String The MD5 checksum of the Amazon SQS message.
CamelAwsSqsMessageId String The Amazon SQS message ID.

Header Type Description
CamelAwsSqsMD5OfBody String The MD5 checksum of the Amazon SQS message.
CamelAwsSqsMessageId String The Amazon SQS message ID.
CamelAwsSqsReceiptHandle String The Amazon SQS message receipt handle.
CamelAwsSqsAttributes Map<String, String> The Amazon SQS message attributes.

Property Default Description
splitEntries true If true Fuse Mediation Router will poll the feed and for the subsequent polls return each entry poll by poll. If the feed contains 7 entries then Fuse Mediation Router will return the first entry on the first poll, the 2nd entry on the next poll, until no more entries where as Fuse Mediation Router will do a new update on the feed. If false then Fuse Mediation Router will poll a fresh feed on every invocation.
filter true Is only used by the split entries to filter the entries to return. Fuse Mediation Router will default use the UpdateDateFilter that only return new entries from the feed. So the client consuming from the feed never receives the same entry more than once. The filter will return the entries ordered by the newest last.
lastUpdate null Is only used by the filter, as the starting timestamp for selection never entries (uses the entry.updated timestamp). Syntax format is: yyyy-MM-ddTHH:MM:ss. Example: 2007-12-24T17:45:59.
throttleEntries true Camel 2.5: Sets whether all entries identified in a single feed poll should be delivered immediately. If true, only one entry is processed per consumer.delay. Only applicable when splitEntries is set to true.
feedHeader true Sets whether to add the Abdera Feed object as a header.
sortEntries false If splitEntries is true, this sets whether to sort those entries by updated date.
consumer.delay 60000 Delay in millis between each poll.
consumer.initialDelay 1000 Millis before polling starts.
consumer.userFixedDelay false If true, use fixed delay between pools, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.

You can append query options to the URI in the following format, ?option=value&option=value&...

Fuse Mediation Router will set the In body on the returned Exchange with the entries. Depending on the splitEntries flag Fuse Mediation Router will either return one Entry or a List<Entry>.

Option Value Behavior
splitEntries true Only a single entry from the currently being processed feed is set: exchange.in.body(Entry)
splitEntries false The entire list of entries from the feed is set: exchange.in.body(List<Entry>)

Fuse Mediation Router can set the Feed object on the in header (see feedHeader option to disable this):

Fuse Mediation Router atom uses these headers.

Header Description
org.apache.camel.component.atom.feed Fuse Mediation Router 1.x: When consuming the org.apache.abdera.model.Feed object is set to this header.
CamelAtomFeed Fuse Mediation Router 2.0: When consuming the org.apache.abdera.model.Feed object is set to this header.

In the following sample we poll James Strachan's blog:

from("atom://http://macstrac.blogspot.com/feeds/posts/default").to("seda:feeds");

In this sample we want to filter only good blogs we like to a SEDA queue. The sample also shows how to set up Fuse Mediation Router standalone, not running in any container or using Spring.

@Override
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());

    // And finally we must start Camel to let the magic routing begins
    context.start();

    return context;
}

/**
 * This is the route builder where we create our routes using the Camel DSL syntax
 */
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);

    // 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;
    }

}

Name Type Default Description
method String null The method name from the bean that will be invoked. If not provided, Camel will try to determine the method itself. In case of ambiguity an exception will be thrown. See Bean Binding for more details. From Camel 2.8 onwards you can specify type qualifiers to pin-point exact method to use for overloaded methods. From Camel 2.9 onwards you can specify parameter values directly in the method syntax.
cache boolean false If enabled, Fuse Mediation Router will cache the result of the first Registry look-up. Cache can be enabled if the bean in the Registry is defined as a singleton scope.
multiParameterArray boolean false Fuse Mediation Router 1.5: How to treat the parameters which are passed from the message body; if it is true, the In message body should be an array of parameters.

You can append query options to the URI in the following format, ?option=value&option=value&...

The object instance that is used to consume messages must be explicitly registered with the Registry. For example, if you are using Spring you must define the bean in the Spring configuration, spring.xml; or if you don't use Spring, put the bean in JNDI.

// 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);

Once an endpoint has been registered, you can build routes that use it to process exchanges.

// lets add simple route
camelContext.addRoutes(new RouteBuilder() {
    public void configure() {
        from("direct:hello").to("bean:bye");
    }
});

A bean: endpoint cannot be defined as the input to the route; i.e. you cannot consume from it, you can only route from some inbound message Endpoint to the bean endpoint as output. So consider using a direct: or queue: endpoint as the input.

You can use the createProxy() methods on ProxyHelper to create a proxy that will generate BeanExchanges and send them to any endpoint:

Endpoint endpoint = camelContext.getEndpoint("direct:hello");
ISay proxy = ProxyHelper.createProxy(endpoint, ISay.class);
String rc = proxy.say();
assertEquals("Good Bye!", rc);

And the same route using Spring DSL:

    <route>
       <from uri="direct:hello">
       <to uri="bean:bye"/>
    </route>

Fuse Mediation Router also supports invoking Bean as an Endpoint. In the route below:

<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"/>

What happens is that when the exchange is routed to the myBean Fuse Mediation Router will use the Bean Binding to invoke the bean. The source for the bean is just a plain POJO:

public class ExampleBean {

    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}

Fuse Mediation Router will use Bean Binding to invoke the sayHello method, by converting the Exchange's In body to the String type and storing the output of the method on the Exchange Out body.

Available as of 2.3

The Validation component performs bean validation of the message body using the Java Bean Validation API (JSR 303). uses the reference implementation, which is Hibernate Validator.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

The following URI options are supported:

Option Default Description
group javax.validation.groups.Default The custom validation group to use.
messageInterpolator org.hibernate.validator.engine. ResourceBundleMessageInterpolator Reference to a custom javax.validation.MessageInterpolator in the Registry.
traversableResolver org.hibernate.validator.engine.resolver. DefaultTraversableResolver Reference to a custom javax.validation.TraversableResolver in the Registry.
constraintValidatorFactory org.hibernate.validator.engine. ConstraintValidatorFactoryImpl Reference to a custom javax.validation.ConstraintValidatorFactory in the Registry.

Assumed we have a java bean with the following annotations

and an interface definition for our custom validation group

with the following route, only the @NotNull constraints on the attributes manufacturer and licensePlate will be validated ( uses the default group javax.validation.groups.Default).

from("direct:start")
.to("bean-validator://x")
.to("mock:end")

If you want to check the constraints from the group OptionalChecks, you have to define the route like this

from("direct:start")
.to("bean-validator://x?group=OptionalChecks")
.to("mock:end")

If you want to check the constraints from both groups, you have to define a new interface first

and then your route definition should looks like this

from("direct:start")
.to("bean-validator://x?group=AllChecks")
.to("mock:end")

And if you have to provide your own message interpolator, traversable resolver and constraint validator factory, you have to write a route like this

<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")

It's also possible to describe your constraints as XML and not as Java annotations. In this case, you have to provide the file META-INF/validation.xml which could looks like this

and the constraints-car.xml file

Available as of Fuse Mediation Router 2.0

The Browse component provides a simple BrowsableEndpoint which can be useful for testing, visualisation tools or debugging. The exchanges sent to the endpoint are all available to be browsed.

Name Default Value Description
maxElementsInMemory 1000 The numer of elements that may be stored in the defined cache
memoryStoreEvictionPolicy MemoryStoreEvictionPolicy.LFU

The number of elements that may be stored in the defined cache. The policy options include:

  • MemoryStoreEvictionPolicy.LFU—Least frequently used.

  • MemoryStoreEvictionPolicy.LRU—Least recently used.

  • MemoryStoreEvictionPolicy.FIFO—First in first out, ordered by creation time.

overflowToDisk true Specifies whether cache may overflow to disk.
eternal false Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired.
timeToLiveSeconds 300 The maximum time between creation time and when an element expires. Is only used if the element is not eternal.
timeToIdleSeconds 300 The maximum amount of time between accesses before an element expires.
diskPersistent true Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds 120 The number of seconds between runs of the disk expiry thread. The default value is 120 seconds.
cacheManagerFactory null If you want to use a custom factory which instantiates and creates the EHCache, net.sf.ehcache.CacheManager, you must specify an instance of type, org.apache.camel.component.cache.CacheManagerFactory.
eventListenerRegistry null Camel 2.8: Sets a list of EHCache net.sf.ehcache.event.CacheEventListener for all new caches\- no need to define it per cache in EHCache xml config anymore. Type: org.apache.camel.component.cache.CacheEventListenerRegistry
cacheLoaderRegistry null Camel 2.8: Sets a list of org.apache.camel.component.cache.CacheLoaderWrapper that extends EHCache net.sf.ehcache.loader.CacheLoader for all new caches\- no need to define it per cache in EHCache xml config anymore. Type: org.apache.camel.component.cache.CacheLoaderRegistry
Header Description
CamelCacheOperation

The operation to be performed on the cache. The valid options are

  • CamelCacheGet

  • CamelCacheCheck

  • CamelCacheAdd

  • CamelCacheUpdate

  • CamelCacheDelete

  • CamelCacheDeleteAll

CamelCacheKey The cache key used to store the message in the cache. The cache key is optional if the CamelCacheOperation is CamelCacheDeleteAll.

EHCache has its own statistics and management from JMX.

Here's a snippet on how to expose them via JMX in a Spring application context:

<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"/>
  </constructor-arg>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
  <constructor-arg value="true"/>
</bean>

Of course you can do the same thing in straight Java:

ManagementService.registerMBeans(CacheManager.getInstance(), mbeanServer, true, true, true, true);

You can get cache hits, misses, in-memory hits, disk hits, size stats this way. You can also change CacheConfiguration parameters on the fly.

Available as of 2.4

The class: component binds beans to message exchanges. It works in the same way as the Bean component but instead of looking up beans from a Registry it creates the bean based on the class name.

Name Type Default Description
method String null The method name that bean will be invoked. If not provided, will try to pick the method itself. In case of ambiguity an exception is thrown. See Bean Binding for more details.
multiParameterArray boolean false How to treat the parameters which are passed from the message body; if it is true, the In message body should be an array of parameters.

You can append query options to the URI in the following format, ?option=value&option=value&...

You simply use the class component just as the Bean component but by specifying the fully qualified classname instead. For example to use the MyFooBean you have to do as follows:

from("direct:start").to("class:org.apache.camel.component.bean.MyFooBean").to("mock:result");

You can also specify which method to invoke on the MyFooBean, for example hello:

from("direct:start").to("class:org.apache.camel.component.bean.MyFooBean?method=hello").to("mock:result");

In the endpoint uri you can specify properties to set on the created instance, for example if it has a setPrefix method:

from("direct:start")
    .to("class:org.apache.camel.component.bean.MyPrefixBean?prefix=Bye")
    .to("mock:result");

And you can also use the # syntax to refer to properties to be looked up in the Registry.

from("direct:start")
    .to("class:org.apache.camel.component.bean.MyPrefixBean?cool=#foo")
    .to("mock:result");

Which will lookup a bean from the Registry with the id foo and invoke the setCool method on the created instance of the MyPrefixBean class.

See more

See more details at the Bean component as the class component works in much the same way.

The cometd: component is a transport for working with the jetty implementation of the cometd/bayeux protocol. Using this component in combination with the dojo toolkit library it's possible to push Fuse Mediation Router messages directly into the browser using an AJAX based mechanism.

Name Default Value Description
resourceBase The root directory for the web resources or classpath. Use the protocol file: or classpath: depending if you want that the component loads the resource from file system or classpath. Classpath is required for OSGI deployment where the resources are packaged in the jar
timeout 240000 The server side poll timeout in milliseconds. This is how long the server will hold a reconnect request before responding.
interval 0 The client side poll timeout in milliseconds. How long a client will wait between reconnects
maxInterval 30000 The max client side poll timeout in milliseconds. A client will be removed if a connection is not received in this time.
multiFrameInterval 1500 The client side poll timeout, if multiple connections are detected from the same browser.
jsonCommented true If true, the server will accept JSON wrapped in a comment and will generate JSON wrapped in a comment. This is a defence against Ajax Hijacking.
logLevel 1 0=none, 1=info, 2=debug.

You can append query options to the URI in the following format, ?option=value&option=value&...

Here is some examples of how to pass the parameters.

For file (when the Webapp resources are located in the Web Application directory) cometd://localhost:8080?resourceBase=file./webapp. For classpath (when the web resources are packaged inside the Webapp folder) cometd://localhost:8080?resourceBase=classpath:webapp.

Available as of Camel 2.7

The context component allows you to create new Camel Components from a CamelContext with a number of routes which is then treated as a black box, allowing you to refer to the local endpoints within the component from other CamelContexts.

It is similar to the Routebox component in idea, though the Context component tries to be really simple for end users; just a simple convention over configuration approach to refer to local endpoints inside the CamelContext Component.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-context</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

context:camelContextId:localEndpointName[?options]

Or you can omit the "context:" prefix.

camelContextId:localEndpointName[?options]

  • camelContextId is the ID you used to register the CamelContext into the Registry.

  • localEndpointName can be a valid Camel URI evaluated within the black box CamelContext. Or it can be a logical name which is mapped to any local endpoints. For example if you locally have endpoints like direct:invoices and seda:purchaseOrders inside a CamelContext of id supplyChain, then you can just use the URIs supplyChain:invoices or supplyChain:purchaseOrders to omit the physical endpoint kind and use pure logical URIs.

You can append query options to the URI in the following format, ?option=value&option=value&...

First you need to create a CamelContext, add some routes in it, start it and then register the CamelContext into the Registry (JNDI, Spring, Guice or OSGi etc).

This can be done in the usual Camel way from this test case (see the createRegistry() method); this example shows Java and JNDI being used...

// 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
        from("direct:purchaseOrder").
          setHeader("received").constant("true").
          to("direct:invoice");
    }
});
blackBox.start();

registry.bind("accounts", blackBox);

Notice in the above route we are using pure local endpoints (direct and seda). Also note we expose this CamelContext using the accounts ID. We can do the same thing in Spring via

<camelContext id="accounts" xmlns="http://camel.apache.org/schema/spring">
  <route> 
    <from uri="direct:purchaseOrder"/>
    ...
    <to uri="direct:invoice"/>
  </route>
</camelContext>

Available as of Fuse Mediation Router 2.3

Using Fuse Mediation Router cryptographic endpoints and Java's Cryptographic extension it is easy to create Digital Signatures for Exchanges. Fuse Mediation Router provides a pair of flexible endpoints which get used in concert to create a signature for an exchange in one part of the exchange's workflow and then verify the signature in a later part of the workflow.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Name Type Default Description
algorithm String DSA The name of the JCE Signature algorithm that will be used.
alias String null An alias name that will be used to select a key from the keystore.
bufferSize Integer 2048 the size of the buffer used in the signature process.
certificate Certificate null A Certificate used to verify the signature of the exchange's payload. Either this or a Public Key is required.
keystore KeyStore null A reference to a JCE Keystore that stores keys and certificates used to sign and verify.
provider String null The name of the JCE Security Provider that should be used.
privateKey PrivatKey null The private key used to sign the exchange's payload.
publicKey PublicKey null The public key used to verify the signature of the exchange's payload.
secureRandom secureRandom null A reference to a SecureRandom object that wil lbe used to initialize the Signature service.
password char[] null The password for the keystore.

The most basic way to way to sign an verify an exchange is with a KeyPair as follows.

from("direct:keypair").to("crypto:sign://basic?privateKey=#myPrivateKey", "crypto:verify://basic?publicKey=#myPublicKey", "mock:result");

The same can be achieved with the Spring XML Extensions using references to keys

<route>
    <from uri="direct:keypair"/>
    <to uri="crypto:sign://basic?privateKey=#myPrivateKey" />
    <to uri="crypto:verify://basic?publicKey=#myPublicKey" />
    <to uri="mock:result"/>
</route>

The JCE provides a very versatile KeyStore for housing pairs of PrivateKeys and Certificates keeping them encrypted and password protected. They can be retrieved from it by applying an alias to the retrieval apis. There are a number of ways to get keys and Certificates into a keystore most often this is done with the external 'keytool' application. This is a good example of using keytool to create a KeyStore with a self signed Cert and Private key.

The examples use a Keystore with a key and cert aliased by 'bob'. The password for the keystore and the key is 'letmein'

The following shows how to use a Keystore via the Fluent builders, it also shows how to load and initialize the keystore.

from("direct:keystore").to("crypto:sign://keystore?keystore=#keystore&alias=bob&password=letmein", "crypto:verify://keystore?keystore=#keystore&alias=bob", "mock:result");

Again in Spring a ref is used to lookup an actual keystore instance.

<route>
    <from uri="direct:keystore"/>
    <to uri="crypto:sign://keystore?keystore=#keystore&lias=bob&assword=letmein" />
    <to uri="crypto:verify://keystore?keystore=#keystore&lias=bob" />
    <to uri="mock:result"/>
</route>        

Changing the Signature algorithm or the Security provider is a simple matter of specifying their names. You will need to also use Keys that are compatible with the algorithm you choose.

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(512, new SecureRandom());
keyPair = keyGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
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");

or

<route>
    <from uri="direct:algorithm"/>
    <to uri="crypto:sign://rsa?algorithm=MD5withRSA&rivateKey=#rsaPrivateKey" />
    <to uri="crypto:verify://rsa?algorithm=MD5withRSA&ublicKey=#rsaPublicKey" />
    <to uri="mock:result"/>
</route>        
<route>
    <from uri="direct:provider"/>
    <to uri="crypto:sign://provider?privateKey=#myPrivateKey&rovider=SUN" />
    <to uri="crypto:verify://provider?publicKey=#myPublicKey&rovider=SUN" />
    <to uri="mock:result"/>
</route>        

When using a Recipient list or similar EIP the recipient of an exchange can vary dynamically. Using the same key across all recipients may neither be feasible or desirable. It would be useful to be able to specify the signature keys dynamically on a per exchange basis. The exchange could then be dynamically enriched with the key of its target recipient prior to signing. To facilitate this the signature mechanisms allow for keys to be supplied dynamically via the message headers below

from("direct:headerkey-sign").to("crypto:sign://alias");
from("direct:headerkey-verify").to("crypto:verify://alias", "mock:result");

or

<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>    

Better again would be to dynamically supply a keystore alias. Again the alias can be supplied in a message header

from("direct:alias-sign").to("crypto:sign://alias?keystore=#keystore");
from("direct:alias-verify").to("crypto:verify://alias?keystore=#keystore", "mock:result");

or

<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>    

The header would be set as follows

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);

See also:

Name Description Example Required? Default Value
cxfBeanBinding CXF bean binding specified by the \# notation. The referenced object must be an instance of org.apache.camel.component.cxf.cxfbean.CxfBeanBinding. cxfBinding=#bindingName No DefaultCxfBeanBinding
bus CXF bus reference specified by the \# notation. The referenced object must be an instance of org.apache.cxf.Bus. bus=#busName No Default bus created by CXF Bus Factory
headerFilterStrategy Header filter strategy specified by the \# notation. The referenced object must be an instance of org.apache.camel.spi.HeaderFilterStrategy. headerFilterStrategy=#strategyName No CxfHeaderFilterStrategy
setDefaultBus Will set the default bus when CXF endpoint create a bus by itself. true, false No false
populateFromClass Since 2.3, the wsdlLocation annotated in the POJO is ignored (by default) unless this option is set to false. Prior to 2.3, the wsdlLocation annotated in the POJO is always honored and it is not possible to ignore. true, false No true
providers Since 2.5, setting the providers for the CXFRS endpoint. providers=#providerRef1,#providerRef2 No null

Name Description Type Required? Default Value In/Out Examples
CamelHttpCharacterEncoding (before 2.0-m2: CamelCxfBeanCharacterEncoding) Character encoding String No None In ISO-8859-1
CamelContentType (before 2.0-m2: CamelCxfBeanContentType) Content type String No \**/*\* In text/xml

CamelHttpBaseUri (2.0-m3 and before: CamelCxfBeanRequestBasePath)

The value of this header will be set in the CXF message as the Message.BASE_PATH property. It is needed by CXF JAX-RS processing. Basically, it is the scheme, host and port portion of the request URI. String Yes The Endpoint URI of the source endpoint in the Camel exchange In http://localhost:9000
CamelHttpPath (before 2.0-m2: CamelCxfBeanRequestPat{}h) Request URI's path String Yes None In consumer/123
CamelHttpMethod (before 2.0-m2: CamelCxfBeanVerb) RESTful request verb String Yes None In GET, PUT, POST, DELETE
CamelHttpResponseCode HTTP response code Integer No None Out 200

The cxf: component provides integration with Apache CXF for connecting to JAX-WS services hosted in CXF.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

CXF dependencies

If you want to learn about CXF dependencies, see the WHICH-JARS text file.

Note

When using CXF as a consumer, the CAMEL:CXF Bean Component allows you to factor out how message payloads are received from their processing as a RESTful or SOAP web service. This has the potential of using a multitude of transports to consume web services. The bean component's configuration is also simpler and provides the fastest method to implement web services using Camel and CXF.

Name Required Description
wsdlURL No

The location of the WSDL. WSDL is obtained from endpoint address by default. For example:

file://local/wsdl/hello.wsdl or wsdl/hello.wsdl

serviceClass Yes

The name of the SEI (Service Endpoint Interface) class. This class can have, but does not require, JSR181 annotations.  Since 2.0, this option is only required by POJO mode. If the wsdlURL option is provided, serviceClass is not required for PAYLOAD and MESSAGE mode. When wsdlURL option is used without serviceClass, the serviceName and portName (endpointName for Spring configuration) options MUST be provided.

Since 2.0, it is possible to use # notation to reference a serviceClass object instance from the registry..

Please be advised that the referenced object cannot be a Proxy (Spring AOP Proxy is OK) as it relies on Object.getClass().getName() method for non Spring AOP Proxy.

Since 2.8, it is possible to omit both wsdlURL and serviceClass options for PAYLOAD and MESSAGE mode. When they are omitted, arbitrary XML elements can be put in CxfPayload's body in PAYLOAD mode to facilitate CXF Dispatch Mode.

For example: org.apache.camel.Hello

serviceName Only if more than one serviceName present in WSDL

The service name this service is implementing, it maps to the wsdl:service@name. For example:

{http://org.apache.camel}ServiceName

portName Only if more than one portName under the serviceName is present, and it is required for camel-cxf consumer since camel 2.2

The port name this service is implementing, it maps to the wsdl:port@name. For example:

{http://org.apache.camel}PortName

dataFormat No Which message data format the CXF endpoint supports. Possible values are: POJO (default), PAYLOAD, MESSAGE.
relayHeaders No Available since Fuse Mediation Router 1.6.1. Please see the Description of relayHeader option section for this option in Fuse Mediation Router 2.0. Should a CXF endpoint relay headers along the route. Currently only available when dataFormat=POJO. Possible values are: true (default), false.
wrapped No Which kind of operation the CXF endpoint producer will invoke. Possible values are: true, false (default).
wrappedStyle No Since 2.5.0 The WSDL style that describes how parameters are represented in the SOAP body. If the value is false, CXF will chose the document-literal unwrapped style, If the value is true, CXF will chose the document-literal wrapped style
setDefaultBus No Specifies whether or not to use the default CXF bus for this endpoint. Possible values are: true, false (default).
bus No

New in Fuse Mediation Router 2.0, use # notation to reference a bus object from the registry—for example, bus=#busName. The referenced object must be an instance of org.apache.cxf.Bus.

By default, uses the default bus created by CXF Bus Factory.

cxfBinding No

New in Fuse Mediation Router 2.0, use # notation to reference a CXF binding object from the registry—for example, cxfBinding=#bindingName. The referenced object must be an instance of org.apache.camel.component.cxf.CxfBinding.

headerFilterStrategy No New in Fuse Mediation Router 2.0, use # notation to reference a header filter strategy object from the registry—for example, headerFilterStrategy=#strategyName. The referenced object must be an instance of org.apache.camel.spi.HeaderFilterStrategy.
loggingFeatureEnabled No New in 2.3, this option enables CXF Logging Feature which writes inbound and outbound SOAP messages to log. Possible values are: true, false (default).
defaultOperationName No

New in 2.4, this option will set the default operationName that will be used by the CxfProducer that invokes the remote service. For example:

defaultOperationName=greetMe

defaultOperationNameSpace No

New in 2.4, this option will set the default operationNamespace that will be used by the CxfProducer which invokes the remote service. For example:

defaultOperationNamespace= http://apache.org/hello_world_soap_http

synchronous No New in 2.5, this option will let CXF endpoint decide to use sync or async API to do the underlying work. The default value is false, which means camel-cxf endpoint will try to use async API by default.
publishedEndpointUrl No

New in 2.5, this option overrides the endpoint URL that appears in the published WSDL that is accessed using the service address URL plus ?wsdl. For example:

publshedEndpointUrl=http://example.com/service

properties.propName No Camel 2.8: Allows you to set custom CXF properties in the endpoint URI. For example, setting properties.mtom-enabled=true to enable MTOM.

The serviceName and portName are QNames, so if you provide them be sure to prefix them with their {namespace} as shown in the examples above.

NOTE From Fuse Mediation Router 1.5.1, the serviceClass for a CXF producer (that is, the to endpoint) should be a Java interface.

DataFormat Description
POJO POJOs (plain old Java objects) are the Java parameters to the method being invoked on the target server. Both Protocol and Logical JAX-WS handlers are supported.
PAYLOAD PAYLOAD is the message payload (the contents of the soap:body) after message configuration in the CXF endpoint is applied. Only Protocol JAX-WS handler is supported. Logical JAX-WS handler is not supported.
MESSAGE MESSAGE is the raw message that is received from the transport layer. JAX-WS handler is not supported.

You can determine the data format mode of an exchange by retrieving the exchange property, CamelCXFDataFormat. The exchange key constant is defined in org.apache.camel.component.cxf.CxfConstants.DATA_FORMAT_PROPERTY.

Since Camel 2.8, there is support for using Aries blueprint dependency injection for your CXF endpoints. The schema is very similar to the Spring schema, so the transition is fairly transparent.

For example:

 <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"
                      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>


Currently the endpoint element is the first supported CXF namespacehandler.

You can also use the bean references just as in spring

<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">
        <routeBuilder ref="reportIncidentRoutes"/>
    </camelContext>

</blueprint>


The relayHeaders=true setting expresses an intent to relay the headers. The actual decision on whether a given header is relayed is delegated to a pluggable instance that implements the MessageHeadersRelay interface. A concrete implementation of MessageHeadersRelay will be consulted to decide if a header needs to be relayed or not. There is already an implementation of SoapMessageHeadersRelay which binds itself to well-known SOAP name spaces. Currently only out-of-band headers are filtered, and in-band headers will always be relayed when relayHeaders=true. If there is a header on the wire, whose name space is unknown to the runtime, then a fall back DefaultMessageHeadersRelay will be used, which simply allows all headers to be relayed.

The relayHeaders=false setting asserts that all headers, in-band and out-of-band, will be dropped.

You can plugin your own MessageHeadersRelay implementations overriding or adding additional ones to the list of relays. In order to override a preloaded relay instance just make sure that your MessageHeadersRelay implementation services the same name spaces as the one you looking to override. Also note, that the overriding relay has to service all of the name spaces as the one you looking to override, or else a runtime exception on route start up will be thrown as this would introduce an ambiguity in name spaces to relay instance mappings.

<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"/>

Take a look at the tests that show how you'd be able to relay/drop headers here:

https://svn.apache.org/repos/asf/camel/branches/camel-1.x/components/camel-cxf/src/test/java/org/apache/camel/component/cxf/soap/headers/CxfMessageHeadersRelayTest.java

Name Description type Required? Default value
relayHeaders All message headers will be processed by Message Header Filters boolean No true (1.6.1 behavior)
relayAllMessageHeaders All message headers will be propagated (without processing by Message Header Filters) boolean No false (1.6.1 behavior)
allowFilterNamespaceClash If two filters overlap in activation namespace, the property control how it should be handled. If the value is true, last one wins. If the value is false, it will throw an exception boolean No false (1.6.1 behavior)

You can configure the CXF endpoint with the Spring configuration file shown below, and you can also embed the endpoint into the camelContext tags. When you are invoking the service endpoint, you can set the operationName and operationNameSpace headers to explicitly state which operation you are calling.

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cxf="http://activemq.apache.org/camel/schema/cxfEndpoint"
        xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                http://activemq.apache.org/camel/schema/cxfEndpoint http://activemq.apache.org/camel/schema/cxf/camel-cxf-1.6.0.xsd
                http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/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>

NOTE In Camel 2.x we change to use http://camel.apache.org/schema/cxf as the CXF endpoint's target namespace.

<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-2.0.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     ">
 ...

Be sure to include the JAX-WS schemaLocation attribute specified on the root beans element. This allows CXF to validate the file and is required. Also note the namespace declarations at the end of the <cxf:cxfEndpoint/> tag--these are required because the combined {namespace}localName syntax is presently not supported for this tag's attribute values.

The cxf:cxfEndpoint element supports many additional attributes:

Name Value
PortName The endpoint name this service is implementing, it maps to the wsdl:port@name. In the format of ns:PORT_NAME where ns is a namespace prefix valid at this scope.
serviceName The service name this service is implementing, it maps to the wsdl:service@name. In the format of ns:SERVICE_NAME where ns is a namespace prefix valid at this scope.
wsdlURL The location of the WSDL. Can be on the classpath, file system, or be hosted remotely.
bindingId The bindingId for the service model to use.
address The service publish address.
bus The bus name that will be used in the JAX-WS endpoint.
serviceClass The class name of the SEI (Service Endpoint Interface) class which could have JSR181 annotation or not.

It also supports many child elements:

Name Value
cxf:inInterceptors The incoming interceptors for this endpoint. A list of <bean> or <ref>.
cxf:inFaultInterceptors The incoming fault interceptors for this endpoint. A list of <bean> or <ref>.
cxf:outInterceptors The outgoing interceptors for this endpoint. A list of <bean> or <ref>.
cxf:outFaultInterceptors The outgoing fault interceptors for this endpoint. A list of <bean> or <ref>.
cxf:properties A properties map which should be supplied to the JAX-WS endpoint. See below.
cxf:handlers A JAX-WS handler list which should be supplied to the JAX-WS endpoint. See below.
cxf:dataBinding You can specify the which DataBinding will be use in the endpoint. This can be supplied using the Spring <bean class="MyDataBinding"/> syntax.
cxf:binding You can specify the BindingFactory for this endpoint to use. This can be supplied using the Spring <bean class="MyBindingFactory"/> syntax.
cxf:features The features that hold the interceptors for this endpoint. A list of <bean>s or <ref>s
cxf:schemaLocations The schema locations for endpoint to use. A list of <schemaLocation>s
cxf:serviceFactory The service factory for this endpoint to use. This can be supplied using the Spring <bean class="MyServiceFactory"/> syntax

You can find more advanced examples which show how to provide interceptors, properties and handlers here: http://cwiki.apache.org/CXF20DOC/jax-ws-configuration.html

Note

You can use CXF:properties to set the CXF endpoint's dataFormat and setDefaultBus properties from a Spring configuration file, as follows:

<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>

If you are using some soap client such as PHP, you will get this kind of error, because CXF doesn't add the XML start document "<?xml version="1.0" encoding="utf-8"?>"

Error:sendSms: SoapFault exception: [Client] looks like we got no XML document in [...]

To resolved this issue, you just need to tell StaxOutInterceptor to write the XML start document for you.

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);        
    }

}

You can add a customer interceptor like this and configure it into you camel-cxf endpont

<cxf:cxfEndpoint id="routerEndpoint" address="http://localhost:${CXFTestSupport.port2}/CXFGreeterRouterTest/CamelContext/RouterPort"
 		serviceClass="org.apache.hello_world_soap_http.GreeterImpl">
     <cxf:outInterceptors>
         <!-- 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> 

Or adding a message header for it like this if you are using Camel 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); 

The camel-cxf endpoint consumer POJO data format is based on the cxf invoker, so the message header has a property with the name of CxfConstants.OPERATION_NAME and the message body is a list of the SEI method parameters.

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 =
                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});
    }

}

The camel-cxf endpoint producer is based on the cxf client API. First you need to specify the operation name in the message header, then add the method parameters to a list, and initialize the message with this parameter list. The response message's body is a messageContentsList, you can get the result from that list.

Note: After Fuse Mediation Router 1.5,the message body changed from an object array to a message content list. If you still want to get the object array from the message body, you can get the body using message.getbody(Object[].class), as follows:

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.
// 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));

PAYLOAD means that you process the payload message from the SOAP envelope. You can use the Header.HEADER_LIST as the key to set or get the SOAP headers and use the List<Element> to set or get SOAP body elements. In Fuse Mediation Router 1.x, you can get the List<Element> and header from the CXF Message, but if you want to set the response message, you need to create the CXF message using the CXF API.

protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from(simpleEndpointURI + "&dataFormat=PAYLOAD").to("log:info").process(new Processor() {
                public void process(final Exchange exchange) throws Exception {
                    Message inMessage = exchange.getIn();
                    if (inMessage instanceof CxfMessage) {
                        CxfMessage cxfInMessage = (CxfMessage) inMessage;
                        CxfMessage cxfOutMessage = (CxfMessage) exchange.getOut();
                        List<Element> inElements = cxfInMessage.getMessage().get(List.class);
                        List<Element> outElements = new ArrayList<Element>();
                        XmlConverter converter = new XmlConverter();
                        String documentString = ECHO_RESPONSE;
                        if (inElements.get(0).getLocalName().equals("echoBoolean")) {
                            documentString = ECHO_BOOLEAN_RESPONSE;
                        }
                        org.apache.cxf.message.Exchange ex = ((CxfExchange)exchange).getExchange();
                        Endpoint ep = ex.get(Endpoint.class);
                        org.apache.cxf.message.Message response = ep.getBinding().createMessage();
                        Document outDocument = converter.toDOMDocument(documentString);
                        outElements.add(outDocument.getDocumentElement());
                        response.put(List.class, outElements);
                        cxfOutMessage.setMessage(response);                            
                    }
                }
            });
        }
    };
}

In Fuse Mediation Router 2.0: CxfMessage.getBody() will return an org.apache.camel.component.cxf.CxfPayload object, which has getters for SOAP message headers and Body elements. This change enables decoupling the native CXF message from the Fuse Mediation Router message.

protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from(SIMPLE_ENDPOINT_URI + "&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<Element> inElements = requestPayload.getBody();
                    List<Element> outElements = new ArrayList<Element>();
                    // 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;
                    if (inElements.get(0).getLocalName().equals("echoBoolean")) {
                        documentString = ECHO_BOOLEAN_RESPONSE;
                        assertEquals("Get a wrong request", ECHO_BOOLEAN_REQUEST, request);
                    } else {
                        assertEquals("Get a wrong request", ECHO_REQUEST, request);
                    }
                    Document outDocument = converter.toDOMDocument(documentString);
                    outElements.add(outDocument.getDocumentElement());
                    // set the payload header with null
                    CxfPayload<SoapHeader> responsePayload = new CxfPayload<SoapHeader>(null, outElements);
                    exchange.getOut().setBody(responsePayload); 
                }
            });
        }
    };
}

POJO means that the data format is a list of Java objects when the CXF endpoint produces or consumes Camel exchanges. Even though Fuse Mediation Router exposes the message body as POJOs in this mode, the CXF component still provides access to read and write SOAP headers. However, since CXF interceptors remove in-band SOAP headers from the header list after they have been processed, only out-of-band SOAP headers are available in POJO mode.

The following example illustrates how to get/set SOAP headers. Suppose we have a route that forwards from one CXF endpoint to another. That is, SOAP Client -> Fuse Mediation Router -> CXF service. We can attach two processors to obtain/insert SOAP headers at (1) before request goes out to the CXF service and (2) before response comes back to the SOAP Client. Processor (1) and (2) in this example are InsertRequestOutHeaderProcessor and InsertResponseOutHeaderProcessor. Our route looks like this:

<route>
    <from uri="cxf:bean:routerRelayEndpointWithInsertion"/>
    <process ref="InsertRequestOutHeaderProcessor" />
    <to uri="cxf:bean:serviceRelayEndpointWithInsertion"/>
    <process ref="InsertResponseOutHeaderProcessor" />
</route>     

In 2.x SOAP headers are propagated to and from Fuse Mediation Router Message headers. The Fuse Mediation Router message header name is org.apache.cxf.headers.Header.list, which is a constant defined in CXF (org.apache.cxf.headers.Header.HEADER_LIST). The header value is a List<> of CXF SoapHeader objects (org.apache.cxf.binding.soap.SoapHeader). The following snippet is the InsertResponseOutHeaderProcessor (that inserts a new SOAP header in the response message). The way to access SOAP headers in both InsertResponseOutHeaderProcessor and InsertRequestOutHeaderProcessor are actually the same. The only difference between the two processors is setting the direction of the inserted SOAP header.

public static class InsertResponseOutHeaderProcessor implements Processor {

    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        List<SoapHeader> soapHeaders = (List)exchange.getIn().getHeader(Header.HEADER_LIST);

        // 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);
        
    }
    
}

In 1.x SOAP headers are not propagated to and from Fuse Mediation Router Message headers. Users have to go deeper into CXF APIs to access SOAP headers. Also, accessing the SOAP headers in a request message is slightly different than in a response message. The InsertRequestOutHeaderProcessor and InsertResponseOutHeaderProcessor are as follow.s:

public static class InsertRequestOutHeaderProcessor implements Processor {
    public void process(Exchange exchange) throws Exception {
        CxfMessage message = exchange.getIn().getBody(CxfMessage.class);
        Message cxf = message.getMessage();
        List<SoapHeader> soapHeaders = (List)cxf.get(Header.HEADER_LIST);

        // 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 IN since it is a request message.
        newHeader.setDirection(Direction.DIRECTION_IN);
        //newHeader.setMustUnderstand(false);
        soapHeaders.add(newHeader);
        
    }
}

public static class InsertResponseOutHeaderProcessor implements Processor {
    public void process(Exchange exchange) throws Exception {
        CxfMessage message = exchange.getIn().getBody(CxfMessage.class);
        Map responseContext = (Map)message.getMessage().get(Client.RESPONSE_CONTEXT);
        List<SoapHeader> soapHeaders = (List)responseContext.get(Header.HEADER_LIST);
        
        // 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);
                                       
    }
}

We have already shown how to access SOAP message (CxfPayload object) in PAYLOAD mode (see How to deal with the message for a camel-cxf endpoint in PAYLOAD data format).

In Fuse Mediation Router 2.x Once you obtain a CxfPayload object, you can invoke the CxfPayload.getHeaders() method that returns a List of DOM Elements (SOAP headers).

from(getRouterEndpointURI()).process(new Processor() {
    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        CxfPayload<SoapHeader> payload = exchange.getIn().getBody(CxfPayload.class);
        List<Element> elements = payload.getBody();
        assertNotNull("We should get the elements here", elements);
        assertEquals("Get the wrong elements size", 1, elements.size());
        assertEquals("Get the wrong namespace URI", "http://camel.apache.org/pizza/types", 
                elements.get(0).getNamespaceURI());
            
        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());

In Fuse Mediation Router 1.x: You can get/set to the CXF Message by the key org.apache.cxf.headers.Header.list which is a constant defined in CXF (org.apache.cxf.headers.Header.HEADER_LIST).

from(routerEndpointURI).process(new Processor() {
    @SuppressWarnings("unchecked")
    public void process(Exchange exchange) throws Exception {
        Message inMessage = exchange.getIn();
        CxfMessage message = (CxfMessage) inMessage;
        List<Element> elements = message.getMessage().get(List.class);
        assertNotNull("We should get the payload elements here" , elements);
        assertEquals("Get the wrong elements size" , elements.size(), 1);
        assertEquals("Get the wrong namespace URI" , elements.get(0).getNamespaceURI(), "http://camel.apache.org/pizza/types");
            
        List<SoapHeader> headers = CastUtils.cast((List<?>)message.getMessage().get(Header.HEADER_LIST));
        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(serviceEndpointURI);

If you are using a CXF endpoint to consume the SOAP request, you may need to throw the SOAP Fault from the camel context. Basically, you can use the throwFault DSL to do that; it works for POJO, PAYLOAD and MESSAGE data format. You can define the soap fault like this:

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);

Then throw it as you like:

from(routerEndpointURI).setFaultBody(constant(SOAP_FAULT));

If your CXF endpoint is working in the MESSAGE data format, you could set the the SOAP Fault message in the message body and set the response code in the message header.

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));
    }

});

The same is true for the POJO data format. You can set the SOAP Fault on the Out body and also indicate it's a fault by calling Message.setFault(true), as follows:

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);

cxf client API provides a way to invoke the operation with request and response context. If you are using a CXF endpoint producer to invoke the external Web service, you can set the request context and get the response context with the following code:

        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/hello_world_soap_http}greetMe",
                      responseContext.get("javax.xml.ws.wsdl.operation").toString());

POJO Mode: Both SOAP with Attachment and MTOM are supported (see example in Payload Mode for enabling MTOM). However, SOAP with Attachment is not tested. Since attachments are marshalled and unmarshalled into POJOs, users typically do not need to deal with the attachment themself. Attachments are propagated to Camel message's attachments since 2.1. So, it is possible to retreive attachments by Camel Message API

DataHandler Message.getAttachment(String id)

.

Payload Mode: MTOM is supported since 2.1. Attachments can be retrieved by Camel Message APIs mentioned above. SOAP with Attachment is not supported as there is no SOAP processing in this mode.

To enable MTOM, set the CXF endpoint property "mtom_enabled" to true. (I believe you can only do it with Spring.)

<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>      

You can produce a Camel message with attachment to send to a CXF endpoint in Payload mode.

Exchange exchange = context.createProducerTemplate().send("direct:testEndpoint", new Processor() {

    public void process(Exchange exchange) throws Exception {
        exchange.setPattern(ExchangePattern.InOut);
        List<Element> elements = new ArrayList<Element>();
        elements.add(DOMUtils.readXml(new StringReader(MtomTestHelper.REQ_MESSAGE)).getDocumentElement());
        CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(),
            elements);
        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 ele = (Element)xu.getValue("//ns:DetailResponse/ns:photo/xop:Include", out.getBody().get(0),
                                   XPathConstants.NODE);
String photoId = ele.getAttribute("href").substring(4); // skip "cid:"

ele = (Element)xu.getValue("//ns:DetailResponse/ns:image/xop:Include", out.getBody().get(0),
                                   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());

You can also consume a Camel message received from a CXF endpoint in Payload mode.

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
        Assert.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 ele = (Element)xu.getValue("//ns:Detail/ns:photo/xop:Include", in.getBody().get(0),
                                           XPathConstants.NODE);
        String photoId = ele.getAttribute("href").substring(4); // skip "cid:"
        Assert.assertEquals(MtomTestHelper.REQ_PHOTO_CID, photoId);

        ele = (Element)xu.getValue("//ns:Detail/ns:image/xop:Include", in.getBody().get(0),
                                           XPathConstants.NODE);
        String imageId = ele.getAttribute("href").substring(4); // skip "cid:"
        Assert.assertEquals(MtomTestHelper.REQ_IMAGE_CID, imageId);

        DataHandler dr = exchange.getIn().getAttachment(photoId);
        Assert.assertEquals("application/octet-stream", dr.getContentType());
        MtomTestHelper.assertEquals(MtomTestHelper.REQ_PHOTO_DATA, IOUtils.readBytesFromStream(dr.getInputStream()));
   
        dr = exchange.getIn().getAttachment(imageId);
        Assert.assertEquals("image/jpeg", dr.getContentType());
        MtomTestHelper.assertEquals(MtomTestHelper.requestJpeg, IOUtils.readBytesFromStream(dr.getInputStream()));

        // create response
        List<Element> elements = new ArrayList<Element>();
        elements.add(DOMUtils.readXml(new StringReader(MtomTestHelper.RESP_MESSAGE)).getDocumentElement());
        CxfPayload<SoapHeader> body = new CxfPayload<SoapHeader>(new ArrayList<SoapHeader>(),
            elements);
        exchange.getOut().setBody(body);
        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")));

    }
}

Message Mode: Attachments are not supported as it does not process the message at all.

It is possible to configure a CXF endpoint so that, when a Java exception is thrown on the server side, the stack trace for the exception is marshalled into a fault message and returned to the client. To enable this feaure, set the dataFormat to PAYLOAD and set the faultStackTraceEnabled property to true in the cxfEndpoint element, as follows:

<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage"
    wsdlURL="ship.wsdl"
    endpointName="s:TestSoapEndpoint"
    serviceName="s:TestService"
    xmlns:s="http://test">
  <cxf:properties>
    <!-- enable sending the stack trace back to client; the default value is false-->
    <entry key="faultStackTraceEnabled" value="true" />
    <entry key="dataFormat" value="PAYLOAD" />
  </cxf:properties>
</cxf:cxfEndpoint>

For security reasons, the stack trace does not include the causing exception (that is, the part of a stack trace that follows Caused by). If you want to include the causing exception in the stack trace, set the exceptionMessageCauseEnabled property to true in the cxfEndpoint element, as follows:

<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage"
    wsdlURL="ship.wsdl"
    endpointName="s:TestSoapEndpoint"
    serviceName="s:TestService"
    xmlns:s="http://test">
  <cxf:properties>
    <!-- enable to show the cause exception message and the default value is false -->
    <entry key="exceptionMessageCauseEnabled" value="true" />
    <!-- enable to send the stack trace back to client,  the default value is false-->
    <entry key="faultStackTraceEnabled" value="true" />
    <entry key="dataFormat" value="PAYLOAD" />
  </cxf:properties>
</cxf:cxfEndpoint>

The cxfrs: component provides integration with Apache CXF for connecting to JAX-RS services hosted in CXF.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Note

When using CXF as a consumer, the CAMEL:CXF Bean Component allows you to factor out how message payloads are received from their processing as a RESTful or SOAP web service. This has the potential of using a multitude of transports to consume web services. The bean component's configuration is also simpler and provides the fastest method to implement web services using Camel and CXF.

Name Description Example Required? default value
resourceClasses The resource classes which you want to export as REST service resourceClasses=org.apache.camel.rs.Example1,org.apache.camel.rs.Exchange2 No None
httpClientAPI New to Fuse Mediation Router 2.1 If it is true, the CxfRsProducer will use the HttpClientAPI to invoke the service httpClientAPI=true No true
synchronous New in 2.5, this option will let CxfRsConsumer decide to use sync or async API to do the underlying work. The default value is false which means it will try to use async API by default. synchronous=true No false
throwExceptionOnFailure New in 2.6, this option tells the CxfRsProducer to inspect return codes and will generate an Exception if the return code is larger than 207. throwExceptionOnFailure=true No true
maxClientCacheSize New in 2.6, you can set the In message header, CamelDestinationOverrideUrl, to dynamically override the target destination Web Service or REST Service defined in your routes. The implementation caches CXF clients or ClientFactoryBean in CxfProvider and CxfRsProvider. This option allows you to configure the maximum size of the cache. maxClientCacheSize=5 No 10

You can also configure the CXF REST endpoint through the Spring configuration. Since there are lots of difference between the CXF REST client and CXF REST Server, we provide different configuration for them. Please check out the schema file and CXF REST user guide for more information.

In camel-cxf schema file, there are two elements for the REST endpoint definition. cxf:rsServer for REST consumer, cxf:rsClient for REST producer. You can find a Fuse Mediation Router REST service route configuration example here.

<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
    ">
  <!-- Defined the real JAXRS back end service  -->
  <jaxrs:server id="restService"
		        address="http://localhost:9002/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:9000/route"
    serviceClass="org.apache.camel.component.cxf.jaxrs.testbean.CustomerService" />

  <!-- Defined the client endpoint to create the cxf-rs consumer -->
  <cxf:rsClient id="rsClient" address="http://localhost:9002/rest"
    serviceClass="org.apache.camel.component.cxf.jaxrs.testbean.CustomerService"/>
  
  <!-- 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>

CXF JAXRS front end implements the JAXRS(JSR311) API, so we can export the resources classes as a REST service. And we leverage the CXF Invoker API to turn a REST request into a normal Java object method invocation. Unlike the camel-restlet, you don't need to specify the URI template within your restlet endpoint, CXF take care of the REST request URI to resource class method mapping according to the JSR311 specification. All you need to do in Fuse Mediation Router is delegate this method request to a right processor or endpoint.

Here is an example of a CXFRS route:

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 = (String) inMessage.getBody(String.class);
                        if ("/customerservice/customers/126".equals(path)) {                            
                            Customer customer = new Customer();
                            customer.setId(Long.parseLong(id));
                            customer.setName("Willem");
                            // We just put the response Object into the out message body
                            exchange.getOut().setBody(customer);
                        } else {
                             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());
                }
                }
                
            });
        }
    };
}
        

And the corresponding resource class used to configure the endpoint:

@Path("/customerservice/")
 public class CustomerServiceResource {
 
     public CustomerServiceResource() {
     }
 
     @GET
     @Path("/customers/{id}/")
     public Customer getCustomer(@PathParam("id") String id) {
         return null;
     }
 
     @PUT
     @Path("/customers/")
     public Response updateCustomer(Customer customer) {
         return null;
     }
 }
 

Important

The resource class is used to configure the JAXRS properties only. The methods will not be executed during the routing of messages to the endpoint, the route itself is responsible for all processing instead.

CXF JAXRS front end implements a proxy based client API, with this API you can invoke the remote REST service through a proxy. camel-cxfrs producer is based on this proxy API. So, you just need to specify the operation name in the message header and prepare the parameter in the message body, camel-cxfrs producer will generate right REST request for you.

Here is an example

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 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");
assertEquals("Get a wrong customer name", response.getName(), "John");
assertEquals("Get a wrong response code", 200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));

CXF JAXRS front end also provides a http centric client API, You can also invoke this API from camel-cxfrs producer. You need to specify the HTTP_PATH and Http method and let the the producer know to use the HTTP centric client by using the URI option httpClientAPI or set the message header with CxfConstants.CAMEL_CXF_RS_USING_HTTP_API. You can turn the response object to the type class that you specify with CxfConstants.CAMEL_CXF_RS_RESPONSE_CLASS.

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);
        // 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 not be null ", response);
assertEquals("Get a wrong customer id ", String.valueOf(response.getId()), "123");
assertEquals("Get a wrong customer name", response.getName(), "John");
assertEquals("Get a wrong response code", 200, exchange.getOut().getHeader(Exchange.HTTP_RESPONSE_CODE));

From Fuse Mediation Router 2.1, we also support to specify the query parameters from CXFRS URI for the CXFRS HTTP centric client.

Exchange exchange = template.send("cxfrs://http://localhost:" + getPort2() + "/" + getClass().getSimpleName() + "/testQuery?httpClientAPI=true&q1=12&q2=13"

To support the Dynamical routing, you can override the URI's query parameters by using the CxfConstants.CAMEL_CXF_RS_QUERY_MAP header to set the parameter map for it.To support the Dynamical routing, you can override the URI's query parameters by using the CxfConstants.CAMEL_CXF_RS_QUERY_MAP header to set the parameter map for it.

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);

The DataSet component (available since 1.3.0) provides a mechanism to easily perform load & soak testing of your system. It works by allowing you to create DataSet instances both as a source of messages and as a way to assert that the data set is received.

Fuse Mediation Router will use the throughput logger when sending dataset's.

dataset:name[?options]

Where name is used to find the DataSet instance in the Registry

Fuse Mediation Router ships with a support implementation of org.apache.camel.component.dataset.DataSet, the org.apache.camel.component.dataset.DataSetSupport class, that can be used as a base for implementing your own DataSet. Fuse Mediation Router also ships with a default implementation, the org.apache.camel.component.dataset.SimpleDataSet that can be used for testing.

Option Default Description
produceDelay 3 Allows a delay in ms to be specified, which causes producers to pause in order to simulate slow producers. Uses a minimum of 3 ms delay unless you set this option to -1 to force no delay at all.
consumeDelay 0 Allows a delay in ms to be specified, which causes consumers to pause in order to simulate slow consumers.
preloadSize 0 Sets how many messages should be preloaded (sent) before the route completes its initialization.
initialDelay 1000 Camel 2.1: Time period in millis to wait before starting sending messages.
minRate 0 Wait until the DataSet contains at least this number of messages

You can append query options to the URI in the following format, ?option=value&option=value&...

Fuse Mediation Router will lookup in the Registry for a bean implementing the DataSet interface. So you can register your own DataSet as:

   <bean id="myDataSet" class="com.mycompany.MyDataSet">
      <property name="size" value="100"/>
   </bean>

For example, to test that a set of messages are sent to a queue and then consumed from the queue without losing any messages:

// 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");

The above would look in the Registry to find the foo DataSet instance which is used to create the messages.

Then you create a DataSet implementation, such as using the SimpleDataSet as described below, configuring things like how big the data set is and what the messages look like etc.

Property Type Description
defaultBody Object Specifies the default message body. For SimpleDataSet it is a constant payload; though if you want to create custom payloads per message, create your own derivation of DataSetSupport.
reportGroup long Specifies the number of messages to be received before reporting progress. Useful for showing progress of a large load test.
size long Specifies how many messages to send/consume.

Available as of Camel 2.5

The db4o: component allows you to work with db4o NoSQL database. The camel-db4o library is provided by the Camel Extra project which hosts all *GPL related components for Camel.

Name Default Value Description
consumeDelete true Option for Db4oConsumer only. Specifies whether or not the entity is deleted after it is consumed.
consumer.delay 500 Option for HibernateConsumer only. Delay in millis between each poll.
consumer.initialDelay 1000 Option for HibernateConsumer only. Millis before polling starts.
consumer.userFixedDelay false Option for HibernateConsumer only. Set to true to use fixed delay between polls, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.

Name Default Value Description
allowMultipleConsumers true @deprecated If set to false, then when a second consumer is started on the endpoint, an IllegalStateException is thrown. Will be removed in Camel 2.1: Direct endpoint does not support multiple consumers.

You can append query options to the URI in the following format, ?option=value&option=value&...

Available as of Camel 2.7

This is an additional component for Camel to run DNS queries, using DNSJava. The component is a thin layer on top of DNSJava. The component offers the following operations:

  • ip, to resolve a domain by its ip

  • lookup, to lookup information about the domain

  • dig, to run DNS queries

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Header Type Operations Description
dns.domain String ip The domain name. Mandatory.
dns.name String lookup The name to lookup. Mandatory.
dns.type - lookup, dig The type of the lookup. Should match the values of org.xbill.dns.Type. Optional.
dns.class - lookup, dig he DNS class of the lookup. Should match the values of org.xbill.dns.DClass. Optional.
dns.query String dig The query itself. Mandatory.
dns.server String dig The server in particular for the query. If none is given, the default one specified by the OS will be used. Optional.

Name Type Default Description
method String null The method name that bean will be invoked. If not provided, will try to pick the method itself. In case of ambiguity an exception is thrown. See Bean Binding for more details.
multiParameterArray boolean false How to treat the parameters which are passed from the message body; if it is true, the In message body should be an array of parameters.

You can append query options to the URI in the following format, ?option=value&option=value&...

The EJB component extends the Bean component in which most of the details from the Bean component applies to this component as well.

In this example we want to invoke the hello method on the EJB. Since this example is based on an unit test using Apache OpenEJB we have to set a JndiContext on the EJB component with the OpenEJB settings.

@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");

    return new InitialContext(properties);
}

Then we are ready to use the EJB in the route:

from("direct:start")
    // invoke the greeter EJB using the local interface and invoke the hello method
    .to("ejb:GreaterImplLocal?method=hello")
    .to("mock:result");

In a real application server

In a real application server you most likely do not have to setup a JndiContext on the EJB component as it will create a default JndiContext on the same JVM as the application server, which usually allows it to access the JNDI registry and lookup the EJBs. However if you need to access a application server on a remote JVM or the likes, you have to prepare the properties beforehand.

And this is the same example using Spring XML instead:

Again since this is based on an unit test we need to setup the EJB component:

<!-- 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>

Before we are ready to use EJB in the routes:

<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>

The Esper component supports the Esper Library for Event Stream Processing. The camel-esper library is provided by the Camel Extra project which hosts all *GPL related components for Fuse Mediation Router.

Name Default Value Description
pattern The Esper Pattern expression as a String to filter events
eql The Esper EQL expression as a String to filter events

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default value Description

Name Type Message Description

Name Default value Description
args null

The arguments of the executable. The arguments may be one or many whitespace-separated tokens, that can be quoted with ", e.g. args="arg 1" arg2 will use two arguments arg 1 and arg2. To include the quotes use "", e.g. args=""arg 1"" arg2 will use the arguments "arg 1" and arg2.

workingDir null The directory in which the command should be executed. If null, the working directory of the current process will be used.
timeout Long.MAX_VALUE The timeout, in milliseconds, after which the executable should be terminated. If the executable has has not finished within the timeout, the component will send a termination request.
outFile null The name of a file, created by the executable, that should be considered as output of the executable. If no outFile is set, the standard output (stdout) of the executable will be considered as output.
binding a DefaultExecBinding instance A reference to a org.apache.commons.exec.ExecBinding in the Registry.
commandExecutor a DefaultCommandExecutor instance A reference to a org.apache.commons.exec.ExecCommandExecutor in the Registry, that customizes the command execution. The default command executor utilizes the commons-exec library. It adds a shutdown hook for every executed command.
useStderrOnEmptyStdout false A boolean which dictates when stdin is empty, it should fallback and use stderr in the Message Body. This option is default false.

The supported headers are defined in org.apache.camel.component.exec.ExecBinding.

Name Type Message Description
ExecBinding.EXEC_COMMAND_EXECUTABLE String in The name of the system command that will be executed. Overrides the executable in the URI.
ExecBinding.EXEC_COMMAND_ARGS java.util.List<String> in The arguments of the executable. The arguments are used literally, no quoting is applied. Overrides existing args in the URI.
ExecBinding.EXEC_COMMAND_ARGS String in Camel 2.5: The arguments of the executable as a Single string where each argument is whitespace separated (see args in URI option). The arguments are used literally, no quoting is applied. Overrides existing args in the URI.
ExecBinding.EXEC_COMMAND_OUT_FILE String in The name of a file, created by the executable, that should be considered as output of the executable. Overrides existing outFile in the URI.
ExecBinding.EXEC_COMMAND_TIMEOUT long in The timeout, in milliseconds, after which the executable should be terminated. Overrides existing timeout in the URI.
ExecBinding.EXEC_COMMAND_WORKING_DIR String in The directory in which the command should be executed. Overrides existing workingDir in the URI.
ExecBinding.EXEC_EXIT_VALUE int out The value of this header is the exit value of the executable. Typically not-zero exit values indicates abnormal termination. Note that the exit value is OS-dependent.
ExecBinding.EXEC_STDERR java.io.InputStream out The value of this header points to the standard error stream (stderr) of the executable. If no stderr is written, the value is null.
ExecBinding.EXEC_USE_STDERR_ON_EMPTY_STDOUT boolean in Indicates when the stdin is empty, should we fallback and use stderr as the body of the Message. By default this option is false.

If the in message body, that that the Exec component receives, is convertible to java.io.InputStream, it is used to feed input of the executable via its stdin. After the execution, the message body is the result of the execution, that is org.apache.camel.components.exec.ExecResult instance containing the stdout, stderr, exit value and out file. The component supports the following ExecResult type converters for convenience:

From To
ExecResult java.io.InputStream
ExecResult String
ExecResult byte []
ExecResult org.w3c.dom.Document

If out file is used (the endpoint is configured with outFile, or there is ExecBinding.EXEC_COMMAND_OUT_FILE header) the converters return the content of the out file. If no out file is used, then the converters will use the stdout of the process for conversion to the target type. For example refer to the usage examples.

The following example executes Apache Ant (Windows only) with the build file CamelExecBuildFile.xml, provided that ant.bat is in the system path, and that CamelExecBuildFile.xml is in the current directory.

from("direct:exec")
.to(exec:ant.bat?args=-f CamelExecBuildFile.xml")

In the next example, the ant.bat command, redirects the ant output to CamelExecOutFile.txt with -l. The file CamelExecOutFile.txt is used as out file with outFile=CamelExecOutFile.txt. The example assumes that ant.bat is in the system path, and that CamelExecBuildFile.xml is in the current directory.

from("direct:exec")
.to("exec:ant.bat?args=-f CamelExecBuildFile.xml -l CamelExecOutFile.txt&outFile=CamelExecOutFile.txt")
.process(new Processor() {
     public void process(Exchange exchange) throws Exception {
        InputStream outFile = exchange.getIn().getBody(InputStream.class);
        assertIsInstanceOf(InputStream.class, outFile);
        // do something with the out file here
     }
  });
Name Default Value Description
autoCreate true Automatically create missing directories in the file's pathname. For the file consumer, that means creating the starting directory. For the file producer, it means the directory where the files should be written.
bufferSize 128kb Write buffer sized in bytes.
fileName null Use Expression such as File Language to dynamically set the filename. For consumers, it's used as a filename filter. For producers, it's used to evaluate the filename to write. If an expression is set, it take precedence over the CamelFileName header. (Note: The header itself can also be an Expression). The expression options support both String and Expression types. If the expression is a String type, it is always evaluated using the File Language. If the expression is an Expression type, the specified Expression type is used - this allows you, for instance, to use OGNL expressions. For the consumer, you can use it to filter filenames, so you can for instance consume today's file using the File Language syntax: mydata-${date:now:yyyyMMdd}.txt.
flatten false Flatten is used to flatten the file name path to strip any leading paths, so it's just the file name. This allows you to consume recursively into sub-directories, but when you eg write the files to another directory they will be written in a single directory. Setting this to true on the producer enforces that any file name recived in CamelFileName header will be stripped for any leading paths.
charset null Camel 2.5: this option is used to specify the encoding of the file, and camel will set the Exchange property with Exchange.CHARSET_NAME with the value of this option.
Name Default Value Description
initialDelay 1000 Milliseconds before polling the file/directory starts.
delay 500 Milliseconds before the next poll of the file/directory.
useFixedDelay true Set to true to use fixed delay between pools, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.
runLoggingLevel TRACE Camel 2.8: The consumer logs a start/complete log line when it polls. This option allows you to configure the logging level for that.
recursive false If a directory, will look for files in all the sub-directories as well.
delete false If true, the file will be deleted after it is processed
noop false If true, the file is not moved or deleted in any way. This option is good for readonly data, or for ETL type requirements. If noop=true, Fuse Mediation Router will set idempotent=true as well, to avoid consuming the same files over and over again.
preMove null Use Expression such as File Language to dynamically set the filename when moving it before processing. For example to move in-progress files into the order directory set this value to order.
move .camel Use Expression such as File Language to dynamically set the filename when moving it after processing. To move files into a .done subdirectory just enter .done.
moveFailed null Use Expression such as File Language to dynamically set the filename when moving failed files after processing. To move files into a error subdirectory just enter error. Note: When moving the files to another location it can/will handle the error when you move it to another location so Fuse Mediation Router cannot pick up the file again.
include null Is used to include files, if filename matches the regex pattern.
exclude null Is used to exclude files, if filename matches the regex pattern.
idempotent false Option to use the Idempotent Consumer EIP pattern to let Fuse Mediation Router skip already processed files. Will by default use a memory based LRUCache that holds 1000 entries. If noop=true then idempotent will be enabled as well to avoid consuming the same files over and over again.
idempotentRepository null Pluggable repository as a org.apache.camel.processor.idempotent.MessageIdRepository class. Will by default use MemoryMessageIdRepository if none is specified and idempotent is true.
inProgressRepository memory Pluggable in-progress repository as a org.apache.camel.processor.idempotent.MessageIdRepository class. The in-progress repository is used to account the current in progress files being consumed. By default a memory based repository is used.
filter null Pluggable filter as a org.apache.camel.component.file.GenericFileFilter class. Will skip files if filter returns false in its accept() method. Fuse Mediation Router also ships with an ANT path matcher filter in the camel-spring component. More details in section below.
sorter null Pluggable sorter as a java.util.Comparator<org.apache.camel.component.file.GenericFile> class.
sortBy null Built-in sort using the File Language. Supports nested sorts, so you can have a sort by file name and as a 2nd group sort by modified date. See sorting section below for details.
readLock markerFile

Used by consumer, to only poll the files if it has exclusive read-lock on the file (i.e. the file is not in-progress or being written). Fuse Mediation Router will wait until the file lock is granted.

The readLock option supports the following built-in strategies:

  • markerFile is the behaviour from Fuse Mediation Router 1.x, where Fuse Mediation Router will create a marker file and hold a lock on the marker file. This option is not available for the FTP component.

  • changed uses a length/modification timestamp to detect whether the file is currently being copied or not. Will wait at least 1 second to determine this, so this option cannot consume files as fast as the others, but can be more reliable as the JDK IO API cannot always determine whether a file is currently being used by another process.

  • rename attempts to rename the file, in order to test whether we can get an exclusive read-lock.

  • none is for no read locks at all.

readLockTimeout 0 (for FTP, 2000) Optional timeout in milliseconds for the read-lock, if supported by the read-lock. If the read-lock could not be granted and the timeout triggered, then Fuse Mediation Router will skip the file. At next poll Fuse Mediation Router, will try the file again, and this time maybe the read-lock could be granted. Currently fileLock, changed and rename support the timeout.
readLockCheckInterval 1000 (for FTP, 5000) Camel 2.6: Interval in millis for the read-lock, if supported by the read lock. This interval is used for sleeping between attempts to acquire the read lock. For example when using the changed read lock, you can set a higher interval period to cater for slow writes. The default of 1 sec. may be too fast if the producer is very slow writing the file.
exclusiveReadLockStrategy null Pluggable read-lock as a org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy implementation.
minDepth 0 Camel 2.8: The minimum depth to start processing when recursively processing a directory. Using minDepth=1 means the base directory. Using minDepth=2 means the first sub directory. This option is not supported by FTP consumer.
maxDepth Integer.MAX_VALUE Camel 2.8: The maximum depth to traverse when recursively processing a directory. This option is not supported by FTP consumer.
doneFileName null Camel 2.6: If provided, Camel will only consume files if a done file exists. This option configures what file name to use. Either you can specify a fixed name. Or you can use dynamic placeholders. The done file is always expected in the same folder as the original file. See using done file and writing done file sections for examples.
processStrategy null A pluggable org.apache.camel.component.file.GenericFileProcessStrategy allowing you to implement your own readLock option or similar. Can also be used when special conditions must be met before a file can be consumed, such as a special ready file exists. If this option is set then the readLock option does not apply.
maxMessagesPerPoll 0 An integer that defines the maximum number of messages to gather per poll. By default, no maximum is set. Can be used to set a limit of e.g. 1000 to avoid having the server read thousands of files as it starts up. Set a value of 0 or negative to disabled it.
startingDirectoryMustExist false Whether the starting directory must exist. Mind that the autoCreate option is default enabled, which means the starting directory is normally auto-created if it doesn't exist. You can disable autoCreate and enable this to ensure the starting directory must exist. Will throw an exception, if the directory doesn't exist.
directoryMustExist false Similar to startingDirectoryMustExist but this applies during polling recursive sub-directories.
Name Default Value Description
fileExist Override What to do if a file already exists with the same name. The following values can be specified: Override, Append, Fail and Ignore. Override, which is the default, replaces the existing file. Append adds content to the existing file. Fail throws a GenericFileOperationException, indicating that there is already an existing file. Ignore silently ignores the problem and does not override the existing file, but assumes everything is okay.
tempPrefix null This option is used to write the file using a temporary name and then, after the write is complete, rename it to the real name. Can be used to identify files being written and also avoid consumers (not using exclusive read locks) reading in progress files. Is often used by FTP when uploading big files.
tempFileName null Camel 2.1: The same as tempPrefix option but offering a more fine grained control on the naming of the temporary filename as it uses the File Language.
keepLastModified false Camel 2.2: Will keep the last modified timestamp from the source file (if any). Will use the Exchange.FILE_LAST_MODIFIED header to located the timestamp. This header can contain either a java.util.Date or long with the timestamp. If the timestamp exists and the option is enabled it will set this timestamp on the written file. Note: This option only applies to the file producer. You cannot use this option with any of the ftp producers.
eagerDeleteTargetFile true Camel 2.3: Whether or not to eagerly delete any existing target file. This option only applies when you use fileExists=Override and the tempFileName option as well. You can use this to disable (set it to false) deleting the target file before the temp file is written. For example you may write big files and want the target file to exists during the temp file is being written. This ensure the target file is only deleted until the very last moment, just before the temp file is being renamed to the target filename.
doneFileName null Camel 2.6: If provided, then Camel will write a 2nd done file when the original file has been written. The done file will be empty. This option configures what file name to use. Either you can specify a fixed name. Or you can use dynamic placeholders. The done file will always be written in the same folder as the original file. See writing done file section for examples.

Any move or delete operations is executed after (post command) the routing has completed; so during processing of the Exchange the file is still located in the inbox folder.

Lets illustrate this with an example:

    from("file://inbox?move=.done").to("bean:handleOrder");

When a file is dropped in the inbox folder, the file consumer notices this and creates a new FileExchange that is routed to the handleOrder bean. The bean then processes the File object. At this point in time the file is still located in the inbox folder. After the bean completes, and thus the route is completed, the file consumer will perform the move operation and move the file to the .done sub-folder.

The move and preMove options should be a directory name, which can be either relative or absolute. If relative, the directory is created as a sub-folder from within the folder where the file was consumed.

By default, Fuse Mediation Router will move consumed files to the .camel sub-folder relative to the directory where the file was consumed.

If you want to delete the file after processing, the route should be:

    from("file://inobox?delete=true").to("bean:handleOrder");

We have introduced a pre move operation to move files before they are processed. This allows you to mark which files have been scanned as they are moved to this sub folder before being processed.

    from("file://inbox?preMove=inprogress").to("bean:handleOrder");

You can combine the pre move and the regular move:

    from("file://inbox?preMove=inprogress&move=.done").to("bean:handleOrder");

So in this situation, the file is in the inprogress folder when being processed and after it's processed, it's moved to the .done folder.

The move and preMove option is Expression-based, so we have the full power of the File Language to do advanced configuration of the directory and name pattern. Fuse Mediation Router will, in fact, internally convert the directory name you enter into a File Language expression. So when we enter move=.done Fuse Mediation Router will convert this into: ${file:parent}/.done/${file:onlyname}. This is only done if Fuse Mediation Router detects that you have not provided a ${ } in the option value yourself. So when you enter an expression containing ${ }, the expression is interpreted as a File Language expression.

So if we want to move the file into a backup folder with today's date as the pattern, we can do:

move=backup/${date:now:yyyyMMdd}/${file:name}
Header Description
CamelFileName Specifies the name of the file to write (relative to the endpoint directory). The name can be a String; a String with a File Language or Simple expression; or an Expression object. If it's null then Fuse Mediation Router will auto-generate a filename based on the message unique ID.
CamelFileNameProduced The actual absolute filepath (path + name) for the output file that was written. This header is set by Camel and its purpose is providing end-users with the name of the file that was written.
Header Description
CamelFileName Name of the consumed file as a relative file path with offset from the starting directory configured on the endpoint.
CamelFileNameOnly Only the file name (the name with no leading paths).
CamelFileAbsolute A boolean option specifying whether the consumed file denotes an absolute path or not. Should normally be false for relative paths. Absolute paths should normally not be used but we added to the move option to allow moving files to absolute paths. But can be used elsewhere as well.
CamelFileAbsolutePath The absolute path to the file. For relative files this path holds the relative path instead.
CamelFilePath The file path. For relative files this is the starting directory + the relative filename. For absolute files this is the absolute path.
CamelFileRelativePath The relative path.
CamelFileParent The parent path.
CamelFileLength A long value containing the file size.
CamelFileLastModified A Date value containing the last modified timestamp of the file.

As the file consumer is BatchConsumer it supports batching the files it polls. By batching it means that Fuse Mediation Router will add some properties to the Exchange so you know the number of files polled the current index in that order.

Property Description
CamelBatchSize The total number of files that was polled in this batch.
CamelBatchIndex The current index of the batch. Starts from 0.
CamelBatchComplete A boolean value indicating the last Exchange in the batch. Is only true for the last entry.

This allows you for instance to know how many files exists in this batch and for instance let the Aggregator2 aggregate this number of files.

Fuse Mediation Router is of course also able to write files, i.e. produce files. In the sample below we receive some reports on the SEDA queue that we process before they are written to a directory.

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");
    }

}

Fuse Mediation Router supports Idempotent Consumer directly within the component so it will skip already processed files. This feature can be enabled by setting the idempotent=true option.

from("file://inbox?idempotent=true").to("...");

By default Fuse Mediation Router uses an in-memory based store for keeping track of consumed files, it uses a least recently used cache holding up to 1000 entries. You can plugin your own implementation of this store by using the idempotentRepository option using the # sign in the value to indicate it's a referring to a bean in the Registry with the specified id.

   <!-- define our store as a plain spring bean -->
   <bean id="myStore" class="com.mycompany.MyIdempotentStore"/>

  <route>
    <from uri="file://inbox?idempotent=true&dempotentRepository=#myStore"/>
    <to uri="bean:processInbox"/>
  </route>

Fuse Mediation Router will log at DEBUG level if it skips a file because it has been consumed before:

DEBUG FileConsumer is idempotent and the file has been consumed before. Will skip this file: target\idempotent\report.txt

In this section we will use the file based idempotent repository org.apache.camel.processor.idempotent.FileIdempotentRepository instead of the in-memory based that is used as default. This repository uses a 1st level cache to avoid reading the file repository. It will only use the file repository to store the content of the 1st level cache. Thereby the repository can survive server restarts. It will load the content of the file into the 1st level cache upon startup. The file structure is very simple as it stores the key in separate lines in the file. By default, the file store has a size limit of 1mb and when the file grows larger, Fuse Mediation Router will truncate the file store and rebuild the content by flushing the 1st level cache into a fresh empty file.

We configure our repository using Spring XML creating our file idempotent repository and define our file consumer to use our repository with the idempotentRepository using \# sign to indicate Registry lookup:

<!-- 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. Fuse Mediation Router 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>

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="file://target/fileidempotent/?idempotent=true&dempotentRepository=#fileStore&ove=done/${file:name}"/>
        <to uri="mock:result"/>
    </route>
</camelContext>

In this section we will use the JPA based idempotent repository instead of the in-memory based that is used as default.

First we need a persistence-unit in META-INF/persistence.xml where we need to use the class org.apache.camel.processor.idempotent.jpa.MessageProcessed as model.

<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>

Then we need to setup a Spring jpaTemplate in the spring XML file:

<!-- 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>

And finally we can create our JPA idempotent repository in the spring XML file as well:

<!-- 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>

And then we just need to reference the jpaStore bean in the file consumer endpoint, using the idempotentRepository option and the # syntax:

  <route>
    <from uri="file://inbox?idempotent=true&dempotentRepository=#jpaStore"/>
    <to uri="bean:processInbox"/>
  </route>

The ANT path matcher is shipped out-of-the-box in the camel-spring jar. So you need to depend on camel-spring if you are using Maven. The reasons is that we leverage Spring's AntPathMatcher to do the actual matching.

The file paths is matched with the following rules:

  • ? matches one character

  • * matches zero or more characters

  • ** matches zero or more directories in a path

The sample below demonstrates how to use it:

<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&ilter=#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>

Fuse Mediation Router supports pluggable sorting strategies. This strategy it to use the File Language to configure the sorting. The sortBy option is configured as follows:

sortBy=group 1;group 2;group 3;...

Where each group is separated with semi colon. In the simple situations you just use one group, so a simple example could be:

sortBy=file:name

This will sort by file name, you can reverse the order by prefixing reverse: to the group, so the sorting is now Z..A:

sortBy=reverse:file:name

As we have the full power of File Language we can use some of the other parameters, so if we want to sort by file size we do:

sortBy=file:length

You can configure to ignore the case, using ignoreCase: for string comparison, so if you want to use file name sorting but to ignore the case then we do:

sortBy=ignoreCase:file:name

You can combine ignore case and reverse, however reverse must be specified first:

sortBy=reverse:ignoreCase:file:name

In the sample below we want to sort by last modified file, so we do:

sortBy=file:modifed

And then we want to group by name as a 2nd option so files with same modifcation is sorted by name:

sortBy=file:modifed;file:name

Now there is an issue here, can you spot it? Well the modified timestamp of the file is too fine as it will be in milliseconds, but what if we want to sort by date only and then subgroup by name? Well as we have the true power of File Language we can use the its date command that supports patterns. So this can be solved as:

sortBy=date:file:yyyyMMdd;file:name

Yeah, that is pretty powerful, oh by the way you can also use reverse per group, so we could reverse the file names:

sortBy=date:file:yyyyMMdd;reverse:file:name

By default this component will attempt to use the Type Converter to turn the inbound message body into a QuickFix Message class and all outputs from FIX will be in the same format.

The Flatpack component supports fixed width and delimited file parsing using the FlatPack library. Notice: This component only supports consuming from flatpack files to Object model. You can not (yet) write from Object model to flatpack format.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Name Default Value Description
delimiter , The default character delimiter for delimited files.
textQualifier " The text qualifier for delimited files.
ignoreFirstRecord true Whether the first line is ignored for delimited files (for the column headers).
splitRows true As of Fuse Mediation Router 1.5, the component can either process each row one by one or the entire content at once.

Fuse Mediation Router will store the following headers on the IN message:

Header Description
camelFlatpackCounter The current row index. For splitRows=false the counter is the total number of rows.

Available as of Fuse Mediation Router 1.6

The freemarker: component allows you to process a message using a FreeMarker template. This can be ideal when using Templating to generate responses for requests.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Option Default Description
contentCache true Cache for the resource content when its loaded.
encoding null Character encoding of the resource content.

Fuse Mediation Router will provide exchange information in the FreeMarker context (just a Map). The Exchange is transfered as:

Key Value
exchange The Exchange itself.
headers The headers of the In message.
camelContext The Camel Context.
request The In message.
body The In message body.
response The Out message (only for InOut message exchange pattern).

Available as of Camel 2.1 Camel provides two headers by which you can define a different resource location for a template or the template content itself. If any of these headers is set then Camel uses this over the endpoint configured resource. This allows you to provide a dynamic template at runtime.

Header Type Description Support Version
FreemarkerConstants.FREEMARKER_RESOURCE org.springframework.core.io.Resource The template resource <= 1.6.2, <= 2.1
FreemarkerConstants.FREEMARKER_RESOURCE_URI String A URI for the template resource to use instead of the endpoint configured. >= 2.1
FreemarkerConstants.FREEMARKER_TEMPLATE String The template to use instead of the endpoint configured. >= 2.1

The options below are exclusive to the FTP2 component:

Name Default Value Description
username null Specifies the username to use to log in to the remote file systen.
password null Specifies the password to use to log in to the remote file system.
binary false Specifies the file transfer mode, BINARY or ASCII. Default is ASCII (false).
disconnect false Camel 2.2: Whether or not to disconnect from remote FTP server right after use. Can be used for both consumer and producer. Disconnect will only disconnect the current connection to the FTP server. If you have a consumer which you want to stop, then you need to stop the consumer/route instead.
localWorkDirectory null When consuming, a local work directory can be used to store the remote file content directly in local files, to avoid loading the content into memory. This is beneficial, if you consume a very big remote file and thus can conserve memory. See below for more details.
passiveMode false FTP only: Specifies whether to use passive mode connections. Default is active mode {false).
securityProtocol TLS

FTPS only: Sets the underlying security protocol. The following values are defined: TLS: Transport Layer Security SSL: Secure Sockets Layer

disableSecureDataChannelDefaults false Camel 2.4: FTPS only: Whether or not to disable using default values for execPbsz and execProt when using secure data transfer. You can set this option to true if you want to be in absolute full control what the options execPbsz and execProt should be used.
execProt null

Camel 2.4: FTPS only: Will by default use option P if secure data channel defaults hasn't been disabled. Possible values are: C: Clear S: Safe (SSL protocol only) E: Confidential (SSL protocol only) P: Private

execPbsz null Camel 2.4: FTPS only: This option specifies the buffer size of the secure data channel. If option useSecureDataChannel has been enabled and this option has not been explicit set, then value 0 is used.
isImplicit false FTPS only: Sets the security mode(implicit/explicit). Default is explicit (false).
knownHostsFile null SFTP only: Sets the known_hosts file, so that the SFTP endpoint can do host key verification.
privateKeyFilePassphrase null SFTP only: Set the private key file passphrase to that the SFTP endpoint can do private key verification.
privateKeyFilePassphrase null SFTP only: Set the private key file passphrase to that the SFTP endpoint can do private key verification.
strictHostKeyChecking no SFTP only:Camel 2.2: Sets whether to use strict host key checking. Possible values are: no, yes and ask. ask does not make sense to use as Camel cannot answer the question for you as its meant for human intervention. Note: The default in Camel 2.1 and below was ask.
maximumReconnectAttempts 3 Specifies the maximum reconnect attempts Fuse Mediation Router performs when it tries to connect to the remote FTP server. Use 0 to disable this behavior.
reconnectDelay 1000 Delay in millis Fuse Mediation Router will wait before performing a reconnect attempt.
connectTimeout 10000 Camel 2.4: Is the connect timeout in millis. This corresponds to using ftpClient.connectTimeout for the FTP/FTPS. For SFTP this option is also used when attempting to connect.
soTimeout null FTP and FTPS Only:Camel 2.4: Is the SocketOptions.SO_TIMEOUT value in millis. Note SFTP will automatic use the connectTimeout as the soTimeout.
timeout 30000 FTP and FTPS Only:Camel 2.4: Is the data timeout in millis. This corresponds to using ftpClient.dataTimeout for the FTP/FTPS. For SFTP there is no data timeout.
throwExceptionOnConnectFailed false Camel 2.5: Whether or not to thrown an exception if a successful connection and login could not be establish. This allows a custom pollStrategy to deal with the exception, for example to stop the consumer or the likes.
siteCommand null FTP and FTPS Only:Camel 2.5: To execute site commands after successful login. Multiple site commands can be separated using a new line character (\n). Use help site to see which site commands your FTP server supports.
stepwise true When consuming directories, specifies whether or not to use stepwise mode for traversing the directory tree. Stepwise means that it will CD one directory at a time. For more details, see Stepwise changing directories.
separator Auto Camel 2.6: Dictates what path separator char to use when uploading files. Auto means use the path provided without altering it. UNIX means use UNIX style path separators. Windows means use Windows style path separators.
ftpClient null FTP and FTPS Only:Camel 2.1: Allows you to use a custom org.apache.commons.net.ftp.FTPClient instance.
ftpClientConfig null FTP and FTPS Only:Camel 2.1: Allows you to use a custom org.apache.commons.net.ftp.FTPClientConfig instance.
serverAliveInterval 0 SFTP Only:Camel 2.8 Allows you to set the serverAliveInterval of the sftp session
serverAliveCountMax 1 SFTP Only:Camel 2.8 Allows you to set the serverAliveCountMax of the sftp session
ftpClient.trustStore.file null FTPS Only: Sets the trust store file, so that the FTPS client can look up for trusted certificates.
ftpClient.trustStore.type JKS FTPS Only: Sets the trust store type.
ftpClient.trustStore.algorithm SunX509 FTPS Only: Sets the trust store algorithm.
ftpClient.trustStore.password null FTPS Only: Sets the trust store password.
ftpClient.keyStore.file null FTPS Only: Sets the key store file, so that the FTPS client can look up for the private certificate.
ftpClient.keyStore.type JKS FTPS Only: Sets the key store type.
ftpClient.keyStore.algorithm SunX509 FTPS Only: Sets the key store algorithm.
ftpClient.keyStore.password null FTPS Only: Sets the key store password.
ftpClient.keyStore.keyPassword null FTPS Only: Sets the private key password.

FTPS component default trust store

By default, the FTPS component trust store accept all certificates. If you only want trust selective certificates, you have to configure the trust store with the ftpClient.trustStore.xxx options or by configuring a custom ftpClient.

More options

See File2 for more options, as all the options from File2 are inherited by FTP2.

You can configure additional options on the ftpClient and ftpClientConfig from the URI directly by using the ftpClient. or ftpClientConfig. prefix.

For example to set the setDataTimeout on the FTPClient to 30 seconds you can do:

from("ftp://foo@myserver?password=secret&ftpClient.dataTimeout=30000")
    .to("bean:foo");

You can mix and match and have use both prefixes, for example to configure date format or timezones.

from("ftp://foo@myserver?password=secret&ftpClient.dataTimeout=30000&ftpClientConfig.serverLanguageCode=fr")
    .to("bean:foo");

You can have as many of these options as you like.

See the documentation of the Apache Commons FTP FTPClientConfig for possible options and more details. And as well for Apache Commons FTP FTPClient.

If you do not like having many and long configuration in the url you can refer to the ftpClient or ftpClientConfig to use by letting Camel lookup in the Registry for it.

For example:

   <bean id="myConfig" class="org.apache.commons.net.ftp.FTPClientConfig">
       <property name="lenientFutureDates" value="true"/>
       <property name="serverLanguageCode" value="fr"/>
   </bean>

And then let Camel lookup this bean when you use the # notation in the url.

from("ftp://foo@myserver?password=secret&ftpClientConfig=#myConfig").to("bean:foo");

See File2 as all the options there also applies for this component.

The FTP consumer will by default leave the consumed files untouched on the remote FTP server. You have to configure it explicit if you want it to delete the files or move them to another location. For example you can use delete=true to delete the files, or use move=.done to move the files into a hidden done sub directory.

The regular File consumer is different as it will by default move files to a .camel sub directory. The reason Camel does not do this by default for the FTP consumer is that it may lack permissions by default to be able to move or delete files.

The following message headers can be used to affect the behavior of the component

Header Description
CamelFileName Specifies the output file name (relative to the endpoint directory) to be used for the output message when sending to the endpoint. If this is not present and no expression either, then a generated message ID is used as the filename instead.
CamelFileNameProduced The actual absolute filepath (path + name) for the output file that was written. This header is set by Fuse Mediation Router and its purpose is providing end-users the name of the file that was written.
CamelFileBatchIndex Current index out of total number of files being consumed in this batch.
CamelFileBatchSize Total number of files being consumed in this batch.
CamelFileHost The remote hostname.
CamelFileLocalWorkPath Path to the local work file, if local work directory is used.

Fuse Mediation Router supports consuming from remote FTP servers and downloading the files directly into a local work directory. This avoids reading the entire remote file content into memory as it is streamed directly into the local file using FileOutputStream.

Fuse Mediation Router will store to a local file with the same name as the remote file, though with .inprogress as extension while the file is being downloaded. Afterwards, the file is renamed to remove the .inprogress suffix. And finally, when the Exchange is complete the local file is deleted.

So if you want to download files from a remote FTP server and store it as files then you need to route to a file endpoint such as:

from("ftp://someone@someserver.com?password=secret&localWorkDirectory=/tmp").to("file://inbox");

Optimization by renaming work file

The route above is ultra efficient as it avoids reading the entire file content into memory. It will download the remote file directly to a local file stream. The java.io.File handle is then used as the Exchange body. The file producer leverages this fact and can work directly on the work file java.io.File handle and perform a java.io.File.rename to the target filename. As Fuse Mediation Router knows it's a local work file, it can optimize and use a rename instead of a file copy, as the work file is meant to be deleted anyway.

Camel FTP can operate in two modes in terms of traversing directories when consuming files (for example, downloading) or producing files (for example, uploading):

  • stepwise

  • not stepwise

You may want to pick either one depending on your situation and security issues. Some Camel end users can only download files if they use stepwise, while others can only download if they do not. At least you have the choice to pick.

Note that stepwise changing of directory will in most cases only work when the user is confined to it's home directory and when the home directory is reported as /.

The difference between the two of them is best illustrated with an example. Suppose we have the following directory structure on the remote FTP server we need to traverse and download files:

      /
      /one
      /one/two
      /one/two/sub-a
      /one/two/sub-b

And that we have a file in each of sub-a (a.txt) and sub-b (b.txt) folder.

The following log shows the conversation between the FTP endpoint and the remote FTP server when the FTP endpoint is operating in stepwise mode:

      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.
      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
      221 Goodbye
      disconnected.                                                 
      
    

As you can see when stepwise is enabled, it will traverse the directory structure using CD xxx.

The ANT path matcher is a filter that is shipped out-of-the-box in the camel-spring jar. So you need to depend on camel-spring if you are using Maven. The reason is that we leverage Spring's AntPathMatcher to do the actual matching.

The file paths are matched with the following rules:

  • ? matches one character

  • * matches zero or more characters

  • ** matches zero or more directories in a path

The sample below demonstrates how to use it:

<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:20123/antpath?password=admin&ecursive=true&elay=10000&nitialDelay=2000&ilter=#myAntFilter"/>

    <route>
        <from ref="myFTPEndpoint"/>
        <to uri="mock:result"/>
    </route>
</camelContext>

<!-- we use the AntPathMatcherRemoteFileFilter 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>

The Fuse Mediation Router components for Google App Engine (GAE) are part of the camel-gae project and provide connectivity to GAE's cloud computing services. They make the GAE cloud computing environment accessible to applications via Fuse Mediation Router interfaces. Following this pattern for other cloud computing environments could make it easier to port Fuse Mediation Router applications from one cloud computing provider to another. The following table lists the cloud computing services provided by Google App Engine and the supporting Fuse Mediation Router components. The documentation of each component can be found by following the link in the Camel Component column.

GAE service Camel component Component description
URL fetch service ghttp Provides connectivity to the GAE URL fetch service but can also be used to receive messages from servlets.
Task queueing service gtask Supports asynchronous message processing on GAE by using the task queueing service as message queue.
Mail service gmail Supports sending of emails via the GAE mail service. Receiving mails is not supported yet but will be added later.
Memcache service Not supported yet.
XMPP service Not supported yet.
Images service Not supported yet.
Datastore service Not supported yet.
Accounts service gauth glogin These components interact with the Google Accounts API for authentication and authorization. Google Accounts is not specific to Google App Engine but is often used by GAE applications for implementing security. The gauth component is used by web applications to implement a Google-specific OAuth consumer. This component can also be used to OAuth-enable non-GAE web applications. The glogin component is used by Java clients (outside GAE) for programmatic login to GAE applications. For instructions how to protect GAE applications against unauthorized access refer to the Security for Fuse Mediation Router GAE applications page.

Setting up a SpringCamelContext on Google App Engine differs between Camel 2.1 and higher versions. The problem is that usage of the Camel-specific Spring configuration XML schema from the http://camel.apache.org/schema/spring namespace requires JAXB and Camel 2.1 depends on a Google App Engine SDK version that doesn't support JAXB yet. This limitation has been removed since Camel 2.2.

JMX must be disabled in any case because the javax.management package isn't on the App Engine JRE whitelist.

With Camel 2.2 or higher, applications can use the http://camel.apache.org/schema/spring namespace for configuring a SpringCamelContext but still need to disable JMX. Here's an example.

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>

Running Fuse Mediation Router on GAE requires usage of the CamelHttpTransportServlet from camel-servlet. The following example shows how to configure this servlet together with a Spring application context XML file.

The location of the Spring application context XML file is given by the contextConfigLocation init parameter. The appctx.xml file must be on the classpath. The servlet mapping makes the Fuse Mediation Router application accessible under http://<appname>.appspot.com/camel/... when deployed to Google App Engine where <appname> must be replaced by a real GAE application name. The second servlet mapping is used internally by the task queueing service for background processing via web hooks. This mapping is relevant for the gtask component and is explained there in more detail.

Available in Fuse Mediation Router 2.3

The gauth component is used by web applications to implement a Google-specific OAuth consumer. It will be later extended to support other OAuth providers as well. Although this component belongs to the Camel Components for Google App Engine (GAE), it can also be used to OAuth-enable non-GAE web applications. For a detailed description of Google's OAuth implementation refer to the Google OAuth API reference.

Name Default Value Required Description
callback null true (can alternatively be set via GAuthAuthorizeBinding.GAUTH_CALLBACK message header) URL where to redirect the user after having granted or denied access.
scope null true (can alternatively be set via GAuthAuthorizeBinding.GAUTH_SCOPE message header) URL identifying the service(s) to be accessed. Scopes are defined by each Google service; see the service's documentation for the correct value. To specify more than one scope, list each one separated with a comma. Example: http://www.google.com/calendar/feeds/ .
consumerKey null true (can alternatively be set on component-level). Domain identifying the web application. This is the domain used when registering the application with Google. Example: camelcloud.appspot.com. For a non-registered application use anonymous.
consumerSecret null one of consumerSecret or keyLoaderRef is required (can alternatively be set on component-level). Consumer secret of the web application. The consumer secret is generated when when registering the application with Google. It is needed if the HMAC-SHA1 signature method shall be used. For a non-registered application use anonymous.
keyLoaderRef null one of consumerSecret or keyLoaderRef is required (can be alternatively set on component-level) Reference to a private key loader in the registry. Part of camel-gae are two key loaders: GAuthPk8Loader for loading a private key from a PKCS#8 file and GAuthJksLoader to load a private key from a Java key store. It is needed if the RSA-SHA1 signature method shall be used. These classes are defined in the org.apache.camel.component.gae.auth package.
authorizeBindingRef Reference to GAuthAuthorizeBinding false Reference to a OutboundBinding<GAuthEndpoint, GoogleOAuthParameters, GoogleOAuthParameters> in the registry for customizing how an Exchange is bound to GoogleOAuthParameters. This binding is used for teh authorization phase. Most applications won't change the default value.
upgradeBindingRef Reference to GAuthAuthorizeBinding false Reference to a OutboundBinding<GAuthEndpoint, GoogleOAuthParameters, GoogleOAuthParameters> in the registry. for customizing how an Exchange is bound to GoogleOAuthParameters. This binding is used for teh token upgrade phase. Most applications won't change the default value.
Name Type Endpoint Message Description
GAuthAuthorizeBinding.GAUTH_CALLBACK String gauth:authorize in Overrides the callback option.
GAuthAuthorizeBinding.GAUTH_SCOPE String gauth:authorize in Overrides the scope option.
GAuthUpgradeBinding.GAUTH_ACCESS_TOKEN String gauth:upgrade out Contains the long-lived access token. This token should be stored by the applications in context of a user.
GAuthUpgradeBinding.GAUTH_ACCESS_TOKEN_SECRET String gauth:upgrade out Contains the access token secret. This token secret should be stored by the applications in context of a user.

Some endpoint options such as consumerKey, consumerSecret or keyLoader are usually set to the same values on gauth:authorize and gauth:upgrade endpoints. The gauth component allows to configure them on component-level. These settings are then inherited by gauth endpoints and need not be set redundantly in the endpoint URIs. Here are some configuration examples.

Here's the minimum setup for adding OAuth to a (non-GAE) web application. In the following example, it is assumed that the web application is running on gauth.example.org.

import java.net.URLEncoder;
import org.apache.camel.builder.RouteBuilder;

public class GAuthRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        // Calback URL to redirect user from Google Authorization back to the web application
        String encodedCallback = URLEncoder.encode("https://gauth.example.org:8443/handler", "UTF-8");
        // Application will request for authorization to access a user's Google Calendar
        String encodedScope = URLEncoder.encode("http://www.google.com/calendar/feeds/", "UTF-8");

        // Route 1: A GET request to http://gauth.example.org/authorize will trigger the the OAuth
        // sequence of interactions. The gauth:authorize endpoint obtains an unauthorized request
        // token from Google and then redirects the user (browser) to a Google authorization page.
        from("jetty:http://0.0.0.0:8080/authorize")
            .to("gauth:authorize?callback=" + encodedCallback + "&scope=" + encodedScope);

        // Route 2: Handle callback from Google. After the user granted access to Google Calendar
        // Google redirects the user to https://gauth.example.org:8443/handler (see callback) along
        // with an authorized request token. The gauth:access endpoint exchanges the authorized
        // request token against a long-lived access token.
        from("jetty:https://0.0.0.0:8443/handler")
            .to("gauth:upgrade")
            // The access token can be obtained from
            // exchange.getOut().getHeader(GAuthUpgradeBinding.GAUTH_ACCESS_TOKEN)
            // The access token secret can be obtained from
            // exchange.getOut().getHeader(GAuthUpgradeBinding.GAUTH_ACCESS_TOKEN_SECRET)
            .process(/* store the tokens in context of the current user ... */);
    }

}

The OAuth sequence is triggered by sending a GET request to http://gauth.example.org/authorize . The user is then redirected to a Google authorization page. After having granted access on this page, Google redirects the user to the web application which handles the callback and finally obtains a long-lived access token from Google.

These two routes can perfectly co-exist with any other web application framework. The framework provides the basis for web application-specific functionality whereas the OAuth service provider integration is done with Fuse Mediation Router. The OAuth integration part could even use resources from an existing servlet container by using the servlet component instead of the jetty component.

What to do with the OAuth access token?

  • Application should store the access token in context of the current user. If the user logs in next time, the access token can directly be loaded from the database, for example, without doing the OAuth dance again.

  • The access token is then used to get access to Google services, such as a Google Calendar API, on behalf of the user. Java applications will most likely use the GData Java library for that. See below for an example how to use the access token with the GData Java library to read a user's calendar feed.

  • The user can revoke the access token at any time from his Google Accounts page. In this case, access to the corresponding Google service will throw an authorization exception. The web application should remove the stored access token and redirect the user again to the Google authorization page for creating another one.

The above example relies on the following component configuration.

<bean id="gauth" class="org.apache.camel.component.gae.auth.GAuthComponent">
    <property name="consumerKey" value="anonymous" />
    <property name="consumerSecret" value="anonymous" />
</bean>

If you don't want that Google displays a warning message on the authorization page, you'll need to register your web application and change the consumerKey and consumerSecret settings.

To OAuth-enable a Google App Engine application, only some small changes in the route builder are required. Assuming the GAE application hostname is camelcloud.appspot.com a configuration might look as follows. Here, the ghttp component is used to handle HTTP(S) requests instead of the jetty component.

GAuthRouteBuilder

import java.net.URLEncoder;
import org.apache.camel.builder.RouteBuilder;

public class TutorialRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        String encodedCallback = URLEncoder.encode("https://camelcloud.appspot.com/handler", "UTF-8");
        String encodedScope = URLEncoder.encode("http://www.google.com/calendar/feeds/", "UTF-8");

        from("ghttp:///authorize")
            .to("gauth:authorize?callback=" + encodedCallback + "&scope=" + encodedScope);

        from("ghttp:///handler")
            .to("gauth:upgrade")
            .process(/* store the tokens in context of the current user ... */);
    }

}

Here's an example how to use an access token to access a user's Google Calendar data with the GData Java library. The example application writes the titles of the user's public and private calendars to stdout.

Access token usage

import com.google.gdata.client.authn.oauth.OAuthHmacSha1Signer;
import com.google.gdata.client.authn.oauth.OAuthParameters;
import com.google.gdata.client.calendar.CalendarService;
import com.google.gdata.data.calendar.CalendarEntry;
import com.google.gdata.data.calendar.CalendarFeed;

import java.net.URL;

public class AccessExample {

    public static void main(String... args) throws Exception {
        String accessToken = ...
        String accessTokenSecret = ...

        CalendarService myService = new CalendarService("exampleCo-exampleApp-1.0");
        OAuthParameters params = new OAuthParameters();
        params.setOAuthConsumerKey("anonymous");
        params.setOAuthConsumerSecret("anonymous");
        params.setOAuthToken(accessToken);
        params.setOAuthTokenSecret(accessTokenSecret);
        myService.setOAuthCredentials(params, new OAuthHmacSha1Signer());

        URL feedUrl = new URL("http://www.google.com/calendar/feeds/default/");
        CalendarFeed resultFeed = myService.getFeed(feedUrl, CalendarFeed.class);

        System.out.println("Your calendars:");
        System.out.println();

        for (int i = 0; i < resultFeed.getEntries().size(); i++) {
            CalendarEntry entry = resultFeed.getEntries().get(i);
            System.out.println(entry.getTitle().getPlainText());
        }
    }
}

The ghttp component contributes to the Camel Components for Google App Engine (GAE). It provides connectivity to the GAE URL fetch service but can also be used to receive messages from servlets (the only way to receive HTTP requests on GAE). This is achieved by extending the Servlet component. As a consequence, ghttp URI formats and options sets differ on the consumer-side (from) and producer-side (to).

Format Context Comment
ghttp:///path[?options]
Consumer See also Servlet component
ghttp://hostname[:port][/path][?options]
ghttps://hostname[:port][/path][?options]
Producer See also Http component
Name Default Value Context Description
bridgeEndpoint true Producer If set to true the Exchange.HTTP_URI header will be ignored. To override the default endpoint URI with the Exchange.HTTP_URI header set this option to false.
throwExceptionOnFailure true Producer Throw a org.apache.camel.component.gae.http if the response code is >= 400. To disable throwing an exception set this option to false.
inboundBindingRef reference to GHttpBinding Consumer Reference to an InboundBinding<GHttpEndpoint, HttpServletRequest, HttpServletResponse> in the Registry for customizing the binding of an Exchange to the Servlet API. The referenced binding is used as post-processor to org.apache.camel.component.http.HttpBinding.
outboundBindingRef reference to GHttpBinding Producer Reference to an OutboundBinding<GHttpEndpoint, HTTPRequest, HTTPResponse> in the Registry for customizing the binding of an Exchange to the URLFetchService.

On the consumer-side, all options of the Servlet component are supported.

On the producer side, the following headers of the Http component are supported.

Name Type Description
Exchange.CONTENT_TYPE String The HTTP content type. Is set on both the in and out message to provide a content type, such as text/html.
Exchange.CONTENT_ENCODING String The HTTP content encoding. Is set on both the in and out message to provide a content encoding, such as gzip.
Exchange.HTTP_METHOD String The HTTP method to execute. One of GET, POST, PUT and DELETE. If not set, POST will be used if the message body is not null, GET otherwise.
Exchange.HTTP_QUERY String Overrides the query part of the endpoint URI or the the query part of Exchange.HTTP_URI (if defined). The query string must be in decoded form.
Exchange.HTTP_URI String Overrides the default endpoint URI if the bridgeEndpoint option is set to false. The URI string must be in decoded form.
Exchange.RESPONSE_CODE int The HTTP response code from URL fetch service responses.

On the consumer-side all headers of the Servlet component component are supported.

For sending resquests to external HTTP services the ghttp component uses the URL fetch service. For example, the Fuse Mediation Router homepage can the retrieved with the following endpoint definition on the producer-side.

from(...)
...
.to("ghttp://camel.apache.org")
...

The HTTP method used depends on the Exchange.HTTP_METHOD message header or on the presence of an in-message body (GET if null, POST otherwise). Retrieving the Camel homepage via a GAE application is as simple as

from("ghttp:///home")
.to("ghttp://camel.apache.org")

Sending a GET request to http://<appname>.appspot.com/camel/home returns the Camel homepage. HTTPS-based communication with external services can be enabled with the ghttps scheme.

from(...)
...
.to("ghttps://svn.apache.org/repos/asf/camel/trunk/")
...

Available in Fuse Mediation Router 2.3 (or latest development snapshot).

The glogin component is used by Fuse Mediation Router applications outside Google App Engine (GAE) for programmatic login to GAE applications. It is part of the Fuse Mediation Router Components for Google App Engine. Security-enabled GAE applications normally redirect the user to a login page. After submitting username and password for authentication, the user is redirected back to the application. That works fine for applications where the client is a browser. For all other applications, the login process must be done programmatically. All the necessary steps for programmatic login are implemented by the glogin component. These are

  1. Get an authentication token from Google Accounts via the ClientLogin API.

  2. Get an authorization cookie from Google App Engine's login API.

The authorization cookie must then be send with subsequent HTTP requests to the GAE application. It expires after 24 hours and must then be renewed.

glogin://hostname[:port][?options]

The hostname is either the internet hostname of a GAE application (e.g. camelcloud.appspot.com) or the name of the host where the development server is running (e.g. localhost). The port is only used when connecting to a development server (i.e. when devMode=true, see options) and defaults to 8080.

Name Default Value Required Description
clientName apache-camel-2.x false A client name with recommended (but not required) format <organization>\-<appname>\-<version>.
userName null true (can alternatively be set via GLoginBinding.GLOGIN_USER_NAME message header) Login username (an email address).
password null true (can alternatively be set via GLoginBinding.GLOGIN_PASSWORD message header) Login password.
devMode false false If set to true a login to a development server is attempted.
devAdmin false false If set to true a login to a development server in admin role is attempted.
Name Type Message Description
GLoginBinding.GLOGIN_HOST_NAME String in Overrides the hostname defined in the endpoint URI.
GLoginBinding.GLOGIN_USER_NAME String in Overrides the userName option.
GLoginBinding.GLOGIN_PASSWORD String in Overrides the password option.
GLoginBinding.GLOGIN_TOKEN String out Contains the authentication token obtained from Google Accounts. Login to a development server does not set this header.
GLoginBinding.GLOGIN_COOKIE String out Contains the application-specific authorization cookie obtained from Google App Engine (or a development server).

The following JUnit test show an example how to login to a development server as well as to a deployed GAE application located at http://camelcloud.appspot.com.

GLoginTest.java

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.ProducerTemplate;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.apache.camel.component.gae.login.GLoginBinding.*;
import static org.junit.Assert.*;

public class GLoginTest {

    private ProducerTemplate template = ...

    @Test
    public void testDevLogin() {
        Exchange result = template.request("glogin://localhost:8888?userName=test@example.org&devMode=true", null);
        assertNotNull(result.getOut().getHeader(GLOGIN_COOKIE));
    }

    @Test
    public void testRemoteLogin() {
        Exchange result = template.request("glogin://camelcloud.appspot.com", new Processor() {
            public void process(Exchange exchange) throws Exception {
                exchange.getIn().setHeader(GLOGIN_USER_NAME, "replaceme@gmail.com");
                exchange.getIn().setHeader(GLOGIN_PASSWORD, "replaceme");
            }
        });
        assertNotNull(result.getOut().getHeader(GLOGIN_COOKIE));
    }

}

The resulting authorization cookie from login to a development server looks like

ahlogincookie=test@example.org:false:11223191102230730701;Path=/

The resulting authorization cookie from login to a deployed GAE application looks (shortened) like

ACSID=AJKiYcE...XxhH9P_jR_V3; expires=Sun, 07-Feb-2010 15:14:51 GMT; path=/

The gmail component contributes to the Camel Components for Google App Engine (GAE). It supports sending of emails via the GAE mail service. Receiving mails is not supported yet but will be added later. Currently, only Google accounts that are application administrators can send emails.

Name Default Value Context Description
to null Producer To-receiver of the email. This can be a single receiver or a comma-separated list of receivers.
cc null Producer Cc-receiver of the email. This can be a single receiver or a comma-separated list of receivers.
bcc null Producer Bcc-receiver of the email. This can be a single receiver or a comma-separated list of receivers.
subject null Producer Subject of the email.
outboundBindingRef reference to GMailBinding Producer Reference to an OutboundBinding<GMailEndpoint, MailService.Message, void> in the Registry for customizing the binding of an Exchange to the mail service.
Name Type Context Description
GMailBinding.GMAIL_SUBJECT String Producer Subject of the email. Overrides subject endpoint option.
GMailBinding.GMAIL_SENDER String Producer Sender of the email. Overrides sender definition in endpoint URI.
GMailBinding.GMAIL_TO String Producer To-receiver(s) of the email. Overrides to endpoint option.
GMailBinding.GMAIL_CC String Producer Cc-receiver(s) of the email. Overrides cc endpoint option.
GMailBinding.GMAIL_BCC String Producer Bcc-receiver(s) of the email. Overrides bcc endpoint option.

Securing GAE applications from unauthorized access is described in the Security and Authentication section of the Google App Engine documentation. Authorization constraints are declared in the web.xml. This applies to Fuse Mediation Router applications as well. In the following example, the application is configured to only allow authenticated users (in any role) to access the application. Additionally, access to /worker/\* URLs masy only be done by users in the admin role. By default, web hook URLs installed by the gtask component match the /worker/\* pattern and should not be accessed by normal users. With this authorization constraint, only the task queuing service (which is always in the admin role) is allowed to access the web hooks. For implementing custom, non-declarative authorization logic, Fuse Mediation Router GAE applications should use the Google Accounts Java API.

Example 34.1. web.xml with authorization constraint

<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>

    <!--
        By default allow any user who is logged in to access the whole 
        application.
     -->
    <security-constraint>
        <web-resource-collection>
            <url-pattern>/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name>
        </auth-constraint>
    </security-constraint>

    <!--
        Allow only admin users to access /worker/* URLs e.g. to prevent
        normal user to access gtask web hooks.
     -->
    <security-constraint>
        <web-resource-collection>
            <url-pattern>/worker/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>admin</role-name>
        </auth-constraint>
    </security-constraint>

</web-app>

The gtask component contributes to the Camel Components for Google App Engine (GAE). It supports asynchronous message processing on GAE by using the task queueing service as message queue. For adding messages to a queue it uses the task queue API. For receiving messages from a queue it installs an HTTP callback handler. The handler is called by an HTTP POST callback (a web hook) initiated by the task queueing service. Whenever a new task is added to a queue a callback will be sent. The gtask component abstracts from these details and supports endpoint URIs that make message queueing on GAE as easy as message queueing with JMS or SEDA.

Name Default Value Context Description
workerRoot worker Producer The servlet mapping for callback handlers. By default, this component requires a callback servlet mapping of /worker/*. If another servlet mapping is used e.g. /myworker/* it must be set as option on the producer side: to("gtask:myqueue?workerRoot=myworker").
inboundBindingRef reference to GTaskBinding Consumer Reference to an InboundBinding<GTaskEndpoint, HttpServletRequest, HttpServletResponse> in the Registry for customizing the binding of an Exchange to the Servlet API. The referenced binding is used as post-processor to org.apache.camel.component.http.HttpBinding.
outboundBindingRef reference to GTaskBinding Producer Reference to an OutboundBinding<GTaskEndpoint, TaskOptions, void> in the Registry for customizing the binding of an Exchange to the task queueing service.

On the consumer-side, all options of the Servlet component are supported.

On the consumer-side all headers of the Servlet component component are supported plus the following.

Name Type Context Description
GTaskBinding.GTASK_QUEUE_NAME String Consumer Name of the task queue.
GTaskBinding.GTASK_TASK_NAME String Consumer Name of the task (generated value).
GTaskBinding.GTASK_RETRY_COUNT int Consumer Number of callback retries.

Available as of Fuse Mediation Router 2.3

HawtDB is a very lightweight and embedable key value database. It allows together with Fuse Mediation Router to provide persistent support for various Fuse Mediation Router features such as Aggregator.

Current features it provides:

  • HawtDBAggregationRepository

HawtDBAggregationRepository is an AggregationRepository which on the fly persists the aggregated messages. This ensures that you will not loose messages, as the default aggregator will use an in memory only AggregationRepository.

It has the following options:

Option Type Description
repositoryName String A mandatory repository name. Allows you to use a shared HawtDBFile for multiple repositories.
persistentFileName String Filename for the persistent storage. If no file exists on startup a new file is created.
bufferSize int The size of the memory segment buffer which is mapped to the file store. By default its 8mb. The value is in bytes.
sync boolean Whether or not the HawtDBFile should sync on write or not. Default is true. By sync on write ensures that its always waiting for all writes to be spooled to disk and thus will not loose updates. If you disable this option, then HawtDB will auto sync when it has batched up a number of writes.
pageSize short The size of memory pages. By default its 512 bytes. The value is in bytes.
hawtDBFile HawtDBFile Use an existing configured org.apache.camel.component.hawtdb.HawtDBFile instance.
returnOldExchange boolean Whether the get operation should return the old existing Exchange if any existed. By default this option is false to optimize as we do not need the old exchange when aggregating.
useRecovery boolean Whether or not recovery is enabled. This option is by default true. When enabled the Fuse Mediation Router Aggregator automatic recover failed aggregated exchange and have them resubmitted.
recoveryInterval long If recovery is enabled then a background task is run every x'th time to scan for failed exchanges to recover and resubmit. By default this interval is 5000 millis.
maximumRedeliveries int Allows you to limit the maximum number of redelivery attempts for a recovered exchange. If enabled then the Exchange will be moved to the dead letter channel if all redelivery attempts failed. By default this option is disabled. If this option is used then the deadLetterUri option must also be provided.
deadLetterUri String An endpoint uri for a Dead Letter Channel where exhausted recovered Exchanges will be moved. If this option is used then the maximumRedeliveries option must also be provided.

The repositoryName option must be provided. Then either the persistentFileName or the hawtDBFile must be provided.

The HawtDBAggregationRepository will by default recover any failed Exchange. It does this by having a background tasks that scans for failed Exchanges in the persistent store. You can use the checkInterval option to set how often this task runs. The recovery works as transactional which ensures that Fuse Mediation Router will try to recover and redeliver the failed Exchange. Any Exchange which was found to be recovered will be restored from the persistent store and resubmitted and send out again.

The following headers is set when an Exchange is being recovered/redelivered:

Header Type Description
Exchange.REDELIVERED Boolean Is set to true to indicate the Exchange is being redelivered.
Exchange.REDELIVERY_COUNTER Integer The redelivery attempt, starting from 1.

Only when an Exchange has been successfully processed it will be marked as complete which happens when the confirm method is invoked on the AggregationRepository. This means if the same Exchange fails again it will be kept retried until it success.

You can use option maximumRedeliveries to limit the maximum number of redelivery attempts for a given recovered Exchange. You must also set the deadLetterUri option so Fuse Mediation Router knows where to send the Exchange when the maximumRedeliveries was hit.

You can see some examples in the unit tests of camel-hawtdb, for example this test.

To use HawtDB in your Fuse Mediation Router routes you need to add the a dependency on camel-hawtdb.

If you use maven you could just add the following to your pom.xml, substituting the version number for the latest & greatest release (see the download page for the latest versions).

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-hawtdb</artifactId>
  <version>2.3.0</version>
</dependency>

See Also:

Available as of Fuse Mediation Router 2.7

The hazelcast: component allows you to work with the Hazelcast distributed data grid / cache. Hazelcast is a in memory data grid, entirely written in Java (single jar). It offers a great palette of different data stores like map, multi map (same key, n values), queue, list and atomic number. The main reason to use Hazelcast is its simple cluster support. If you have enabled multicast on your network you can run a cluster with hundred nodes with no extra configuration. Hazelcast can simply configured to add additional features like n copies between nodes (default is 1), cache persistence, network configuration (if needed), near cache, enviction and so on. For more information consult the Hazelcast documentation on http://www.hazelcast.com/documentation.jsp .

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

If you want to store a value in a map you can use the map cache producer. The map cache producer provides 5 operations (put, get, update, delete, query). For the first 4 you have to provide the operation inside the "hazelcast.operation.type" header variable. In Java DSL you can use the constants from org.apache.camel.component.hazelcast.HazelcastConstants.

Header Variables for the request message:

Name Type Description
hazelcast.operation.type String valid values are: put, delete, get, update, query
hazelcast.objectId String the object id to store / find your object inside the cache (not needed for the query operation)
Name Type Description
CamelHazelcastOperationType String valid values are: put, delete, get, update, query Version 2.8
CamelHazelcastObjectId String the object id to store / find your object inside the cache (not needed for the query operation) Version 2.8

You can call the samples with:

template.sendBodyAndHeader("direct:[put|get|update|delete|query]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");

Hazelcast provides event listeners on their data grid. If you want to be notified if a cache will be manipulated, you can use the map consumer. There're 4 events: put, update, delete and envict. The event type will be stored in the "hazelcast.listener.action" header variable. The map consumer provides some additional information inside these variables:

Header Variables inside the response message:

Name Type Description
hazelcast.listener.time Long time of the event in millis
hazelcast.listener.type String the map consumer sets here "cachelistener"
hazelcast.listener.action String type of event - here added, updated, envicted and removed
hazelcast.objectId String the oid of the object
hazelcast.cache.name String the name of the cache - e.g. "foo"
hazelcast.cache.type String the type of the cache - here map
Name Type Description
CamelHazelcastListenerTime Long time of the event in millis Version 2.8
CamelHazelcastListenerType String the map consumer sets here "cachelistener" Version 2.8
CamelHazelcastListenerAction String type of event - here added, updated, envicted and removed. Version 2.8
CamelHazelcastObjectId String the oid of the object Version 2.8
CamelHazelcastCacheName String the name of the cache - e.g. "foo" Version 2.8
CamelHazelcastCacheType String the type of the cache - here map Version 2.8

The object value will be stored within put and update actions inside the message body.

Here's a sample:

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!");

A multimap is a cache where you can store n values to one key. The multimap producer provides 4 operations (put, get, removevalue, delete).

Header Variables for the request message:

Name Type Description
hazelcast.operation.type String valid values are: put, get, removevalue, delete
hazelcast.objectId String the object id to store / find your object inside the cache

Header Variables for the request message in Fuse Mediation Router 2.8:

Name Type Description
CamelHazelcastOperationType String valid values are: put, delete, get, update, query Available as of Fuse Mediation Router 2.8
CamelHazelcastObjectId String the object id to store / find your object inside the cache (not needed for the query operation) Version 2.8

You can call the samples with:

template.sendBodyAndHeader("direct:[put|get|update|delete|query]", "my-foo", HazelcastConstants.OBJECT_ID, "4711");

Hazelcast provides event listeners on their data grid. If you want to be notified if a cache will be manipulated, you can use the map consumer. There're 4 events: put, update, delete and envict. The event type will be stored in the "hazelcast.listener.action" header variable. The map consumer provides some additional information inside these variables:

Header Variables inside the response message:

Name Type Description
hazelcast.listener.time Long time of the event in millis
hazelcast.listener.type String the map consumer sets here "cachelistener"
hazelcast.listener.action String type of event - here added, updated, envicted and removed
hazelcast.objectId String the oid of the object
hazelcast.cache.name String the name of the cache - e.g. "foo"
hazelcast.cache.type String the type of the cache - here map
Name Type Description
CamelHazelcastListenerTime Long time of the event in millis Version 2.8
CamelHazelcastListenerType String the map consumer sets here "cachelistener" Version 2.8
CamelHazelcastListenerAction String type of event - here added, updated, envicted and removed. Version 2.8
CamelHazelcastObjectId String the oid of the object Version 2.8
CamelHazelcastCacheName String the name of the cache - e.g. "foo" Version 2.8
CamelHazelcastCacheType String the type of the cache - here map Version 2.8

The object value will be stored within put and update actions inside the message body.

Here's a sample:

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!");

A multimap is a cache where you can store n values to one key. The multimap producer provides 4 operations (put, get, removevalue, delete).

Header Variables for the request message:

Name Type Description
hazelcast.operation.type String valid values are: put, get, removevalue, delete
hazelcast.objectId String the object id to store / find your object inside the cache
Name Type Description
CamelHazelcastOperationType String valid values are: put, get, removevalue, delete Version 2.8
CamelHazelcastObjectId String the object id to store / find your object inside the cache Version 2.8

For the multimap cache this component provides the same listeners / variables as for the map cache consumer (except the update and enviction listener). The only difference is the multimap prefix inside the URI. Here is a sample:

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!");

Header Variables inside the response message:

Name Type Description
hazelcast.listener.time Long time of the event in millis
hazelcast.listener.type String the map consumer sets here "cachelistener"
hazelcast.listener.action String type of event - here added and removed (and soon envicted)
hazelcast.objectId String the oid of the object
hazelcast.cache.name String the name of the cache - e.g. "foo"
hazelcast.cache.type String the type of the cache - here multimap

Eviction will be added as feature, soon (this is a Hazelcast issue).

Name Type Description
CamelHazelcastListenerTime Long time of the event in millis Version 2.8
CamelHazelcastListenerType String the map consumer sets here "cachelistener" Version 2.8
CamelHazelcastListenerAction String type of event - here added and removed (and soon envicted) Version 2.8
CamelHazelcastObjectId String the oid of the object Version 2.8
CamelHazelcastCacheName String the name of the cache - e.g. "foo" Version 2.8
CamelHazelcastCacheType String the type of the cache - here multimap Version 2.8

The SEDA producer provides no operations. You only send data to the specified queue.

Name default value Description
transferExchange false Fuse Mediation Router 2.8.0: if set to true the whole Exchange will be transfered. If header or body contains not serializable objects, they will be skipped.

Java DSL :

from("direct:foo")
.to("hazelcast:seda:foo");

Spring DSL :

<route>
   <from uri="direct:start" />
   <to uri="hazelcast:seda:foo" />
</route>

An atomic number is an object that simply provides a grid wide number (long). The operations for this producer are setvalue (set the number with a given value), get, increase (+1), decrease (-1) and destroy.

Header Variables for the request message:

Name Type Description
hazelcast.operation.type String valid values are: setvalue, get, increase, decrease, destroy
Name Type Description
CamelHazelcastOperationType String valid values are: setvalue, get, increase, decrease, destroy Available as of Fuse Mediation Router version 2.8

Hazelcast makes sense in one single "server node", but it's extremly powerful in a clustered environment. The instance consumer fires if a new cache instance will join or leave the cluster.

Here's a sample:

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");

Each event provides the following information inside the message header:

Header Variables inside the response message:

Name Type Description
hazelcast.listener.time Long time of the event in millis
hazelcast.listener.type String the map consumer sets here "instancelistener"
hazelcast.listener.action String type of event - here added or removed
hazelcast.instance.host String host name of the instance
hazelcast.instance.port Integer port number of the instance
Name Type Description
CamelHazelcastListenerTime Long time of the event in millis Version 2.8
CamelHazelcastListenerType String the map consumer sets here "instancelistener" Version 2.8
CamelHazelcastListenerActionn String type of event - here added or removed. Version 2.8
CamelHazelcastInstanceHost String host name of the instance Version 2.8
CamelHazelcastInstancePort Integer port number of the instance Version 2.8
Name Default Value Description
overwrite true The file can be overwritten
bufferSize 4096 The buffer size used by HDFS
replication 3 The HDFS replication factor
blockSize 67108864 The size of the HDFS blocks
fileType NORMAL_FILE

It can be SEQUENCE_FILE, MAP_FILE, ARRAY_FILE, or BLOOMMAP_FILE, see Hadoop

fileSystemType HDFS It can be LOCAL for local filesystem
keyType NULL

The type for the key in case of sequence or map files. See below.

valueType TEXT

The type for the key in case of sequence or map files. See below.

splitStrategy

A string describing the strategy on how to split the file based on different criteria. See below.

openedSuffix opened

When a file is opened for reading/ writing the file is renamed with this suffix to avoid to read it during the writing phase.

readSuffix read

Once the file has been read is renamed with this suffix to avoid to read it again.

initialDelay 0

For the consumer, how much to wait (milliseconds) before to start scanning the directory.

delay 0

The interval (milliseconds) between the directory scans.

pattern *

The pattern used for scanning the directory

chunkSize 4096

When reading a normal file, this is split into chunks producing a message per chunk

The hibernate: component allows you to work with databases using Hibernate as the object relational mapping technology to map POJOs to database tables. The camel-hibernate library is provided by the Camel Extra project which hosts all GPL related components for Fuse Mediation Router.

Important

Note that Camel also ships with a JPA component. The JPA component abstracts from the underlying persistence provider and allows you to work with Hibernate, OpenJPA or EclipseLink.

hibernate:[entityClassName][?options]

For sending to the endpoint, the entityClassName is optional. If specified it is used to help use the Type Conversion to ensure the body is of the correct type.

For consuming, the entityClassName is mandatory.

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default Value Description
entityType entityClassName Is the provided entityClassName from the URI.
consumeDelete true Option for HibernateConsumer only. Specifies whether or not the entity is deleted after it is consumed.
consumeLockEntity true Option for HibernateConsumer only. Specifies whether or not to use exclusive locking of each entity while processing the results from the pooling.
flushOnSend true Option for HibernateProducer only. Flushes the EntityManager after the entity bean has been persisted.
maximumResults -1 Option for HibernateConsumer only. Set the maximum number of results to retrieve on the Query.
consumer.delay 500 Option for HibernateConsumer only. Delay in millis between each poll.
consumer.initialDelay 1000 Option for HibernateConsumer only. Millis before polling starts.
consumer.userFixedDelay false Option for HibernateConsumer only. Set to true to use fixed delay between polls, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.

The hl7 component is used for working with the HL7 MLLP protocol and the HL7 model using the HAPI library.

This component supports the following:

  • HL7 MLLP codec for Mina.

  • Agnostic data format using either plain String objects or HAPI HL7 model objects.

  • Type Converter from/to HAPI and String.

  • HL7 DataFormat using HAPI library.

  • Even more easy-of-use as it is integrated well with the camel-mina component.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

HL7 is often used with the HL7 MLLP protocol that is a text based TCP socket based protocol. This component ships with a Mina Codec that conforms to the MLLP protocol so you can easily expose a HL7 listener that accepts HL7 requests over the TCP transport.

To expose a HL7 listener service we reuse the existing camel-mina component where we just use the HL7MLLPCodec as codec.

The HL7 MLLP codec has the following options:

Name Default Value Description
startByte 0x0b The start byte spanning the HL7 payload. Is the HL7 default value of 0x0b (11 decimal).
endByte1 0x1c The first end byte spanning the HL7 payload. Is the HL7 default value of 0x1c (28 decimal).
endByte2 0x0d The 2nd end byte spanning the HL7 payload. Is the HL7 default value of 0x0d (13 decimal).
charset JVM Default The encoding (is a charset name) to use for the codec. If not provided, Fuse Mediation Router will use the JVM default Charset.
convertLFtoCR true Will convert \n to \r (0x0d, 13 decimal) as HL7 usually uses \r as segment terminators. The HAPI library requires the use of \r.
validate true Fuse Mediation Router 2.0: Whether HAPI Parser should validate or not.

In our Spring XML file, we configure an endpoint to listen for HL7 requests using TCP:

        <endpoint id="hl7listener" uri="mina:tcp://localhost:8888?sync=true&codec=#hl7codec"/>

Notice we configure it to use camel-mina with TCP on the localhost on port 8888. We use sync=true to indicate that this listener is synchronous and therefore will return a HL7 response to the caller. Then we set up mina to use our HL7 codec with codec=#hl7codec. Notice that hl7codec is just a Spring bean ID, so we could have named it mygreatcodecforhl7 or whatever. The codec can also be set up in the Spring XML file:

    <bean id="hl7codec" class="org.apache.camel.component.hl7.HL7MLLPCodec">
        <property name="charset" value="iso-8859-1"/>
    </bean>

And here we configure the charset encoding to use, and iso-8859-1 is commonly used.

The endpoint hl7listener can then be used in a route as a consumer, as this java DSL example illustrates:

    from("hl7listener").to("patientLookupService");

This is a very simple route that will listen for HL7 and route it to a service named patientLookupService that is also a Spring bean ID we have configured in the Spring XML as:

    <bean id="patientLookupService" class="com.mycompany.healtcare.service.PatientLookupService"/>

And another powerful feature of Fuse Mediation Router is that we can have our busines logic in POJO classes that are not at all tied to Fuse Mediation Router as shown here:

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
    }

Notice that this class is just using imports from the HAPI library and none from Fuse Mediation Router.

The HL7MLLP codec uses plain String as data format. And Fuse Mediation Router uses Type Converter to convert from/to strings to the HAPI HL7 model objects. However, you can use the plain String objects if you prefer, for instance if you need to parse the data yourself.

See samples for such an example.

Key MSH field Example
hl7.msh.sendingApplication MSH-3 MYSERVER
hl7.msh.sendingFacility MSH-4 MYSERVERAPP
hl7.msh.receivingApplication MSH-5 MYCLIENT
hl7.msh.receivingFacility MSH-6 MYCLIENTAPP
hl7.msh.timestamp MSH-7 20071231235900
hl7.msh.security MSH-8 null
hl7.msh.messageType MSH-9-1 ADT
hl7.msh.triggerEvent MSH-9-2 A01
hl7.msh.messageControl MSH-10 1234
hl7.msh.processingId MSH-11 P
hl7.msh.versionId MSH-12 2.4

Key MSH field Example
CamelHL7SendingApplication MSH-3 MYSERVER
CamelHL7SendingFacility MSH-4 MYSERVERAPP
CamelHL7ReceivingApplication MSH-5 MYCLIENT
CamelHL7ReceivingFacility MSH-6 MYCLIENTAPP
CamelHL7Timestamp MSH-7 20071231235900
CamelHL7Security MSH-8 null
CamelHL7MessageType MSH-9-1 ADT
CamelHL7TriggerEvent MSH-9-2 A01
CamelHL7MessageControl MSH-10 1234
CamelHL7ProcessingId MSH-11 P
CamelHL7VersionId MSH-12 2.4

All headers are String types. If a header value is missing, its value is null.

The HL7 Data Format supports the following options:

Option Default Description
validate true Camel 2.0: Whether the HAPI Parser should validate.

To use HL7 in your camel routes you need to add a dependency on camel-hl7, which implements this data format.

If you use Maven, you could just add the following to your pom.xml, substituting the version number for the latest & greatest release (see the download page for the latest versions).

<dependency>
  <groupId>org.apache.camel</groupId>
  <artifactId>camel-hl7</artifactId>
  <version>2.2.0</version>
</dependency>

Since HAPI 0.6, the library has been split into a base library and several structures libraries, one for each HL7v2 message version:

By default camel-hl7 only references the HAPI base library. Applications are responsible for including structures libraries themselves. For example, if a application works with HL7v2 message versions 2.4 and 2.5 then the following dependencies must be added:

<dependency>
    <groupId>ca.uhn.hapi</groupId>
    <artifactId>hapi-structures-v24</artifactId>
    <version>1.0</version>
</dependency>
<dependency>
    <groupId>ca.uhn.hapi</groupId>
    <artifactId>hapi-structures-v25</artifactId>
    <version>1.0</version>
</dependency>

An OSGi bundle containing the base library, all structures libraries and required dependencies (on the bundle classpath) can be downloaded from the HAPI Maven repository as well.

<dependency>
    <groupId>ca.uhn.hapi</groupId>
    <artifactId>hapi-osgi-base</artifactId>
    <version>1.0.1</version>
</dependency>

In the following example we send a HL7 request to a HL7 listener and retrieves a response. We use plain String types in this example:

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("mina:tcp://127.0.0.1:8888?sync=true&codec=#hl7codec", in.toString());

In the next sample, we want to route HL7 requests from our HL7 listener to our business logic. We have our business logic in a plain POJO that we have registered in the registry as hl7service = for instance using Spring and letting the bean id = hl7service.

Our business logic is a plain POJO only using the HAPI library so we have these operations defined:

public class MyHL7BusinessLogic {

    // This is a plain POJO that has NO imports whatsoever on Fuse Mediation Router.
    // 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();
    }
}

Then we set up the Fuse Mediation Router routes using the RouteBuilder as follows:

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
from("mina: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()
    // marhsal response back
    .marshal(hl7);

Notice that we use the HL7 DataFormat to enrich our Camel Message with the MSH fields preconfigued on the Camel Message. This lets us much more easily define our routes using the fluent builders. If we do not use the HL7 DataFormat, then we do not gains these headers and we must resort to a different technique for computing the MSH trigger event (= what kind of HL7 message it is). This is a big advantage of the HL7 DataFormat over the plain HL7 type converters.

The http: component provides HTTP based endpoints for consuming external HTTP resources (as a client to call external servers using HTTP).

Name Default Value Description
throwExceptionOnFailure true Fuse Mediation Router 2.0: Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardles of the HTTP status code.
bridgeEndpoint false

Camel 2.1: If the option is true , HttpProducer will ignore the Exchange.HTTP_URI header, and use the endpoint's URI for request. You may also set the throwExcpetionOnFailure to be false to let the HttpProducer send all the fault response back. Camel 2.3: If the option is true, HttpProducer and CamelServlet will skip the gzip processing if the content-encoding is "gzip".

disableStreamCache false Camel 2.3: DefaultHttpBinding will copy the request input stream into a stream cache and put it into message body if this option is false to support read it twice, otherwise DefaultHttpBinding will set the request input stream direct into the message body.
httpBindingRef null Reference to a org.apache.camel.component.http.HttpBinding in the Registry.
httpBinding null Camel 2.3: Reference to a org.apache.camel.component.http.HttpBinding in the Registry.
httpClientConfigurerRef null Reference to a org.apache.camel.component.http.HttpClientConfigurer in the Registry. From Camel 2.3 onwards prefer to use the httpClientConfigurer option.
httpClientConfigurer null Camel 2.3: Reference to a org.apache.camel.component.http.HttpClientConfigurer in the Registry.
httpClient.XXX null Setting options on the HttpClientParams. For instance httpClient.soTimeout=5000 will set the SO_TIMEOUT to 5 seconds.
clientConnectionManager null Camel 2.3: To use a custom org.apache.http.conn.ClientConnectionManager.
transferException false Camel 2.6: If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or Servlet Camel components). On the producer side the exception will be deserialized and thrown as is, instead of the HttpOperationFailedException. The caused exception is required to be serialized.

The following authentication options can also be set on the HttpEndpoint:

Name Default Value Description
authMethod null Authentication method, either as Basic, Digest or NTLM.
authMethodPriority null Priority of authentication methods. Is a list separated with comma. For example: Basic,Digest to exclude NTLM.
authUsername null Username for authentication
authPassword null Password for authentication
authDomain null Domain for NTML authentication
authHost null Optional host for NTML authentication
proxyHost null The proxy host name
proxyPort null The proxy port number
proxyAuthMethod null Authentication method for proxy, either as Basic, Digest or NTLM.
proxyAuthUsername null Username for proxy authentication
proxyAuthPassword null Password for proxy authentication
proxyAuthDomain null Domain for proxy NTML authentication
proxyAuthHost null Optional host for proxy NTML authentication

When using authentication you must provide the choice of method for the authMethod or authProxyMethod options. You can configure the proxy and authentication details on either the HttpComponent or the HttpEndoint. Values provided on the HttpEndpoint will take precedence over HttpComponent. Its most likely best to configure this on the HttpComponent which allows you to do this once.

The Http component uses convention over configuration which means that if you have not explicit set a authMethodPriority then it will fallback and use the select(ed) authMethod as priority as well. So if you use authMethod.Basic then the auhtMethodPriority will be Basic only.

The following Exchange properties are recognized by HTTP endpoints:

Name Type Description
Exchange.HTTP_URI String URI to call. Will override existing URI set directly on the endpoint.
Exchange.HTTP_PATH String Request URI's path, the header will be used to build the request URI with the HTTP_URI. Camel 2.3.0: If the path is start with "/", http producer will try to find the relative path based on the Exchange.HTTP_BASE_URI header or the exchange.getFromEndpoint().getEndpointUri();
Exchange.HTTP_QUERY String URI parameters. Will override existing URI parameters set directly on the endpoint.
Exchange.HTTP_RESPONSE_CODE int The HTTP response code from the external server. Is 200 for OK.
Exchange.HTTP_CHARACTER_ENCODING String Character encoding.
Exchange.CONTENT_TYPE String The HTTP content type. Is set on both the IN and OUT message to provide a content type, such as text/html.
Exchange.CONTENT_ENCODING String The HTTP content encoding. Is set on both the IN and OUT message to provide a content encoding, such as gzip.
Exchange.HTTP_SERVLET_REQUEST HttpServletRequest Fuse Mediation Router 2.3: The HttpServletRequest object.
Exchange.HTTP_SERVLET_RESPONSE HttpServletResponse Fuse Mediation Router 2.3: The HttpServletResponse object.
Exchange.HTTP_PROTOCOL_VERSION String Camel 2.5: You can set the http protocol version with this header, eg. "HTTP/1.0". If you didn't specify the header, HttpProducer will use the default value "HTTP/1.1"

Only for >= Fuse Mediation Router 1.6.2 The HTTP component will detect Java System Properties for http.proxyHost and http.proxyPort and use them if provided. See more at SUN http proxy documentation.

To avoid the System properties conflicts, from Fuse Mediation Router 2.2.0 you can only set the proxy configure from CameContext or URI. Java DSL :

 context.getProperties().put("http.proxyHost", "172.168.18.9");
 context.getProperties().put("http.proxyPort" "8080");

Spring XML

   <camelContext>
       <properties>
           <property key="http.proxyHost" value="172.168.18.9"/>
           <property key="http.proxyPort" value="8080"/>
      </properties>
   </camelContext>

Fuse Mediation Router will first set the settings from Java System or CamelContext Properties and then the endpoint proxy options if provided. So you can override the system properties with the endpoint options.

Available as of Fuse Mediation Router 2.0 In the route below we want to route a message that we enrich with data returned from a remote HTTP call. As we want any response from the remote server, we set the throwExceptionOnFailure option to false so we get any response in the AggregationStrategy. As the code is based on a unit test that simulates a HTTP status code 404, there is some assertion code etc.

// We set throwExceptionOnFailure to false to let Fuse Mediation Router 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:8222/myserver?throwExceptionOnFailure=false&user=Camel", 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:8222/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);
            }
        });

The Http Component has a org.apache.commons.httpclient.HttpConnectionManager where you can configure various global configuration for the given component. By global, we mean that any endpoint the component creates has the same shared HttpConnectionManager. So, if we want to set a different value for the max connection per host, we need to define it on the HTTP component and not on the endpoint URI that we usually use. So here comes:

First, we define the http component in Spring XML. Yes, we use the same scheme name, http, because otherwise Fuse Mediation Router will auto-discover and create the component with default settings. What we need is to overrule this so we can set our options. In the sample below we set the max connection to 5 instead of the default of 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>

And then we can just use it as we normally do in our routes:

<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>

As of Camel 2.8, the HTTP component supports SSL/TLS configuration through the Camel JSSE Configuration Utility.  This utility greatly decreases the amount of component specific code you need to write and is configurable at the endpoint and component levels. The following examples demonstrate how to use the utility with the component.

The version of the Apache HTTP client used in this component resolves SSL/TLS information from a global "protocol" registry. This component provides an implementation, org.apache.camel.component.http.SSLContextParametersSecureProtocolSocketFactory, of the HTTP client's protocol socket factory in order to support the use of the Camel JSSE Configuration utility. The following example demonstrates how to configure the protocol registry and use the registered protocol information in a route.

 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");

Available as of Camel 2.3

The http4: component provides HTTP based endpoints for consuming external HTTP resources (as a client to call external servers using HTTP).

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-http4</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

camel-http4 vs camel-http

Camel-http4 uses HttpClient 4.x while camel-http uses HttpClient 3.x.

Name Default Value Description
x509HostnameVerifier BrowserCompatHostnameVerifier Camel 2.7: You can refer to a different org.apache.http.conn.ssl.X509HostnameVerifier instance in the Registry such as org.apache.http.conn.ssl.StrictHostnameVerifier or org.apache.http.conn.ssl.AllowAllHostnameVerifier.
throwExceptionOnFailure true Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code.
bridgeEndpoint false If the option is true , HttpProducer will ignore the Exchange.HTTP_URI header, and use the endpoint's URI for request. You may also set the throwExcpetionOnFailure to be false to let the HttpProducer send all the fault response back. If the option is true, HttpProducer and CamelServlet will skip the gzip processing if the content-encoding is "gzip".
disableStreamCache false DefaultHttpBinding will copy the request input stream into a stream cache and put it into message body if this option is false to support read it twice, otherwise DefaultHttpBinding will set the request input stream direct into the message body.
httpBindingRef null Reference to a org.apache.camel.component.http.HttpBinding in the Registry. Prefer to use the httpBinding option.
httpBinding null Reference to a org.apache.camel.component.http.HttpBinding in the Registry.
httpClientConfigurerRef null Reference to a org.apache.camel.component.http.HttpClientConfigurer in the Registry. Prefer to use the httpClientConfigurer option.
httpClientConfigurer null Reference to a org.apache.camel.component.http.HttpClientConfigurer in the Registry.
httpClient.XXX null Setting options on the BasicHttpParams. For instance httpClient.soTimeout=5000 will set the SO_TIMEOUT to 5 seconds. Look on the setter methods of the following parameter beans for a complete reference: AuthParamBean, ClientParamBean, ConnConnectionParamBean, ConnRouteParamBean, CookieSpecParamBean, HttpConnectionParamBean and HttpProtocolParamBean
clientConnectionManager null To use a custom org.apache.http.conn.ClientConnectionManager.
transferException false If enabled and an Exchange failed processing on the consumer side, and if the caused Exception was send back serialized in the response as a application/x-java-serialized-object content type (for example using Jetty or Servlet Camel components). On the producer side the exception will be deserialized and thrown as is, instead of the HttpOperationFailedException. The caused exception is required to be serialized.
maxTotalConnections 200 The maximum number of connections.
connectionsPerRoute 20 The maximum number of connections per route.
sslContextParametersRef null Camel 2.8: Reference to a org.apache.camel.util.jsse.SSLContextParameters in the Registry. This reference overrides any configured SSLContextParameters at the component level. See Using the JSSE Configuration Utility.

The following authentication options can also be set on the HttpEndpoint:

Since Fuse Mediation Router 2.8.0, the basic authentication and proxy options are as follows:

Name Default Value Description
authUsername null Username for authentication.
authPassword null Password for authentication.
authDomain null The domain name for authentication.
authHost null The host name authentication.
proxyAuthHost null The proxy host name.
proxyAuthPort null The proxy port number.
proxyAuthScheme null The proxy scheme, will fallback and use the scheme from the endpoint if not configured.
proxyAuthUsername null Username for proxy authentication.
proxyAuthPassword null Password for proxy authentication.
proxyAuthDomain null The proxy domain name.
proxyAuthNtHost null The proxy Nt host name.
Name Default Value Description
httpBinding null To use a custom org.apache.camel.component.http.HttpBinding.
httpClientConfigurer null To use a custom org.apache.camel.component.http.HttpClientConfigurer.
httpConnectionManager null To use a custom org.apache.commons.httpclient.HttpConnectionManager.
x509HostnameVerifier null Camel 2.7: To use a custom org.apache.http.conn.ssl.X509HostnameVerifier
sslContextParameters null Camel 2.8: To configure a custom SSL/TLS configuration options at the component level. See Using the JSSE Configuration Utility for more details.
Name Type Description
Exchange.HTTP_URI String URI to call. Will override existing URI set directly on the endpoint.
Exchange.HTTP_PATH String Request URI's path, the header will be used to build the request URI with the HTTP_URI.
Exchange.HTTP_QUERY String URI parameters. Will override existing URI parameters set directly on the endpoint.
Exchange.HTTP_RESPONSE_CODE int The HTTP response code from the external server. Is 200 for OK.
Exchange.HTTP_CHARACTER_ENCODING String Character encoding.
Exchange.CONTENT_TYPE String The HTTP content type. Is set on both the IN and OUT message to provide a content type, such as text/html.
Exchange.CONTENT_ENCODING String The HTTP content encoding. Is set on both the IN and OUT message to provide a content encoding, such as gzip.

As of Camel 2.8, the HTTP4 component supports SSL/TLS configuration through the Camel JSSE Configuration Utility. This utility greatly decreases the amount of component specific code you need to write and is configurable at the endpoint and component levels. The following examples demonstrate how to use the utility with the HTTP4 component.

Basically camel-http4 component is built on the top of Apache HTTP client. Please refer to SSL/TLS customization for details or have a look into the org.apache.camel.component.http4.HttpsServerTestSupport unit test base class. You can also implement a custom org.apache.camel.component.http4.HttpClientConfigurer to do some configuration on the http client if you need full control of it.

However if you just want to specify the keystore and truststore you can do this with Apache HTTP HttpClientConfigurer, for example:

KeyStore keystore = ...;
KeyStore truststore = ...;

SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("https", 443, new SSLSocketFactory(keystore, "mypassword", truststore)));

And then you need to create a class that implements HttpClientConfigurer, and registers https protocol providing a keystore or truststore per example above. Then, from your camel route builder class you can hook it up like so:

HttpComponent httpComponent = getContext().getComponent("http4", HttpComponent.class);
httpComponent.setHttpClientConfigurer(new MyHttpClientConfigurer());

If you are doing this using the Spring DSL, you can specify your HttpClientConfigurer using the URI. For example:

<bean id="myHttpClientConfigurer"
 class="my.https.HttpClientConfigurer">
</bean>

<to uri="https4://myhostname.com:443/myURL?httpClientConfigurer=myHttpClientConfigurer"/>

As long as you implement the HttpClientConfigurer and configure your keystore and truststore as described above, it will work fine.

The ibatis: component allows you to query, poll, insert, update and delete data in a relational database using Apache iBATIS.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Option Type Default Description
consumer.onConsume String null Statements to run after consuming. Can be used, for example, to update rows after they have been consumed and processed in Fuse Mediation Router. See sample later. Multiple statements can be separated with comma.
consumer.useIterator boolean true If true each row returned when polling will be processed individually. If false the entire List of data is set as the IN body.
consumer.routeEmptyResultSet boolean false Fuse Mediation Router 2.0: Sets whether empty result set should be routed or not. By default, empty result sets are not routed.
statementType StatementType null Fuse Mediation Router 1.6.1/2.0: Mandatory to specify for IbatisProducer to control which iBatis SqlMapClient method to invoke. The enum values are: QueryForObject, QueryForList, Insert, Update, Delete.
maxMessagesPerPoll int 0 Fuse Mediation Router 2.0: An integer to define a maximum messages to gather per poll. By default, no maximum is set. Can be used to set a limit of e.g. 1000 to avoid when starting up the server that there are thousands of files. Set a value of 0 or negative to disabled it.

Fuse Mediation Router will populate the result message, either IN or OUT with a header with the operationName used:

Header Type Description
org.apache.camel.ibatis.queryName String Fuse Mediation Router 1.x: The statementName used (for example: insertAccount).
CamelIBatisStatementName String Fuse Mediation Router 2.0: The statementName used (for example: insertAccount).
CamelIBatisResult Object Fuse Mediation Router 1.6.2/2.0: The response returned from iBatis in any of the operations. For instance an INSERT could return the auto-generated key, or number of rows etc.

Since this component does not support scheduled polling, you need to use another mechanism for triggering the scheduled polls, such as the Timer or Quartz components.

In the sample below we poll the database, every 30 seconds using the Timer component and send the data to the JMS queue:

from("timer://pollTheDatabase?delay=30000").to("ibatis:selectAllAccounts?statementType=QueryForList").to("activemq:queue:allAccounts");

And the iBatis SQL map file used:

  <!-- Select with no parameters using the result map for Account class. -->
  <select id="selectAllAccounts" resultMap="AccountResult">
    select * from ACCOUNT
  </select>

The irc component implements an IRC (Internet Relay Chat) transport.

Name Description Example Default Value
channels New in 2.0, comma separated list of IRC channels to join. channels=#channel1,#channel2 null
nickname The nickname used in chat. irc:MyNick@irc.server.org#channel or irc:irc.server.org#channel?nickname=MyUser null
username The IRC server user name. irc:MyUser@irc.server.org#channel or irc:irc.server.org#channel?username=MyUser Same as nickname.
password The IRC server password. password=somepass None
realname The IRC user's actual name. realname=MyName None
colors Whether or not the server supports color codes. true, false true
onReply Whether or not to handle general responses to commands or informational messages. true, false false
onNick Handle nickname change events. true, false true
onQuit Handle user quit events. true, false true
onJoin Handle user join events. true, false true
onKick Handle kick events. true, false true
onMode Handle mode change events. true, false true
onPart Handle user part events. true, false true
onTopic Handle topic change events. true, false true
onPrivmsg Handle message events. true, false true
trustManager New in 2.0, the trust manager used to verify the SSL server's certificate. trustManager=#referenceToTrustManagerBean The default trust manager, which accepts all certificates, will be used.
keys Camel 2.2: Comma separated list of IRC channel keys. Important to be listed in same order as channels. When joining multiple channels with only some needing keys just insert an empty value for that channel. irc:MyNick@irc.server.org/#channel?keys=chankey null

As of Fuse Mediation Router 2.0, you can also connect to an SSL enabled IRC server, as follows:

ircs:host[:port]/#room?username=user&password=pass

By default, the IRC transport uses SSLDefaultTrustManager. If you need to provide your own custom trust manager, use the trustManager parameter as follows:

ircs:host[:port]/#room?username=user&password=pass&trustManager=#referenceToMyTrustManagerBean

Available as of Camel 2.5

Jasypt is a simplified encryption library which makes encryption and decryption easy. Camel integrates with Jasypt to allow sensitive information in Properties files to be encrypted. By dropping camel-jasypt on the classpath those encrypted values will automatic be decrypted on-the-fly by Camel. This ensures that human eyes can't easily spot sensitive information such as usernames and passwords.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

The Jasypt component provides a little command line tooling to encrypt or decrypt values.

The console output the syntax and which options it provides:

Apache Camel Jasypt takes the following options

  -h or -help = Displays the help screen
  -c or -command <command> = Command either encrypt or decrypt
  -p or -password <password> = Password to use
  -i or -input <input> = Text to encrypt or decrypt
  -a or -algorithm <algorithm> = Optional algorithm to use

For example to encrypt the value tiger you run with the following parameters. In the apache camel kit, you cd into the lib folder and run the following java cmd, where <CAMELHOME>_ is where you have downloaded and extract the Camel distribution.

$ cd <CAMEL_HOME>/lib
$ java -jar camel-jasypt-2.5.0.jar -c encrypt -p secret -i tiger

Which outputs the following result

Encrypted text: qaEEacuW7BUti8LcMgyjKw==

This means the encrypted representation qaEEacuW7BUti8LcMgyjKw== can be decrypted back to tiger if you know the master password which was secret. If you run the tool again then the encrypted value will return a different result. But decrypting the value will always return the correct original value.

So you can test it by running the tooling using the following parameters:

$ cd <CAMEL_HOME>/lib
$ java -jar camel-jasypt-2.5.0.jar -c decrypt -p secret -i qaEEacuW7BUti8LcMgyjKw==

Which outputs the following result:

Decrypted text: tiger

The idea is then to use those encrypted values in your Properties files. Notice how the password value is encrypted and the value has the tokens surrounding 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==)

The options below are exclusive for the Jasypt component.

Name Default Value Type Description
password null String Specifies the master password to use for decrypting. This option is mandatory. See below for more details.
algorithm null String Name of an optional algorithm to use.

The master password used by Jasypt must be provided, so its capable of decrypting the values. However having this master password out in the opening may not be an ideal solution. Therefore you could for example provided it as a JVM system property or as a OS environment setting. If you decide to do so then the password option supports prefixes which dictates this. sysenv: means to lookup the OS system environment with the given key. sys: means to lookup a JVM system property.

For example you could provided the password before you start the application

$ export CAMEL_ENCRYPTION_PASSWORD=secret

Then start the application, such as running the start script.

When the application is up and running you can unset the environment

$ unset CAMEL_ENCRYPTION_PASSWORD

The password option is then a matter of defining as follows: password=sysenv:CAMEL_ENCRYPTION_PASSWORD.

In Java DSL you need to configure Jasypt as a JasyptPropertiesParser instance and set it on the Properties component as show below:

// 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);

The properties file myproperties.properties then contain the encrypted value, such as shown below. Notice how the password value is encrypted and the value has the tokens surrounding 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==)

In Spring XML you need to configure the JasyptPropertiesParser which is shown below. Then the Camel Properties component is told to use jasypt as the properties parser, which means Jasypt have its chance to decrypt values looked up in the properties.

<!-- 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>

The Properties component can also be inlined inside the <camelContext> tag which is shown below. Notice how we use the propertiesParserRef attribute to refer to Jasypt.

<!-- 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"
                         propertiesParserRef="jasypt"/>
    <route>
        <from uri="direct:start"/>
        <to uri="{{cool.result}}"/>
    </route>
</camelContext>

The javaspace component is a transport for working with any JavaSpace compliant implementation and this component has been tested with both the Blitz implementation and the GigaSpace implementation. This component can be used for sending and receiving any object inheriting from the Jini net.jini.core.entry.Entry class. It is also possible to pass the bean ID of a template that can be used for reading/taking the entries from the space. This component can be used for sending/receiving any serializable object acting as a sort of generic transport. The JavaSpace component contains a special optimization for dealing with the BeanExchange. It can be used to invoke a POJO remotely, using a JavaSpace as a transport. This latter feature can provide a simple implementation of the master/worker pattern, where a POJO provides the business logic for the worker. Look at the test cases for examples of various use cases for this component.

Name Default Value Description
spaceName null Specifies the JavaSpace name.
verb take Specifies the verb for getting JavaSpace entries. The values can be: take or read.
transactional false If true, sending and receiving entries is performed within a transaction.
transactionalTimeout Long.MAX_VALUE Specifies the transaction timeout.
concurrentConsumers 1 Specifies the number of concurrent consumers getting entries from the JavaSpace.
templateId null If present, this option specifies the Spring bean ID of the template to use for reading/taking entries.

The jbi component is implemented by the ServiceMix Camel module and provides integration with a JBI Normalized Message Router, such as the one provided by Apache ServiceMix.

Important

See below for information about how to use StreamSource types from ServiceMix in Fuse Mediation Router.

The following code:

from("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")

Automatically exposes a new endpoint to the bus, where the service QName is \{http://foo.bar.org}MyService and the endpoint name is MyEndpoint (see #URI-format).

When a JBI endpoint appears at the end of a route, for example:

to("jbi:endpoint:http://foo.bar.org/MyService/MyEndpoint")

The messages sent by this producer endpoint are sent to the already deployed JBI endpoint.

jbi:service:serviceNamespace[sep]serviceName[?options]
jbi:endpoint:serviceNamespace[sep]serviceName[sep]endpointName[?options]
jbi:name:endpointName[?options]

The separator that should be used in the endpoint URL is:

For more details of valid JBI URIs see the ServiceMix URI Guide.

Using the jbi:service: or jbi:endpoint: URI formats sets the service QName on the JBI endpoint to the one specified. Otherwise, the default Fuse Mediation Router JBI Service QName is used, which is:

{http://activemq.apache.org/camel/schema/jbi}endpoint

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default value Description
mep MEP of the Camel Exchange Allows users to override the MEP set on the Exchange object. Valid values for this option are in-only, in-out, robust-in-out and in-optional-out.
operation Value of the jbi.operation header property Specifies the JBI operation for the MessageExchange. If no value is supplied, the JBI binding will use the value of the jbi.operation header property.
serialization basic Default value (basic) will check if headers are serializable by looking at the type, setting this option to strict will detect objects that can not be serialized although they implement the Serializable interface. Set to nocheck to disable this check altogether, note that this should only be used for in-memory transports like SEDAFlow, otherwise you can expect to get NotSerializableException thrown at runtime.
convertException false false: send any exceptions thrown from the Camel route back unmodified true: convert all exceptions to a JBI FaultException (can be used to avoid non-serializable exceptions or to implement generic error handling

If you have some Fuse Mediation Router routes that you want to deploy inside JBI as a Service Unit, you can use the JBI Service Unit Archetype to create a new Maven project for the Service Unit.

If you have an existing Maven project that you need to convert into a JBI Service Unit, you may want to consult ServiceMix Maven JBI Plugins for further help. The key steps are as follows:

  • Create a Spring XML file at src/main/resources/camel-context.xml to bootstrap your routes inside the JBI Service Unit.

  • Change the POM file's packaging to jbi-service-unit.

Your pom.xml should look something like this to enable the jbi-service-unit packaging:

<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 Fuse Mediation Router based JBI Service Unit</name>

  <url>http://www.myorganization.org</url>

  <properties>
    <camel-version>1.0.0</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>
      <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>

For more information, see the following references:

The jcr component allows you to add nodes to a JCR (JSR-170) compliant content repository (for example, Apache Jackrabbit).

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

The jdbc component enables you to access databases through JDBC, where SQL queries and operations are sent in the message body. This component uses the standard JDBC API, unlike the SQL Component component, which uses spring-jdbc.

Warning

This component can only be used to define producer endpoints, which means that you cannot use the JDBC component in a from() statement.

Important

This component can not be used as a Transactional Client. If you need transaction support in your route, you should use the SQL component instead.

Name Default Value Description
readSize 0 / 2000 The default maximum number of rows that can be read by a polling query. The default value is 2000 for Fuse Mediation Router 1.5.0 or older. In newer releases the default value is 0.
statement.<xxx> null Fuse Mediation Router 2.1: Sets additional options on the java.sql.Statement that is used behind the scenes to execute the queries. For instance, statement.maxRows=10. For detailed documentation, see the java.sql.Statement javadoc documentation.
useJDBC4ColumnNameAndLabelSemantics true Fuse Mediation Router 1.6.3/2.2: Sets whether to use JDBC 4/3 column label/name semantics. You can use this option to turn it false in case you have issues with your JDBC driver to select data. This only applies when using SQL SELECT using aliases (e.g. SQL SELECT id as identifier, name as given_name from persons).
Header Description
CamelJdbcRowCount If the query is a SELECT, the row count is returned in this OUT header.
CamelJdbcUpdateCount If the query is an UPDATE, the update count is returned in this OUT header.

In the following example, we fetch the rows from the customer table.

First we register our datasource in the Fuse Mediation Router registry as testdb:

JndiRegistry reg = super.createRegistry();
reg.bind("testdb", ds);
return reg;

Then we configure a route that routes to the JDBC component, so the SQL will be executed. Note how we refer to the testdb datasource that was bound in the previous step:

// lets add simple route
public void configure() throws Exception {
    from("direct:hello").to("jdbc:testdb?readSize=100");
}

Or you can create a DataSource in Spring like this:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <route>
     <from uri="timer://kickoff?period=10000"/>
     <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-->
<bean id="testdb" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
	<property name="url" value="jdbc:hsqldb:mem:camel_jdbc" />
	<property name="username" value="sa" />
  <property name="password" value="" />
</bean>	

We create an endpoint, add the SQL query to the body of the IN message, and then send the exchange. The result of the query is returned in the OUT body:

// 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());
ArrayList<HashMap<String, Object>> data = out.getOut().getBody(ArrayList.class);
assertNotNull("out body could not be converted to an ArrayList - was: "
    + out.getOut().getBody(), data);
assertEquals(2, data.size());
HashMap<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"));

If you want to work on the rows one by one instead of the entire ResultSet at once you need to use the Splitter EIP such as:

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");

If we want to poll a database using the JDBC component, we need to combine it with a polling scheduler such as the Timer or Quartz etc. In the following example, we retrieve data from the database every 60 seconds:

from("timer://foo?period=60000").setBody(constant("select * from customer")).to("jdbc:testdb").to("activemq:queue:customers");

See also:

The jetty component provides HTTP-based endpoints for consuming HTTP requests. That is, the Jetty component behaves as a simple Web server. Jetty can also be used as a http client which mean you can also use it with Camel as a Producer.

Upgrading from Jetty 6 to 7

You can read more about upgrading Jetty here

Stream

Jetty is stream based, which means the input it receives is submitted to Camel as a stream. That means you will only be able to read the content of the stream once. If you find a situation where the message body appears to be empty or you need to access the data multiple times (eg: doing multicasting, or redelivery error handling) you should use Stream Caching or convert the message body to a String which is safe to be re-read multiple times.

Name Default Value Description
sessionSupport false Specifies whether to enable the session manager on the server side of Jetty.
httpClient.XXX null Fuse Mediation Router 1.6.0/2.0: Configuration of Jetty's HttpClient. For example, setting httpClient.idleTimeout=30000 sets the idle timeout to 30 seconds.
httpBindingRef null Fuse Mediation Router 1.6.0/2.0: Reference to an org.apache.camel.component.http.HttpBinding in the Registry. HttpBinding can be used to customize how a response should be written.
jettyHttpBindingRef null Camel 2.6.0: Reference to an org.apache.camel.component.jetty.JettyHttpBinding in the Registry. JettyHttpBinding can be used to customize how a response should be written.
matchOnUriPrefix false Fuse Mediation Router 2.0: Whether or not the CamelServlet should try to find a target consumer by matching the URI prefix if no exact match is found.
handlers null Fuse Mediation Router 1.6.1/2.0: Specifies a comma-delimited set of org.mortbay.jetty.Handler instances in your Registry (such as your Spring ApplicationContext). These handlers are added to the Jetty servlet context (for example, to add security).
chunked true Camel 2.2: If this option is false Jetty servlet will disable the HTTP streaming and set the content-length header on the response
enableJmx false Camel 2.3: If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX support for more details.
disableStreamCache false Camel 2.3: Determines whether or not the raw input stream from Jetty is cached or not (Camel will read the stream into a in memory/overflow to file, Stream caching) cache. By default Camel will cache the Jetty input stream to support reading it multiple times to ensure it Camel can retrieve all data from the stream. However you can set this option to true when you for example need to access the raw stream, such as streaming it directly to a file or other persistent store. DefaultHttpBinding will copy the request input stream into a stream cache and put it into message body if this option is false to support reading the stream multiple times. If you use Jetty to bridge/proxy an endpoint then consider enabling this option to improve performance, in case you do not need to read the message payload multiple times.
bridgeEndpoint false

Camel 2.1: If the option is true , HttpProducer will ignore the Exchange.HTTP_URI header, and use the endpoint's URI for request. You may also set the throwExceptionOnFailure to be false to let the HttpProducer send all the fault response back. Camel 2.3: If the option is true, HttpProducer and CamelServlet will skip the gzip processing if the content-encoding is "gzip". Also consider setting disableStreamCache to true to optimize when bridging.

enableMultipartFilter true Canel 2.5: Whether Jetty org.eclipse.jetty.servlets.MultiPartFilter is enabled or not. You should set this value to false when bridging endpoints, to ensure multipart requests is proxied/bridged as well.
multipartFilterRef null Camel 2.6: Allows using a custom multipart filter. Note: setting multipartFilterRef forces the value of enableMultipartFilter to true.
continuationTimeout null Camel 2.6: Allows to set a timeout in millis when using Jetty as consumer (server). By default Jetty uses 30000. You can use a value of <= 0 to never expire. If a timeout occurs then the request will be expired and Jetty will return back a http error 503 to the client. This option is only in use when using Jetty with the Asynchronous Routing Engine.
useContinuation true Camel 2.6: Whether or not to use Jetty continuations for the Jetty Server.
sslContextParametersRef null Camel 2.8: Reference to a org.apache.camel.util.jsse.SSLContextParameters in the CAMEL:Registry. This reference overrides any configured SSLContextParameters at the component level. See Using the JSSE Configuration Utility.

DefaultHttpBinding will copy the request input stream into a stream cache and put it into message body if this option is false to support reading the stream multiple times. |

Fuse Mediation Router uses the same message headers as the HTTP component. From Camel 2.2, it also uses (Exchange.HTTP_CHUNKED,CamelHttpChunked) header to turn on or turn off the chuched encoding on the camel-jetty consumer.

Fuse Mediation Router also populates all request.parameter and request.headers. For example, given a client request with the URL, http://myserver/myserver?orderid=123, the exchange will contain a header named orderid with the value 123. This feature was introduced in Fuse Mediation Router 1.5.

From Camel 1.6.3 and Camel 2.2.0, you can get the request.parameter from the message header not only from Get Method, but also other HTTP method.

The JettyHttpComponent provides the following options:

Name Default Value Description
enableJmx false Camel 2.3: If this option is true, Jetty JMX support will be enabled for this endpoint. See Jetty JMX support for more details.
sslKeyPassword null Consumer only: The password for the keystore when using SSL.
sslPassword null Consumer only: The password when using SSL.
sslKeystore null Consumer only: The path to the keystore.
minThreads null Camel 2.5Consumer only: To set a value for minimum number of threads in server thread pool.
maxThreads null Camel 2.5Consumer only: To set a value for maximum number of threads in server thread pool.
threadPool null Camel 2.5Consumer only: To use a custom thread pool for the server.
sslSocketConnectors null Camel 2.3Consumer only: A map which contains per port number specific SSL connectors. See section SSL support for more details.
socketConnectors null Camel 2.5Consumer only: A map which contains per port number specific HTTP connectors. Uses the same principle as sslSocketConnectors and therefore see section SSL support for more details.
sslSocketConnectorProperties null Camel 2.5Consumer only. A map which contains general SSL connector properties. See section SSL support for more details.
socketConnectorProperties null Camel 2.5Consumer only. A map which contains general HTTP connector properties. Uses the same principle as sslSocketConnectorProperties and therefore see section SSL support for more details.
httpClient null Producer only: To use a custom HttpClient with the jetty producer.
httpClientMinThreads null Producer only: To set a value for minimum number of threads in HttpClient thread pool.
httpClientMaxThreads null Producer only: To set a value for maximum number of threads in HttpClient thread pool.
httpClientThreadPool null Producer only: To use a custom thread pool for the client.
sslContextParameters null Camel 2.8: To configure a custom SSL/TLS configuration options at the component level. See Using the JSSE Configuration Utility for more details.

In this sample we define a route that exposes a HTTP service at http://localhost:8080/myapp/myservice:

from("jetty:http://localhost:9080/myapp/myservice").process(new MyBookService());

Usage of localhost

When you specify localhost in a URL, Fuse Mediation Router exposes the endpoint only on the local TCP/IP network interface, so it cannot be accessed from outside the machine it operates on.

If you need to expose a Jetty endpoint on a specific network interface, the numerical IP address of this interface should be used as the host. If you need to expose a Jetty endpoint on all network interfaces, the 0.0.0.0 address should be used.

Our business logic is implemented in the MyBookService class, which accesses the HTTP request contents and then returns a response. Note: The assert call appears in this example, because the code is part of an unit test.

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 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>");
    }
}

The following sample shows a content-based route that routes all requests containing the URI parameter, one, to the endpoint, mock:one, and all others to mock:other.

from("jetty:" + serverUri)
    .choice()
    .when().simple("in.header.one").to("mock:one")
    .otherwise()
    .to("mock:other");

So if a client sends the HTTP request, http://serverUri?one=hello, the Jetty component will copy the HTTP request parameter, one to the exchange's in.header. We can then use the simple language to route exchanges that contain this header to a specific endpoint and all others to another. If we used a language more powerful than Simple—such as El or OGNL—we could also test for the parameter value and do routing based on the header value as well.

The session support option, sessionSupport, can be used to enable a HttpSession object and access the session object while processing the exchange. For example, the following route enables sessions:

<route>
    <from uri="jetty:http://0.0.0.0/myapp/myservice/?sessionSupport=true"/>
    <processRef ref="myCode"/>
<route>

The myCode Processor can be instantiated by a Spring bean element:

   <bean id="myCode" class="com.mycompany.MyCodeProcessor"/>

Where the processor implementation can access the HttpSession as follows:

public void process(Exchange exchange) throws Exception {
    HttpSession session = ((HttpExchange)exchange).getRequest().getSession();
    ...
}

As of Camel 2.8, the Jetty component supports SSL/TLS configuration through the Camel JSSE Configuration Utility.  This utility greatly decreases the amount of component specific code you need to write and is configurable at the endpoint and component levels. The following examples demonstrate how to use the utility with the Jetty component.

Jetty provides SSL support out of the box. To enable Jetty to run in SSL mode, simply format the URI with the https:// prefix—for example:

<from uri="jetty:https://0.0.0.0/myapp/myservice/"/>

Jetty also needs to know where to load your keystore from and what passwords to use in order to load the correct SSL certificate. Set the following JVM System Properties:

until Camel 2.2

from Camel 2.3 onwards

For details of how to configure SSL on a Jetty endpoint, read the following documentation at the Jetty Site: http://docs.codehaus.org/display/JETTY/How+to+configure+SSL]{clickable}

Some SSL properties aren't exposed directly by Camel, however Camel does expose the underlying SslSocketConnector, which will allow you to set properties like needClientAuth for mutual authentication requiring a client certificate or wantClientAuth for mutual authentication where a client doesn't need a certificate but can have one. There's a slight difference between Camel 1.6.x and 2.x:

Camel 1.x

  <bean id="jetty" class="org.apache.camel.component.jetty.JettyHttpComponent">
    <property name="sslSocketConnector">
      <bean class="org.mortbay.jetty.security.SslSocketConnector">
        <property name="password" value="..." />
        <property name="keyPassword" value="..." />
        <property name="keystore" value="..." />
        <property name="wantClientAuth" value="..." />
        <property name="truststore" value="..." />
      </bean>
    </property>
  </bean>

Until Camel 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>

Camel 2.3 to 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>

From Camel 2.5 we switch to use SslSelectChannelConnector

<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>

The value you use as keys in the above map is the port you configure Jetty to listen on.

Available as of Fuse Mediation Router 1.6.1/2.0: You can configure a list of Jetty handlers on the endpoint, which can be useful for enabling advanced Jetty security features. These handlers are configured in Spring XML as follows:

        <-- 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>

And from Camel 2.3 onwards you can configure a list of Jetty handlers as follows:

<-- 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>

You can then define the endpoint as:

from("jetty:http://0.0.0.0:9080/myservice?handlers=securityHandler")

If you need more handlers, set the handlers option equal to a comma-separated list of bean IDs.

You may want to return a custom reply message when something goes wrong, instead of the default reply message Camel Jetty replies with. You could use a custom HttpBinding to be in control of the message mapping, but often it may be easier to use Camel's Exception Clause to construct the custom reply message. For example as show here, where we return Dude something went wrong with HTTP error code 500:

from("jetty://http://localhost:8234/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)
        .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(500))
    .end()
    // now just force an exception immediately
    .throwException(new IllegalArgumentException("I cannot do this"));

From Camel 2.3.0, camel-jetty support to multipart form post out of box. The submitted form-data are mapped into the message header. Camel-jetty creates an attachment for each uploaded file. The file name is mapped to the name of the attachment. The content type is set as the content type of the attachment file name. You can find the example here.

// 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:9080/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("Got 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"));
    }

});

From Camel 2.3.0, camel-jetty supports the enabling of Jetty's JMX capabilities at the component and endpoint level with the endpoint configuration taking priority. Note that JMX must be enabled within the Camel context in order to enable JMX support in this component as the component provides Jetty with a reference to the MBeanServer registered with the Camel context. Because the camel-jetty component caches and reuses Jetty resources for a given protocol/host/port pairing, this configuration option will only be evaluated during the creation of the first endpoint to use a protocol/host/port pairing. For example, given two routes created from the following XML fragments, JMX support would remain enabled for all endpoints listening on "https://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"/>

The camel-jetty component also provides for direct configuration of the Jetty MBeanContainer. Jetty creates MBean names dynamically. If you are running another instance of Jetty outside of the Camel context and sharing the same MBeanServer between the instances, you can provide both instances with a reference to the same MBeanContainer in order to avoid name collisions when registering Jetty MBeans.

See also:

  • Http

The Jing component uses the Jing Library to perform XML validation of the message body using either:

Note that the MSV component can also support RelaxNG XML syntax.

rng:someLocalOrRemoteResource
rnc:someLocalOrRemoteResource

Where rng means use the RelaxNG XML Syntax whereas rnc means use RelaxNG Compact Syntax. The following examples show possible URI values

Example Description
rng:foo/bar.rng References the XML file foo/bar.rng on the classpath
rnc:http://foo.com/bar.rnc References the RelaxNG Compact Syntax file from the URL, http://foo.com/bar.rnc.

You can append query options to the URI in the following format, ?option=value&option=value&...

Option Default Description
useDom false Fuse Mediation Router 2.0: Specifies whether DOMSource/DOMResult or SaxSource/SaxResult should be used by the validator.

The following example shows how to configure a route from the endpoint direct:start which then goes to one of two endpoints, either mock:valid or mock:invalid based on whether or not the XML matches the given RelaxNG Compact Syntax schema (which is supplied on the classpath).

<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>
                <exception>org.apache.camel.ValidationException</exception>
                <to uri="mock:invalid"/>
            </doCatch>
            <doFinally>
                <to uri="mock:finally"/>
            </doFinally>
        </doTry>
    </route>
</camelContext>

The JMS component allows messages to be sent to (or consumed from) a JMS Queue or Topic. The implementation of the JMS Component uses Spring's JMS support for declarative transactions, using Spring's JmsTemplate for sending and a MessageListenerContainer for consuming.

For users with Fuse Mediation Router 1.6.1 or older

JMS consumers have a bad default in Fuse Mediation Router 1.6.1 or older. The maxMessagesPerTask is set to 1, whereas it really should be -1. This issue causes Spring to create a new thread after it has processed a message, causing the thread count to rise continuously. You can see this in the log where a new thread name is used. To remedy this, change a route such as:

<from uri="jms:queue:foo"/>

By adding the maxMessagesPerTask option and setting its value to -1, as follows:

<from uri="jms:queue:foo&axMessagesPerTask=-1"/>

This has been fixed in Fuse Mediation Router 1.6.2/2.0.

Using ActiveMQ

If you are using Apache ActiveMQ, you should prefer the ActiveMQ component as it has been particularly optimized for ActiveMQ. All of the options and samples on this page are also valid for the ActiveMQ component.

Using JMS API 1.0.2

The old JMS API 1.0.2 has been @deprecated in Camel 2.1 and will be removed in Camel 2.2 release. Its no longer provided in Spring 3.0 which we want to be able to support out of the box in Camel 2.2+ releases.

Note that the JMS component reuses Spring 2's JmsTemplate for sending messages. This is not ideal for use in a non-J2EE container and typically requires some caching in the JMS provider to avoid bad performance. So if you intend to use Apache ActiveMQ as your Message Broker, then we recommend that you either

  • Use the ActiveMQ component, which is already configured to use ActiveMQ efficiently, or

  • Use the PoolingConnectionFactory in ActiveMQ.

If you wish to use durable topic subscriptions, you need to specify both clientId and durableSubscriptionName. Note that the value of the clientId must be unique and can only be used by a single JMS connection instance in your entire network. You may prefer to use Virtual Topics instead to avoid this limitation. More background on durable messaging here.

When using message headers, the JMS specification states that header names must be valid Java identifiers. So, by default, Fuse Mediation Router ignores any headers that do not match this rule. So try to name your headers as if they are valid Java identifiers. One benefit of doing this is that you can then use your headers inside a JMS Selector (whose SQL92 syntax mandates Java identifier syntax for headers).

From Fuse Mediation Router 1.4 onwards, a simple strategy for mapping header names is used by default. The strategy is to replace any dots in the header name with the underscore character and to reverse the replacement when the header name is restored from a JMS message sent over the wire. What does this mean? No more losing method names to invoke on a bean component, no more losing the filename header for the File Component, and so on.

The current header name strategy for accepting header names in Fuse Mediation Router is as follows:

  • Replace all dots with underscores (for example, org.apache.camel.MethodName becomes org_apache_camel_MethodName).

  • Test if the name is a valid java identifier using the JDK core classes.

  • If the test success, the header is added and sent over the wire; otherwise it is dropped (and logged at DEBUG level).

In Fuse Mediation Router 2.0 the strategy for mapping header names has been changed to use the following replacement strategy:

  • Dots are replaced by _DOT_ and the replacement is reversed when Fuse Mediation Router consume the message

  • Hyphen is replaced by _HYPHEN_ and the replacement is reversed when Fuse Mediation Router consumes the message

You can configure many different properties on the JMS endpoint which map to properties on the JMSConfiguration POJO. Note: Many of these properties map to properties on Spring JMS, which Fuse Mediation Router uses for sending and receiving messages. So you can get more information about these properties by consulting the relevant Spring documentation.

Option Default Value Description
acceptMessagesWhileStopping false Specifies whether the consumer accept messages while it is stopping.
acknowledgementModeName AUTO_ACKNOWLEDGE The JMS acknowledgement name, which is one of: TRANSACTED, CLIENT_ACKNOWLEDGE, AUTO_ACKNOWLEDGE, DUPS_OK_ACKNOWLEDGE
acknowledgementMode -1 The JMS acknowledgement mode defined as an Integer. Allows you to set vendor-specific extensions to the acknowledgment mode. For the regular modes, it is preferable to use the acknowledgementModeName instead.
alwaysCopyMessage false If true, Fuse Mediation Router will always make a JMS message copy of the message when it is passed to the producer for sending. Copying the message is needed in some situations, such as when a replyToDestinationSelectorName is set (incidentally, Fuse Mediation Router will set the alwaysCopyMessage option to true, if a replyToDestinationSelectorName is set)
autoStartup true Specifies whether the consumer container should auto-startup.
cacheLevelName - Sets the cache level by name for the underlying JMS resources. Possible values are: CACHE_AUTO, CACHE_CONNECTION, CACHE_CONSUMER, CACHE_NONE, and CACHE_SESSION. See the Spring documentation and see the warning above. The default setting is CACHE_CONSUMER for Camel 2.7.1 or older. Camel 2.8 uses CACHE_AUTO as default value.
cacheLevel - Sets the cache level by ID for the underlying JMS resources. See cacheLevelName option for more details.
clientId null Sets the JMS client ID to use. Note that this value, if specified, must be unique and can only be used by a single JMS connection instance. It is typically only required for durable topic subscriptions. You may prefer to use Virtual Topics instead.
consumerType Default The consumer type to use, which can be one of: Simple, Default or ServerSessionPool. The consumer type determines which Spring JMS listener to use. Default will use org.springframework.jms.listener.DefaultMessageListenerContainer, Simple will use org.springframework.jms.listener.SimpleMessageListenerContainer, and ServerSessionPool will use org.springframework.jms.listener.serversession.ServerSessionMessageListenerContainer. If the option, useVersion102=true, Camel will use the JMS 1.0.2 Spring classes instead. ServerSessionPool is @deprecated and will be removed in Camel 2.0. This option has been removed from Camel 2.7 onwards.
concurrentConsumers 1 Specifies the default number of concurrent consumers.
connectionFactory null The default JMS connection factory to use for the listenerConnectionFactory and templateConnectionFactory, if neither is specified.
deliveryPersistent true Specifies whether persistent delivery is used by default.
destination null Fuse Mediation Router 2.0: Specifies the JMS Destination object to use on this endpoint.
destinationName null Fuse Mediation Router 2.0: Specifies the JMS destination name to use on this endpoint.
destinationResolver null A pluggable org.springframework.jms.support.destination.DestinationResolver that allows you to use your own resolver (for example, to lookup the real destination in a JNDI registry).
disableReplyTo false If true, ignore the JMSReplyTo header and so treat messages as InOnly by default and do not send a reply back.
durableSubscriptionName null The durable subscriber name for specifying durable topic subscriptions. The clientId option must be configured as well.
disableTimeToLive false Camel 2.8: Use this option to force disabling time to live. For example when you do request/reply over JMS, then Camel will by default use the requestTimeout value as time to live on the message being send. The problem is that the sender and receiver systems have to have their clocks synchronized, so they are in sync. This is not always so easy to archive. So you can use disableTimeToLive=true to not set a time to live value on the send message. Then the message will not expire on the receiver system. See below in section About time to live for more details.
eagerLoadingOfProperties false Enables eager loading of JMS properties as soon as a message is received, which is generally inefficient, because the JMS properties might not be required. But this feature can sometimes catch early any issues with the underlying JMS provider and the use of JMS properties. This feature can also be used for testing purposes, to ensure JMS properties can be understood and handled correctly.
forceSendOriginalMessage false Camel 2.7: When using mapJmsMessage=false Camel will create a new JMS message to send to a new JMS destination if you touch the headers (get or set) during the route. Set this option to true to force Camel to send the original JMS message that was received.
exceptionListener null Specifies the JMS Exception Listener that is to be notified of any underlying JMS exceptions.
explicitQosEnabled false Set if the deliveryMode, priority or timeToLive qualities of service should be used when sending messages. This option is based on Spring's JmsTemplate. The deliveryMode, priority and timeToLive options are applied to the current endpoint. This contrasts with the preserveMessageQos option, which operates at message granularity, reading QoS properties exclusively from the Fuse Mediation Router In message headers.
exposeListenerSession true Specifies whether the listener session should be exposed when consuming messages.
idleTaskExecutionLimit 1 Specifies the limit for idle executions of a receive task, not having received any message within its execution. If this limit is reached, the task will shut down and leave receiving to other executing tasks (in the case of dynamic scheduling; see the maxConcurrentConsumers setting).
jmsMessageType null Fuse Mediation Router 2.0: Allows you to force the use of a specific javax.jms.Message implementation for sending JMS messages. Possible values are: Bytes, Map, Object, Stream, Text. By default, Fuse Mediation Router would determine which JMS message type to use from the In body type. This option allows you to specify it.
jmsKeyFormatStrategy default Fuse Mediation Router 2.0: Pluggable strategy for encoding and decoding JMS keys so they can be compliant with the JMS specification. Fuse Mediation Router provides two implementations out of the box: default and passthrough. The default strategy will safely marshal dots and hyphens (. and -). The passthrough strategy leaves the key as is. Can be used for JMS brokers which do not care whether JMS header keys contain illegal characters. You can provide your own implementation of the org.apache.camel.component.jms.JmsKeyFormatStrategy and refer to it using the # notation.
jmsOperations null Allows you to use your own implementation of the org.springframework.jms.core.JmsOperations interface. Fuse Mediation Router uses JmsTemplate as default. Can be used for testing purpose, but not used much as stated in the spring API docs.
lazyCreateTransactionManager true Fuse Mediation Router 2.0: If true, Fuse Mediation Router will create a JmsTransactionManager, if there is no transactionManager injected when option transacted=true.
listenerConnectionFactory null The JMS connection factory used for consuming messages.
mapJmsMessage true Fuse Mediation Router 1.6.2/2.0: Specifies whether Fuse Mediation Router should auto map the received JMS message to an appropiate payload type, such as javax.jms.TextMessage to a String etc. See section about how mapping works below for more details.
maxConcurrentConsumers 1 Specifies the maximum number of concurrent consumers.
maxMessagesPerTask -1 The number of messages per task. -1 is unlimited.
messageConverter null Fuse Mediation Router 1.6.2/2.0: To use a custom Spring org.springframework.jms.support.converter.MessageConverter so you can be 100% in control how to map to/from a javax.jms.Message.
messageIdEnabled true When sending, specifies whether message IDs should be added. The message IDs are generated using the UUID generator registered with the CamelContext—for details, see Built-In UUID Generators in Programing EIP Components.
messageTimestampEnabled true Specifies whether timestamps should be enabled by default on sending messages.
password null The password for the connector factory.
priority 4 Values greater than 1 specify the message priority when sending (where 0 is the lowest priority and 9 is the highest). The explicitQosEnabled option must also be enabled in order for this option to have any effect.
pubSubNoLocal false Specifies whether to inhibit the delivery of messages published by its own connection.
receiveTimeout None The timeout for receiving messages (in milliseconds).
recoveryInterval 5000 Specifies the interval between recovery attempts, in milliseconds. The default is 5000 ms, that is, 5 seconds.
preserveMessageQos false Camel 2.0: Set to true, if you want to send message using the QoS settings specified on the message, instead of the QoS settings on the JMS endpoint. The following three headers are considered JMSPriority, JMSDeliveryMode, and JMSExpiration. You can provide all or only some of them. If not provided, Camel will fall back to use the values from the endpoint instead. So, when using this option, the headers override the values from the endpoint. The explicitQosEnabled option, by contrast, will only use options set on the endpoint, and not values from the message header.
replyTo null Provides an explicit ReplyTo destination, which overrides any incoming value of Message.getJMSReplyTo(). If you do Request Reply over JMS then read the section further below for more details.
replyToDestinationSelectorName null Sets the JMS Selector using the fixed name to be used so you can filter out your own replies from the others when using a shared queue (that is, if you are not using a temporary reply queue).
replyToDeliveryPersistent true Specifies whether to use persistent delivery by default for replies.
requestTimeout 20000 The timeout for waiting for a reply when using the InOut Exchange Pattern (in milliseconds). The default is 20 seconds. See below in section About time to live for more details.
selector null Sets the JMS Selector, which is an SQL 92 predicate that is used to filter messages within the broker. You may have to encode special characters such as = as %3D
subscriptionDurable false @deprecated: Enabled by default, if you specify a durableSubscriberName and a clientId.
taskExecutor null Allows you to specify a custom task executor for consuming messages.
taskExecutorSpring2 null To use when using Spring 2.x with Camel. Allows you to specify a custom task executor for consuming messages.
templateConnectionFactory null The JMS connection factory used for sending messages.
timeToLive null When sending messages, specifies the time-to-live of the message (in milliseconds). The explicitQosEnabled option must also be enabled in order for this option to have any effect.
transacted false Specifies whether to use transacted mode for sending/receiving messages using the InOnly Exchange Pattern. See the section Enabling Transacted Consumption for more details.
transactedInOut false @deprecated: Specifies whether to use transacted mode for sending messages using the InOut Exchange Pattern. Applies only to producer endpoints. See section Enabling Transacted Consumption for more details.
transactionManager null The Spring transaction manager to use.
transactionName null The name of the transaction to use.
transactionTimeout null The timeout value of the transaction, if using transacted mode.
transferException false Camel 2.0: If enabled and you are using Request Reply messaging (InOut) and an Exchange failed on the consumer side, then the caused Exception will be send back in response as a javax.jms.ObjectMessage. If the client is Camel, the returned Exception is rethrown. This allows you to use Camel JMS as a bridge in your routing - for example, using persistent queues to enable robust routing. Notice that if you also have transferExchange enabled, this option takes precedence. The caught exception is required to be serializable. The original Exception on the consumer side can be wrapped in an outer exception such as org.apache.camel.RuntimeCamelException when returned to the producer.
transferExchange false Fuse Mediation Router 2.0: You can transfer the exchange over the wire instead of just the body and headers. The following fields are transferred: In body, Out body, Fault body, In headers, Out headers, Fault headers, exchange properties, exchange exception. This requires that the objects are serializable. Fuse Mediation Router will exclude any non-serializable objects and log it at WARN level.
username null The username for the connector factory.
useMessageIDAsCorrelationID false Specifies whether JMSMessageID should always be used as JMSCorrelationID for InOut messages.
useVersion102 false @deprecated (removed from Camel 2.5 onwards): Specifies whether the old JMS API should be used.

Fuse Mediation Router automatically maps messages between javax.jms.Message and org.apache.camel.Message.

When sending a JMS message, Fuse Mediation Router converts the message body to the following JMS message types:

Body Type JMS Message Comment
String javax.jms.TextMessage
org.w3c.dom.Node javax.jms.TextMessage The DOM will be converted to String.
Map javax.jms.MapMessage
java.io.Serializable javax.jms.ObjectMessage
byte[] javax.jms.BytesMessage
java.io.File javax.jms.BytesMessage
java.io.Reader javax.jms.BytesMessage
java.io.InputStream javax.jms.BytesMessage
java.nio.ByteBuffer javax.jms.BytesMessage

When receiving a JMS message, Fuse Mediation Router converts the JMS message to the following body type:

JMS Message Body Type
javax.jms.TextMessage String
javax.jms.BytesMessage byte[]
javax.jms.MapMessage Map<String, Object>
javax.jms.ObjectMessage Object

The exchange that is sent over the JMS wire must conform to the JMS Message spec.

For the exchange.in.header the following rules apply for the header keys:

  • Keys starting with JMS or JMSX are reserved.

  • exchange.in.headers keys must be literals and all be valid Java identifiers (do not use dots in the key name).

  • From Fuse Mediation Router 1.4 until Fuse Mediation Router 1.6.x, Fuse Mediation Router automatically replaces all dots with underscores in key names. This replacement is reversed when Fuse Mediation Router consumes JMS messages.

  • From Fuse Mediation Router 2.0 onwards, Fuse Mediation Router replaces dots & hyphens and the reverse when when consuming JMS messages:. is replaced by _DOT_ and the reverse replacement when Fuse Mediation Router consumes the message.- is replaced by _HYPHEN_ and the reverse replacement when Fuse Mediation Router consumes the message.

  • See also the option jmsKeyFormatStrategy introduced in Fuse Mediation Router 2.0, which allows you to use your own custom strategy for formatting keys.

For the exchange.in.header, the following rules apply for the header values:

  • The values must be primitives or their counter objects (such as Integer, Long, Character). The types, String, CharSequence, Date, BigDecimal and BigInteger are all converted to their toString() representation. All other types are dropped.

Fuse Mediation Router will log with category org.apache.camel.component.jms.JmsBinding at DEBUG level if it drops a given header value. For example:

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}

Fuse Mediation Router adds the following properties to the Exchange when it receives a message:

Property Type Description
org.apache.camel.jms.replyDestination javax.jms.Destination The reply destination.

Fuse Mediation Router adds the following JMS properties to the In message headers when it receives a JMS message:

Header Type Description
JMSCorrelationID String The JMS correlation ID.
JMSDeliveryMode int The JMS delivery mode.
JMSDestination javax.jms.Destination The JMS destination.
JMSExpiration long The JMS expiration.
JMSMessageID String The JMS unique message ID.
JMSPriority int The JMS priority (with 0 as the lowest priority and 9 as the highest).
JMSRedelivered boolean Is the JMS message redelivered.
JMSReplyTo javax.jms.Destination The JMS reply-to destination.
JMSTimestamp long The JMS timestamp.
JMSType String The JMS type.
JMSXGroupID String The JMS group ID.

As all the above information is standard JMS you can check the JMS documentation for further details.

The JmsProducer behaves as follows, depending on configuration:

Exchange Pattern Other options Description
InOut Fuse Mediation Router will expect a reply, set a temporary JMSReplyTo, and after sending the message, it will start to listen for the reply message on the temporary queue.
InOut JMSReplyTo is set Fuse Mediation Router will expect a reply and, after sending the message, it will start to listen for the reply message on the specified JMSReplyTo queue.
InOnly Fuse Mediation Router will send the message and not expect a reply.
InOnly JMSReplyTo is set

By default, Fuse Mediation Router suppresses the JMSReplyTo destination and clears the JMSReplyTo header before sending the message. Fuse Mediation Router then sends the message and does not expect a reply. Fuse Mediation Router logs this in the log at DEBUG level and you should see: DEBUG JmsProducer - Disabling JMSReplyTo as this Exchange is not OUT capable with JMSReplyTo: myReplyQueue to destination: myQueue.

If you want to leave the JMSReplyTo header in the outgoing message, you must set either preserveMessageQos=true or explicitQosEnabled=true. From Fuse Mediation Router 2.6 onwards, you can also populate the JMSReplyTo header by setting the replyTo option in the URI. For example, if you send a message to the jms:queue:Foo?replyTo=FooReply&preserveMessageQos=true URI, the JMSReplyTo header is included, even if the exchange is InOnly.

Available as of Fuse Mediation Router 1.6.2/2.0 If you need to send messages to a lot of different JMS destinations, it makes sense to reuse a JMS endpoint and specify the real destination in a message header. This allows Fuse Mediation Router to reuse the same endpoint, but send to different destinations. This greatly reduces the number of endpoints created and economizes on memory and thread resources.

You can specify the destination in the following headers:

Header Type Description
CamelJmsDestination javax.jms.Destination Fuse Mediation Router 2.0: A destination object.
CamelJmsDestinationName String Fuse Mediation Router 1.6.2/2.0: The destination name.

For example, the following route shows how you can compute a destination at run time and use it to override the destination appearing in the JMS URL:

from("file://inbox")
  .to("bean:computeDestination")
  .to("activemq:queue:dummy");

The queue name, dummy, is just a placeholder. It must be provided as part of the JMS endpoint URL, but it will be ignored in this example.

In the computeDestination bean, specify the real destination by setting the CamelJmsDestinationName header as follows:

public void setJmsHeader(Exchange exchange) {
   String id = ....
   exchange.getIn().setHeader("CamelJmsDestinationName", "order:" + id");
}

Then Fuse Mediation Router will read this header and use it as the destination instead of the one configured on the endpoint. So, in this example Fuse Mediation Router sends the message to activemq:queue:order:2, assuming the id value was 2.

If both the CamelJmsDestination and the CamelJmsDestinationName headers are set, CamelJmsDestination takes priority.

You can configure your JMS provider in Spring XML as follows:

<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&roker.useJmx=false"/>
    </bean>
  </property>
</bean>

Basically, you can configure as many JMS component instances as you wish and give them a unique name using the id attribute. The preceding example configures an activemq component. You could do the same to configure MQSeries, TibCo, BEA, Sonic and so on.

Once you have a named JMS component, you can then refer to endpoints within that component using URIs. For example for the component name, activemq, you can then refer to destinations using the URI format, activemq:[queue:|topic:]destinationName. You can use the same approach for all other JMS providers.

This works by the SpringCamelContext lazily fetching components from the spring context for the scheme name you use for Endpoint URIs and having the Component resolve the endpoint URIs.

See this link at nabble for details of how a Fuse Mediation Router user configured JMS to connect to remote WebSphere MQ brokers.

When doing messaging between systems, its desirable that the systems have synchronized clocks. For example when sending a JMS message, then you can set a time to live value on the message. Then the receiver can inspect this value, and determine if the message is already expired, and thus drop the message instead of consume and process it. However this requires that both sender and receiver have synchronized clocks. If you are using ActiveMQ then you can use the timestamp plugin to synchronize clocks.

Read first above about synchronized clocks.

When you do request/reply (InOut) over JMS with Camel then Camel uses a timeout on the sender side, which is default 20 seconds from the requestTimeout option. You can control this by setting a higher/lower value. However the time to live value is still set on the JMS message being send. So that requires the clocks to be synchronized between the systems. If they are not, then you may want to disable the time to live value being set. This is now possible using the disableTimeToLive option from Camel 2.8 onwards. So if you set this option to disableTimeToLive=true, then Camel does not set any time to live value when sending JMS messages. But the request timeout is still active. So for example if you do request/reply over JMS and have disabled time to live, then Camel will still use a timeout by 20 seconds (the requestTimeout option). That option can of course also be configured. So the two options requestTimeout and disableTimeToLive gives you fine grained control when doing request/reply.

When you do fire and forget (InOut) over JMS with Camel then Camel by default does not set any time to live value on the message. You can configure a value by using the timeToLive option. For example to indicate a 5 sec., you set timeToLive=5000. The option disableTimeToLive can be used to force disabling the time to live, also for InOnly messaging. The requestTimeout option is not being used for InOnly messaging.

Avaiable as of Fuse Mediation Router 2.0

When using Fuse Mediation Router as a JMS listener, it sets an Exchange property with the value of the ReplyTo javax.jms.Destination object, having the key ReplyTo. You can obtain this Destination as follows:

Destination replyDestination = exchange.getIn().getHeader(JmsConstants.JMS_REPLY_DESTINATION, Destination.class);

And then later use it to send a reply using regular JMS or Fuse Mediation Router.

    // we need to pass in the JMS component, and in this sample we use ActiveMQ
    JmsEndpoint endpoint = JmsEndpoint.newInstance(replyDestination, activeMQComponent);
    // now we have the endpoint we can use regular Fuse Mediation Router API to send a message to it
    template.sendBody(endpoint, "Here is the late reply.");

A different solution to sending a reply is to provide the replyDestination object in the same Exchange property when sending. Fuse Mediation Router will then pick up this property and use it for the real destination. The endpoint URI must include a dummy destination, however. For example:

    // 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.");
        }
    }

In the sample below we send a Request Reply style message Exchange (we use the requestBody method = InOut) to the slow queue for further processing in Camel and we wait for a return reply:

// send a in-out with a timeout for 5 sec
Object out = template.requestBody("activemq:queue:slow?requestTimeout=5000", "Hello World");

Fuse Mediation Router also has annotations so you can use POJO Consuming and POJO Producing.

Available as of Camel 2.0 Normally, when using JMS as the transport, it only transfers the body and headers as the payload. If you want to use JMS with a Dead Letter Channel, using a JMS queue as the Dead Letter Queue, then normally the caused Exception is not stored in the JMS message. You can, however, use the transferExchange option on the JMS dead letter queue to instruct Camel to store the entire Exchange in the queue as a javax.jms.ObjectMessage that holds a org.apache.camel.impl.DefaultExchangeHolder. This allows you to consume from the Dead Letter Queue and retrieve the caused exception from the Exchange property with the key Exchange.EXCEPTION_CAUGHT. The demo below illustrates this:

// setup error handler to use JMS as queue and store the entire Exchange
errorHandler(deadLetterChannel("jms:queue:dead?transferExchange=true"));

Then you can consume from the JMS queue and analyze the problem:

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();

You can use JMS to store the cause error message or to store a custom body, which you can initialize yourself. The following example uses the Message Translator EIP to do a transformation on the failed exchange before it is moved to the JMS dead letter queue:

// 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");

Here we only store the original cause error message in the transform. You can, however, use any Expression to send whatever you like. For example, you can invoke a method on a Bean or use a custom processor.

When sending to a JMS destination using camel-jms the producer will use the MEP to detect if its InOnly or InOut messaging. However there can be times where you want to send an InOnly message but keeping the JMSReplyTo header. To do so you have to instruct Camel to keep it, otherwise the JMSReplyTo header will be dropped.

For example to send an InOnly message to the foo queue, but with a JMSReplyTo with bar queue you can do as follows:

      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");
      }
      });
      
    

Notice we use preserveMessageQos=true to instruct Camel to keep the JMSReplyTo header.

Property Required Default Description
format xml Format for the message body. Either xml or raw. If xml, the notification is serialized to XML. If raw, the raw java object is set as the body.
password Credentials for making a remote connection.
objectDomain Yes The domain of the MBean you are connecting to.
objectName The name key for the MBean you are connecting to. Either this property of a list of keys must be provided (but not both). For more details, see ObjectName Construction.
notificationFilter Reference to a bean that implements the NotificationFilter interface. The #beanID syntax should be used to reference the bean in the registry.
handback Value to hand back to the listener when a notification is received. This value will be put into the jmx.handback message header.

property type applies to description
monitorType enum all one of the counters, guage, string
observedAttribute string all the attribute being observed
granularityPeriod long all granularity period (in millis) for the attribute being observed. As per JMX, default is 10 seconds
initThreshold number counter initial threshold value
offset number counter offset value
modulus number counter modulus value
differenceMode boolean counter, gauge true if difference should be reported, false for actual value
notifyHigh boolean gauge high notification on/off switch
notifyLow boolean gauge low notification on/off switch
highThreshold number gauge threshold for reporting high notification
lowThreshold number gauge threshold for reporting low notificaton
notifyDiffer boolean string true to fire notification when string differs
notifyMatch boolean string true to fire notification when string matches
stringToCompare string string string to compare against the attribute value

The monitor style consumer is only supported for the local mbean server. JMX does not currently support remote deployment of mbeans without either having the classes already remotely deployed or an adapter library on both the client and server to facilitate a proxy deployment.

You can store a Java entity bean in a database by sending it to a JPA producer endpoint. The body of the In message is assumed to be an entity bean (that is, a POJO with an @Entity annotation on it) or a collection or an array of entity beans.

If the body does not contain one of the preceding types, put a Message TranslatorMessage Translator in front of the endpoint to perform the necessary conversion first.

jpa:[entityClassName][?options]

For sending to the endpoint, the entityClassName is optional. If specified, it helps the Type Converter to ensure the body is of the correct type.

For consuming, the entityClassName is mandatory.

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default Value Description
entityType entityClassName Overrides the entityClassName from the URI.
persistenceUnit camel The JPA persistence unit used by default.
consumeDelete true JPA consumer only: If true, the entity is deleted after it is consumed; if false, the entity is not deleted.
consumeLockEntity true JPA consumer only: Specifies whether or not to set an exclusive lock on each entity bean while processing the results from polling.
flushOnSend true JPA producer only: Flushes the EntityManager after the entity bean has been persisted.
maximumResults -1 JPA consumer only: Set the maximum number of results to retrieve on the Query.
transactionManager null Fuse Mediation Router 1.6.1/2.0: Specifies the transaction manager to use. If none provided, Fuse Mediation Router will use a JpaTransactionManager by default. Can be used to set a JTA transaction manager (for integration with an EJB container).
consumer.delay 500 JPA consumer only: Delay in milliseconds between each poll.
consumer.initialDelay 1000 JPA consumer only: Milliseconds before polling starts.
consumer.useFixedDelay false JPA consumer only: Set to true to use fixed delay between polls, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.
maxMessagesPerPoll 0 Fuse Mediation Router 2.0:JPA consumer only: An integer value to define the maximum number of messages to gather per poll. By default, no maximum is set. Can be used to avoid polling many thousands of messages when starting up the server. Set a value of 0 or negative to disable.
consumer.query JPA consumer only: To use a custom query when consuming data.
consumer.namedQuery JPA consumer only: To use a named query when consuming data.
consumer.nativeQuery JPA consumer only: To use a custom native query when consuming data.
consumer.resultClass Camel 2.7: JPA consumer only: Defines the type of the returned payload (we will call entityManager.createNativeQuery(nativeQuery, resultClass) instead of entityManager.createNativeQuery(nativeQuery)). Without this option, we will return an object array. Only has an affect when using in conjunction with native query when consuming data.
usePersist false Camel 2.5: JPA producer only: Indicates to use entityManager.persist(entity) instead of entityManager.merge(entity). Note: entityManager.persist(entity) doesn't work for detached entities (where the EntityManager has to execute an UPDATE instead of an INSERT query)!

Fuse Mediation Router adds the following message headers to the exchange:

Header Type Description
CamelJpaTemplate JpaTemplate Fuse Mediation Router 2.0: The JpaTemplate object that is used to access the entity bean. You need this object in some situations, for instance in a type converter or when you are doing some custom processing.

In this section we will use the JPA based idempotent repository.

First we need to setup a persistence-unit in the persistence.xml file:

<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>

Second we have to setup a org.springframework.orm.jpa.JpaTemplate which is used by the 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>

Afterwards we can configure our 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>

And finally we can create our JPA idempotent repository in the spring XML file as well:

 <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>

For the data queue message exchange:

Name Default value Description
ccsid default system CCSID Specifies the CCSID to use for the connection with the AS/400 system.
format text Specifies the data format for sending messages valid options are: text (represented by String) and binary (represented by byte[])
consumer.delay 500 Delay in milliseconds between each poll.
consumer.initialDelay 1000 Milliseconds before polling starts.
consumer.userFixedDelay false true to use fixed delay between polls, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.
guiAvailable false Camel 2.8: Specifies whether AS/400 prompting is enabled in the environment running Camel.

For the remote program call (Camel 2.7):

Name Default value Description
outputFieldsIdx Specifies which fields (program parameters) are output parameters.
fieldsLength Specifies the fields (program parameters) length as in the AS/400 program definition.

Available as of Camel 2.5

The language component allows you to send Exchange to an endpoint which executes a script by any of the supported Languages in Camel. By having a component to execute language scripts, it allows more dynamic routing capabilities. For example by using the Routing SlipRouting Slip or Dynamic RouterDynamic Router EIPs you can send messages to language endpoints where the script is dynamic defined as well.

This component is provided out of the box in camel-core and hence no additional JARs is needed. You only have to include additional Camel components if the language of choice mandates it, such as using Groovy or JavaScript languages.

The component supports the following options.

Name Default Value Type Description
languageName null String The name of the Language to use, such as simple, groovy, javascript etc. This option is mandatory.
script null String The script to execute.
transform true boolean Whether or not the result of the script should be used as the new message body. By setting to false the script is executed but the result of the script is discarded.

The following message headers can be used to affect the behavior of the component

Header Description
CamelLanguageScript The script to execute provided in the header. Takes precedence over script configured on the endpoint.

For example you can use the Simple language to Message TranslatorMessage Translator a message:

from("direct:start").to("language:simple:Hello ${body}").to("mock:result");

In case you want to convert the message body type you can do this as well:

from("direct:start").to("language:simple:${mandatoryBodyAs(String)}").to("mock:result");

You can also use the Groovy language, such as this example where the input message will by multiplied with 2:

from("direct:start").to("language:groovy:request.body * 2").to("mock:result");

You can also provide the script as a header as shown below. Here we use XPath language to extract the text from the <foo> tag.

Object out = producer.requestBodyAndHeader("language:xpath", "<foo>Hello World</foo>", Exchange.LANGUAGE_SCRIPT, "/foo/text()");
assertEquals("Hello World", out);

  • Languages

  • Routing SlipRouting Slip

  • Dynamic RouterDynamic Router

ldap:ldapServerBean[?options]

The ldapServerBean portion of the URI refers to a DirContext bean in the registry. The LDAP component only supports producer endpoints, which means that an ldap URI cannot appear in the from at the start of a route.

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default Value Description
base ou=system The base DN for searches.
scope subtree Specifies how deeply to search the tree of entries, starting at the base DN. Value can be object, onelevel, or subtree.
pageSize No paging used. When specified the LDAP module uses paging to retrieve all results (most LDAP Servers throw an exception when trying to retrieve more than 1000 entries in one query). To be able to use this, an LdapContext (subclass of DirContext) has to be passed in as ldapServerBean (otherwise an exception is thrown)
returnedAttributes Depends on LDAP Server (could be all or none) . Comma-separated list of attributes that should be set in each entry of the result

deprecated: is renamed to the Browse component in Fuse Mediation Router 2.0

The List component provides a simple BrowsableEndpoint which can be useful for testing, visualisation tools or debugging. The exchanges sent to the endpoint are all available to be browsed.

Option Default Type Description
level INFO String Logging level to use. Possible values: FATAL, ERROR, WARN, INFO, DEBUG, TRACE, OFF
groupSize null Integer An integer that specifies a group size for throughput logging.
groupInterval null Integer Camel 2.6: If specified will group message stats by this time interval (in millis)
groupDelay 0 Integer Camel 2.6: Set the initial delay for stats (in millis)
groupActiveOnly true boolean Camel 2.6: If true, will hide stats when no new messages have been received for a time interval, if false, show stats regardless of message traffic

The log formats the execution of exchanges to log lines. By default, the log uses LogFormatter to format the log output, where LogFormatter has the following options:

Option Default Description
showAll false Quick option for turning all options on (multiline, maxChars has to be manually set if to be used).
showExchangeId false Show the unique exchange ID.
showExchangePattern true Camel 2.3: Shows the Message Exchange Pattern (or MEP for short).
showProperties false Show the exchange properties.
showHeaders false Show the In message headers.
showBodyType true Show the In body Java type.
showBody true Show the In body.
showOut false If the exchange has an Out message, show the Out message.
showException false Fuse Mediation Router 2.0: If the exchange has an exception, show the exception message (no stack trace).
showCaughtException false Fuse Mediation Router 2.0: If the exchange has a caught exception, show the exception message (no stack trace). A caught exception is stored as a property on the exchange and for instance a doCatch can catch exceptions. See Try Catch Finally.
showStackTrace false Fuse Mediation Router 2.0: Show the stack trace, if an exchange has an exception. Only effective if one of showAll, showException or showCaughtException are enabled.
showFuture false Camel 2.1: Whether Camel should show java.util.concurrent.Future bodies or not. If enabled Camel could potentially wait until the Future task is done. Will by default not wait.
showStreams false Camel 2.8: Whether Camel should show stream bodies or not (eg such as java.io.InputStream). Beware if you enable this option then you may not be able later to access the message body as the stream have already been read by this logger. To remedy this you have to use Stream Caching.
multiline false If true, each piece of information is logged on a new line.
maxChars Fuse Mediation Router 2.0: Limits the number of characters logged per line.

Available as of Fuse Mediation Router 2.2

The lucene component is based on the Apache Lucene project. Apache Lucene is a powerful high-performance, full-featured text search engine library written entirely in Java. For more details about Lucene, please see the following links * http://lucene.apache.org/java/docs/ * http://lucene.apache.org/java/docs/features.html

The lucene component in camel facilitates integration and utilization of Lucene endpoints in enterprise integration patterns and scenarios. The lucene component does the following

  • builds a searchable index of documents when payloads are sent to the Lucene Endpoint

  • facilitates performing of indexed searches in Fuse Mediation Router

This component only supports producer endpoints.

Name Default Value Description
analyzer StandardAnalyzer An Analyzer builds TokenStreams, which analyze text. It thus represents a policy for extracting index terms from text. The value for analyzer can be any class that extends the abstract class org.apache.lucene.analysis.Analyzer. Lucene also offers a rich set of analyzers out of the box
indexDir ./indexDirectory A file system directory in which index files are created upon analysis of the document by the specified analyzer
srcDir null An optional directory containing files to be used to be analyzed and added to the index at producer startup.
Name Default Value Description
analyzer StandardAnalyzer An Analyzer builds TokenStreams, which analyze text. It thus represents a policy for extracting index terms from text. The value for analyzer can be any class that extends the abstract class org.apache.lucene.analysis.Analyzer. Lucene also offers a rich set of analyzers out of the box
indexDir ./indexDirectory A file system directory in which index files are created upon analysis of the document by the specified analyzer
maxHits 10 An integer value that limits the result set of the search operation
Header Description
QUERY The Lucene Query to performed on the index. The query may include wildcards and phrases

The mail component provides access to Email via Spring's Mail support and the underlying JavaMail system.

Property Default Description
host The host name or IP address to connect to.
port See #DefaultPorts The TCP port number to connect on.
username The user name on the email server.
password null The password on the email server.
ignoreUriScheme false If false, Fuse Mediation Router uses the scheme to determine the transport protocol (POP, IMAP, SMTP etc.)
defaultEncoding null The default encoding to use for Mime Messages.
contentType text/plain New option in Fuse Mediation Router 1.5. The mail message content type. Use text/html for HTML mails.
folderName INBOX The folder to poll.
destination username@host @deprecated Use the to option instead. The TO recipients (receivers of the email).
to username@host As of Fuse Mediation Router 1.4, the TO recipients (the receivers of the mail). Separate multiple email addresses with a comma.
CC null As of Fuse Mediation Router 1.4, the CC recipients (the receivers of the mail). Separate multiple email addresses with a comma.
BCC null As of Fuse Mediation Router 1.4, the BCC recipients (the receivers of the mail). Separate multiple email addresses with a comma.
from camel@localhost The FROM email address.
subject As of Camel 2.3, the Subject of the message being sent. Note: Setting the subject in the header takes precedence over this option.
delete false Fuse Mediation Router 2.0: Deletes the messages after they have been processed. This is done by setting the DELETED flag on the mail message. If false, the SEEN flag is set instead.
unseen true Fuse Mediation Router 2.0: Is used to fetch only unseen messages (that is, new messages). Note that POP3 does not support the SEEN flag; use IMAP instead.
fetchSize -1 As of Fuse Mediation Router 1.4, this option sets the maximum number of messages to consume during a poll. This can be used to avoid overloading a mail server, if a mailbox folder contains a lot of messages. Default value of -1 means no fetch size and all messages will be consumed. Setting the value to 0 is a special corner case, where Fuse Mediation Router will not consume any messages at all.
alternateBodyHeader mail_alternateBody Fuse Mediation Router 1.6.1: Specifies the key to an IN message header that contains an alternative email body. For example, if you send emails in text/html format and want to provide an alternative mail body for non-HTML email clients, set the alternative mail body with this key as a header. In Fuse Mediation Router 2.0, this option has been renamed to alternativeBodyHeader.
alternativeBodyHeader CamelMailAlternativeBody Fuse Mediation Router 2.0: Specifies the key to an IN message header that contains an alternative email body. For example, if you send emails in text/html format and want to provide an alternative mail body for non-HTML email clients, set the alternative mail body with this key as a header.
debugMode false As of Fuse Mediation Router 1.4, it is possible to enable debug mode on the underlying mail framework. The SUN Mail framework logs the debug messages to System.out by default.
connectionTimeout 30000 As of Fuse Mediation Router 1.4, the connection timeout can be configured in milliseconds. Default is 30 seconds.
consumer.initialDelay 1000 Milliseconds before the polling starts.
consumer.delay 60000 As of Fuse Mediation Router 1.4, the default consumer delay is now 60 seconds. Fuse Mediation Router will therefore only poll the mailbox once a minute to avoid overloading the mail server. The default value in Fuse Mediation Router 1.3 is 500 milliseconds.
consumer.useFixedDelay false Set to true to use a fixed delay between polls, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.
mail.XXX null As of Fuse Mediation Router 2.0, you can set any additional java mail properties. For instance if you want to set a special property when using POP3 you can now provide the option directly in the URI such as: mail.pop3.forgettopheaders=true. You can set multiple such options, for example: mail.pop3.forgettopheaders=true&mail.mime.encodefilename=true.
mapMailMessage true Camel 2.8: Specifies whether Camel should map the received mail message to Camel body/headers. If set to true, the body of the mail message is mapped to the body of the Camel IN message and the mail headers are mapped to IN headers. If this option is set to false then the IN message contains a raw javax.mail.Message. You can retrieve this raw message by calling exchange.getIn().getBody(javax.mail.Message.class).
javaMailSender null Camel 2.0: Specifies a pluggable org.springframework.mail.javamail.JavaMailSender instance in order to use a custom email implementation. If none provided, Camel uses the default org.springframework.mail.javamail.JavaMailSenderImpl.
ignoreUnsupportedCharset false Fuse Mediation Router 2.0: Option to let Fuse Mediation Router ignore unsupported charset in the local JVM when sending mails. If the charset is unsupported then charset=XXX (where XXX represents the unsupported charset) is removed from the content-type and it relies on the platform default instead.

Fuse Mediation Router uses the message exchange's IN body as the MimeMessage text content. The body is converted to String.class.

Fuse Mediation Router copies all of the exchange's IN headers to the MimeMessage headers.

The subject of the MimeMessage can be configured using a header property on the IN message. The code below demonstrates this:

from("direct:a").setHeader("subject", constant(subject)).to("smtp://james2@localhost");

The same applies for other MimeMessage headers such as recipients, so you can use a header property as To:

Map map = new HashMap();
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);

SUN JavaMail is used under the hood for consuming and producing mails. We encourage end-users to consult these references when using either POP3 or IMAP protocol. Note particularly that POP3 has a much more limited set of features than IMAP.

mina:tcp://hostname[:port][?options]
mina:udp://hostname[:port][?options]
mina:vm://hostname[:port][?options]

From Fuse Mediation Router 1.3 onwards you can specify a codec in the Registry using the codec option. If you are using TCP and no codec is specified then the textline flag is used to determine if text line based codec or object serialization should be used instead. By default the object serialization is used.

For UDP, if no codec is specified the default uses a basic ByteBuffer based codec.

The VM protocol is used as a direct forwarding mechanism in the same JVM. See the MINA VM-Pipe API documentation for details.

A Mina producer has a default timeout value of 30 seconds, while it waits for a response from the remote server.

In normal use, camel-mina only supports marshalling the body content—essage headers and exchange properties are not sent. However, the option, transferExchange, does allow you to transfer the exchange itself over the wire. See options below.

You can append query options to the URI in the following format, ?option=value&option=value&...

Option Default Value Description
codec null As of 1.3, you can refer to a named ProtocolCodecFactory instance in your Registry such as your Spring ApplicationContext, which is then used for the marshalling.
codec null Fuse Mediation Router 2.0: You must use the # notation to look up your codec in the Registry. For example, use #myCodec to look up a bean with the id value, myCodec.
disconnect false Camel 2.3: Whether or not to disconnect(close) from Mina session right after use. Can be used for both consumer and producer.
textline false Only used for TCP. If no codec is specified, you can use this flag in 1.3 or later to indicate a text line based codec; if not specified or the value is false, then Object Serialization is assumed over TCP.
textlineDelimiter DEFAULT Fuse Mediation Router 1.6.0/2.0 Only used for TCP and if textline=true. Sets the text line delimiter to use. Possible values are: DEFAULT, AUTO, WINDOWS, UNIX or MAC. If none provided, Fuse Mediation Router will use DEFAULT. This delimiter is used to mark the end of text.
sync true As of 1.3, you can configure the exchange pattern to be either InOnly (default) or InOut. Setting sync=true means a synchronous exchange (InOut), where the client can read the response from MINA (the exchange Out message). The default value has changed in Fuse Mediation Router 1.5 to true. In older releases, the default value is false.
lazySessionCreation See description As of 1.3, sessions can be lazily created to avoid exceptions, if the remote server is not up and running when the Fuse Mediation Router producer is started. From Fuse Mediation Router 2.0 onwards, the default is true. In Fuse Mediation Router 1.x, the default is false.
timeout 30000 As of 1.3, you can configure the timeout that specifies how long to wait for a response from a remote server. The timeout unit is in milliseconds, so 60000 is 60 seconds. The timeout is only used for Mina producer.
encoding JVM Default As of 1.3, you can configure the encoding (a charset name) to use for the TCP textline codec and the UDP protocol. If not provided, Fuse Mediation Router will use the JVM default Charset.
transferExchange false Only used for TCP. As of 1.3, you can transfer the exchange over the wire instead of just the body. The following fields are transferred: In body, Out body, fault body, In headers, Out headers, fault headers, exchange properties, exchange exception. This requires that the objects are serializable. Fuse Mediation Router will exclude any non-serializable objects and log it at WARN level.
minaLogger false As of 1.3, you can enable the Apache MINA logging filter. Apache MINA uses slf4j logging at INFO level to log all input and output.
filters null

As of 2.0, you can set a list of Mina IoFilters to register. The filters value must be one of the following:

  • Camel 2.2: comma-separated list of bean references (e.g. #filterBean1,#filterBean2) where each bean must be of type org.apache.mina.common.IoFilter.

  • Camel 2.0: a reference to a bean of type List<org.apache.mina.common.IoFilter>.

encoderMaxLineLength -1 As of 2.1, you can set the textline protocol encoder max line length. By default the default value of Mina itself is used which are Integer.MAX_VALUE.
decoderMaxLineLength -1 As of 2.1, you can set the textline protocol decoder max line length. By default the default value of Mina itself is used which are 1024.
allowDefaultCodec true The mina component installs a default codec if both, codec is null and textline is false. Setting allowDefaultCodec to false prevents the mina component from installing a default codec as the first element in the filter chain. This is useful in scenarios where another filter must be the first in the filter chain, like the SSL filter.
disconnectOnNoReply true Camel 2.3: If sync is enabled then this option dictates MinaConsumer if it should disconnect where there is no reply to send back.
noReplyLogLevel WARN Camel 2.3: If sync is enabled this option dictates MinaConsumer which logging level to use when logging a there is no reply to send back. Values are: FATAL, ERROR, INFO, DEBUG, OFF.

In Fuse Mediation Router 2.0 the codec option must use # notation for lookup of the codec bean in the Registry. In Fuse Mediation Router 2.0 the lazySessionCreation option now defaults to true.

In Fuse Mediation Router 1.5 the sync option has changed its default value from false to true, as we felt it was confusing for end-users when they used Mina to call remote servers and Fuse Mediation Router wouldn't wait for the response.

In Fuse Mediation Router 1.4 or later codec=textline is no longer supported. Use the textline=true option instead.

See the Mina documentation how to write your own codec. To use your custom codec with camel-mina, you should register your codec in the Registry; for example, by creating a bean in the Spring XML file. Then use the codec option to specify the bean ID of your codec. See HL7 that has a custom codec.

Available as of Fuse Mediation Router 2.0

Configuration of Mina endpoints is now possible using regular Spring bean style configuration in the Spring DSL.

However, in the underlying Apache Mina toolkit, it is relatively difficult to set up the acceptor and the connector, because you can not use simple setters. To resolve this difficulty, we leverage the MinaComponent as a Spring factory bean to configure this for us. If you really need to configure this yourself, there are setters on the MinaEndpoint to set these when needed.

The sample below shows the factory approach:

<!-- 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>

<!-- 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>

And then we can refer to our endpoint directly in the route, as follows:

<route>
    <!-- here we route from or mina endpoint we have defined above -->
    <from ref="myMinaEndpoint"/>
    <to uri="mock:result"/>
</route>

Available since Fuse Mediation Router 2.0

Filters permit you to use some Mina Filters, such as SslFilter. You can also implement some customized filters. Please note that codec and logger are also implemented as Mina filters of type, IoFilter. Any filters you may define are appended to the end of the filter chain; that is, after codec and logger.

For instance, the example below will send a keep-alive message after 10 seconds of inactivity:

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);
    }
}

As Fuse Mediation Router Mina may use a request-reply scheme, the endpoint as a client would like to drop some message, such as greeting when the connection is established. For example, when you connect to an FTP server, you will get a 220 message with a greeting (220 Welcome to Pure-FTPd). If you don't drop the message, your request-reply scheme will be broken.

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")) {
                // Dropping greeting
                return;
            }
        }
        nextFilter.messageReceived(session, message);
    }
}

Then, you can configure your endpoint using Spring DSL:

<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>

The Mock component provides a powerful declarative testing mechanism, which is similar to jMock in that it allows declarative expectations to be created on any Mock endpoint before a test begins. Then the test is run, which typically fires messages to one or more endpoints, and finally the expectations can be asserted in a test case to ensure the system worked as expected.

This allows you to test various things like:

  • The correct number of messages are received on each endpoint,

  • The correct payloads are received, in the right order,

  • Messages arrive on an endpoint in order, using some Expression to create an order testing function,

  • Messages arrive match some kind of Predicate such as that specific headers have certain values, or that parts of the messages match some predicate, such as by evaluating an XPath or XQuery Expression.

Note that there is also the Test endpoint which is a Mock endpoint, but which uses a second endpoint to provide the list of expected message bodies and automatically sets up the Mock endpoint assertions. In other words, it's a Mock endpoint that automatically sets up its assertions from some sample messages in a File or database, for example.

Option Default Description
reportGroup null A size to use a throughput logger for reporting

Here's a simple example of Mock endpoint in use. First, the endpoint is resolved on the context. Then we set an expectation, and then, after the test has run, we assert that our expectations have been met.

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();

You typically always call the assertIsSatisfied() method to test that the expectations were met after running a test.

Fuse Mediation Router will by default wait 10 seconds when the assertIsSatisfied() is invoked. This can be configured by setting the setResultWaitTime(millis) method.

When the assertion is satisfied then Camel will stop waiting and continue from the assertIsSatisfied method. That means if a new message arrives on the mock endpoint, just a bit later, that arrival will not affect the outcome of the assertion. Suppose you do want to test that no new messages arrives after a period thereafter, then you can do that by setting the setAssertPeriod method.

You can see from the javadoc of MockEndpoint the various helper methods you can use to set expectations. The main methods are as follows:

Method Description
expectedMessageCount(int) To define the expected message count on the endpoint.
expectedMinimumMessageCount(int) To define the minimum number of expected messages on the endpoint.
expectedBodiesReceived(...) To define the expected bodies that should be received (in order).
expectedHeaderReceived(...) To define the expected header that should be received
expectsAscending(Expression) To add an expectation that messages are received in order, using the given Expression to compare messages.
expectsDescending(Expression) To add an expectation that messages are received in order, using the given Expression to compare messages.
expectsNoDuplicates(Expression) To add an expectation that no duplicate messages are received; using an Expression to calculate a unique identifier for each message. This could be something like the JMSMessageID if using JMS, or some unique reference number within the message.

Here's another example:

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

In addition, you can use the message(int messageIndex) method to add assertions about a specific message that is received.

For example, to add expectations of the headers or body of the first message (using zero-based indexing like java.util.List), you can use the following code:

resultEndpoint.message(0).header("foo").isEqualTo("bar");

There are some examples of the Mock endpoint in use in the camel-core processor tests.

Available as of Camel 2.7

Camel now allows you to automatic mock existing endpoints in your Camel routes.

Important: The endpoints are still in action, what happens is that a Mock endpoint is injected and receives the message first, it then delegate the message to the target endpoint. You can view this as a kind of intercept and delegate or endpoint listener.

Suppose you have the given route below:

@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"));
        }
    };
}

You can then use the adviceWith feature in Camel to mock all the endpoints in a given route from your unit test, as shown below:

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"));
    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"));
}

Notice that the mock endpoints is given the uri mock:<endpoint>, for example mock:direct:foo. Camel logs at INFO level the endpoints being mocked:

INFO  Adviced endpoint [direct://foo] with mock endpoint [mock:direct:foo]

Mocked endpoints are without parameters

Endpoints which are mocked will have their parameters stripped off. For example the endpoint "log:foo?showAll=true" will be mocked to the following endpoint "mock:log:foo". Notice the parameters has been removed.

Its also possible to only mock certain endpoints using a pattern. For example to mock all log endpoints you do as shown:

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"));
}

The pattern supported can be a wildcard or a regular expression. See more details about this at Intercept as its the same matching function used by Camel.

Important

Mind that mocking endpoints causes the messages to be copied when they arrive on the mock. That means Camel will use more memory. This may not be suitable when you send in a lot of messages.

Instead of using the adviceWith to instruct Camel to mock endpoints, you can easily enable this behavior when using the camel-test Test Kit. The same route can be tested as follows. Notice that we return "*" from the isMockEndpoints method, which tells Camel to mock all endpoints. If you only want to mock all log endpoints you can return "log*" instead.

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"));
        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"));
            }
        };
    }
}

If you do not use the camel-test component for unit testing (as shown above) you can use a different approach when using XML files for routes. The solution is to create a new XML file used by the unit test and then include the intended XML file which has the route you want to test.

Suppose we have the route in the camel-route.xml file:

<!-- 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>
        </transform>
    </route>

</camelContext>

Then we create a new XML file as follows, where we include the camel-route.xml file and define a spring bean with the class org.apache.camel.impl.InterceptSendToMockEndpointStrategy which tells Camel to mock all endpoints:

<!-- 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"/>

Then in your unit test you load the new XML file (test-camel-route.xml) instead of camel-route.xml.

To only mock all log endpoints you can define the pattern in the constructor for the bean:

<bean id="mockAllEndpoints" class="org.apache.camel.impl.InterceptSendToMockEndpointStrategy">
    <constructor-arg index="0" value="log*"/>
</bean>

Available as of Camel 2.7

The Mock endpoint stores the arrival time of the message as a property on the Exchange.

Date time = exchange.getProperty(Exchange.RECEIVED_TIMESTAMP, Date.class);

You can use this information to know when the message arrived on the mock. But it also provides foundation to know the time interval between the previous and next message arrived on the mock. You can use this to set expectations using the arrives DSL on the Mock endpoint.

For example to say that the first message should arrive between 0-2 seconds before the next you can do:

mock.message(0).arrives().noLaterThan(2).seconds().beforeNext();

You can also define this as that 2nd message (0 index based) should arrive no later than 0-2 seconds after the previous:

mock.message(1).arrives().noLaterThan(2).seconds().afterPrevious();

You can also use between to set a lower bound. For example suppose that it should be between 1-4 seconds:

mock.message(1).arrives().between(1, 4).seconds().afterPrevious();

You can also set the expectation on all messages, for example to say that the gap between them should be at most 1 second:

mock.allMessages().arrives().noLaterThan(1).seconds().beforeNext();

time units

In the example above we use seconds as the time unit, but Camel offers milliseconds, and minutes as well.

The MSV component performs XML validation of the message body using the MSV Library and any of the supported XML schema languages, such as XML Schema or RelaxNG XML Syntax.

Note that the Jing component also supports RelaxNG Compact Syntax

Option Default Description
useDom true Fuse Mediation Router 2.0: Whether DOMSource/DOMResult or SaxSource/SaxResult should be used by the validator. Note: DOM must be used by the MSV component.

The following example shows how to configure a route from endpoint direct:start which then goes to one of two endpoints, either mock:valid or mock:invalid based on whether or not the XML matches the given RelaxNG XML Schema (which is supplied on the classpath).

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <from uri="direct:start"/>
        <doTry>
            <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>

Available as of Camel 2.7

The mybatis: component allows you to query, poll, insert, update and delete data in a relational database using MyBatis.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>
Option Type Default Description
consumer.onConsume String null Statements to run after consuming. Can be used, for example, to update rows after they have been consumed and processed in Camel. See sample later. Multiple statements can be separated with comma.
consumer.useIterator boolean true If true each row returned when polling will be processed individually. If false the entire List of data is set as the IN body.
consumer.routeEmptyResultSet boolean false Sets whether empty result set should be routed or not. By default, empty result sets are not routed.
statementType StatementType null Mandatory to specify for producer to control which kind of operation to invoke. The enum values are: SelectOne, SelectList, Insert, Update, Delete.
maxMessagesPerPoll int 0 An integer to define a maximum messages to gather per poll. By default, no maximum is set. Can be used to set a limit of e.g. 1000 to avoid when starting up the server that there are thousands of files. Set a value of 0 or negative to disabled it.

Camel will populate the result message, either IN or OUT with a header with the statement used:

Header Type Description
CamelMyBatisStatementName String The statementName used (for example: insertAccount).
CamelMyBatisResult Object The response returned from MtBatis in any of the operations. For instance an INSERT could return the auto-generated key, or number of rows etc.

Since this component does not support scheduled polling, you need to use another mechanism for triggering the scheduled polls, such as the Timer or Quartz components.

In the sample below we poll the database, every 30 seconds using the Timer component and send the data to the JMS queue:

from("timer://pollTheDatabase?delay=30000").to("mbatis:selectAllAccounts").to("activemq:queue:allAccounts");

And the MyBatis SQL mapping file used:

  <!-- Select with no parameters using the result map for Account class. -->
  <select id="selectAllAccounts" resultMap="AccountResult">
    select * from ACCOUNT
  </select>

Available as of Fuse Mediation Router 2.3

The Nagios component allows you to send passive checks to Nagios.

nagios://host[:port][?Options]

Fuse Mediation Router provides two abilities with the Nagios component. You can send passive check messages by sending a message to its endpoint. Fuse Mediation Router also provides a EventNotifer which allows you to send notifications to Nagios.

Name Default Value Description
host none This is the address of the Nagios host where checks should be send.
port The port number of the host.
password Password to be authenticated when sending checks to Nagios.
connectionTimeout 5000 Connection timeout in millis.
timeout 5000 Sending timeout in millis.
nagiosSettings To use an already configured com.googlecode.jsendnsca.core.NagiosSettings object.
sendSync true Whether or not to use synchronous when sending a passive check. Setting it to false will allow Fuse Mediation Router to continue routing the message and the passive check message will be send asynchronously.

Name Description
CamelNagiosHostName This is the address of the Nagios host where checks should be send. This header will override any existing hostname configured on the endpoint.
CamelNagiosLevel This is the severity level. You can use values CRITICAL, WARNING, OK. Fuse Mediation Router will by default use OK.
CamelNagiosServiceName The servie name. Will default use the CamelContext name.

You can send a message to Nagios where the message payload contains the message. By default it will be OK level and use the CamelContext name as the service name. You can overrule these values using headers as shown above.

For example we send the Hello Nagios message to Nagios as follows:

    template.sendBody("direct:start", "Hello Nagios");

    from("direct:start").to("nagios:127.0.0.1:5667?password=secret").to("mock:result");

To send a CRITICAL message you can send the headers such as:

        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);

The Nagios component also provides an EventNotifer which you can use to send events to Nagios. For example we can enable this from Java as follows:

        NagiosEventNotifier notifier = new NagiosEventNotifier();
        notifier.getConfiguration().setHost("localhost");
        notifier.getConfiguration().setPort(5667);
        notifier.getConfiguration().setPassword("password");

        CamelContext context = ... 
        context.getManagementStrategy().addEventNotifier(notifier);
        return context;

In Spring XML its just a matter of defining a Spring bean with the type EventNotifier and Fuse Mediation Router will pick it up as documented here: Advanced configuration of CamelContext using Spring.

Name Default Value Description
keepAlive true Setting to ensure socket is not closed due to inactivity
tcpNoDelay true Setting to improve TCP protocol performance
broadcast false Setting to choose Multicast over UDP
connectTimeout 10000 Time to wait for a socket connection to be available. Value is in millis.
reuseAddress true Setting to facilitate socket multiplexing
sync true Setting to set endpoint as one-way or request-response
ssl false Setting to specify whether SSL encryption is applied to this endpoint
sendBufferSize 65536 bytes The TCP/UDP buffer sizes to be used during outbound communication. Size is bytes.
receiveBufferSize 65536 bytes The TCP/UDP buffer sizes to be used during inbound communication. Size is bytes.
corePoolSize 10 The number of allocated threads at component startup. Defaults to 10
maxPoolSize 100 The maximum number of threads that may be allocated to this endpoint. Defaults to 100
disconnect false Whether or not to disconnect(close) from Netty Channel right after use. Can be used for both consumer and producer.
lazyChannelCreation true Channels can be lazily created to avoid exceptions, if the remote server is not up and running when the Fuse Mediation Router producer is started.
transferExchange false Only used for TCP. You can transfer the exchange over the wire instead of just the body. The following fields are transferred: In body, Out body, fault body, In headers, Out headers, fault headers, exchange properties, exchange exception. This requires that the objects are serializable. Fuse Mediation Router will exclude any non-serializable objects and log it at WARN level.
disconnectOnNoReply true If sync is enabled then this option dictates NettyConsumer if it should disconnect where there is no reply to send back.
noReplyLogLevel WARN If sync is enabled this option dictates NettyConsumer which logging level to use when logging a there is no reply to send back. Values are: FATAL, ERROR, INFO, DEBUG, OFF.
allowDefaultCodec true Camel 2.4: The netty component installs a default codec if both, encoder/deocder is null and textline is false. Setting allowDefaultCodec to false prevents the netty component from installing a default codec as the first element in the filter chain.
textline false Camel 2.4: Only used for TCP. If no codec is specified, you can use this flag to indicate a text line based codec; if not specified or the value is false, then Object Serialization is assumed over TCP.
delimiter LINE Camel 2.4: The delimiter to use for the textline codec. Possible values are LINE and NULL.
decoderMaxLineLength 1024 Camel 2.4: The max line length to use for the textline codec.
autoAppendDelimiter true Camel 2.4: Whether or not to auto append missing end delimiter when sending using the textline codec.
encoding null Camel 2.4: The encoding (a charset name) to use for the textline codec. If not provided, Camel will use the JVM default Charset.

Codec Handlers and SSL Keystores can be enlisted in the Registry, such as in the Spring XML file. The values that could be passed in, are the following:

Name Description
passphrase password setting to use in order to encrypt/decrypt payloads sent using SSH
keyStoreFormat keystore format to be used for payload encryption. Defaults to "JKS" if not set
securityProvider Security provider to be used for payload encryption. Defaults to "SunX509" if not set.
keyStoreFile Client side certificate keystore to be used for encryption
trustStoreFile Server side certificate keystore to be used for encryption
sslHandler Reference to a class that could be used to return an SSL Handler
encoder A custom Handler class that can be used to perform special marshalling of outbound payloads. Must override org.jboss.netty.channel.ChannelDownStreamHandler.
encorders A list of encoder to be used. You can use a String which have values separated by comma, and have the values be looked up in the Registry. Just remember to prefix the value with # so Fuse Mediation Router knows it should lookup.
decoder A custom Handler class that can be used to perform special marshalling of inbound payloads. Must override org.jboss.netty.channel.ChannelUpStreamHandler.
decoders A list of decorder to be used. You can use a String which have values separated by comma, and have the values be looked up in the Registry. Just remember to prefix the value with # so Fuse Mediation Router knows it should lookup.

In certain cases it may be necessary to add chains of encoders and decoders to the netty pipeline. To add multpile codecs to a Fuse Mediation Router netty endpoint the 'encoders' and 'decoders' uri parameters should be used. Like the 'encoder' and 'decoder' parameters they are used to supply references (to lists of ChannelUpstreamHandlers and ChannelDownstreamHandlers) that should be added to the pipeline. Note that if encoders is specified then the encoder param will be ignored, similarly for decoders and the decoder param.

The lists of codecs need to be added to the Fuse Mediation Router's registry so they can be resolved when the endpoint is created.

LengthFieldBasedFrameDecoder lengthDecoder = new LengthFieldBasedFrameDecoder(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<ChannelUpstreamHandler> decoders = new ArrayList<ChannelUpstreamHandler>();
decoders.add(lengthDecoder);
decoders.add(stringDecoder);

List<ChannelDownstreamHandler> encoders = new ArrayList<ChannelDownstreamHandler>();
encoders.add(lengthEncoder);
encoders.add(stringEncoder);

registry.bind("encoders", encoders);
registry.bind("decoders", decoders);

Spring's native collections support can be used to specify the codec lists in an application context

    <util:list id="decoders" list-class="java.util.LinkedList">
        <bean class="org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder">
            <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">
        <constructor-arg value="4"/>
    </bean>
    <bean id="string-encoder" class="org.jboss.netty.handler.codec.string.StringEncoder"/>

    <bean id="length-decoder" class="org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder">
        <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>

The bean names can then be used in netty endpoint definitions either as a comma separated list or contained in a List e.g.

                from("direct:multiple-codec").to("netty:tcp://localhost:5150?encoders=#encoders&sync=false");
                
                from("netty:tcp://localhost:5150?decoders=#length-decoder,#string-decoder&sync=false").to("mock:multiple-codec");
            }
        };
    }
}

or via spring.

<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&ync=false"/>
    </route>
    <route>
        <from uri="netty:tcp://localhost:5150?decoders=#length-decoder,#string-decoder&ync=false"/>
        <to uri="mock:multiple-codec"/>
    </route>
</camelContext>

Available as of Camel 2.5

Custom channel pipelines provide complete control to the user over the handler/interceptor chain by inserting custom handler(s), encoder(s) and decoders without having to specify them in the Netty Endpoint URL in a very simple way.

In order to add a custom pipeline, a custom channel pipeline factory must be created and registered with the context through the context registry (JNDIRegistry,or the Spring ApplicationContextRegistry etc).

A custom pipeline factory must be constructed as follows

The example below shows how ServerChannel Pipeline factory may be created

public class SampleServerChannelPipelineFactory extends ServerPipelineFactory {
    private int maxLineSize = 1024;
    private boolean invoked;

    public ChannelPipeline getPipeline() throws Exception {
        invoked = true;
      
        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));
        channelPipeline.addLast("handler", new ServerChannelHandler(consumer));

        return channelPipeline;
    }
      
    public boolean isfactoryInvoked() {
        return invoked;
    }
}

The custom channel pipeline factory can then be added to the registry and instantiated/utilized on a camel route as follows:

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);
            }
          }
    }
});

The nmr component is an adapter to the Normalized Message Router (NMR) in ServiceMix, which is intended for use by Camel applications deployed directly into the OSGi container. You can exchange objects with NMR and not only XML like this is the case with the JBI specification. The interest of this component is that you can interconnect camel routes deployed in different OSGI bundles.

By contrast, the JBI component is intended for use by Camel applications deployed into the ServiceMix JBI container.

An NMR endpoint supports the following options:

Option Default Value Description
synchronous false When this is set to true on a consumer endpoint, an incoming, synchronous NMR Exchange will be handled on the sender's thread instead of being handled on a new thread of the NMR endpoint's thread pool
runAsSubject false When this is set to true on a consumer endpoint, the endpoint will be invoked on behalf of the Subject that is set on the Exchange (i.e. the call to Subject.getSubject(AccessControlContext) returns the Subject instance)
timeout 0 When this is set to a value greater than 0, the producer endpoint will time out if it doesn't receive a response from the NMR within the given timeout period (in milliseconds). Configuring a timeout value will switch to using synchronous interactions with the NMR instead of the usual asynchronous messaging.

The pojo: component is now just an alias for the Bean component.

Has been removed in Fuse Mediation Router 2.0.

Name Default Value Description
mediaSize MediaSizeName.NA_LETTER Sets the stationary as defined by enumeration settings in the javax.print.attribute.standard.MediaSizeName API API. The default setting is to use North American Letter sized stationary
copies 1 Sets number of copies based on the javax.print.attribute.standard.Copies API
sides Sides.ONE_SIDED Sets one sided or two sided printing based on the javax.print.attribute.standard.Sides API
flavor DocFlavor.BYTE_ARRAY Sets DocFlavor based on the javax.print.DocFlavor API
mimeType AUTOSENSE Sets mimeTypes supported by the javax.print.DocFlavor API

Name Default value Description

Name Type Message Description

Name Type Default Description
cache boolean true Whether or not to cache loaded properties.
locations String null A list of locations to load properties. You can use comma to separate multiple locations. This option will override any default locations and only use the locations from this option.
  • Property Placeholders in Implementing Enterprise Integration Patterns

  • Jasypt for using encrypted values (for example, passwords) in the properties

The quartz: component provides a scheduled delivery of messages using the Quartz scheduler. Each endpoint represents a different timer (in Quartz terms, a Trigger and JobDetail).

Parameter Default Description
cron None Specifies a cron expression (not compatible with the trigger.\* or job.\* options).
trigger.repeatCount 0 SimpleTrigger: How many times should the timer repeat?
trigger.repeatInterval 0 SimpleTrigger: The amount of time in milliseconds between repeated triggers.
job.name null Sets the job name.
job._XXX_ null Sets the job option with the _XXX_ setter name.
trigger._XXX_ null Sets the trigger option with the _XXX_ setter name.
stateful false Uses a Quartz StatefulJob instead of the default job.
fireNow false New to Camel 2.2.0, if it is true will fire the trigger when the route is start when using SimpleTrigger.

For example, the following routing rule will fire two timer events to the mock:results endpoint:

from("quartz://myGroup/myTimerName?trigger.repeatInterval=2&trigger.repeatCount=1").routeId("myRoute").to("mock:result");

When using a StatefulJob, the JobDataMap is re-persisted after every execution of the job, thus preserving state for the next execution.

By default Quartz will look for a quartz.properties file in the root of the classpath. If you are using WAR deployments this means just drop the quartz.properties in WEB-INF/classes.

However the Camel Quartz component also allows you to configure properties:

Parameter Default Type Description
properties null Properties Camel 2.4: You can configure a java.util.Propoperties instance.
propertiesFile null String Camel 2.4: File name of the properties to load from the classpath

To do this you can configure this in Spring XML as follows

<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent">
    <property name="propertiesFile" value="com/mycompany/myquartz.properties"/>
</bean>

Available as of Camel 2.4

The Quartz component offers an option to let the Quartz scheduler be started delayed, or not auto started at all.

Parameter Default Type Description
startDelayedSeconds 0 int Camel 2.4: Seconds to wait before starting the quartz scheduler.
autoStartScheduler true boolean Camel 2.4: Whether or not the scheduler should be auto started.

To do this you can configure this in Spring XML as follows

<bean id="quartz" class="org.apache.camel.component.quartz.QuartzComponent">
    <property name="startDelayedSeconds" value="5"/>
</bean>

Available as of Camel 2.4

If you use Quartz in clustered mode, e.g. the JobStore is clustered. Then from Camel 2.4 onwards the Quartz component will not pause/remove triggers when a node is being stopped/shutdown. This allows the trigger to keep running on the other nodes in the cluster.

Note

When running in clustered node, no checking is done to ensure unique job name/group for endpoints.

Avaiable as of Fuse Mediation Router 2.0 Quartz supports Cron-like expressions for specifying timers in a handy format. You can use these expressions in the cron URI parameter; though to preserve valid URI encoding we allow + to be used instead of spaces. Quartz provides a little tutorial on how to use cron expressions.

For example the following will fire a message every five minutes starting at 12pm (noon) to 6pm on weekdays:

from("quartz://myGroup/myTimerName?cron=0+0/5+12-18+?+*+MON-FRI").to("activemq:Totally.Rocks");

which is equivalent to using the cron expression

0 0/5 12-18 ? * MON-FRI

The following table shows the URI character encodings we use to preserve valid URI syntax:

URI Character Cron character
\+ Space

@deprecated Quartz supports Cron-like expressions for specifying timers in a handy format. You can use these expressions in the URI; though to preserve valid URI encoding we allow / to be used instead of spaces and $ to be used instead of ?.

For example, the following endpoint URI will fire a message at 12pm (noon) every day

from("quartz://myGroup/myTimerName/0/0/12/*/*/$").to("activemq:Totally.Rocks");

which is equivalent to using the cron expression

0 0 12 * * ?

The following table shows the URI character encodings we use to preserve valid URI syntax:

URI Character Cron character
/ Space
$ ?

See also:

The queue: component provides asynchronous SEDA behaviour so that messages are exchanged on a BlockingQueue and consumers are invoked in a seperate thread pool to the producer.

Note that queues are only visible within a single CamelContext. If you want to communicate across CamelContext instances such as to communicate across web applications, see the VM component.

Note also that this component has nothing to do with JMS, if you want a distributed SEA then try using either JMS or ActiveMQ or even MINA

Available as of Camel 2.0

The quickfix component adapts the QuickFIX/J FIX engine for using in Camel . This component uses the standard Financial Interchange (FIX) protocol for message transport.

Previous Versions

The quickfix component was rewritten for Camel 2.5. For information about using the quickfix component prior to 2.5 see the documentation section below.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

The exchange headers include information to help with exchange filtering, routing and other processing. The following headers are available:

Header Name Description
EventCategory One of AppMessageReceived, AppMessageSent, AdminMessageReceived, AdminMessageSent, SessionCreated, SessionLogon, SessionLogoff. See the QuickfixjEventCategory enum.
SessionID The FIX message SessionID
MessageType The FIX MsgType tag value
DataDictionary Specifies a data dictionary to used for parsing an incoming message. Can be an instance of a data dictionary or a resource path for a QuickFIX/J data dictionary file

The DataDictionary header is useful if string messages are being received and need to be parsed in a route. QuickFIX/J requires a data dictionary to parse certain types of messages (with repeating groups, for example). By injecting a DataDictionary header in the route after receiving a message string, the FIX engine can properly parse the data.

When the component detects an initiator or acceptor session setting in the QuickFIX/J configuration file it will automatically create the corresponding initiator and/or acceptor connector. These settings can be in the default or in a specific session section of the configuration file.

Session Setting Component Action
ConnectionType=initiator Create an initiator connector
ConnectionType=acceptor Create an acceptor connector

The threading model for the QuickFIX/J session connectors can also be specified. These settings affect all sessions in the configuration file and must be placed in the settings default section.

Default/Global Setting Component Action
ThreadModel=ThreadPerConnector Use SocketInitiator or SocketAcceptor (default)
ThreadModel=ThreadPerSession Use ThreadedSocketInitiator or ThreadedSocketAcceptor

The QuickFIX/J logger implementation can be specified by including the following settings in the default section of the configuration file. The ScreenLog is the default if none of the following settings are present in the configuration. It's an error to include settings that imply more than one log implementation.

Default/Global Setting Component Action
ScreenLogShowEvents Use a ScreenLog
ScreenLogShowIncoming Use a ScreenLog
ScreenLogShowOutgoing Use a ScreenLog
SLF4J* Camel 2.6+. Use a SLF4JLog. Any of the SLF4J settings will cause this log to be used.
FileLogPath Use a FileLog
JdbcDriver Use a JdbcLog
Default/Global Setting Component Action
UseJmx if Y, then enable QuickFIX/J JMX

Camel 2.6+

The QuickFIX/J component includes a Spring FactoryBean for configuring the session settings within a Spring context. A type converter for QuickFIX/J session ID strings is also included. The following example shows a simple configuration of an acceptor and initiator session with default settings for both sessions.

<!-- 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>
      <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>
    

Available since Camel 2.0

The quickfix component is an implementation of the QuickFIX/J engine for Java . This engine allows to connect to a FIX server which is used to exchange financial messages according to FIX protocol standard.

Note: The component can be used to send/receives messages to a FIX server.

ref:someName

Where someName is the name of an endpoint in the Registry (usually, but not always, the Spring registry). If you are using the Spring registry, someName would be the bean ID of an endpoint in the Spring registry.

This component can be used when you need dynamic discovery of endpoints in the Registry where you can compute the URI at runtime. Then you can look up the endpoint using the following code:

   // 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);
   ...

And you could have a list of endpoints defined in the Registry such as:

  <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>

The Restlet component provides Restlet based endpoints for consuming and producing RESTful resources.

restlet:restletUrl[?options]

Format of restletUrl:

protocol://hostname[:port][/resourcePattern]

Restlet promotes decoupling of protocol and application concerns. The reference implementation of Restlet Engine supports a number of protocols. However, we have tested the HTTP protocol only. The default port is port 80. We do not automatically switch default port based on the protocol yet.

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default Value Description
headerFilterStrategy=#refName (2.x or later) An instance of RestletHeaderFilterStrategy Use the # notation (headerFilterStrategy=#refName) to reference a header filter strategy in the Camel Registry. The strategy will be plugged into the restlet binding if it is HeaderFilterStrategyAware.
restletBindingRef (1.x), An instance of DefaultRestletBinding The bean ID of a RestletBinding object in the Camel Registry.
restletBinding (2.x or later), restletBinding=#refName. An instance of DefaultRestletBinding The bean ID of a RestletBinding object in the Camel Registry.
restletMethod GET On a producer endpoint, specifies the request method to use. On a consumer endpoint, specifies that the endpoint consumes only restletMethod requests. The string value is converted to org.restlet.data.Method by the Method.valueOf(String) method.
restletMethod GET On a producer endpoint, specifies the request method to use. On a consumer endpoint, specifies that the endpoint consumes only restletMethod requests. The string value is converted to org.restlet.data.Method by the Method.valueOf(String) method.
restletMethods (2.x or later) None Consumer only Specify one or more methods separated by commas (e.g. restletMethods=post,put) to be serviced by a restlet consumer endpoint. If both restletMethod and restletMethods options are specified, the restletMethod setting is ignored.
restletRealmRef (1.x), null The bean ID of the Realm Map in the Camel Registry.
restletUriPatterns=#refName (2.x or later) None Consumer only Specify one ore more URI templates to be serviced by a restlet consumer endpoint, using the # notation to reference a List<String> in the Camel Registry. If a URI pattern has been defined in the endpoint URI, both the URI pattern defined in the endpoint and the restletUriPatterns option will be honored.
throwExceptionOnFailure (2.6 or later) true Producer only Throws exception on a producer failure.
Name Type Description
org.apache.camel.restlet.auth.login String Login name for basic authentication. It is set on the IN message by the application and gets filtered before the restlet request header by Fuse Mediation Router.
org.apache.camel.restlet.auth.password String Password name for basic authentication. It is set on the IN message by the application and gets filtered before the restlet request header by Fuse Mediation Router.
org.apache.camel.restlet.mediaType String Specifies the content type, which can be set on the OUT message by the application/processor. The value is the content-type of the response message. If this header is not set, the content-type is set based on the object type of the OUT message body.
org.apache.camel.restlet.queryString String The query string of the request URI. It is set on the IN message by DefaultRestletBinding when the restlet component receives a request.
org.apache.camel.restlet.responseCode String or Integer The response code can be set on the OUT message by the application/processor. The value is the response code of the response message. If this header is not set, the response code is set by the restlet runtime engine.
org.restlet.* Attributes of a restlet message that get propagated to Fuse Mediation Router IN headers.
Name Type Description
CamelContentType String Specifies the content type, which can be set on the OUT message by the application/processor. The value is the content-type of the response message. If this header is not set, the content-type is based on the object type of the OUT message body. In Camel 2.3 onward, if the Content-Type header is specified in the Camel IN message, the value of the header determine the content type for the Restlet request message. nbsp; Otherwise, it is defaulted to "application/x-www-form-urlencoded'. Prior to release 2.3, it is not possible to change the request content type default.
CamelHttpMethod String The HTTP request method. This is set in the IN message header.
CamelHttpQuery String The query string of the request URI. It is set on the IN message by DefaultRestletBinding when the restlet component receives a request.
CamelHttpResponseCode String or Integer The response code can be set on the OUT message by the application/processor. The value is the response code of the response message. If this header is not set, the response code is set by the restlet runtime engine.
CamelHttpUri String The HTTP request URI. This is set in the IN message header.
CamelRestletLogin String Login name for basic authentication. It is set on the IN message by the application and gets filtered before the restlet request header by Fuse Mediation Router.
CamelRestletPassword String Password name for basic authentication. It is set on the IN message by the application and gets filtered before the restlet request header by Fuse Mediation Router.
CamelRestletRequest Request Camel 2.8: The org.restlet.Request object which holds all request details.
CamelRestletResponse Response Camel 2.8: The org.restlet.Response object. You can use this to create responses using the API from Restlet. See examples below.
org.restlet.* Attributes of a Restlet message that get propagated to Fuse Mediation Router IN headers.

The following route starts a restlet consumer endpoint that listens for POST requests on http://localhost:8080 . The processor creates a response that echoes the request body and the value of the id header.

from("restlet:http://localhost:9080/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"));
    }
});

The restletRealm setting (in Fuse Mediation Router 2.x, use the # notation, that is, restletRealm=#refName) in the URI query is used to look up a Realm Map in the registry. If this option is specified, the restlet consumer uses the information to authenticate user logins. Only authenticated requests can access the resources. In this sample, we create a Spring application context that serves as a registry. The bean ID of the Realm Map should match the restletRealmRef.

<util:map id="realm">
	<entry key="admin" value="foo" />
	<entry key="bar" value="foo" />
</util:map>

The following sample starts a direct endpoint that sends requests to the server on http://localhost:8080 (that is, our restlet consumer endpoint).

// 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:9080/securedOrders?restletMethod=post");

That is all we need. We are ready to send a request and try out the restlet component:

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);

The sample client sends a request to the direct:start-auth endpoint with the following headers:

  • CamelRestletLogin (used internally by Fuse Mediation Router)

  • CamelRestletPassword (used internally by Fuse Mediation Router)

  • id (application header)

Note

org.apache.camel.restlet.auth.login and org.apache.camel.restlet.auth.password will not be propagated as Restlet header.

The sample client gets a response like the following:

received [<order foo='1'/>] as an order id = 89531

It is possible to create a single route to service multiple HTTP methods using the restletMethods option. This snippet also shows how to retrieve the request method from the header:

from("restlet:http://localhost:9080/users/{username}?restletMethods=post,get")
    .process(new Processor() {
        public void process(Exchange exchange) throws Exception {
            // echo the method
            exchange.getOut().setBody(exchange.getIn().getHeader(Exchange.HTTP_METHOD,
                                                                 String.class));

        }
    });

In addition to servicing multiple methods, the next snippet shows how to create an endpoint that supports multiple URI templates using the restletUriPatterns option. The request URI is available in the header of the IN message as well. If a URI pattern has been defined in the endpoint URI (which is not the case in this sample), both the URI pattern defined in the endpoint and the restletUriPatterns option will be honored.

from("restlet:http://localhost:9080?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:9080/users/homer".equals(uri)) {
                exchange.getOut().setBody(out + " " + exchange.getIn().getHeader("username", String.class));
            } else if ("http://localhost:9080/atom/collection/foo/component/bar".equals(uri)) {
                exchange.getOut().setBody(out + " " + exchange.getIn().getHeader("id", String.class)
                                          + " " + exchange.getIn().getHeader("cid", String.class));

            }

        }
    });

The restletUriPatterns=#uriTemplates option references the List<String> bean defined in the Spring XML configuration.

<util:list id="uriTemplates">
    <value>/users/{username}</value>
    <value>/atom/collection/{id}/component/{cid}</value>
</util:list>

Available as of Camel 2.8

You may want to use the org.restlet.Response API to populate the response. This gives you full access to the Restlet API and fine grained control of the response. See the route snippet below where we generate the response from an inlined Camel Processor:

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);
         }
     });
 

Available as of Camel 2.8 There are three possible ways to configure a Restlet application within a servlet container and using the subclassed SpringServerServlet enables configuration within Camel by injecting the Restlet Component.

Use of the Restlet servlet within a servlet container enables routes to be configured with relative paths in URIs (removing the restrictions of hard-coded absolute URIs) and for the hosting servlet container to handle incoming requests (rather than have to spawn a separate server process on a new port).

To configure, add the following to your camel-context.xml;

 <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>

And add this to your web.xml;

 <!-- 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>

You will then be able to access the deployed route at http://localhost:8080/mywebapp/rs/demo/1234 where;

localhost:8080 is the server and port of your servlet container mywebapp is the name of your deployed webapp Your browser will then show the following content;

"Request type : GET and ID : 1234"

You will need to add dependency on the Spring extension to restlet which you can do in your Maven pom.xml file:

 <dependency>
   <groupId>org.restlet.jee</groupId>
   <artifactId>org.restlet.ext.spring</artifactId>
   <version>${restlet-version}</version>
 </dependency>

And you would need to add dependency on the restlet maven repository as well:

 <repository>  
    <id>maven-restlet</id>  
    <name>Public online Restlet repository</name>  
    <url>http://maven.restlet.org</url>  
 </repository>

The rmi: component binds PojoExchanges to the RMI protocol (JRMP).

Since this binding is just using RMI, normal RMI rules still apply regarding what methods can be invoked. This component supports only PojoExchanges that carry a method invocation from an interface that extends the Remote interface. All parameters in the method should be either Serializable or Remote objects.

Name Default Value Description
method null As of Fuse Mediation Router 1.3, you can set the name of the method to invoke.
remoteInterfaces null Its now possible to use this option from Camel 2.7: in the XML DSL. It can be a list of interface names separated by comma.

Available as of Camel 2.6

The routebox component enables the creation of specialized endpoints that offer encapsulation and a strategy based indirection service to a collection of camel routes hosted in an automatically created or user injected camel context.

Routebox endpoints are camel endpoints that may be invoked directly on camel routes. The routebox endpoint performs the following key functions * encapsulation - acts as a blackbox, hosting a collection of camel routes stored in an inner camel context. The inner context is fully under the control of the routebox component and is JVM bound. * strategy based indirection - direct payloads sent to the routebox endpoint along a camel route to specific inner routes based on a user defined internal routing strategy or a dispatch map. * exchange propagation - forward exchanges modified by the routebox endpoint to the next segment of the camel route.

The routebox component supports both consumer and producer endpoints.

Producer endpoints are of two flavors * Producers that send or dispatch incoming requests to a external routebox consumer endpoint * Producers that directly invoke routes in an internal embedded camel context thereby not sending requests to an external consumer.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-routebox</artifactId>
    <version>x.x.x</version>
    <!-- use the same version as your Camel core version -->
</dependency>

Name Default Value Description
dispatchStrategy null A string representing a key in the Camel Registry matching an object value implementing the interface org.apache.camel.component.routebox.strategy.RouteboxDispatchStrategy
dispatchMap null A string representing a key in the Camel Registry matching an object value of the type HashMap<String, String>. The HashMap key should contain strings that can be matched against the value set for the exchange header ROUTE_DISPATCH_KEY. The HashMap value should contain inner route consumer URI's to which requests should be directed.
innerContext auto created A string representing a key in the Camel Registry matching an object value of the type org.apache.camel.CamelContext. If a CamelContext is not provided by the user a CamelContext is automatically created for deployment of inner routes.
innerRegistry null A string representing a key in the Camel Registry matching an object value that implements the interface org.apache.camel.spi.Registry. If Registry values are utilized by inner routes to create endpoints, an innerRegistry parameter must be provided
routeBuilders empty List A string representing a key in the Camel Registry matching an object value of the type List<org.apache.camel.builder.RouteBuilder>. If the user does not supply an innerContext pre-primed with inner routes, the routeBuilders option must be provided as a non-empty list of RouteBuilders containing inner routes
innerProtocol Direct The Protocol used internally by the Routebox component. Can be Direct or SEDA. The Routebox component currently offers protocols that are JVM bound.
sendToConsumer true Dictates whether a Producer endpoint sends a request to an external routebox consumer. If the setting is false, the Producer creates an embedded inner context and processes requests internally.
forkContext true The Protocol used internally by the Routebox component. Can be Direct or SEDA. The Routebox component currently offers protocols that are JVM bound.
threads 20 Number of threads to be used by the routebox to receive requests. Setting applicable only for innerProtocol SEDA.
queueSize unlimited Create a fixed size queue to receive requests. Setting applicable only for innerProtocol SEDA.

Property Default Description
splitEntries true If true, Fuse Mediation Router splits a feed into its individual entries and returns each entry, poll by poll. For example, if a feed contains seven entries, Fuse Mediation Router returns the first entry on the first poll, the second entry on the second poll, and so on. When no more entries are left in the feed, Fuse Mediation Router contacts the remote RSS URI to obtain a new feed. If false, Fuse Mediation Router obtains a fresh feed on every poll and returns all of the feed's entries.
filter true Use in combination with the splitEntries option in order to filter returned entries. By default, Fuse Mediation Router applies the UpdateDateFilter filter, which returns only new entries from the feed, ensuring that the consumer endpoint never receives an entry more than once. The filter orders the entries chronologically, with the newest returned last.
throttleEntries true Camel 2.5: Sets whether all entries identified in a single feed poll should be delivered immediately. If true, only one entry is processed per consumer.delay. Only applicable when splitEntries is set to true.
lastUpdate null Use in combination with the filter option to block entries earlier than a specific date/time (uses the entry.updated timestamp). The format is: yyyy-MM-ddTHH:MM:ss. Example: 2007-12-24T17:45:59.
feedHeader true Specifies whether to add the ROME SyndFeed object as a header.
sortEntries false If splitEntries is true, this specifies whether to sort the entries by updated date.
consumer.delay 60000 Delay in milliseconds between each poll.
consumer.initialDelay 1000 Milliseconds before polling starts.
consumer.userFixedDelay false Set to true to use fixed delay between pools, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.

Fuse Mediation Router initializes the In body on the Exchange with a ROME SyndFeed. Depending on the value of the splitEntries flag, Fuse Mediation Router returns either a SyndFeed with one SyndEntry or a java.util.List of SyndEntrys.

Option Value Behavior
splitEntries true A single entry from the current feed is set in the exchange.
splitEntries false The entire list of entries from the current feed is set in the exchange.
Header Description
org.apache.camel.component.rss.feed Fuse Mediation Router 1.x: The entire SyncFeed object.
CamelRssFeed Fuse Mediation Router 2.0: The entire SyncFeed object.

You can filter out entries quite easily using XPath, as shown in the data format section above. You can also exploit Fuse Mediation Router's Bean Integration to implement your own conditions. For instance, a filter equivalent to the XPath example above would be:

// 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");

The custom bean for this would be:

public static class FilterBean {
    public boolean titleContainsCamel(@Body SyndFeed feed) {
        SyndEntry firstEntry = (SyndEntry) feed.getEntries().get(0);
        return firstEntry.getTitle().contains("Camel");
    }
}

Available as of Fuse Mediation Router 2.3

The scalate: component allows you to process a message using Scalate template, which supports either SSP or Scaml format templates. This can be ideal when using Templating to generate responses for requests.

Maven users will need to add the following dependency to their pom.xml for this component:

<dependency>
    <groupId>org.fusesource.scalate</groupId>
    <artifactId>scalate-camel</artifactId>
    <version>1.0</version>
</dependency>

Fuse Mediation Router will provide exchange information in the Scalate context (just a Map). The Exchange is transfered as:

key value
exchange The Exchange itself.
headers The headers of the In message.
camelContext The Camel Context intance.
request The In message.
in The In message.
body The In message body.
out The Out message (only for InOut message exchange pattern).
response The Out message (only for InOut message exchange pattern).

The seda: component provides asynchronous SEDA behavior, so that messages are exchanged on a BlockingQueue and consumers are invoked in a separate thread from the producer.

Note that queues are only visible within a single CamelContext. If you want to communicate across CamelContext instances (for example, communicating between Web applications), see the VM component.

This component does not implement any kind of persistence or recovery, if the VM terminates while messages are yet to be processed. If you need persistence, reliability or distributed SEDA, try using either JMS or ActiveMQ.

Synchronous

The Direct component provides synchronous invocation of any consumers when a producer sends a message exchange.

seda:queueName[?options]

Where queueName can be any string that uniquely identifies the endpoint within the current CamelContext.

You can append query options to the URI in the following format, ?option=value&option=value&...

Note

When matching consumer entpoints to producer endpoints, only the queueName is considered and any option settings are ignored. That is, the identity of a consumer endpoint depends only on the queueName. If you want to attach multiple consumers to the same queue, use the approach described in Using multipleConsumers.

Name Default Description
size Unbounded The maximum size (= capacity of the number of messages it can max hold) of the SEDA queue. The default value in Camel 2.2 or older is 1000. From Camel 2.3 onwards the size is unbounded by default.
concurrentConsumers 1 Fuse Mediation Router 1.6.1/2.0: Number of concurrent threads processing exchanges.
waitForTaskToComplete IfReplyExpected Fuse Mediation Router 2.0: Option to specify whether the caller should wait for the async task to complete or not before continuing. The following three options are supported: Always, Never or IfReplyExpected. The first two values are self-explanatory. The last value, IfReplyExpected, will only wait if the message is Request Reply based. The default option is IfReplyExpected. See more information about Async messaging.
timeout 30000 Fuse Mediation Router 2.0: Timeout in millis a seda producer will at most waiting for an async task to complete. See waitForTaskToComplete and Async for more details. In Camel 2.2 you can now disable timeout by using 0 or a negative value.
multipleConsumers false Camel 2.2: Specifies whether multiple consumers are allowed or not. If enabled, you can use SEDA for a publish/subscribe style of messaging. Send a message to a SEDA queue and have multiple consumers receive a copy of the message.
limitConcurrentConsumers true Camel 2.3: Whether to limit the concurrentConsumers to maximum 500. If its configured with a higher number an exception will be thrown. You can disable this check by turning this option off.

In Fuse Mediation Router 2.0 the Seda component supports using Request Reply, where the caller will wait for the Async route to complete. For instance:

from("mina:tcp://0.0.0.0:9876?textline=true&sync=true").to("seda:input");

from("seda:input").to("bean:processInput").to("bean:createResponse");

In the route above, we have a TCP listener on port 9876 that accepts incoming requests. The request is routed to the seda:input queue. As it is a Request Reply message, we wait for the response. When the consumer on the seda:input queue is complete, it copies the response to the original message response.

Fuse Mediation Router 1.x does not have this feature implemented, the Seda queues in Fuse Mediation Router 1.x will never wait.

Camel 2.0 - 2.2: Works only with 2 endpoints

Using Request Reply over SEDA or VM only works with 2 endpoints. You cannot chain endpoints by sending to A -> B -> C etc. Only between A -> B. The reason is the implementation logic is fairly simple. To support 3+ endpoints makes the logic much more complex to handle ordering and notification between the waiting threads properly.

This has been improved in Camel 2.3 onwards, which allows you to chain as many endpoints as you like.

Be aware that adding a thread pool to a SEDA endpoint by doing something like:

from("seda:stageName").thread(5).process(...)

Can wind up with two BlockQueues: one from the SEDA endpoint, and one from the workqueue of the thread pool, which may not be what you want. Instead, you might want to consider configuring a Direct endpoint with a thread pool, which can process messages both synchronously and asynchronously. For example:

from("direct:stageName").thread(5).process(...)

You can also directly configure number of threads that process messages on a SEDA endpoint using the concurrentConsumers option.

The servlet: component provides HTTP based endpoints for consuming HTTP requests that arrive at a HTTP endpoint and this endpoint is bound to a published Servlet.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>
Name Default Value Description
httpBindingRef null Reference to an org.apache.camel.component.http.HttpBinding in the Registry. A HttpBinding implementation can be used to customize how to write a response.
matchOnUriPrefix false Whether or not the CamelServlet should try to find a target consumer by matching the URI prefix, if no exact match is found.
servletName null Specifies the servlet name that the servlet endpoint will bind to. If there is no servlet name specified, the servlet endpoint will be bind to first published Servlet

Fuse Mediation Router will apply the same Message Headers as the HTTP component.

Fuse Mediation Router will also populate allrequest.parameter and request.headers. For example, if a client request has the URL, http://myserver/myserver?orderid=123, the exchange will contain a header named orderid with the value 123.

In this sample, we define a route that exposes a HTTP service at http://localhost:8080/camel/services/hello. First, you need to publish the CamelHttpTransportServlet through the normal Web Container, or OSGi Service. Use the Web.xml file to publish the CamelHttpTransportServlet as follows:

<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>

Then you can define your route as follows:

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_PATH, String.class);
        assertEquals("Get a wrong content type", CONTENT_TYPE, contentType);
        // assert camel http header
        String charsetEncoding = exchange.getIn().getHeader(Exchange.HTTP_CHARACTER_ENCODING, String.class);
        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>");
    }
});

Specify the relative path for camel-servlet endpoint

Since we are binding the Http transport with a published servlet, and we don't know the servlet's application context path, the camel-servlet endpoint uses the relative path to specify the endpoint's URL. A client can access the camel-servlet endpoint through the servlet publish address: ("http://localhost:8080/camel/services") + RELATIVE_PATH("/hello").

The standalone Fuse Mediation Router package contains a demonstration of how to deploy the Servlet component in the Tomcat Web container. The demonstration is located in the examples/camel-example-servlet-tomcat directory. When deploying a Servlet component in the Web container, it is necessary to create a Spring application context explicitly by creating a Spring ContextLoaderListener instance in the WEB-INF/web.xml file.

For example, to create a Spring application context that loads Spring definitions (including the camelContext and route definitions) from the camel-config.xml file, define a web.xml file as follows:

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>My Web Application</display-name>

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

    <!-- the listener that kick-starts Spring -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Camel servlet -->
    <servlet>
        <servlet-name>CamelServlet</servlet-name>
        <servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Camel servlet mapping -->
    <servlet-mapping>
        <servlet-name>CamelServlet</servlet-name>
        <url-pattern>/camel/*</url-pattern>
    </servlet-mapping>

</web-app>

When using the Servlet component in a Camel/Spring application it's often required to load the Spring ApplicationContext after the Servlet component has started. This can be accomplished by using Spring's ContextLoaderServlet instead of ContextLoaderListener. In that case you'll need to start ContextLoaderServlet after CamelHttpTransportServlet like this:

<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> 
  </servlet> 
<web-app>

From Camel 2.6.0, you can publish the CamelHttpTransportServlet as an OSGi service with help of SpringDM like this.

<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" />
            <entry key="matchOnUriPrefix" value="true" />
            <entry key="servlet-name" value="CamelServlet"/>
        </osgi:service-properties>
    </osgi:service>

</beans>

Then use this service in your camel route like this:

<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>

Alternatively - pre Camel 2.6 - you can use an Activator to publish the CamelHttpTransportServlet on the OSGi platform

import java.util.Dictionary;
import java.util.Hashtable;

import org.apache.camel.component.servlet.CamelHttpTransportServlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import 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>();
                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);
        }
    }

}

Name Default Value Type Description
iniResourcePath or ini none Resource String or Ini Object A mandatory Resource String for the iniResourcePath or an instance of an Ini object must be passed to the security policy. Resources can be acquired from the file system, classpath, or URLs when prefixed with "file:, classpath:, or url:" respectively. For e.g "classpath:shiro.ini"
passPhrase An AES 128 based key byte[] A passPhrase to decrypt ShiroSecurityToken(s) sent along with Message Exchanges
alwaysReauthenticate true boolean Setting to ensure re-authentication on every individual request. If set to false, the user is authenticated and locked such than only requests from the same user going forward are authenticated.
permissionsList none List<Permission> A List of permissions required in order for an authenticated user to be authorized to perform further action i.e continue further on the route. If no Permissions list is provided to the ShiroSecurityPolicy object, then authorization is deemed as not required
cipherService AES org.apache.shiro.crypto.CipherService Shiro ships with AES & Blowfish based CipherServices. You may use one these or pass in your own Cipher implementation

Available as of Camel 2.5

The sip component in Camel is a communication component, based on the Jain SIP implementation (available under the JCP license).

Session Initiation Protocol (SIP) is an IETF-defined signaling protocol, widely used for controlling multimedia communication sessions such as voice and video calls over Internet Protocol (IP).The SIP protocol is an Application Layer protocol designed to be independent of the underlying transport layer; it can run on Transmission Control Protocol (TCP), User Datagram Protocol (UDP) or Stream Control Transmission Protocol (SCTP).

The Jain SIP implementation supports TCP and UDP only.

The Camel SIP component only supports the SIP Publish and Subscribe capability as described in the RFC3903 - Session Initiation Protocol (SIP) Extension for Event

This camel component supports both producer and consumer endpoints.

Camel SIP Producers (Event Publishers) and SIP Consumers (Event Subscribers) communicate event & state information to each other using an intermediary entity called a SIP Presence Agent (a stateful brokering entity).

For SIP based communication, a SIP Stack with a listener must be instantiated on both the SIP Producer and Consumer (using separate ports if using localhost). This is necessary in order to support the handshakes & acknowledgements exchanged between the SIP Stacks during communication.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

The SIP Component offers an extensive set of configuration options & capability to create custom stateful headers needed to propagate state via the SIP protocol.

Name Default Value Description
stackName NAME_NOT_SET Name of the SIP Stack instance associated with an SIP Endpoint.
transport tcp Setting for choice of transport potocol. Valid choices are "tcp" or "udp".
fromUser Username of the message originator. Mandatory setting unless a registry based custom FromHeader is specified.
fromHost Hostname of the message originator. Mandatory setting unless a registry based FromHeader is specified
fromPort Port of the message originator. Mandatory setting unless a registry based FromHeader is specified
toUser Username of the message receiver. Mandatory setting unless a registry based custom ToHeader is specified.
toHost Hostname of the message receiver. Mandatory setting unless a registry based ToHeader is specified
toPort Portname of the message receiver. Mandatory setting unless a registry based ToHeader is specified
maxforwards 0 the number of intermediaries that may forward the message to the message receiver. Optional setting. May alternatively be set using as registry based MaxForwardsHeader
eventId Setting for a String based event Id. Mandatory setting unless a registry based FromHeader is specified
eventHeaderName Setting for a String based event Id. Mandatory setting unless a registry based FromHeader is specified
maxMessageSize 1048576 Setting for maximum allowed Message size in bytes.
cacheConnections false Should connections be cached by the SipStack to reduce cost of connection creation. This is useful if the connection is used for long running conversations.
consumer false This setting is used to determine whether the kind of header (FromHeader,ToHeader etc) that needs to be created for this endpoint
automaticDialogSupport off Setting to specify whether every communication should be associated with a dialog.
contentType text Setting for contentType can be set to any valid MimeType.
contentSubType xml Setting for contentSubType can be set to any valid MimeSubType.
receiveTimeoutMillis 10000 Setting for specifying amount of time to wait for a Response and/or Acknowledgement can be received from another SIP stack
useRouterForAllUris false This setting is used when requests are sent to the Presence Agent via a proxy.
msgExpiration 3600 The amount of time a message received at an endpoint is considered valid
presenceAgent false This setting is used to distingish between a Presence Agent & a consumer. This is due to the fact that the SIP Camel component ships with a basic Presence Agent (for testing purposes only). Consumers have to set this flag to true.

SIP requires a number of headers to be sent/received as part of a request. These SIP header can be enlisted in the Registry, such as in the Spring XML file.

The values that could be passed in, are the following:

Name Description
fromHeader a custom Header object containing message originator settings. Must implement the type javax.sip.header.FromHeader
toHeader a custom Header object containing message receiver settings. Must implement the type javax.sip.header.ToHeader
viaHeaders List of custom Header objects of the type javax.sip.header.ViaHeader. Each ViaHeader containing a proxy address for request forwarding. (Note this header is automatically updated by each proxy when the request arrives at its listener)
contentTypeHeader a custom Header object containing message content details. Must implement the type javax.sip.header.ContentTypeHeader
callIdHeader a custom Header object containing call details. Must implement the type javax.sip.header.CallIdHeader
maxForwardsHeader a custom Header object containing details on maximum proxy forwards. This header places a limit on the viaHeaders possible. Must implement the type javax.sip.header.MaxForwardsHeader
eventHeader a custom Header object containing event details. Must implement the type javax.sip.header.EventHeader
contactHeader an optional custom Header object containing verbose contact details (email, phone number etc). Must implement the type javax.sip.header.ContactHeader
expiresHeader a custom Header object containing message expiration details. Must implement the type javax.sip.header.ExpiresHeader
extensionHeader a custom Header object containing user/application specific details. Must implement the type javax.sip.header.ExtensionHeader

In the example below, a SIP Subscriber is created to receive SIP Event publications sent to a user "johndoe@localhost:5154"

@Override  
protected RouteBuilder createRouteBuilder() throws Exception {  
    return new RouteBuilder() {  
        @Override  
        public void configure() throws Exception {    
            // Create PresenceAgent  
            from("sip://agent@localhost:5152?stackName=PresenceAgent&presenceAgent=true&eventHeaderName=evtHdrName&eventId=evtid")  
                .to("mock:neverland");  
                  
            // Create Sip Consumer(Event Subscriber)  
            from("sip://johndoe@localhost:5154?stackName=Subscriber&toUser=agent&toHost=localhost&toPort=5152&eventHeaderName=evtHdrName&eventId=evtid")  
                .to("log:ReceivedEvent?level=DEBUG")  
                .to("mock:notification");  
                  
        }  
    };  
}  

The Camel SIP component also ships with a Presence Agent that is meant to be used for Testing and Demo purposes only. An example of instantiating a Presence Agent is given above.

Note that the Presence Agent is set up as a user agent@localhost:5152 and is capable of communicating with both Publisher as well as Subscriber. It has a separate SIP stackName distinct from Publisher as well as Subscriber. While it is set up as a Camel Consumer, it does not actually send any messages along the route to the endpoint "mock:neverland".

The camel-smooks component from Camel Extra has been removed. The Smooks Library integrates natively with Camel and we encourage end users to use that.

This component provides access to an SMSC (Short Message Service Center) over the SMPP protocol to send and receive SMS. The JSMPP is used.

Using Fuse Mediation Router 2.2 onwards

This component is only available for Fuse Mediation Router 2.2 or newer.

Name Default Value Description
password password Specifies the password to use to log in to the SMSC.
systemType cp This parameter is used to categorize the type of ESME (External Short Message Entity) that is binding to the SMSC (max. 13 characters).
dataCoding 0

Camel 2.5 onwarts Defines encoding of data according the SMPP 3.4 specification, section 5.2.19. Example data encodings are: 0: SMSC Default Alphabet 4: 8 bit Alphabet 8: UCS2 Alphabet

encoding ISO-8859-1 Defines the encoding scheme of the short message user data.
enquireLinkTimer 5000 Defines the interval in milliseconds between the confidence checks. The confidence check is used to test the communication path between an ESME and an SMSC.
transactionTimer 10000 Defines the maximum period of inactivity allowed after a transaction, after which an SMPP entity may assume that the session is no longer active. This timer may be active on either communicating SMPP entity (i.e. SMSC or ESME).
initialReconnectDelay 5000 Defines the initial delay in milliseconds after the consumer/producer tries to reconnect to the SMSC, after the connection was lost.
reconnectDelay 5000 Defines the interval in milliseconds between the reconnect attempts, if the connection to the SMSC was lost and the previous was not succeed.
registeredDelivery 1

Is used to request an SMSC delivery receipt and/or SME originated acknowledgements. The following values are defined: 0: No SMSC delivery receipt requested. 1: SMSC delivery receipt requested where final delivery outcome is success or failure. 2: SMSC delivery receipt requested where the final delivery outcome is delivery failure.

serviceType CMT

The service type parameter can be used to indicate the SMS Application service associated with the message. The following generic service_types are defined:

  • CMT: Cellular Messaging

  • CPT: Cellular Paging

  • VMN: Voice Mail Notification

  • VMA: Voice Mail Alerting

  • WAP: Wireless Application Protocol

  • USSD: Unstructured Supplementary Services Data

sourceAddr 1616 Defines the address of SME (Short Message Entity) which originated this message.
destAddr 1717 Defines the destination SME address. For mobile terminated messages, this is the directory number of the recipient MS.
sourceAddrTon 0

Defines the type of number (TON) to be used in the SME originator address parameters. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

destAddrTon 0

Defines the type of number (TON) to be used in the SME destination address parameters. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

sourceAddrNpi 0

Defines the numeric plan indicator (NPI) to be used in the SME originator address parameters. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

destAddrNpi 0

Defines the numeric plan indicator (NPI) to be used in the SME destination address parameters. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

priorityFlag 1

Allows the originating SME to assign a priority level to the short message. Four Priority Levels are supported:

  • 0: Level 0 (lowest) priority

  • 1: Level 1 priority

  • 2: Level 2 priority

  • 3: Level 3 (highest) priority

replaceIfPresentFlag 0

Used to request the SMSC to replace a previously submitted message, that is still pending delivery. The SMSC will replace an existing message provided that the source address, destination address and service type match the same fields in the new message. The following replace if present flag values are defined:

  • 0: Don't replace

  • 1: Replace

dataCoding 0

Camel 2.5 onwarts Defines encoding of data according the SMPP 3.4 specification, section 5.2.19. Example data encodings are: 0: SMSC Default Alphabet 4: 8 bit Alphabet 8: UCS2 Alphabet

typeOfNumber 0

Defines the type of number (TON) to be used in the SME. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

numberingPlanIndicator 0

Defines the numeric plan indicator (NPI) to be used in the SME. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

lazySessionCreation false Camel 2.8 onwarts Sessions can be lazily created to avoid exceptions, if the SMSC is not available when the Camel producer is started.

You can have as many of these options as you like.

smpp://smppclient@localhost:2775?password=password&enquireLinkTimer=3000&transactionTimer=5000&systemType=consumer

The following message headers can be used to affect the behavior of the SMPP producer

Header Description
CamelSmppDestAddr Defines the destination SME address. For mobile terminated messages, this is the directory number of the recipient MS.
CamelSmppDestAddrTon

Defines the type of number (TON) to be used in the SME destination address parameters. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

CamelSmppDestAddrNpi

Defines the numeric plan indicator (NPI) to be used in the SME destination address parameters. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

CamelSmppSourceAddr Defines the address of SME (Short Message Entity) which originated this message.
CamelSmppSourceAddrTon

Defines the type of number (TON) to be used in the SME originator address parameters. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

CamelSmppSourceAddrNpi

Defines the numeric plan indicator (NPI) to be used in the SME originator address parameters. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

CamelSmppServiceType

The service type parameter can be used to indicate the SMS Application service associated with the message. The following generic service_types are defined:

  • CMT: Cellular Messaging

  • CPT: Cellular Paging

  • VMN: Voice Mail Notification

  • VMA: Voice Mail Alerting

  • WAP: Wireless Application Protocol

  • USSD: Unstructured Supplementary Services Data

CamelSmppRegisteredDelivery

Is used to request an SMSC delivery receipt and/or SME originated acknowledgements. The following values are defined:

  • 0: No SMSC delivery receipt requested.

  • 1: SMSC delivery receipt requested where final delivery outcome is success or failure.

  • 2: SMSC delivery receipt requested where the final delivery outcome is delivery failure.

CamelSmppPriorityFlag

Allows the originating SME to assign a priority level to the short message. Four Priority Levels are supported:

  • 0: Level 0 (lowest) priority

  • 1: Level 1 priority

  • 2: Level 2 priority

  • 3: Level 3 (highest) priority

CamelSmppScheduleDeliveryTime This parameter specifies the scheduled time at which the message delivery should be first attempted. It defines either the absolute date and time or relative time from the current SMSC time at which delivery of this message will be attempted by the SMSC. It can be specified in either absolute time format or relative time format. The encoding of a time format is specified in chapter 7.1.1. in the smpp specification v3.4.
CamelSmppValidityPeriod The validity period parameter indicates the SMSC expiration time, after which the message should be discarded if not delivered to the destination. It can be defined in absolute time format or relative time format. The encoding of absolute and relative time format is specified in chapter 7.1.1 in the smpp specification v3.4.
CamelSmppReplaceIfPresentFlag

The replace if present flag parameter is used to request the SMSC to replace a previously submitted message, that is still pending delivery. The SMSC will replace an existing message provided that the source address, destination address and service type match the same fields in the new message. The following values are defined:

  • 0: Don't replace

  • 1: Replace

CamelSmppDataCoding

The data coding according to the SMPP 3.4 specification, section 5.2.19: 0: SMSC Default Alphabet 4: 8 bit Alphabet 8: UCS2 Alphabet

The following message headers are used by the SMPP producer to set the response from the SMSC in the message header

Header Description
CamelSmppId the id to identify the submitted short message for later use (delivery receipt, query sm, cancel sm, replace sm).

The following message headers are used by the SMPP consumer to set the request data from the SMSC in the message header

Header Description
CamelSmppSequenceNumber only for alert notification, deliver sm and data sm: A sequence number allows a response PDU to be correlated with a request PDU. The associated SMPP response PDU must preserve this field.
CamelSmppCommandId only for alert notification, deliver sm and data sm: The command id field identifies the particular SMPP PDU. For the complete list of defined values see chapter 5.1.2.1 in the smpp specification v3.4.
CamelSmppSourceAddr only for alert notification, deliver sm and data sm: Defines the address of SME (Short Message Entity) which originated this message.
CamelSmppSourceAddrNpi

only for alert notification and data sm: Defines the numeric plan indicator (NPI) to be used in the SME originator address parameters. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

CamelSmppSourceAddrTon

only for alert notification and data sm: Defines the type of number (TON) to be used in the SME originator address parameters. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

CamelSmppEsmeAddr only for alert notification: Defines the destination ESME address. For mobile terminated messages, this is the directory number of the recipient MS.
CamelSmppEsmeAddrNpi

only for alert notification: Defines the numeric plan indicator (NPI) to be used in the ESME originator address parameters. The following NPI values are defined:

  • 0: Unknown

  • 1: ISDN (E163/E164)

  • 2: Data (X.121)

  • 3: Telex (F.69)

  • 6: Land Mobile (E.212)

  • 8: National

  • 9: Private

  • 10: ERMES

  • 13: Internet (IP)

  • 18: WAP Client Id (to be defined by WAP Forum)

CamelSmppEsmeAddrTon

only for alert notification: Defines the type of number (TON) to be used in the ESME originator address parameters. The following TON values are defined:

  • 0: Unknown

  • 1: International

  • 2: National

  • 3: Network Specific

  • 4: Subscriber Number

  • 5: Alphanumeric

  • 6: Abbreviated

CamelSmppId only for smsc delivery receipt and data sm: The message ID allocated to the message by the SMSC when originally submitted.
CamelSmppDelivered only for smsc delivery receipt: Number of short messages delivered. This is only relevant where the original message was submitted to a distribution list.The value is padded with leading zeros if necessary.
CamelSmppDoneDate only for smsc delivery receipt: The time and date at which the short message reached it's final state. The format is as follows: YYMMDDhhmm.
CamelSmppStatus

only for smsc delivery receipt and data sm: The final status of the message. The following values are defined:

  • DELIVRD: Message is delivered to destination

  • EXPIRED: Message validity period has expired.

  • DELETED: Message has been deleted.

  • UNDELIV: Message is undeliverable

  • ACCEPTD: Message is in accepted state (i.e. has been manually read on behalf of the subscriber by customer service)

  • UNKNOWN: Message is in invalid state

  • REJECTD: Message is in a rejected state

CamelSmppError only for smsc delivery receipt: Where appropriate this may hold a Network specific error code or an SMSC error code for the attempted delivery of the message. These errors are Network or SMSC specific and are not included here.
CamelSmppSubmitDate only for smsc delivery receipt: The time and date at which the short message was submitted. In the case of a message which has been replaced, this is the date that the original message was replaced. The format is as follows: YYMMDDhhmm.
CamelSmppSubmitted only for smsc delivery receipt: Number of short messages originally submitted. This is only relevant when the original message was submitted to a distribution list.The value is padded with leading zeros if necessary.
CamelSmppDestAddr only for deliver sm and data sm: Defines the destination SME address. For mobile terminated messages, this is the directory number of the recipient MS.
CamelSmppScheduleDeliveryTime only for deliver sm and data sm: This parameter specifies the scheduled time at which the message delivery should be first attempted. It defines either the absolute date and time or relative time from the current SMSC time at which delivery of this message will be attempted by the SMSC. It can be specified in either absolute time format or relative time format. The encoding of a time format is specified in Section 7.1.1. in the smpp specification v3.4.
CamelSmppValidityPeriod only for deliver sm: The validity period parameter indicates the SMSC expiration time, after which the message should be discarded if not delivered to the destination. It can be defined in absolute time format or relative time format. The encoding of absolute and relative time format is specified in Section 7.1.1 in the smpp specification v3.4.
CamelSmppServiceType only for deliver sm and data sm: The service type parameter indicates the SMS Application service associated with the message.
CamelSmppRegisteredDelivery

only for data sm: Is used to request an delivery receipt and/or SME originated acknowledgements. The following values are defined: 0: No SMSC delivery receipt requested. 1: SMSC delivery receipt requested where final delivery outcome is success or failure. 2: SMSC delivery receipt requested where the final delivery outcome is delivery failure.

CamelSmppDestAddrNpi

only for data sm: Defines the numeric plan indicator (NPI) in the destination address parameters. The following NPI values are defined: 0: Unknown 1: ISDN (E163/E164) 2: Data (X.121) 3: Telex (F.69) 6: Land Mobile (E.212) 8: National 9: Private 10: ERMES 13: Internet (IP) 18: WAP Client Id (to be defined by WAP Forum)

CamelSmppDestAddrTon

only for data sm: Defines the type of number (TON) in the destination address parameters. The following TON values are defined: 0: Unknown 1: International 2: National 3: Network Specific 4: Subscriber Number 5: Alphanumeric 6: Abbreviated

CamelSmppMessageType

Camel 2.6 onwarts: Identifies the type of an incoming message: AlertNotification: an SMSC alert notification DataSm: an SMSC data short message DeliveryReceipt: an SMSC delivery receipt DeliverSm: an SMSC deliver short message

See the documentation of the JSMPP Library for more details about the underlying library.

This component supports the general Camel exception handling capabilities. Camel 2.8 onwarts: When the SMPP consumer receives a DeliverSm or DataSm short message and the processing of these messages fails, you can also throw a ProcessRequestException instead of handle the failure. In this case, this exception is forwarded to the underlying JSMPP library which will return the included error code to the SMSC. This feature is useful to e.g. instruct the SMSC to resend the short message at a later time. This could be done with the following lines of code:

 from("smpp://smppclient@localhost:2775?password=password&enquireLinkTimer=3000&transactionTimer=5000&systemType=consumer")
   .doTry()
     .to("bean:dao?method=updateSmsState")
   .doCatch(Exception.class)
     .throwException(new ProcessRequestException("update of sms state failed", 100))
   .end();
 
 

Please refer to the SMPP specification for the complete list of error codes and their meanings.

Name Default Value Description
type none The type of action you want to perform. Actually you can enter here POLL or TRAP. The value POLL will instruct the endpoint to poll a given host for the supplied OID keys. If you put in TRAP you will setup a listener for SNMP Trap Events.
address none This is the IP address and the port of the host to poll or where to setup the Trap Receiver. Example: 127.0.0.1:162
protocol udp Here you can select which protocol to use. You can use either udp or tcp.
retries 2 Defines how often a retry is made before canceling the request.
timeout 1500 Sets the timeout value for the request in millis.
snmpVersion 0 (which means SNMPv1) Sets the snmp version for the request.
snmpCommunity public Sets the community octet string for the snmp request.
delay 60 seconds Defines the delay in seconds between to poll cycles.
oids none Defines which values you are interested in. Please have a look at the Wikipedia to get a better understanding. You may provide a single OID or a coma separated list of OIDs. Example: 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"

Name Description Example Required Default Value
inputChannel The Spring integration input channel name that this endpoint wants to consume from, where the specified channel name is defined in the Spring context. inputChannel=requestChannel No
outputChannel The Spring integration output channel name that is used to send messages to the Spring integration context. outputChannel=replyChannel No
inOut The exchange pattern that the Spring integration endpoint should use. inOut=true No inOnly for the Spring integration consumer and outOnly for the Spring integration provider
consumer.delay Delay in milliseconds between each poll. consumer.delay=60000 No 500
consumer.initialDelay Milliseconds before polling starts. consumer.initialDelay=10000 No 1000
consumer.userFixedDelay Specify true to use fixed delay between polls, otherwise fixed rate is used. See the Java[ScheduledExecutorService|http://java.sun.com/j2se/1.5.0/docs/api/index.html?java/lang/Character.html] class for details. consumer.userFixedDelay=false No false

You can set up a Spring integration endpoint using a URI, as follows:

<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">
	
	<channel id="inputChannel"/>
   	<channel id="outputChannel"/>
   	<channel id="onewayChannel"/>

	<service-activator input-channel="inputChannel"	          
	          ref="helloService"
	          method="sayHello"/>
	          	      
	<service-activator input-channel="onewayChannel"	          
	          ref="helloService"
	          method="greet"/>
	          
	<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"/>
        <!-- Using the &as the separator of & -->
        <to uri="spring-integration:inputChannel?inOut=true&nputChannel=outputChannel"/>
      </route>
      <route>      
        <from uri="direct:onewayMessage"/>
        <to uri="spring-integration:onewayChannel?inOut=false"/>
      </route>
    </camelContext>
<channel id="requestChannel"/>
<channel id="responseChannel"/>

<beans:bean id="myProcessor" class="org.apache.camel.component.spring.integration.MyProcessor"/>

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
  <route>
    <!-- Using the &as the separator of & -->
    <from uri="spring-integration://requestChannel?outputChannel=responseChannel&nOut=true"/>
    <process ref="myProcessor"/>
  </route>
</camelContext>

Or directly using a Spring integration channel name:

<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">
	<channel id="outputChannel"/>

    <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
      <route>
        <!-- camel will create a spring integration endpoint automatically -->
        <from uri="outputChannel"/>
        <to uri="mock:result"/>
      </route>
    </camelContext>

Spring integration also provides the Spring integration's source and target adapters, which can route messages from a Spring integration channel to a Fuse Mediation Router endpoint or from a Fuse Mediation Router endpoint to a Spring integration channel.

This example uses the following namespaces:

<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
	   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
    ">

You can bind your source or target to a Fuse Mediation Router endpoint as follows:

<!-- 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 -->
<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>

Available as of Camel 2.3

The camel-spring-security component provides role-based authorization for Camel routes. It leverages the authentication and user services provided by Spring Security (formerly Acegi Security) and adds a declarative, role-based policy system to control whether a route can be executed by a given principal.

If you are not familiar with the Spring Security authentication and authorization system, please review the current reference documentation on the SpringSource web site linked above.

Access to a route is controlled by an instance of a SpringSecurityAuthorizationPolicy object. A policy object contains the name of the Spring Security authority (role) required to run a set of endpoints and references to Spring Security AuthenticationManager and AccessDecisionManager objects used to determine whether the current principal has been assigned that role. Policy objects may be configured as Spring beans or by using an <authorizationPolicy> element in Spring XML.

The <authorizationPolicy> element may contain the following attributes:

Name Default Value Description
id null The unique Spring bean identifier which is used to reference the policy in routes (required)
access null The Spring Security authority name that is passed to the access decision manager (required)
authenticationManager authenticationManager The name of the Spring Security AuthenticationManager object in the context
accessDecisionManager accessDecisionManager The name of the Spring Security AccessDecisionManager object in the context
authenticationAdapter DefaultAuthenticationAdapter Camel 2.4 The name of a camel-spring-securityAuthenticationAdapter object in the context that is used to convert a javax.security.auth.Subject into a Spring Security Authentication instance.
useThreadSecurityContext true If a javax.security.auth.Subject cannot be found in the In message header under Exchange.AUTHENTICATION, check the Spring Security SecurityContextHolder for an Authentication object.
alwaysReauthenticate false If set to true, the SpringSecurityAuthorizationPolicy will always call AuthenticationManager.authenticate() each time the policy is accessed.

A Spring Security AuthenticationManager and AccessDecisionManager are required to use this component. Here is an example of how to configure these objects in Spring XML using the Spring Security namespace:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:spring-security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans.xsd
			http://www.springframework.org/schema/security
			http://www.springframework.org/schema/security/spring-security.xsd">

    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="true"/>
        <property name="decisionVoters">
            <list>
                <bean class="org.springframework.security.access.vote.RoleVoter"/>
            </list>
        </property>
    </bean>
    
    <spring-security:authentication-manager alias="authenticationManager">
    	<spring-security:authentication-provider user-service-ref="userDetailsService"/>
    </spring-security:authentication-manager>
   
    <spring-security:user-service id="userDetailsService">
        <spring-security:user name="jim" password="jimspassword" authorities="ROLE_USER, ROLE_ADMIN"/>
        <spring-security:user name="bob" password="bobspassword" authorities="ROLE_USER"/>
    </spring-security:user-service>

</beans>

Now that the underlying security objects are set up, we can use them to configure an authorization policy and use that policy to control access to a route:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:spring-security="http://www.springframework.org/schema/security"
       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
          http://camel.apache.org/schema/spring-security
          http://camel.apache.org/schema/spring-security/camel-spring-security.xsd
          http://www.springframework.org/schema/security
		  http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">

    <!-- import the spring security configuration  -->
    <import resource="classpath:org/apache/camel/component/spring/security/commonSecurity.xml"/>

    <authorizationPolicy id="admin" access="ROLE_ADMIN"
                         authenticationManager="authenticationManager"
                         accessDecisionManager="accessDecisionManager"
                         xmlns="http://camel.apache.org/schema/spring-security"/>

    <camelContext id="myCamelContext" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="direct:start"/>
            <!-- The exchange should be authenticated with the role of ADMIN before it is send to mock:endpoint -->
            <policy ref="admin">
                <to uri="mock:end"/>
            </policy>
        </route>
    </camelContext>

</beans>

In this example, the endpoint mock:end will not be executed unless a Spring Security Authentication object that has been or can be authenticated and contains the ROLE_ADMIN authority can be located by the adminSpringSecurityAuthorizationPolicy.

The process of obtaining security credentials that are used for authorization is not specified by this component. You can write your own processors or components which get authentication information from the exchange depending on your needs. For example, you might create a processor that gets credentials from an HTTP request header originating in the camel-jetty component. No matter how the credentials are collected, they need to be placed in the In message or the SecurityContextHolder so the camel-spring-security component can access them:

import javax.security.auth.Subject;
import org.apache.camel.*;
import org.apache.commons.codec.binary.Base64;
import org.springframework.security.authentication.*;


public class MyAuthService implements Processor {
    public void process(Exchange exchange) throws Exception {
        // get the username and password from the HTTP header
        // http://en.wikipedia.org/wiki/Basic_access_authentication
        String userpass = new String(Base64.decodeBase64(exchange.getIn().getHeader("Authorization", String.class)));
        String[] tokens= userpass.split(":");
        
        // create an Authentication object
        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(tokens[0], tokens[1]);

        // wrap it in a Subject
        Subject subject = new Subject();
        subject.getPrincipals().add(token);

        // place the Subject in the In message
        exchange.getIn().setHeader(Exchange.AUTHENTICATION, subject);

        // you could also do this if useThreadSecurityContext is set to true
        // SecurityContextHolder.getContext().setAuthentication(authToken);
    }
}

The SpringSecurityAuthorizationPolicy will automatically authenticate the Authentication object if necessary.

There are two issues to be aware of when using the SecurityContextHolder instead of or in addition to the Exchange.AUTHENTICATION header. First, the context holder uses a thread-local variable to hold the Authentication object. Any routes that cross thread boundaries, like seda or jms, will lose the Authentication object. Second, the Spring Security system appears to expect that an Authentication object in the context is already authenticated and has roles (see the Technical Overview section 5.3.1 for more details).

The default behavior of camel-spring-security is to look for a Subject in the Exchange.AUTHENTICATION header. This Subject must contain at least one principal, which must be a subclass of org.springframework.security.core.Authentication. You can customize the mapping of Subject to Authentication object by providing an implementation of the org.apache.camel.component.spring.security.AuthenticationAdapter to your <authorizationPolicy> bean. This can be useful if you are working with components that do not use Spring Security but do provide a Subject. At this time, only the camel-cxf component populates the Exchange.AUTHENTICATION header.

If authentication or authorization fails in the SpringSecurityAuthorizationPolicy, a CamelAuthorizationException will be thrown. This can be handled using Camel's standard exception handling methods, like the Exception clause. The CamelAuthorizationException will have a reference to the ID of the policy which threw the exception so you can handle errors based on the policy as well as the type of exception:

<onException>
  <exception>org.springframework.security.authentication.AccessDeniedException</exception>
  <choice>
    <when>
      <simple>${exception.policyId} == 'user'</simple>
      <transform>
        <constant>You do not have ROLE_USER access!</constant>
      </transform>
    </when>
    <when>
      <simple>${exception.policyId} == 'admin'</simple>
      <transform>
        <constant>You do not have ROLE_ADMIN access!</constant>
      </transform>
    </when>
  </choice>
</onException>

The spring-ws: component allows you to integrate with Spring Web Services. It offers both clientside support, for accessing web services, and serverside support for creating your own contract-first web services.

Dependencies

As of Camel 2.8 this component ships with Spring-WS 2.0.x which (like the rest of Camel) requires Spring 3.0.x.

Earlier Camel versions shipped Spring-WS 1.5.9 which is compatible with Spring 2.5.x and 3.0.x. In order to run earlier versions of camel-spring-ws on Spring 2.5.x you need to add the spring-webmvc module from Spring 2.5.x. In order to run Spring-WS 1.5.9 on Spring 3.0.x you need to exclude the OXM module from Spring 3.0.x as this module is also included in Spring-WS 1.5.9 (see this post)

The URI scheme for this component is as follows

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

To expose a web service, mapping-type needs to be set to one of the following values:

Mapping type Description
rootqname Offers the option to map web service requests based on the qualified name of the root element contained in the message.
soapaction Used to map web service requests based on the SOAP action specified in the header of the message.
uri In order to map web service requests that target a specific URI.
xpathresult Used to map web service requests based on the evaluation of an XPath expression against the incoming message. The result of the evaluation should match the XPath result specified in the endpoint URI.
beanname Allows you to reference a org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher in order to integrate with existing (legacy) endpoint mappings like PayloadRootQNameEndpointMapping, SoapActionEndpointMapping, etc

As a consumer the address should contain a value relevant to the specified mapping-type (e.g. a SOAP action, XPath expression). As a producer the address should be set to the URI of the web service you are calling upon.

You can append query options to the URI in the following format, ?option=value&option=value&....

Name Required? Description
soapAction No SOAP action to include inside a SOAP request when accessing remote web services
wsAddressingAction No WS-Addressing 1.0 action header to include when accessing web services. The To header is set to the address of the web service as specified in the endpoint URI (default Spring-WS behavior).
expression Only when mapping-type is xpathresult XPath expression to use in the process of mapping web service requests, should match the result specified by xpathresult

The following options can be specified in the registry (most likely a Spring application context) and referenced from the endpoint URI using the #beanID notation.

Name Required? Description
webServiceTemplate No Option to provide a custom WebServiceTemplate. This allows for full control over client-side web services handling; like adding a custom interceptor or specifying a fault resolver, message sender or message factory.
messageSender No Option to provide a custom WebServiceMessageSender. For example to perform authentication or use alternative transports
messageFactory No Option to provide a custom WebServiceMessageFactory. For example when you want Apache Axiom to handle web service messages instead of SAAJ
transformerFactory No Option to override the default TransformerFactory. The provided transformer factory must be of type javax.xml.transform.TransformerFactory
endpointMapping Only when mapping-type is rootqname, soapaction, uri or xpathresult Reference to org.apache.camel.component.spring.ws.bean.CamelEndpointMapping in the Registry/ApplicationContext. Only one bean is required in the registry to serve all Camel/Spring-WS endpoints. This bean is auto-discovered by the MessageDispatcher and used to map requests to Camel endpoints based on characteristics specified on the endpoint (like root QName, SOAP action, etc)

Name Type Description
CamelSpringWebserviceEndpointUri String URI of the web service you are accessing as a client; overrides the address part of the endpoint URI.
CamelSpringWebserviceSoapAction String Header to specify the SOAP action of the message; overrides the soapAction option, if present
CamelSpringWebserviceAddressingAction URI Use this header to specify the WS-Addressing action of the message; overrides the wsAddressingAction option, if present

To call a web service at http://foo.com/bar simply define a route:

from("direct:example").to("spring-ws:http://foo.com/bar")

And sent a message:

template.requestBody("direct:example", "<foobar xmlns=\"http://foo.com\"><msg>test message</msg></foobar>");

Remember, if it's a SOAP service you're calling you don't have to include SOAP tags. Spring-WS will perform the XML-to-SOAP marshaling.

In order to expose a web service using this component you first need to set-up a MessageDispatcher to look for endpoint mappings in a Spring XML file. If you plan on running inside a servlet container you probably want to use a MessageDispatcherServlet configured in web.xml.

By default the MessageDispatcherServlet will look for a Spring XML named /WEB-INF/spring-ws-servlet.xml. To use Camel with Spring-WS the only mandatory bean in that XML file is CamelEndpointMapping. This bean allows the MessageDispatcher to dispatch web service requests to your routes.

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>

More information on setting up Spring-WS can be found in Writing Contract-First Web Services.

With the XML configuration in-place you can now use Camel's DSL to define what web service requests are handled by your endpoint. The following route will receive all web service requests that have a root element named GetFoo within the http://example.com/ namespace:

from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping")
.convertBodyTo(String.class).to(mock:example)

The following route will receive web service requests containing the http://example.com/GetFoo SOAP action:

from("spring-ws:soapaction:http://example.com/GetFoo?endpointMapping=#endpointMapping")
.convertBodyTo(String.class).to(mock:example)

The following route will receive all requests sent to http://example.com/foobar:

from("spring-ws:uri:http://example.com/foobar?endpointMapping=#endpointMapping")
.convertBodyTo(String.class).to(mock:example)

The route below receives requests that contain the element <foobar>abc</foobar> anywhere inside the message (and the default namespace).

from("spring-ws:xpathresult:abc?expression=//foobar&endpointMapping=#endpointMapping")
.convertBodyTo(String.class).to(mock:example)

For every endpoint with mapping-type beanname one bean of type CamelEndpointDispatcher with a corresponding name is required in the Registry/ApplicationContext. This bean acts as a bridge between the Camel endpoint and an existing endpoint mapping like PayloadRootQNameEndpointMapping.

Note

The use of the beanname mapping-type is primarily meant for (legacy) situations where you're already using Spring-WS and have endpoint mappings defined in a Spring XML file. The beanname mapping-type allows you to wire your Camel route into an existing endpoint mapping. When you're starting from scratch it's recommended to define your endpoint mappings as Camel URI's (as illustrated above with endpointMapping) since it requires less configuration and is more expressive. Alternatively you could use vanilla Spring-WS with the help of annotations.

An example of a route using 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>

<bean id="QuoteEndpointDispatcher" class="org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher" />
<bean id="FutureEndpointDispatcher" class="org.apache.camel.component.spring.ws.bean.CamelEndpointDispatcher" />

Camel's pluggable data formats offer support for POJO/XML marshalling using libraries such as JAXB, XStream, JibX, Castor and XMLBeans. You can use these data formats in your route to sent and receive POJOs (Plain Old Java Objects), to and from web services.

When accessing web services you can marshal the request and unmarshal the response message:

JaxbDataFormat jaxb = new JaxbDataFormat(false);
jaxb.setContextPath("com.example.model");

from("direct:example").marshal(jaxb).to("spring-ws:http://foo.com/bar").unmarshal(jaxb);

Similarly when providing web services, you can unmarshal XML requests to POJOs and marshal the response message back to XML:

from("spring-ws:rootqname:{http://example.com/}GetFoo?endpointMapping=#endpointMapping").unmarshal(jaxb)
.to("mock:example").marshal(jaxb);

The sql: component allows you to work with databases using JDBC queries. The difference between this component and JDBC component is that in case of SQL the query is a property of the endpoint and it uses message payload as parameters passed to the query.

This component uses spring-jdbc behind the scenes for the actual SQL handling.

The SQL component also supports:

  • a JDBC based repository for the Idempotent Consumer EIP pattern. See further below.

  • a JDBC based repository for the Aggregator EIP pattern. See further below.

Important

This component can be used as a Transactional Client.

Option Type Default Description
dataSourceRef String null Fuse Mediation Router 1.5.1/2.0: Reference to a DataSource to look up in the registry.
placeholder String # Camel 2.4: Specifies a character that will be replaced to ? in SQL query. Notice, that it is simple String.replaceAll() operation and no SQL parsing is involved (quoted strings will also change)
template.<xxx> null Sets additional options on the Spring JdbcTemplate that is used behind the scenes to execute the queries. For instance, template.maxRows=10. For detailed documentation, see the JdbcTemplate javadoc documentation.

When performing update operations, the SQL Component stores the update count in the following message headers:

Header Description
SqlProducer.UPDATE_COUNT Fuse Mediation Router 1.x: The number of rows updated for update operations, returned as an Integer object.
CamelSqlUpdateCount Fuse Mediation Router 2.0: The number of rows updated for update operations, returned as an Integer object.
CamelSqlRowCount Fuse Mediation Router 2.0: The number of rows returned for select operations, returned as an Integer object.
CamelSqlQuery Camel 2.8: Query to execute. This query takes precedence over the query specified in the endpoint URI. Note that query parameters in the header are represented by a ? instead of a # symbol

In the sample below we execute a query and retrieve the result as a List of rows, where each row is a Map<String, Object and the key is the column name.

First, we set up a table to use for our sample. As this is based on an unit test, we do it java code:

// this is the database we create with some initial data for our unit test
jdbcTemplate.execute("create table projects (id integer primary key,"
                     + "project varchar(10), license varchar(5))");
jdbcTemplate.execute("insert into projects values (1, 'Camel', 'ASF')");
jdbcTemplate.execute("insert into projects values (2, 'AMQ', 'ASF')");
jdbcTemplate.execute("insert into projects values (3, 'Linux', 'XXX')");

Then we configure our route and our sql component. Notice that we use a direct endpoint in front of the sql endpoint. This allows us to send an exchange to the direct endpoint with the URI, direct:simple, which is much easier for the client to use than the long sql: URI. Note that the DataSource is looked up up in the registry, so we can use standard Spring XML to configure our DataSource.

from("direct:simple")
    .to("sql:select * from projects where license = # order by id?dataSourceRef=jdbc/myDataSource")
    .to("mock:result");

And then we fire the message into the direct endpoint that will route it to our sql component that queries the database.

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"));

We could configure the DataSource in Spring XML as follows:

 <jee:jndi-lookup id="myDS" jndi-name="jdbc/myDataSource"/> 

In this section we will use the JDBC based idempotent repository.

First we have to create the database table which will be used by the idempotent repository.

For Camel 2.7, we use the follwing schema:

 CREATE TABLE CAMEL_MESSAGEPROCESSED (
   processorName VARCHAR(255),
   messageId VARCHAR(100)
 )

In Camel 2.8, we added the createdAt column:

 CREATE TABLE CAMEL_MESSAGEPROCESSED (
   processorName VARCHAR(255),
   messageId VARCHAR(100),
   createdAt TIMESTAMP
 )

We recommend to have a unique constraint on the columns processorName and messageId. Because the syntax for this constraint differs for database to database, we do not show it here.

Second we need to setup a javax.sql.DataSource in the spring XML file:

<bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
    <property name="url" value="jdbc:hsqldb:mem:camel_jdbc"/>
    <property name="username" value="sa"/>
    <property name="password" value=""/>
</bean>

And finally we can create our JDBC idempotent repository in the spring XML file as well:

<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>

Available as of Camel 2.6

JdbcAggregationRepository is an AggregationRepository which on the fly persists the aggregated messages. This ensures that you will not loose messages, as the default aggregator will use an in memory only AggregationRepository. The JdbcAggregationRepository allows together with Camel to provide persistent support for the Aggregator.

It has the following options:

Option Type Description
dataSource DataSource Mandatory: The javax.sql.DataSource to use for accessing the database.
repositoryName String Mandatory: The name of the repository.
transactionManager TransactionManager Mandatory: The org.springframework.transaction.PlatformTransactionManager to mange transactions for the database. The TransactionManager must be able to support databases.
lobHandler LobHandler A org.springframework.jdbc.support.lob.LobHandler to handle Lob types in the database. Use this option to use a vendor specific LobHandler, for example when using Oracle.
returnOldExchange boolean Whether the get operation should return the old existing Exchange if any existed. By default this option is false to optimize as we do not need the old exchange when aggregating.
useRecovery boolean Whether or not recovery is enabled. This option is by default true. When enabled the Camel Aggregator automatic recover failed aggregated exchange and have them resubmitted.
recoveryInterval long If recovery is enabled then a background task is run every x'th time to scan for failed exchanges to recover and resubmit. By default this interval is 5000 millis.
maximumRedeliveries int Allows you to limit the maximum number of redelivery attempts for a recovered exchange. If enabled then the Exchange will be moved to the dead letter channel if all redelivery attempts failed. By default this option is disabled. If this option is used then the deadLetterUri option must also be provided.
deadLetterUri String An endpoint uri for a Dead Letter Channel where exhausted recovered Exchanges will be moved. If this option is used then the maximumRedeliveries option must also be provided.

The JdbcAggregationRepository will by default recover any failed Exchange. It does this by having a background tasks that scans for failed Exchanges in the persistent store. You can use the checkInterval option to set how often this task runs. The recovery works as transactional which ensures that Camel will try to recover and redeliver the failed Exchange. Any Exchange which was found to be recovered will be restored from the persistent store and resubmitted and send out again.

The following headers is set when an Exchange is being recovered/redelivered:

Header Type Description
Exchange.REDELIVERED Boolean Is set to true to indicate the Exchange is being redelivered.
Exchange.REDELIVERY_COUNTER Integer The redelivery attempt, starting from 1.

Only when an Exchange has been successfully processed it will be marked as complete which happens when the confirm method is invoked on the AggregationRepository. This means if the same Exchange fails again it will be kept retried until it success.

You can use option maximumRedeliveries to limit the maximum number of redelivery attempts for a given recovered Exchange. You must also set the deadLetterUri option so Camel knows where to send the Exchange when the maximumRedeliveries was hit.

You can see some examples in the unit tests of camel-sql, for example this test.

Name Default Value Description
delay 0 Initial delay in milliseconds before consuming or producing the stream.
encoding JVM Default As of 1.4, you can configure the encoding (is a charset name) to use text-based streams (for example, message body is a String object). If not provided, Fuse Mediation Router uses the JVM default Charset.
promptMessage null Fuse Mediation Router 2.0: Message prompt to use when reading from stream:in; for example, you could set this to Enter a command:
promptDelay 0 Fuse Mediation Router 2.0: Optional delay in milliseconds before showing the message prompt.
initialPromptDelay 2000 Fuse Mediation Router 2.0: Initial delay in milliseconds before showing the message prompt. This delay occurs only once. Can be used during system startup to avoid message prompts being written while other logging is done to the system out.
fileName null Fuse Mediation Router 2.0: When using the stream:file URI format, this option specifies the filename to stream to/from.
scanStream false

Fuse Mediation Router 2.0: To be used for continuously reading a stream such as the unix tail command. Camel 2.4 to Camel 2.6: will retry opening the file if it is overwritten, somewhat like tail --retry

retry false Camel 2.7: will retry opening the file if it's overwritten, somewhat like tail --retry
scanStreamDelay 0 Fuse Mediation Router 2.0: Delay in milliseconds between read attempts when using scanStream.
groupLines 0 Camel 2.5: To group X number of lines in the consumer. For example to group 10 lines and therefore only spit out an Exchange with 10 lines, instead of 1 Exchange per line.

In the following sample we route messages from the direct:in endpoint to the System.out stream:

@Test
public void testStringContent() throws Exception {
    template.sendBody("direct:in", "Hello Text World\n");
}

@Test
public void testBinaryContent() {
    template.sendBody("direct:in", "Hello Bytes World\n".getBytes());
}

protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from("direct:in").to("stream:out");
        }
    };
}

The following sample demonstrates how the header type can be used to determine which stream to use. In the sample we use our own output stream, MyOutputStream.

private OutputStream mystream = new MyOutputStream();
private StringBuffer sb = new StringBuffer();

@Test
public void testStringContent() {
    template.sendBody("direct:in", "Hello");
    // 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);
    }
}

The following sample demonstrates how to continuously read a file stream (analogous to the UNIX tail command):

from("stream:file?fileName=/server/logs/server.log&scanStream=true&scanStreamDelay=1000").to("bean:logService?method=parseLogLine");

The string-template: component allows you to process a message using a String Template. This can be ideal when using Templating to generate responses for requests.

Maven users will need to add the following dependency to their pom.xml for this component:

<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>

Option Default Description
contentCache false New option in Fuse Mediation Router 1.4. Cache for the resource content when its loaded.

Fuse Mediation Router will provide exchange information as attributes (just a java.util.Map) to the string template. The Exchange is transfered as:

key value
exchange The Exchange itself.
headers The headers of the In message.
camelContext The Camel Context.
request The In message.
in The In message.
body The In message body.
out The Out message (only for InOut message exchange pattern).
response The Out message (only for InOut message exchange pattern).

The test component extends the Mock component to support pulling messages from another endpoint on startup to set the expected message bodies on the underlying Mock endpoint. That is, you use the test endpoint in a route and messages arriving on it will be implicitly compared to some expected messages extracted from some other location.

So you can use, for example, an expected set of message bodies as files. This will then set up a properly configured Mock endpoint, which is only valid if the received messages match the number of expected messages and their message payloads are equal.

test:expectedMessagesEndpointUri

Where expectedMessagesEndpointUri refers to some other Component URI that the expected message bodies are pulled from before starting the test.

Name Default Value Description
time null A java.util.Date the first event should be generated. If using the URI, the pattern expected is: yyyy-MM-dd HH:mm:ss or yyyy-MM-dd'T'HH:mm:ss.
pattern null Allows you to specify a custom Date pattern to use for setting the time option using URI syntax.
period 1000 If greater than 0, generate periodic events every period milliseconds.
delay 0 The number of milliseconds to wait before the first event is generated. Should not be used in conjunction with the time option.
fixedRate false Events take place at approximately regular intervals, separated by the specified period.
daemon true Specifies whether or not the thread associated with the timer endpoint runs as a daemon.
repeatCount 0 Camel 2.8: Specifies a maximum limit of number of fires. So if you set it to 1, the timer will only fire once. If you set it to 5, it will only fire five times. A value of zero or negative means fire forever.

When the timer is fired, it adds the following information as properties to the Exchange:

Name Type Description
Exchange.TIMER_NAME String The value of the name option.
Exchange.TIMER_TIME Date The value of the time option.
Exchange.TIMER_PERIOD long The value of the period option.
Exchange.TIMER_FIRED_TIME Date The time when the consumer fired.
Exchange.TIMER_COUNTER Long Camel 2.8: The current fire counter. Starts from 1.

When the timer is fired, it adds the following information as headers to the IN message

Name Type Description
Exchange.TIMER_FIRED_TIME java.util.Date The time when the consumer fired
Option Default Description
useDom false Fuse Mediation Router 2.0: Whether DOMSource/{{DOMResult}} or SaxSource/{{SaxResult}} should be used by the validator.
useSharedSchema true Camel 2.3: Whether the Schema instance should be shared or not. This option is introduced to work around a JDK 1.6.x bug. Xerces should not have this issue.

The following example shows how to configure a route from endpoint direct:start which then goes to one of two endpoints, either mock:valid or mock:invalid based on whether or not the XML matches the given schema (which is supplied on the classpath).

<camelContext xmlns="http://camel.apache.org/schema/spring">
    <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>
</camelContext>

The velocity: component allows you to process a message using an Apache Velocity template. This can be ideal when using Templating to generate responses for requests.

Option Default Description
loaderCache true Velocity based file loader cache.
contentCache New option in Fuse Mediation Router 1.4: Cache for the resource content when it is loaded. By default, it's false in Fuse Mediation Router 1.x. By default, it's true in Fuse Mediation Router 2.x.
encoding null New option in Fuse Mediation Router 1.6: Character encoding of the resource content.
propertiesFile null New option in Camel 2.1: The URI of the properties file which is used for VelocityEngine initialization.

The velocity component sets some headers on the message (you cannot set these yourself):

Header Description
org.apache.camel.velocity.resource Fuse Mediation Router 1.x: The resource as an org.springframework.core.io.Resource object.
org.apache.camel.velocity.resourceUri Fuse Mediation Router 1.x: The templateName as a String object.
CamelVelocityResource Fuse Mediation Router 2.0: The resource as an org.springframework.core.io.Resource object.
CamelVelocityResourceUri Fuse Mediation Router 2.0: The templateName as a String object.

In Fuse Mediation Router 1.4 headers set during the Velocity evaluation are returned to the message and added as headers. This makes it possible to return values from Velocity to the Message.

For example, to set the header value of fruit in the Velocity template .tm:

$in.setHeader('fruit', 'Apple')

The fruit header is now accessible from the message.out.headers.

Fuse Mediation Router will provide exchange information in the Velocity context (just a Map). The Exchange is transfered as:

key value
exchange The Exchange itself.
headers The headers of the In message.
camelContext The Camel Context intance.
request The In message.
in The In message.
body The In message body.
out The Out message (only for InOut message exchange pattern).
response The Out message (only for InOut message exchange pattern).

Available as of Camel 2.1 Camel provides two headers by which you can define a different resource location for a template or the template content itself. If any of these headers is set then Camel uses this over the endpoint configured resource. This allows you to provide a dynamic template at runtime.

Header Type Description
CamelVelocityResourceUri String Camel 2.1: A URI for the template resource to use instead of the endpoint configured.
CamelVelocityTemplate String Camel 2.1: The template to use instead of the endpoint configured.

The vm: component provides asynchronous SEDA behavior so that messages are exchanged on a BlockingQueue and consumers are invoked in a separate thread pool to the producer.

This component differs from the Seda component in that VM supports communication across CamelContext instances, so you can use this mechanism to communicate across web applications, provided that the camel-core.jar is on the system/boot classpath.

This component is an extension to the Seda component.

vm:someName[?options]

Where someName can be any string to uniquely identify the endpoint within the JVM (or at least within the classloader which loaded the camel-core.jar)

You can append query options to the URI in the following format, ?option=value&option=value&...

An exactly identical VM endpoint URI must be used for both the producer endpoint and the consumer endpoint. Otherwise Camel will create a second VM endpoint, even thought the someName portion of the URI is identical. For example:

from("direct:foo").to("vm:bar?concurrentConsumers=5");
 
from("vm:bar?concurrentConsumers=5").to("file://output");

Notice that we have to use the full URI including options in both the producer and consumer.

In Camel 2.4 this has been fixed, so it is the queue name that must match—for example, the preceding example uses bar as the queue name.

Name Description
room If this option is specified, the component will connect to MUC (Multi User Chat). Usually, the domain name for MUC is different from the login domain. For example, if you are superman@jabber.org and want to join the krypton room, then the room URL is krypton@conference.jabber.org. Note the conference part.
user User name (without server name). If not specified, anonymous login will be attempted.
password Password.
resource XMPP resource. The default is Camel.
createAccount If true, an attempt to create an account will be made. Default is false.
participant JID (Jabber ID) of person to receive messages. room parameter has precedence over participant.
nickname Use nickname when joining room. If room is specified and nickname is not, user will be used for the nickname.
serviceName Fuse Mediation Router 1.6/2.0 The name of the service you are connecting to. For Google Talk, this would be gmail.com.

The xquery: component allows you to process a message using an XQuery template. This can be ideal when using Templating to generate respopnses for requests.

The xslt: component allows you to process a message using an XSLT template. This can be ideal when using Templating to generate respopnses for requests.

xslt:templateName[?options]

Where templateName is the classpath-local URI of the template to invoke; or the complete URL of the remote template. Refer to the Spring Documentation for more detail of the URI syntax

You can append query options to the URI in the following format, ?option=value&option=value&...

Here are some example URIs

URI Description
xslt:com/acme/mytransform.xs Refers to the file, com/acme/mytransform.xsl, on the classpath.
xslt:file:///foo/bar.xs Refers to the file, /foo/bar.xsl.
xslt:http://acme.com/cheese/foo.xsl Refers to the remote HTTP resource.
Name Default Value Description
converter null Option to override default XmlConverter. Will lookup for the converter in the Registry. The provided converted must be of type org.apache.camel.converter.jaxp.XmlConverter.
transformerFactory null New added in Fuse Mediation Router 1.6 Option to override default TransformerFactory. Will lookup for the transformerFactory in the Registry. The provided transformer factory must be of type javax.xml.transform.TransformerFactory.
transformerFactoryClass null New added in Fuse Mediation Router 1.6 Option to override default TransformerFactory. Will create a TransformerFactoryClass instance and set it to the converter.
uriResolver null Camel 2.3: Allows you to use a custom javax.xml.transformation.URIResolver. Camel will by default use its own implementation org.apache.camel.builder.xml.XsltUriResolver which is capable of loading from classpath.
resultHandlerFactory null Camel 2.3: Allows you to use a custom org.apache.camel.builder.xml.ResultHandlerFactory which is capable of using custom org.apache.camel.builder.xml.ResultHandler types.
failOnNullBody true Camel 2.3: Whether or not to throw an exception if the input body is null.
deleteOutputFile false Camel 2.6: If you have output=file then this option dictates whether or not the output file should be deleted when the Exchange is done processing. For example suppose the output file is a temporary file, then it can be a good idea to delete it after use.
output string Camel 2.3: Option to specify which output type to use. Possible values are: string, bytes, DOM, file. The first three options are all in memory based, where as file is streamed directly to a java.io.File. For file you must specify the filename in the IN header with the key Exchange.XSLT_FILE_NAME which is also CamelXsltFileName. Also any paths leading to the filename must be created beforehand, otherwise an exception is thrown at runtime.
contentCache true Camel 2.6: Cache for the resource content (the stylesheet file) when it is loaded. If set to false Camel will reloader the stylesheet file on each message processing. This is good for development.

Camel 1.6.2/2.2 or older If you use xsl:include in your XSL files then in Camel 2.2 or older it uses the default javax.xml.transform.URIResolver which means it can only lookup files from file system, and its does that relative from the JVM starting folder.

For example this include:

<xsl:include href="staff_template.xsl"/>

Will lookup the staff_tempkalte.xsl file from the starting folder where the application was started.

Camel 1.6.3/2.3 or newer Now Camel provides its own implementation of URIResolver which allows Camel to load included files from the classpath and more intelligent than before.

For example this include:

<xsl:include href="staff_template.xsl"/>

Will now be located relative from the starting endpoint, which for example could be:

.to("xslt:org/apache/camel/component/xslt/staff_include_relative.xsl")

Which means Camel will locate the file in the classpath as org/apache/camel/component/xslt/staff_template.xsl. This allows you to use xsl include and have xsl files located in the same folder such as we do in the example org/apache/camel/component/xslt.

You can use the following two prefixes classpath: or file: to instruct Camel to look either in classpath or file system. If you omit the prefix then Camel uses the prefix from the endpoint configuration. If that neither has one, then classpath is assumed.

You can also refer back in the paths such as

    <xsl:include href="../staff_other_template.xsl"/>

Which then will resolve the xsl file under org/apache/camel/component.