Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

This tutorial will be updated whenever new features are added to the Camel Components for Google App Engine.

...

Goal of this tutorial is to get a non-trivial Camel application running on Google App Engine (GAE). For developing that application the Camel Components for Google App Engine will be are 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 addressexample web application generates a weather report for a city that is entered by the user into a form and sends the weather report via email to either the currently logged-in user or a user-defined receiver. The following figure gives an overview. Users of this application need to login with their Google account.

POSTed form data are dispatched to the Camel application via the ghttp component. Then the The application queues the message transforms the report request and enqueues it with the gtask component for further background processing. This includes retrieval of It then generates an immediate HTML response containing information about the city and the receiver of the report. The response also contains a link logging out from the application. In the background, the application retrieves weather data from the Google Weather Service, transforming transforms the data to generate a simple weather report and sending that sends the report by email via the gmail component.

Note
titleJava clients

Clients other than web browsers may also interact with this application by POSTing the form data and an authentication cookie. At the moment the example application doesn't include a standalone Java client that demonstrates how to do that. This is work in progress. In the meantime, refer to the glogin component documentation for instructions how to access security-enabled GAE services.

Tip
titleTutorial online

The next two sections describe how to checkout, build and deploy the example application. If you want to skip these steps, go directly to the #Usage section and use the pre-deployed example application at http://camelcloud.appspot.com.

Prerequisites

  • Sign up for a Google App Engine account if you don't have alreadyone.
  • Create a new application via the admin console or reuse an existing one for uploading the example.
  • Install the Google App Engine SDK for Java. This tutorial has been tested with version 1.23.6.

Deployment

To deploy the example applicationFirst, first checkout the sources with from the Camel code repository.

No Format
svn co http://svn.apache.org/repos/asf/camel/trunk/examples/camel-example-gae  camel 

Navigate to the camel-example-gae

...

and install from here.

Open the camel-example-gae/src/main/webapp/WEB-INF/application-web.xml file in an editor and replace the template application name replaceme with the name of the application that you created in the previous section. Optionally, adjust the version number if needed.

Code Block
xml
xml
titleappengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <!-- use 
        Set your own application name and version here
     -->
    <application>replaceme</application> 
    <version>1</version>
	
    <!-- Configure java.util.logging --><static-files>
        <exclude path="/index.html" />
    </static-files>

    <system-properties>
        <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
    </system-properties>
	
</appengine-web-app>

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

Code Block
xmlxml
titlecontext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
    ...

    <bean id="tutorialRouteBuilder"
        class="org.apache.camel.example.gae.TutorialRouteBuilder">
        <!-- use your own GAE admin email address here -->
        <property name="sender" value="replaceme@gmail.com" />
    </bean>
    
</beans>

Then go to the camel-example-gae directory and enter

...

where version 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.

Note
titleLocal development server

Please note that on the local development server, sending emails does not work and queued tasks must be executed manually from the developer console.

Usage

Usage

In the following, the application name camelcloud will be used as an example. If you deployed the example application somewhere else, use your application name instead. Go to http://replacemecamelcloud.appspot.comImage Removed where replaceme must be replaced with the application name you entered in appengine-web.xml. The following form should now appear.

Image Removed

. The application will redirect you to a login page (see also Security for Camel GAE Applications).

Image Added

After login, the application displays the tutorial's main page where you can enter Enter the name of a city and your email address, for example:

Image Removed

Then press Submit. The immediate response is

No Format

Weather report will be sent to you@yourprovider.com

optionally enter an email address where to send the waether report. If you check Send report to me the report will be send to the email address that you used for login.

Image Added

After pressing Submit the response is

Image Added

The home link brings you back to the main page, the logout link is to logout from the application (which brings you back to the login page). In the background, the current weather conditions for the user-defined entered city will be obtained retrieved 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 (within a certain time frame) are served much faster. Check your emails and you should now see a new email with subject Wheather report and content similar to this one:

...

The report is partly internationalized, depending on the language settings of your browser.

Route builder walkthrough

Code walkthrough

