camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Camel > Tutorial for Camel on Google App Engine
Date Fri, 20 Nov 2009 16:41:00 GMT
<html>
<head>
    <base href="http://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/1519/1/1/_/styles/combined.css?spaceKey=CAMEL&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background-color: white" bgcolor="white">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
     <h2><a href="http://cwiki.apache.org/confluence/display/CAMEL/Tutorial+for+Camel+on+Google+App+Engine">Tutorial
for Camel on Google App Engine</a></h2>
     <h4>Page <b>edited</b> by             <a href="http://cwiki.apache.org/confluence/display/~mrt1nz">Martin
Krasser</a>
    </h4>
     
          <br/>
     <div class="notificationGreySide">
         <h2><a name="TutorialforCamelonGoogleAppEngine-CamelonGoogleAppEngineTutorial"></a>Camel
on Google App Engine Tutorial</h2>

<div class='panelMacro'><table class='infoMacro'><colgroup><col width='24'><col></colgroup><tr><td
valign='top'><img src="/confluence/images/icons/emoticons/information.gif" width="16"
height="16" align="absmiddle" alt="" border="0"></td><td><p>This tutorial
will be updated whenever new features are added to the <a href="/confluence/display/CAMEL/GAE"
title="GAE">Camel Components for Google App Engine</a>.</p></td></tr></table></div>

<h3><a name="TutorialforCamelonGoogleAppEngine-Overview"></a>Overview</h3>

<p>Goal of this tutorial is to get a non-trivial Camel application running on Google
App Engine (GAE). For developing that application the <a href="/confluence/display/CAMEL/GAE"
title="GAE">Camel Components for Google App Engine</a> will be used. The application
allows the user to enter the name of a city and an email adsress in an HTML form. The form
data are submitted by the user to a Camel application, running on GAE, which retrieves weather
data for the given city. It then sends a weather report to the user-defined email address.
The following figure gives an overview.</p>

<p><img src="/confluence/download/attachments/5965078/gae-0.PNG" align="absmiddle"
border="0" /></p>

<p>POSTed form data are dispatched to the Camel application via the <a href="/confluence/display/CAMEL/ghttp"
title="ghttp">ghttp</a> component. Then the application queues the message with the
<a href="/confluence/display/CAMEL/gtask" title="gtask">gtask</a> component for
further background processing. This includes retrieval of weather data from the Google Weather
Service, transforming the data to generate a report and sending that report by email via the
<a href="/confluence/display/CAMEL/gmail" title="gmail">gmail</a> component.</p>

<h3><a name="TutorialforCamelonGoogleAppEngine-Prerequisites"></a>Prerequisites</h3>

<ul>
	<li><a href="https://appengine.google.com/" rel="nofollow">Sign up for a Google
App Engine account</a> if you don't have already.</li>
	<li>Create a new application via the <a href="https://appengine.google.com/" rel="nofollow">admin
console</a> or reuse an existing one for uploading the example.</li>
	<li>Install the <a href="http://code.google.com/appengine/downloads.html" rel="nofollow">Google
App Engine SDK for Java</a>. This tutorial has been tested with version 1.2.6.</li>
</ul>


<h3><a name="TutorialforCamelonGoogleAppEngine-Deployment"></a>Deployment</h3>

<p>To deploy the example application, first checkout the sources with </p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>svn co http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-gae camel-example-gae
</pre>
</div></div>

<p>Open the <tt>camel-example-gae/src/main/webapp/WEB-INF/application-web.xml</tt>
file in an editor and replace the template application name <tt>replaceme</tt>
with the name of the application that you created in the previous section.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>appengine-web.xml</b></div><div
class="codeContent panelContent">
<pre class="code-xml">
<span class="code-tag">&lt;?xml version=<span class="code-quote">"1.0"</span>
encoding=<span class="code-quote">"utf-8"</span>?&gt;</span>
<span class="code-tag">&lt;appengine-web-app xmlns=<span class="code-quote">"http://appengine.google.com/ns/1.0"</span>&gt;</span>
    <span class="code-tag"><span class="code-comment">&lt;!-- use your own
application name here --&gt;</span></span>
    <span class="code-tag">&lt;application&gt;</span>replaceme<span
class="code-tag">&lt;/application&gt;</span> 
    <span class="code-tag">&lt;version&gt;</span>1<span class="code-tag">&lt;/version&gt;</span>
	
    <span class="code-tag"><span class="code-comment">&lt;!-- Configure java.util.logging
--&gt;</span></span>
    <span class="code-tag">&lt;system-properties&gt;</span>
        <span class="code-tag">&lt;property name=<span class="code-quote">"java.util.logging.config.file"</span>
value=<span class="code-quote">"WEB-INF/logging.properties"</span>/&gt;</span>
    <span class="code-tag">&lt;/system-properties&gt;</span>
	
<span class="code-tag">&lt;/appengine-web-app&gt;</span></pre>
</div></div>

