camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Book Getting Started
Date Fri, 08 Jul 2011 12:01:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/CAMEL/Book+Getting+Started">Book
Getting Started</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~janstey">Jonathan
Anstey</a>
    </h4>
        <br/>
                         <h4>Changes (0)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <div id="chapter-getting-started" class="chapter"><h1><a name="BookGettingStarted-GettingStartedwithApacheCamel"></a>Getting
Started with Apache Camel</h1></div>

<p><a name="BookGettingStarted-eipbook"></a></p>
<h2><a name="BookGettingStarted-TheEnterpriseIntegrationPatterns%28EIP%29book"></a>The
<em>Enterprise Integration Patterns</em> (EIP) book</h2>
<p>The purpose of a "patterns" book is not to advocate new techniques that the authors
have invented, but rather to document existing best practices within a particular field. By
doing this, the authors of a patterns book hope to spread knowledge of best practices and
promote a vocabulary for discussing architectural designs.<br/>
One of the most famous patterns books is <a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612"
class="external-link" rel="nofollow"><em>Design Patterns: Elements of Reusable Object-oriented
Software</em></a> by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides,
commonly known as the <a href="http://en.wikipedia.org/wiki/Design_Patterns" class="external-link"
rel="nofollow">"Gang of Four" (GoF)</a> book.  Since the publication of <em>Design
Patterns</em>, many other pattern books, of varying quality, have been written. One
famous patterns book is called <a href="http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683"
class="external-link" rel="nofollow"><em>Enterprise Integration Patterns: Designing,
Building, and Deploying Messaging Solutions</em></a> by Gregor Hohpe and Bobby
Woolf. It is common for people to refer to this book by its initials <em>EIP</em>.
As the subtitle of EIP suggests, the book focuses on design patterns for asynchronous messaging
systems. The book discusses 65 patterns. Each pattern is given a textual name and most are
also given a graphical symbol, intended to be used in architectural diagrams.</p>