The TutorialRouteBuilder implements the message processing routes shown in the #Overview section. Input form data are received via the ghttp component. After receiving the request a RequestProcessor adds the form data and information about the current user to a ReportData POJO. The ReportData object is then serialized and queued for background processing. Queueing messages on GAE is done with the gtask component. After adding the ReportData object to the queue an HTML response is generated with the ResponseProcessor.

Code Block
java
java
titleTutorialRouteBuilder.java
package org.apache.camel.example.gae;

import org.w3c.dom.Document;

import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.gae.mail.GMailBinding;
import org.apache.camel.processor.aggregate.AggregationStrategy;

public class TutorialRouteBuilder extends RouteBuilder {

    private String sender;
    @Override
    public void setSenderconfigure(String sender)) throws Exception {
        this.sender = sender;from("ghttp:///weather")
    }
    
    @Override
    public void configure() throws Exception {
.process(new RequestProcessor())
            from("ghttp:///weather".marshal().serialization()
            .to("gtask://default")
            .setHeaderunmarshal(Exchange.CONTENT_TYPE, constant("text/plain"))).serialization()
            .transform(constant("Weather report will be sent to ").append(header("mailto")process(new ResponseProcessor());
      
        from("gtask://default")
            .unmarshal().serialization()
            .setHeader(Exchange.HTTP_QUERY, constant("weather=").append(header("city"ReportData.city()))
            .toenrich("ghttp://www.google.com/ig/api")
            .process(new WeatherProcessor())        , reportDataAggregator())
            .setHeader(GMailBinding.GMAIL_SUBJECT, constant("Weather report"))
            .setHeader(GMailBinding.GMAIL_TOSENDER, header("mailto"ReportData.requestor())
            .to("gmail://" + sender);
    }

}

Form data are received via the ghttp component. After receiving the request it is added to the default queue for background processing. Queueing messages on GAE is done with the gtask component. After queueing the request a response is generated for being displayed in the browser. The value of the mailto header is the email address the user entered in the form.

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

Code Block
javajava
titleWeatherProcessor.java

package org.apache.camel.example.gae;

import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.w3c.dom.Document;

public class WeatherProcessor implements Processor {

    @Override
    public void process(Exchange exchange) throws Exception {setHeader(GMailBinding.GMAIL_TO, ReportData.recipient())
        // convert XML body to DOM tree
        Document doc = exchange.getIn().getBody(Document.class);

        XPathFactory xpfactory = XPathFactory.newInstance();
.process(new ReportGenerator())        XPath xpath = xpfactory.newXPath();

        // Extract result values via XPath
        String city = xpath.evaluate.to("gmail://forecast_information/city/@data", docdefault");
        String cond = xpath.evaluate("//current_conditions/condition/@data", doc);}

    private static   String temp = xpath.evaluate("//current_conditions/temp_c/@data", doc);

        String msg = null;AggregationStrategy reportDataAggregator() {
        ifreturn (city != null && city.length() > 0new AggregationStrategy() {
            msgpublic =Exchange new StringBuffer()
                .append("\n").append("Weather report for:  ").append(city)
aggregate(Exchange reportExchange, Exchange weatherExchange) {
                ReportData reportData = reportExchange.appendgetIn("\n").append("Current condition:   ").append(cond)getBody(ReportData.class);
                reportData.append("\n").append("Current temperature: ").append(temp).append(" (Celsius)").toString(setWeather(weatherExchange.getIn().getBody(Document.class));
        } else {
            // create an error messagereturn reportExchange;
            msg}
 = "Error getting weather report for " + exchange.getIn().getHeader("city", String.class) };
        }
        exchange.getIn().setBody(msg);
    }

}

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 gmail component is used. The recipient is derived from the user-defined mailto header valueBackground processing of the queued messages starts from("gtask://default"). The first step is to enrich the previously generated ReportData object with data from the Google weather service. The service URL is dynamically constructed by setting the Exchange.HTTP_QUERY header to weather=<city>. For example, if the user entered London in the city field of the form the resulting URL is ghttp://www.google.com/ig/api?weather=London. The weather service is accessed with the ghttp component and the weather service response is aggregated into the ReportData object using a custom aggregator returned by the reportDataAggregator() method. Generating a simple weather report from ReportData is done by the ReportGenerator. The report is then sent by email with the gmail component.