<p>Open <tt>camel-example-gae/src/main/resources/context.xml</tt> file and
change the <tt>sender</tt> property value to the email address of your Google
App Engine account.</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>context.xml</b></div><div class="codeContent
panelContent">
<pre class="code-xml">
&lt;beans xmlns=<span class="code-quote">"http://www.springframework.org/schema/beans"</span>
       <span class="code-keyword">xmlns:xsi</span>=<span class="code-quote">"http://www.w3.org/2001/XMLSchema-instance"</span>
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt;
    
    ...

    &lt;bean id=<span class="code-quote">"tutorialRouteBuilder"</span>
        class=<span class="code-quote">"org.apache.camel.example.gae.TutorialRouteBuilder"</span>&gt;
        <span class="code-tag"><span class="code-comment">&lt;!-- use your
own GAE admin email address here --&gt;</span></span>
        <span class="code-tag">&lt;property name=<span class="code-quote">"sender"</span>
value=<span class="code-quote">"replaceme@gmail.com"</span> /&gt;</span>
    <span class="code-tag">&lt;/bean&gt;</span>
    
<span class="code-tag">&lt;/beans&gt;</span>
</pre>
</div></div>

<p>Then go to the <tt>camel-example-gae</tt> directory and enter</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>mvn install
</pre>
</div></div>

<p>This will create the application <tt>war</tt> file in the target directory.
Finally use the <tt>appcfg</tt> command-line tool of the App Engine SDK to deploy
the application.</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>appcfg update target/camel-example-gae-&lt;version&gt;
</pre>
</div></div>

<p>where <tt>version</tt> needs to be replaced with the version of Camel
you're using. You will be prompted for the email address and password of your Google App Engine
account. After deployment the example application is ready to use.</p>

<h3><a name="TutorialforCamelonGoogleAppEngine-Usage"></a>Usage</h3>

<p>Go to <tt><a href="http://replaceme.appspot.com" rel="nofollow">http://replaceme.appspot.com</a></tt>
where <tt>replaceme</tt> must be replaced with the application name you entered
in <tt>appengine-web.xml</tt>. The following form should now appear.</p>

<p><img src="/confluence/download/attachments/5965078/gae-5.PNG" align="absmiddle"
border="0" /></p>

<p>Enter the name of a city and your email address, for example:</p>

<p><img src="/confluence/download/attachments/5965078/gae-6.PNG" align="absmiddle"
border="0" /></p>

<p>Then press <tt>Submit</tt>. The immediate response is </p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>Weather report will be sent to you@yourprovider.com
</pre>
</div></div>

<p>In the background, the current weather conditions for the user-defined city will
be obtained from the Google weather service and a formatted weather report will be send by
email. Submitting the form the first time initializes the application on Google App Engine
which can take several seconds. Subsequent submissions are served much faster. Check your
emails and you should now see a new email with subject <tt>Wheather report</tt>
and content similar to this one:</p>

<div class="preformatted panel" style="border-width: 1px;"><div class="preformattedContent
panelContent">
<pre>Weather report for:  London, England
Current condition:   Klar
Current temperature: 12 (Celsius) 
</pre>
</div></div>

<p>The report is partly internationalized, depending on the language settings of your
browser.</p>

<h3><a name="TutorialforCamelonGoogleAppEngine-Routebuilderwalkthrough"></a>Route
builder walkthrough</h3>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>TutorialRouteBuilder.java</b></div><div
class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.example.gae;

<span class="code-keyword">import</span> org.apache.camel.Exchange;
<span class="code-keyword">import</span> org.apache.camel.builder.RouteBuilder;
<span class="code-keyword">import</span> org.apache.camel.component.gae.mail.GMailBinding;

