1.4. Endpoints
Overview
Apache Camel endpoints are the sources and sinks of messages in a route. An endpoint is a very general sort of building block: the only requirement it must satisfy is that it acts either as a source of messages (a consumer endpoint) or as a sink of messages (a producer endpoint). Hence, there are a great variety of different endpoint types supported in Apache Camel, ranging from protocol supporting endpoints, such as HTTP, to simple timer endpoints, such as Quartz, that generate dummy messages at regular time intervals. One of the major strengths of Apache Camel is that it is relatively easy to add a custom component that implements a new endpoint type.
Endpoint URIs
Endpoints are identified by endpoint URIs, which have the following general form:
scheme:contextPath[?queryOptions]
The URI scheme identifies a protocol, such as
http
, and the contextPath provides URI details that are interpreted by the protocol. In addition, most schemes allow you to define query options, queryOptions, which are specified in the following format:
?option01=value01&option02=value02&...
For example, the following HTTP URI can be used to connect to the Google search engine page:
http://www.google.com
The following File URI can be used to read all of the files appearing under the
C:\temp\src\data
directory:
file://C:/temp/src/data
Not every scheme represents a protocol. Sometimes a scheme just provides access to a useful utility, such as a timer. For example, the following Timer endpoint URI generates an exchange every second (=1000 milliseconds). You could use this to schedule activity in a route.
timer://tickTock?period=1000
Working with Long Endpoint URIs
Sometimes endpoint URIs can become quite long due to all the accompanying configuration information supplied. In JBoss Fuse 6.2 onwards, there are two approaches you can take to make your working with lengthy URIs more manageable.
- Configure Endpoints Separately
- You can configure the endpoint separately, and from the routes refer to the endpoints using their shorthand IDs.
<camelContext ...> <endpoint id="foo" uri="ftp://foo@myserver"> <property name="password" value="secret"/> <property name="recursive" value="true"/> <property name="ftpClient.dataTimeout" value="30000"/> <property name="ftpClient.serverLanguageCode" value="fr"/> </endpoint> <route> <from uri="ref:foo"/> ... </route> </camelContext>
You can also configure some options in the URI and then use theproperty
attribute to specify additional options (or to override options from the URI).<endpoint id="foo" uri="ftp://foo@myserver?recursive=true"> <property name="password" value="secret"/> <property name="ftpClient.dataTimeout" value="30000"/> <property name="ftpClient.serverLanguageCode" value="fr"/> </endpoint>
- Split Endpoint Configuration Across New Lines
- You can split URI attributes using new lines.
<route> <from uri="ftp://foo@myserver?password=secret& recursive=true&ftpClient.dataTimeout=30000& ftpClientConfig.serverLanguageCode=fr"/> <to uri="bean:doSomething"/> </route>
NoteYou can specify one or more options on each line, each separated by&
.
Specifying time periods in a URI
Many of the Apache Camel components have options whose value is a time period (for example, for specifying timeout values and so on). By default, such time period options are normally specified as a pure number, which is interpreted as a millisecond time period. But Apache Camel also supports a more readable syntax for time periods, which enables you to express the period in hours, minutes, and seconds. Formally, the human-readable time period is a string that conforms to the following syntax:
[NHour(h|hour)][NMin(m|minute)][NSec(s|second)]
Where each term in square brackets,
[]
, is optional and the notation, (A|B)
, indicates that A
and B
are alternatives.
For example, you can configure
timer
endpoint with a 45 minute period as follows:
from("timer:foo?period=45m") .to("log:foo");
You can also use arbitrary combinations of the hour, minute, and second units, as follows:
from("timer:foo?period=1h15m") .to("log:foo"); from("timer:bar?period=2h30s") .to("log:bar"); from("timer:bar?period=3h45m58s") .to("log:bar");
Specifying raw values in URI options
By default, the option values that you specify in a URI are automatically URI-encoded. In some cases this is undesirable beahavior. For example, when setting a password option, it is preferable to transmit the raw character string without URI encoding.
It is possible to switch of URI encoding by specifying an option value with the syntax,
RAW(RawValue)
. For example,
from("SourceURI")
.to("ftp:joe@myftpserver.com?password=RAW(se+re?t&23)&binary=true")
In this example, the password value is transmitted as the literal value,
se+re?t&23
.
Case-insensitive enum options
Some endpoint URI options get mapped to Java
enum
constants. For example, the level
option of the Log component, which can take the enum
values, INFO
, WARN
, ERROR
, and so on. This type conversion is case-insensitive, so any of the following alternatives could be used to set the logging level of a Log producer endpoint:
<to uri="log:foo?level=info"/> <to uri="log:foo?level=INfo"/> <to uri="log:foo?level=InFo"/>
Apache Camel components
Each URI scheme maps to a Apache Camel component, where a Apache Camel component is essentially an endpoint factory. In other words, to use a particular type of endpoint, you must deploy the corresponding Apache Camel component in your runtime container. For example, to use JMS endpoints, you would deploy the JMS component in your container.
Apache Camel provides a large variety of different components that enable you to integrate your application with various transport protocols and third-party products. For example, some of the more commonly used components are: File, JMS, CXF (Web services), HTTP, Jetty, Direct, and Mock. For the full list of supported components, see the Apache Camel component documentation.
Most of the Apache Camel components are packaged separately to the Camel core. If you use Maven to build your application, you can easily add a component (and its third-party dependencies) to your application simply by adding a dependency on the relevant component artifact. For example, to include the HTTP component, you would add the following Maven dependency to your project POM file:
<!-- Maven POM File --> <properties> <camel-version>2.15.1.redhat-620133</camel-version> ... </properties> <dependencies> ... <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-http</artifactId> <version>${camel-version}</version> </dependency> ... </dependencies>
The following components are built-in to the Camel core (in the
camel-core
artifact), so they are always available:
- Bean
- Browse
- Dataset
- Direct
- File
- Log
- Mock
- Properties
- Ref
- SEDA
- Timer
- VM
Consumer endpoints
A consumer endpoint is an endpoint that appears at the start of a route (that is, in a
from()
DSL command). In other words, the consumer endpoint is responsible for initiating processing in a route: it creates a new exchange instance (typically, based on some message that it has received or obtained), and provides a thread to process the exchange in the rest of the route.
For example, the following JMS consumer endpoint pulls messages off the
payments
queue and processes them in the route:
from("jms:queue:payments") .process(SomeProcessor) .to("TargetURI");
Or equivalently, in Spring XML:
<camelContext id="CamelContextID" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="jms:queue:payments"/> <process ref="someProcessorId"/> <to uri="TargetURI"/> </route> </camelContext>
Some components are consumer only—that is, they can only be used to define consumer endpoints. For example, the Quartz component is used exclusively to define consumer endpoints. The following Quartz endpoint generates an event every second (1000 milliseconds):
from("quartz://secondTimer?trigger.repeatInterval=1000") .process(SomeProcessor) .to("TargetURI");
If you like, you can specify the endpoint URI as a formatted string, using the
fromF()
Java DSL command. For example, to substitute the username and password into the URI for an FTP endpoint, you could write the route in Java, as follows:
fromF("ftp:%s@fusesource.com?password=%s", username, password) .process(SomeProcessor) .to("TargetURI");
Where the first occurrence of
%s
is replaced by the value of the username
string and the second occurrence of %s
is replaced by the password
string. This string formatting mechanism is implemented by String.format()
and is similar to the formatting provided by the C printf()
function. For details, see java.util.Formatter.
Producer endpoints
A producer endpoint is an endpoint that appears in the middle or at the end of a route (for example, in a
to()
DSL command). In other words, the producer endpoint receives an existing exchange object and sends the contents of the exchange to the specified endpoint.
For example, the following JMS producer endpoint pushes the contents of the current exchange onto the specified JMS queue:
from("SourceURI") .process(SomeProcessor) .to("jms:queue:orderForms");
Or equivalently in Spring XML:
<camelContext id="CamelContextID" xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="SourceURI"/> <process ref="someProcessorId"/> <to uri="jms:queue:orderForms"/> </route> </camelContext>
Some components are producer only—that is, they can only be used to define producer endpoints. For example, the HTTP endpoint is used exclusively to define producer endpoints.
from("SourceURI") .process(SomeProcessor) .to("http://www.google.com/search?hl=en&q=camel+router");
If you like, you can specify the endpoint URI as a formatted string, using the
toF()
Java DSL command. For example, to substitute a custom Google query into the HTTP URI, you could write the route in Java, as follows:
from("SourceURI") .process(SomeProcessor) .toF("http://www.google.com/search?hl=en&q=%s", myGoogleQuery);
Where the occurrence of
%s
is replaced by your custom query string, myGoogleQuery
. For details, see java.util.Formatter.