<h2><a name="BookGettingStarted-TheCamelproject"></a>The Camel project</h2>
<p>Camel (<a href="http://activemq.apache.org/camel/" class="external-link" rel="nofollow">http://activemq.apache.org/camel/</a>)
is an open-source, Java-based project that helps the user implement many of the design patterns
in the EIP book. Because Camel implements many of the design patterns in the EIP book, it
would be a good idea for people who work with Camel to have the EIP book as a reference.</p>

<h2><a name="BookGettingStarted-OnlinedocumentationforCamel"></a>Online
documentation for Camel</h2>
<p>The documentation is all under the Documentation category on the right-side menu
of the Camel website (also available in <a href="http://camel.apache.org/manual.html" class="external-link"
rel="nofollow">PDF form</a>.  <a href="/confluence/display/CAMEL/Books" title="Books">Camel-related
books</a> are also available, in particular the <a href="http://manning.com/ibsen"
class="external-link" rel="nofollow">Camel in Action</a> book, presently serving
as the Camel bible--it has a <a href="http://www.manning.com/ibsen/Camel_ch01_update.pdf"
class="external-link" rel="nofollow">free Chapter One (pdf)</a>, which is highly
recommended to read to get more familiar with Camel.</p>

<h3><a name="BookGettingStarted-Ausefultipfornavigatingtheonlinedocumentation"></a>A
useful tip for navigating the online documentation</h3>
<p>The breadcrumbs at the top of the online Camel documentation can help you navigate
between parent and child subsections.  <br/>
For example, If you are on the "Languages" documentation page then the left-hand side of the
reddish bar contains the following links.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Apache Camel &gt; Documentation &gt; Architecture &gt; Languages
</pre>
</div></div>
<p>As you might expect, clicking on "Apache Camel" takes you back to the home page of
the Apache Camel project, and clicking on "Documentation" takes you to the main documentation
page. You can interpret the "Architecture" and "Languages" buttons as indicating you are in
the "Languages" section of the "Architecture" chapter. Adding browser bookmarks to pages that
you frequently reference can also save time.  </p>

<p><a name="BookGettingStarted-onlinejavadocdocs"></a></p>
<h2><a name="BookGettingStarted-OnlineJavadocdocumentation"></a>Online Javadoc
documentation</h2>
<p>The Apache Camel website provides <a href="http://camel.apache.org/maven/current/camel-core/apidocs/index.html"
class="external-link" rel="nofollow">Javadoc documentation</a>. It is important to
note that the Javadoc documentation is spread over several <em>independent</em>
Javadoc hierarchies rather than being all contained in a single Javadoc hierarchy. In particular,
there is one Javadoc hierarchy for the <em>core</em> APIs of Camel, and a separate
Javadoc hierarchy for each component technology supported by Camel. For example, if you will
be using Camel with ActiveMQ and FTP then you need to look at the Javadoc hierarchies for
the <a href="http://camel.apache.org/maven/current/camel-core/apidocs/index.html" class="external-link"
rel="nofollow">core API</a> and <a href="http://camel.apache.org/maven/current/camel-spring/apidocs/index.html"
class="external-link" rel="nofollow">Spring API</a>.</p>

<h2><a name="BookGettingStarted-ConceptsandterminologyfundamentaltoCamel"></a>Concepts
and terminology fundamental to Camel</h2>
<p>In this section some of the concepts and terminology that are fundamental to Camel
are explained. This section is not meant as a complete Camel tutorial, but as a first step
in that direction.</p>

<p><a name="BookGettingStarted-endpoint"></a></p>
<h3><a name="BookGettingStarted-Endpoint"></a>Endpoint</h3>
<p>The term <em>endpoint</em> is often used when talking about inter-process
communication. For example, in client-server communication, the client is one endpoint and
the server is the other endpoint. Depending on the context, an endpoint might refer to an
<em>address</em>, such as a host:port pair for TCP-based communication, or it
might refer to a <em>software entity</em> that is contactable at that address.
For example, if somebody uses "www.example.com:80" as an example of an endpoint, they might
be referring to the actual port at that host name (that is, an address), or they might be
referring to the web server (that is, software contactable at that address). Often, the distinction
between the address and software contactable at that address is not an important one.<br/>
Some middleware technologies make it possible for several software entities to be contactable
at the same physical address. For example, CORBA is an object-oriented, remote-procedure-call
(RPC) middleware standard. If a CORBA server process contains several objects then a client
can communicate with any of these objects at the same <em>physical</em> address
(host:port), but a client communicates with a particular object via that object's <em>logical</em>
address (called an <em>IOR</em> in CORBA terminology), which consists of the physical
address (host:port) plus an id that uniquely identifies the object within its server process.
(An IOR contains some additional information that is not relevant to this present discussion.)
When talking about CORBA, some people may use the term "endpoint" to refer to a CORBA server's
<em>physical address</em>, while other people may use the term to refer to the
<em>logical address</em> of a single CORBA object, and other people still might
use the term to refer to any of the following:</p>
<ul>
	<li>The physical address (host:port) of the CORBA server process</li>
	<li>The logical address (host:port plus id) of a CORBA object.</li>
	<li>The CORBA server process (a relatively heavyweight software entity)</li>
	<li>A CORBA object (a lightweight software entity)</li>
</ul>


<p>Because of this, you can see that the term <em>endpoint</em> is ambiguous
in at least two ways. First, it is ambiguous because it might refer to an address or to a
software entity contactable at that address. Second, it is ambiguous in the <em>granularity</em>
of what it refers to: a heavyweight versus lightweight software entity, or physical address
versus logical address. It is useful to understand that different people use the term <em>endpoint</em>
in slightly different (and hence ambiguous) ways because Camel's usage of this term might
be different to whatever meaning you had previously associated with the term.<br/>
Camel provides out-of-the-box support for endpoints implemented with many different communication
technologies. Here are some examples of the Camel-supported endpoint technologies.</p>
<ul>
	<li>A JMS queue.</li>
	<li>A web service.</li>
	<li>A file. A file may sound like an unlikely type of endpoint, until you realize that
in some systems one application might write information to a file and, later, another application
might read that file.</li>
	<li>An FTP server.</li>
	<li>An email address. A client can send a message to an email address, and a server
can read an incoming message from a mail server.</li>
	<li>A POJO (plain old Java object).</li>
</ul>


<p>In a Camel-based application, you create (Camel wrappers around) some endpoints and
connect these endpoints with <em>routes</em>, which I will discuss later in <a
href="#BookGettingStarted-routes">Section 4.8 ("Routes, RouteBuilders and Java DSL")</a>.
Camel defines a Java interface called <tt>Endpoint</tt>. Each Camel-supported
endpoint has a class that implements this <tt>Endpoint</tt> interface. As I discussed
in <a href="#BookGettingStarted-onlinejavadocdocs">Section 3.3 ("Online Javadoc documentation")</a>,
Camel provides a separate Javadoc hierarchy for each communications technology supported by
Camel. Because of this, you will find documentation on, say, the <tt>JmsEndpoint</tt>
class in the <a href="http://camel.apache.org/maven/current/camel-jms/apidocs/" class="external-link"
rel="nofollow">JMS Javadoc hierarchy</a>, while documentation for, say, the <tt>FtpEndpoint</tt>
class is in the <a href="http://camel.apache.org/maven/current/camel-ftp/apidocs/" class="external-link"
rel="nofollow">FTP Javadoc hierarchy</a>.</p>

<h3><a name="BookGettingStarted-CamelContext"></a>CamelContext</h3>
<p>A <tt>CamelContext</tt> object represents the Camel runtime system. You
typically have one <tt>CamelContext</tt> object in an application. A typical application
executes the following steps.</p>
<ol>
	<li>Create a <tt>CamelContext</tt> object.</li>
	<li>Add endpoints &#8211; and possibly Components, which are discussed in <a
href="#BookGettingStarted-componentsanduris">Section 4.5 ("Components")</a> &#8211;
to the <tt>CamelContext</tt> object.</li>
	<li>Add routes to the <tt>CamelContext</tt> object to connect the endpoints.</li>
	<li>Invoke the <tt>start()</tt> operation on the <tt>CamelContext</tt>
object. This starts Camel-internal threads that are used to process the sending, receiving
and processing of messages in the endpoints.</li>
	<li>Eventually invoke the <tt>stop()</tt> operation on the <tt>CamelContext</tt>
object. Doing this gracefully stops all the endpoints and Camel-internal threads.</li>
</ol>


<p>Note that the <tt>CamelContext.start()</tt> operation does not block
indefinitely. Rather, it starts threads internal to each <tt>Component</tt> and
<tt>Endpoint</tt> and then <tt>start()</tt> returns. Conversely, <tt>CamelContext.stop()</tt>
waits for all the threads internal to each <tt>Endpoint</tt> and <tt>Component</tt>
to terminate and then <tt>stop()</tt> returns.<br/>
If you neglect to call <tt>CamelContext.start()</tt> in your application then
messages will not be processed because internal threads will not have been created.<br/>
If you neglect to call <tt>CamelContext.stop()</tt> before terminating your application
then the application may terminate in an inconsistent state. If you neglect to call <tt>CamelContext.stop()</tt>
in a JUnit test then the test may fail due to messages not having had a chance to be fully
processed.</p>

<h3><a name="BookGettingStarted-CamelTemplate"></a>CamelTemplate</h3>
<p>Camel used to have a class called <tt>CamelClient</tt>, but this was
renamed to be <tt>CamelTemplate</tt> to be similar to a naming convention used
in some other open-source projects, such as the <tt>TransactionTemplate</tt> and
<tt>JmsTemplate</tt> classes in <a href="http://www.springframework.org/" class="external-link"
rel="nofollow">Spring</a>.<br/>
The <tt>CamelTemplate</tt> class is a thin wrapper around the <tt>CamelContext</tt>
class. It has methods that send a <tt>Message</tt> or <tt>Exchange</tt>
&#8211; both discussed in <a href="#BookGettingStarted-messageandexchange">Section
4.6 ("Message and Exchange")</a>) &#8211; to an <tt>Endpoint</tt> &#8211;
discussed in <a href="#BookGettingStarted-endpoint">Section 4.1 ("Endpoint")</a>.
This provides a way to enter messages into source endpoints, so that the messages will move
along routes &#8211; discussed in <a href="#BookGettingStarted-routes">Section 4.8
("Routes, RouteBuilders and Java DSL")</a> &#8211; to destination endpoints.</p>

<p><a name="BookGettingStarted-urluriurniri"></a></p>
<h3><a name="BookGettingStarted-TheMeaningofURL%2CURI%2CURNandIRI"></a>The
Meaning of URL, URI, URN and IRI </h3>
<p>Some Camel methods take a parameter that is a <em>URI</em> string. Many
people know that a URI is "something like a URL" but do not properly understand the relationship
between URI and URL, or indeed its relationship with other acronyms such as IRI and URN.<br/>
Most people are familiar with <em>URLs</em> (uniform resource locators), such
as "http://...", "ftp://...", "mailto:...". Put simply, a URL specifies the <em>location</em>
of a resource.<br/>
A <em>URI</em> (uniform resource identifier) is a URL <em>or</em>
a URN. So, to fully understand what URI means, you need to first understand what is a URN.<br/>
<em>URN</em> is an acronym for <em>uniform resource name</em>. There
are may "unique identifier" schemes in the world, for example, ISBNs (globally unique for
books), social security numbers (unique within a country), customer numbers (unique within
a company's customers database) and telephone numbers. Each "unique identifier" scheme has
its own notation. A URN is a wrapper for different "unique identifier" schemes. The syntax
of a URN is "urn:&lt;scheme-name&gt;:&lt;unique-identifier&gt;". A URN uniquely
identifies a <em>resource</em>, such as a book, person or piece of equipment.
By itself, a URN does not specify the <em>location</em> of the resource. Instead,
it is assumed that a <em>registry</em> provides a mapping from a resource's URN
to its location. The URN specification does not state what form a registry takes, but it might
be a database, a server application, a wall chart or anything else that is convenient. Some
hypothetical examples of URNs are "urn:employee:08765245", "urn:customer:uk:3458:hul8" and
"urn:foo:0000-0000-9E59-0000-5E-2". The &lt;scheme-name&gt; ("employee", "customer"
and "foo" in these examples) part of a URN implicitly defines how to parse and interpret the
&lt;unique-identifier&gt; that follows it. An arbitrary URN is meaningless unless:
(1) you know the semantics implied by the &lt;scheme-name&gt;, and (2) you have access
to the registry appropriate for the &lt;scheme-name&gt;. A registry does not have
to be public or globally accessible. For example, "urn:employee:08765245" might be meaningful
only within a specific company.<br/>
To date, URNs are not (yet) as popular as URLs. For this reason, URI is widely misused as
a synonym for URL.<br/>
<em>IRI</em> is an acronym for <em>internationalized resource identifier</em>.
An IRI is simply an internationalized version of a URI. In particular, a URI can contain letters
and digits in the US-ASCII character set, while a IRI can contain those same letters and digits,
and <em>also</em> European accented characters, Greek letters, Chinese ideograms
and so on.</p>

<h3><a name="BookGettingStarted-Components"></a>Components</h3>
<p><em>Component</em> is confusing terminology; <em>EndpointFactory</em>
would have been more appropriate because a <tt>Component</tt> is a factory for
creating <tt>Endpoint</tt> instances. For example, if a Camel-based application
uses several JMS queues then the application will create one instance of the <tt>JmsComponent</tt>
class (which implements the <tt>Component</tt> interface), and then the application
invokes the <tt>createEndpoint()</tt> operation on this <tt>JmsComponent</tt>
object several times. Each invocation of <tt>JmsComponent.createEndpoint()</tt>
creates an instance of the <tt>JmsEndpoint</tt> class (which implements the <tt>Endpoint</tt>
interface). Actually, application-level code does not invoke <tt>Component.createEndpoint()</tt>
directly. Instead, application-level code normally invokes <tt>CamelContext.getEndpoint()</tt>;
internally, the <tt>CamelContext</tt> object finds the desired <tt>Component</tt>
object (as I will discuss shortly) and then invokes <tt>createEndpoint()</tt>
on it.<br/>
Consider the following code.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
myCamelContext.getEndpoint(<span class="code-quote">"pop3:<span class="code-comment">//john.smith@mailserv.example.com?password=myPassword"</span>);</span>
</pre>
</div></div>
<p>The parameter to <tt>getEndpoint()</tt> is a URI. The URI <em>prefix</em>
(that is, the part before ":") specifies the name of a component. Internally, the <tt>CamelContext</tt>
object maintains a mapping from names of components to <tt>Component</tt> objects.
For the URI given in the above example, the <tt>CamelContext</tt> object would
probably map the <tt>pop3</tt> prefix to an instance of the <tt>MailComponent</tt>
class. Then the <tt>CamelContext</tt> object invokes <tt>createEndpoint("pop3://john.smith@mailserv.example.com?password=myPassword")</tt>
on that <tt>MailComponent</tt> object. The <tt>createEndpoint()</tt>
operation splits the URI into its component parts and uses these parts to create and configure
an <tt>Endpoint</tt> object.<br/>
In the previous paragraph, I mentioned that a <tt>CamelContext</tt> object maintains
a mapping from component names to <tt>Component</tt> objects. This raises the
question of how this map is populated with named <tt>Component</tt> objects. There
are two ways of populating the map. The first way is for application-level code to invoke
<tt>CamelContext.addComponent(String componentName, Component component)</tt>.
The example below shows a single <tt>MailComponent</tt> object being registered
in the map under 3 different names.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
Component mailComponent = <span class="code-keyword">new</span> org.apache.camel.component.mail.MailComponent();
myCamelContext.addComponent(<span class="code-quote">"pop3"</span>, mailComponent);
myCamelContext.addComponent(<span class="code-quote">"imap"</span>, mailComponent);
myCamelContext.addComponent(<span class="code-quote">"smtp"</span>, mailComponent);
</pre>
</div></div>
<p>The second (and preferred) way to populate the map of named <tt>Component</tt>
objects in the <tt>CamelContext</tt> object is to let the <tt>CamelContext</tt>
object perform lazy initialization. This approach relies on developers following a convention
when they write a class that implements the <tt>Component</tt> interface. I illustrate
the convention by an example. Let's assume you write a class called <tt>com.example.myproject.FooComponent</tt>
and you want Camel to automatically recognize this by the name "foo". To do this, you have
to write a properties file called "META-INF/services/org/apache/camel/component/foo" (without
a ".properties" file extension) that has a single entry in it called <tt>class</tt>,
the value of which is the fully-scoped name of your class. This is shown below.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>META-INF/services/org/apache/camel/component/foo</b></div><div
class="codeContent panelContent">
<pre class="code-java">
class=com.example.myproject.FooComponent
</pre>
</div></div>
<p>If you want Camel to also recognize the class by the name "bar" then you write another
properties file in the same directory called "bar" that has the same contents. Once you have
written the properties file(s), you create a jar file that contains the <tt>com.example.myproject.FooComponent</tt>
class and the properties file(s), and you add this jar file to your CLASSPATH. Then, when
application-level code invokes <tt>createEndpoint("foo:...")</tt> on a <tt>CamelContext</tt>
object, Camel will find the "foo"" properties file on the CLASSPATH, get the value of the
<tt>class</tt> property from that properties file, and use reflection APIs to
create an instance of the specified class.<br/>
As I said in <a href="#BookGettingStarted-endpoint">Section 4.1 ("Endpoint")</a>,
Camel provides out-of-the-box support for numerous communication technologies. The out-of-the-box
support consists of classes that implement the <tt>Component</tt> interface plus
properties files that enable a <tt>CamelContext</tt> object to populate its map
of named <tt>Component</tt> objects.<br/>
Earlier in this section I gave the following example of calling <tt>CamelContext.getEndpoint()</tt>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
myCamelContext.getEndpoint(<span class="code-quote">"pop3:<span class="code-comment">//john.smith@mailserv.example.com?password=myPassword"</span>);</span>
</pre>
</div></div>
<p>When I originally gave that example, I said that the parameter to <tt>getEndpoint()</tt>
was a URI. I said that because the online Camel documentation and the Camel source code both
claim the parameter is a URI. In reality, the parameter is restricted to being a URL. This
is because when Camel extracts the component name from the parameter, it looks for the first
":", which is a simplistic algorithm. To understand why, recall from <a href="#BookGettingStarted-urluriurniri">Section
4.4 ("The Meaning of URL, URI, URN and IRI")</a> that a URI can be a URL <em>or</em>
a URN. Now consider the following calls to <tt>getEndpoint</tt>.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<pre class="code-java">
myCamelContext.getEndpoint(<span class="code-quote">"pop3:..."</span>);
myCamelContext.getEndpoint(<span class="code-quote">"jms:..."</span>);
myCamelContext.getEndpoint(<span class="code-quote">"urn:foo:..."</span>);
myCamelContext.getEndpoint(<span class="code-quote">"urn:bar:..."</span>);
</pre>
</div></div>
<p>Camel identifies the components in the above example as "pop3", "jms", "urn" and
"urn". It would be more useful if the latter components were identified as "urn:foo" and "urn:bar"
or, alternatively, as "foo" and "bar" (that is, by skipping over the "urn:" prefix). So, in
practice you must identify an endpoint with a URL (a string of the form "&lt;scheme&gt;:...")
rather than with a URN (a string of the form "urn:&lt;scheme&gt;:..."). This lack
of proper support for URNs means the you should consider the parameter to <tt>getEndpoint()</tt>
as being a URL rather than (as claimed) a URI.</p>

<p><a name="BookGettingStarted-messageandexchange"></a></p>
<h3><a name="BookGettingStarted-MessageandExchange"></a>Message and Exchange</h3>
<p>The <tt>Message</tt> interface provides an abstraction for a single message,
such as a request, reply or exception message.<br/>
There are concrete classes that implement the <tt>Message</tt> interface for each
Camel-supported communications technology. For example, the <tt>JmsMessage</tt>
class provides a JMS-specific implementation of the <tt>Message</tt> interface.
The public API of the <tt>Message</tt> interface provides get- and set-style methods
to access the <em>message id</em>, <em>body</em> and individual <em>header</em>
fields of a messge.<br/>
The <tt>Exchange</tt> interface provides an abstraction for an exchange of messages,
that is, a request message and its corresponding reply or exception message. In Camel terminology,
the request, reply and exception messages are called <em>in</em>, <em>out</em>
and <em>fault</em> messages.<br/>
There are concrete classes that implement the <tt>Exchange</tt> interface for
each Camel-supported communications technology. For example, the <tt>JmsExchange</tt>
class provides a JMS-specific implementation of the <tt>Exchange</tt> interface.
The public API of the <tt>Exchange</tt> interface is quite limited. This is intentional,
and it is expected that each class that implements this interface will provide its own technology-specific
operations.<br/>
Application-level programmers rarely access the <tt>Exchange</tt> interface (or
classes that implement it) directly. However, many classes in Camel are generic types that
are instantiated on (a class that implements) <tt>Exchange</tt>. Because of this,
the <tt>Exchange</tt> interface appears a lot in the generic signatures of classes
and methods.</p>

<h3><a name="BookGettingStarted-Processor"></a>Processor</h3>
<p>The <tt>Processor</tt> interface represents a class that processes a
message. The signature of this interface is shown below.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Processor</b></div><div class="codeContent
panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel;
<span class="code-keyword">public</span> <span class="code-keyword">interface</span>
Processor {
    void process(Exchange exchange) <span class="code-keyword">throws</span> Exception;
}
</pre>
</div></div>
<p>Notice that the parameter to the <tt>process()</tt> method is an <tt>Exchange</tt>
rather than a <tt>Message</tt>. This provides flexibility. For example, an implementation
of this method initially might call <tt>exchange.getIn()</tt> to get the input
message and process it. If an error occurs during processing then the method can call <tt>exchange.setException()</tt>.<br/>
An application-level developer might implement the <tt>Processor</tt> interface
with a class that executes some business logic. However, there are many classes in the Camel
library that implement the <tt>Processor</tt> interface in a way that provides
support for a design pattern in the <a href="#BookGettingStarted-eipbook">EIP book</a>.
For example, <tt>ChoiceProcessor</tt> implements the message router pattern, that
is, it uses a cascading if-then-else statement to route a message from an input queue to one
of several output queues. Another example is the <tt>FilterProcessor</tt> class
which discards messages that do not satisfy a stated <em>predicate</em> (that
is, condition).</p>

<p><a name="BookGettingStarted-routes"></a></p>
<h3><a name="BookGettingStarted-Routes%2CRouteBuildersandJavaDSL"></a>Routes,
RouteBuilders and Java DSL</h3>
<p>A <em>route</em> is the step-by-step movement of a <tt>Message</tt>
from an input queue, through arbitrary types of decision making (such as filters and routers)
to a destination queue (if any). Camel provides two ways for an application developer to specify
routes. One way is to specify route information in an XML file. A discussion of that approach
is outside the scope of this document. The other way is through what Camel calls a Java <em>DSL</em>
(domain-specific language).</p>

<h4><a name="BookGettingStarted-IntroductiontoJavaDSL"></a>Introduction
to Java DSL</h4>
<p>For many people, the term "domain-specific language" implies a compiler or interpreter
that can process an input file containing keywords and syntax specific to a particular domain.
This is <em>not</em> the approach taken by Camel. Camel documentation consistently
uses the term "Java DSL" instead of "DSL", but this does not entirely avoid potential confusion.
The Camel "Java DSL" is a class library that can be used in a way that looks almost like a
DSL, except that it has a bit of Java syntactic baggage. You can see this in the example below.
Comments afterwards explain some of the constructs used in the example.</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>Example of Camel's "Java DSL"</b></div><div
class="codeContent panelContent">
<pre class="code-java">
RouteBuilder builder = <span class="code-keyword">new</span> RouteBuilder() {
    <span class="code-keyword">public</span> void configure() {
        from(<span class="code-quote">"queue:a"</span>).filter(header(<span
class="code-quote">"foo"</span>).isEqualTo(<span class="code-quote">"bar"</span>)).to(<span
class="code-quote">"queue:b"</span>);
        from(<span class="code-quote">"queue:c"</span>).choice()
                .when(header(<span class="code-quote">"foo"</span>).isEqualTo(<span
class="code-quote">"bar"</span>)).to(<span class="code-quote">"queue:d"</span>)
                .when(header(<span class="code-quote">"foo"</span>).isEqualTo(<span
class="code-quote">"cheese"</span>)).to(<span class="code-quote">"queue:e"</span>)
                .otherwise().to(<span class="code-quote">"queue:f"</span>);
    }
};
CamelContext myCamelContext = <span class="code-keyword">new</span> DefaultCamelContext();
myCamelContext.addRoutes(builder);
</pre>
</div></div>
<p>The first line in the above example creates an object which is an instance of an
anonymous subclass of <tt>RouteBuilder</tt> with the specified <tt>configure()</tt>
method.<br/>
The <tt>CamelContext.addRoutes(RouterBuilder builder)</tt> method invokes <tt>builder.setContext(this)</tt>
&#8211; so the <tt>RouteBuilder</tt> object knows which <tt>CamelContext</tt>
object it is associated with &#8211; and then invokes <tt>builder.configure()</tt>.
The body of <tt>configure()</tt> invokes methods such as <tt>from()</tt>,
<tt>filter()</tt>, <tt>choice()</tt>, <tt>when()</tt>,
<tt>isEqualTo()</tt>, <tt>otherwise()</tt> and <tt>to()</tt>.<br/>
The <tt>RouteBuilder.from(String uri)</tt> method invokes <tt>getEndpoint(uri)</tt>
on the <tt>CamelContext</tt> associated with the <tt>RouteBuilder</tt>
object to get the specified <tt>Endpoint</tt> and then puts a <tt>FromBuilder</tt>
"wrapper" around this <tt>Endpoint</tt>. The <tt>FromBuilder.filter(Predicate
predicate)</tt> method creates a <tt>FilterProcessor</tt> object for the
<tt>Predicate</tt> (that is, condition) object built from the <tt>header("foo").isEqualTo("bar")</tt>
expression. In this way, these operations incrementally build up a <tt>Route</tt>
object (with a <tt>RouteBuilder</tt> wrapper around it) and add it to the <tt>CamelContext</tt>
object associated with the <tt>RouteBuilder</tt>.</p>

<h4><a name="BookGettingStarted-CritiqueofJavaDSL"></a>Critique of Java
DSL</h4>
<p>The online Camel documentation compares Java DSL favourably against the alternative
of configuring routes and endpoints in a XML-based Spring configuration file. In particular,
Java DSL is less verbose than its XML counterpart. In addition, many integrated development
environments (IDEs) provide an auto-completion feature in their editors. This auto-completion
feature works with Java DSL, thereby making it easier for developers to write Java DSL.<br/>
However, there is another option that the Camel documentation neglects to consider: that of
writing a parser that can process DSL stored in, say, an external file. Currently, Camel does
not provide such a DSL parser, and I do not know if it is on the "to do" list of the Camel
maintainers. I think that a DSL parser would offer a significant benefit over the current
Java DSL. In particular, the DSL would have a syntactic definition that could be expressed
in a relatively short BNF form. The effort required by a Camel user to learn how to use DSL
by reading this BNF would almost certainly be significantly less than the effort currently
required to study the API of the <tt>RouterBuilder</tt> classes.</p>


<h3><a name="BookGettingStarted-ContinueLearningaboutCamel"></a>Continue
Learning about Camel</h3>

<p>Return to the main <a href="/confluence/display/CAMEL/Getting+Started" title="Getting
Started">Getting Started</a> page for additional introductory reference information.</p>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Book+Getting+Started">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=60182&revisedVersion=12&originalVersion=11">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/CAMEL/Book+Getting+Started?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message