<span class="code-keyword">public</span> class TutorialRouteBuilder <span class="code-keyword">extends</span>
RouteBuilder {

    <span class="code-keyword">private</span> <span class="code-object">String</span>
sender;
    
    <span class="code-keyword">public</span> void setSender(<span class="code-object">String</span>
sender) {
        <span class="code-keyword">this</span>.sender = sender;
    }
    
    @Override
    <span class="code-keyword">public</span> void configure() <span class="code-keyword">throws</span>
Exception {
        from(<span class="code-quote">"ghttp:<span class="code-comment">///weather"</span>)
</span>            .to(<span class="code-quote">"gtask:<span class="code-comment">//<span
class="code-keyword">default</span>"</span>)
</span>            .setHeader(Exchange.CONTENT_TYPE, constant(<span class="code-quote">"text/plain"</span>))
            .transform(constant(<span class="code-quote">"Weather report will be sent
to "</span>).append(header(<span class="code-quote">"mailto"</span>)));
      
        from(<span class="code-quote">"gtask:<span class="code-comment">//<span
class="code-keyword">default</span>"</span>)
</span>            .setHeader(Exchange.HTTP_QUERY, constant(<span class="code-quote">"weather="</span>).append(header(<span
class="code-quote">"city"</span>)))
            .to(<span class="code-quote">"ghttp:<span class="code-comment">//www.google.com/ig/api"</span>)
</span>            .process(<span class="code-keyword">new</span> WeatherProcessor())
       
            .setHeader(GMailBinding.GMAIL_SUBJECT, constant(<span class="code-quote">"Weather
report"</span>))
            .setHeader(GMailBinding.GMAIL_TO, header(<span class="code-quote">"mailto"</span>))
            .to(<span class="code-quote">"gmail:<span class="code-comment">//"</span>
+ sender);
</span>    }

}
</pre>
</div></div>

<p>Form data are received via the <a href="/confluence/display/CAMEL/ghttp" title="ghttp">ghttp</a>
component. After receiving the request it is added to the <tt>default</tt> queue
for background processing. Queueing messages on GAE is done with the <a href="/confluence/display/CAMEL/gtask"
title="gtask">gtask</a> component. After queueing the request a response is generated
for being displayed in the browser. The value of the <tt>mailto</tt> header is
the email address the user entered in the form.</p>

<p>Background processing of the queued messages starts <tt>from("gtask://default")</tt>.
The first step is the construction of the Google weather service URL followed by the weather
service invocation using the <a href="/confluence/display/CAMEL/ghttp" title="ghttp">ghttp</a>
component. For example, if the user entered <tt>London</tt> in the city field
of the form the resulting URL is <tt><a href="http://www.google.com/ig/api?weather=London"
rel="nofollow">http://www.google.com/ig/api?weather=London</a></tt>. The resulting
XML data are processed by the <tt>WeatherProcessor</tt>:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>WeatherProcessor.java</b></div><div
class="codeContent panelContent">
<pre class="code-java">
<span class="code-keyword">package</span> org.apache.camel.example.gae;

<span class="code-keyword">import</span> javax.xml.xpath.XPath;
<span class="code-keyword">import</span> javax.xml.xpath.XPathFactory;

<span class="code-keyword">import</span> org.apache.camel.Exchange;
<span class="code-keyword">import</span> org.apache.camel.Processor;
<span class="code-keyword">import</span> org.w3c.dom.Document;

<span class="code-keyword">public</span> class WeatherProcessor <span class="code-keyword">implements</span>
Processor {

    @Override
    <span class="code-keyword">public</span> void process(Exchange exchange) <span
class="code-keyword">throws</span> Exception {
        <span class="code-comment">// convert XML body to DOM tree
</span>        Document doc = exchange.getIn().getBody(Document.class);

        XPathFactory xpfactory = XPathFactory.newInstance();
        XPath xpath = xpfactory.newXPath();

        <span class="code-comment">// Extract result values via XPath
</span>        <span class="code-object">String</span> city = xpath.evaluate(<span
class="code-quote">"<span class="code-comment">//forecast_information/city/@data"</span>,
doc);
</span>        <span class="code-object">String</span> cond = xpath.evaluate(<span
class="code-quote">"<span class="code-comment">//current_conditions/condition/@data"</span>,
doc);
</span>        <span class="code-object">String</span> temp = xpath.evaluate(<span
class="code-quote">"<span class="code-comment">//current_conditions/temp_c/@data"</span>,
doc);
</span>
        <span class="code-object">String</span> msg = <span class="code-keyword">null</span>;
        <span class="code-keyword">if</span> (city != <span class="code-keyword">null</span>
&amp;&amp; city.length() &gt; 0) {
            msg = <span class="code-keyword">new</span> <span class="code-object">StringBuffer</span>()
                .append(<span class="code-quote">"\n"</span>).append(<span
class="code-quote">"Weather report <span class="code-keyword">for</span>: 
"</span>).append(city)
                .append(<span class="code-quote">"\n"</span>).append(<span
class="code-quote">"Current condition:   "</span>).append(cond)
                .append(<span class="code-quote">"\n"</span>).append(<span
class="code-quote">"Current temperature: "</span>).append(temp).append(<span class="code-quote">"
(Celsius)"</span>).toString();
        } <span class="code-keyword">else</span> {
            <span class="code-comment">// create an error message
</span>            msg = <span class="code-quote">"Error getting weather report
<span class="code-keyword">for</span> "</span> + exchange.getIn().getHeader(<span
class="code-quote">"city"</span>, <span class="code-object">String</span>.class);
        }
        exchange.getIn().setBody(msg);
    }

}
</pre>
</div></div> 

<p>This processor extracts data from the XML result with XPath expressions and creates
a simple text-based report for being sent by email. For sending the email the <a href="/confluence/display/CAMEL/gmail"
title="gmail">gmail</a> component is used. The recipient is derived from the user-defined
<tt>mailto</tt> header value.</p>
     </div>
     <div id="commentsSection" class="wiki-content pageSection">
       <div style="float: right;">
            <a href="http://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
       </div>

       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Tutorial+for+Camel+on+Google+App+Engine">View
Online</a>
       |
       <a href="http://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=5965078&revisedVersion=3&originalVersion=2">View
Change</a>
              |
       <a href="http://cwiki.apache.org/confluence/display/CAMEL/Tutorial+for+Camel+on+Google+App+Engine?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message