Developing Groovy based web application and deploying to Google App Engine

SHARE & COMMENT :

We have seen how to develop a ZK based application and deploy it to OpenShift. Google has also a Paas offering called Google App Engine(GAE) which supports Java, Python and Dart applications. Gaelyk is a simple Groovy based toolkit to develop and deploy application to GAE. In this article lets build a simple Gaelyk based application and deploy it to GAE.

also read:

The sample application developed would show the details of location information from where this application was accessed, information lie Name of the city, country, region, latitude, longitude and timezone would be shown.

Setting up Gaelyk

But before that we need to download and setup Gaelyk. Faster way to start with Gaelyk is to download the Template project and extract its contents. Gaelyk template project uses Gradle build system to manage all the dependencies. To draw an analogy Gradle is similar to Maven. The template project has defined all the require dependencies and also provides a Gradle wrapper gradlew using which you can run gradle tasks without having to install Gradle. Also Gradle manages downloading and configuring the Google App Engine SDK, so you need not worry about that.

$ gradlew tasks

shows the available tasks, it might download the dependencies it doesnt find in its local repository. To run the template project:

$ gradlew gaeRun

The application will be deployed in the embedded jetty container and can be accessed at http://localhost:8080/. Gaelyk builds on top of Groovlets and Groovy templates. Groovy templates and Groovlets reside in the WEB-INF/pages and WEB-INF/groovy folders respectively. Also all the GAE services can be accessed from with in these Groovlets and Groovy Templates using the shortcodes provided by Gaelyk like memcache for accessing the caching service, datastore for accessing the GAE Datastore service and so on.

Location Information from IP Address

For this we make use of the API provided by the IPInfoDb. We are interested in City wise precision and the results in JSON, hence make use of the following API:


http://api.ipinfodb.com/v3/ip-city/?key=<your_api_key>&ip=<ip_address>&format=json

The above api returns result which is something like

{
  "statusCode" : "OK",
  "statusMessage" : "",
  "ipAddress" : "74.125.45.100",
  "countryCode" : "US",
  "countryName" : "UNITED STATES",
  "regionName" : "CALIFORNIA",
  "cityName" : "MOUNTAIN VIEW",
  "zipCode" : "94043",
  "latitude" : "37.3956",
  "longitude" : "-122.076",
  "timeZone" : "-08:00"
}

parsing the above JSON in Groovy we would have something like

 
//Setting up the JSON data.
def myIp = request.remoteAddr
def api_key="<enter the api key for IpInfoDb here>"
def ipUrl = "http://api.ipinfodb.com/v3/ip-city/?key=${api_key}&ip=${myIp}&format=json"
def jsonSlurper = new JsonSlurper()
def locationInformation = jsonSlurper.parseText(new URL(ipUrl).text)

In the above code request represents the HttpServletRequest object and to access the IP address of the client we make use of the getRemoteAddr() method of HttpServletRequest. In groovy one can invoke getPropertyName as just propertyName, hence request.remoteAddr. If you are running this locally then you might want to replace the IP address 127.0.0.1 with your actual IP address. Something like:

 
def myIp = request.remoteAddr
if(myIp.equals("127.0.0.1")){
    myIp = "YOUR IP ADDRESS"
}

The subsequent code makes a GET request to the API URL and parses the obtained JSON response to get the location information.

 
//Parsing the JSON to get the required information
locationInformation = jsonSlurper.parseText(new URL(ipUrl).text)

//We set this as parameters to the request object
request.ipAddress = locationInformation.ipAddress
request.country = locationInformation.countryName
request.region = locationInformation.regionName
request.city = locationInformation.cityName
request.latitude = locationInformation.latitude
request.longitude = locationInformation.longitude
request.timezone = locationInformation.timeZone

Gaelyk provides a flexible URL routing system where in we can map the URL to corresponding Groovlets. These routes are declared in the routes.groovy file which is present in the WEB-INF directory. Lets create a Groovlet for our Index page and call it: index.groovy and this groovlet would be responsible for intercepting the request and obtaining the required data and forwarding to the right groovy template. The template project which you would have downloaded would have a groovy template by name: index.gtpl, and the groovlet which we created would forward the request to index.gtpl. The template project has the “/” route pointing to a different handler, we would update that to point to our groovlet.

 
//Updating the routes.groovy
get "/", forward: "/index.groovy"

As already mentioned the groovlet: index.groovy would be responsible for obtaining the location information from the IP address and setting those values in the request, which are then displayed by the groovy template- index.gtpl

 
//Contents of index.groovy
import groovy.json.JsonSlurper

def myIp = request.remoteAddr
if(myIp.equals("127.0.0.1")){
  myIp = "YOUR IP ADDRESS"
}

def api_key="YOUR IPINFODB API KEY"

def ipUrl = "http://api.ipinfodb.com/v3/ip-city/?key=${api_key}&ip=${myIp}&format=json"
def jsonSlurper = new JsonSlurper()
def locationInformation = null
//Use memcache to cache the location information
if (memcache[myIp] != null){
  locationInformation = memcache[myIp]
}
else{
  locationInformation = jsonSlurper.parseText(new URL(ipUrl).text)
  memcache[myIp] = locationInformation
}
request.ipAddress = locationInformation.ipAddress
request.country = locationInformation.countryName
request.region = locationInformation.regionName
request.city = locationInformation.cityName
request.latitude = locationInformation.latitude
request.longitude = locationInformation.longitude
request.timezone = locationInformation.timeZone

//Forward to the corresponding groovy template
forward '/WEB-INF/pages/index.gtpl'

The interesting piece of information in the above code snippet is:memcache. This binding refers to the Memcache service provided by Google App Engine. We cache the location information against the IP address and any subsequent requests from the same IP would fetch from the cache instead.

The values set as part of the request parameters are then retrieved by the index.gtpl as:

<% include '/WEB-INF/includes/header.gtpl' %>
<div class="row">
  <div class="span12">
    <h2>You are accessing from</h2>
    <ul>
      <li>Your IP Address: ${request.ipAddress}</li>
      <li>Country: ${request.country}</li>
      <li>Region: ${request.region}</li>
      <li>City: ${request.city}</li>
      <li>Latitude: ${request.latitude}</li>
      <li>Longitude: ${request.longitude}</li>
      <li>Timezone: ${request.timezone}</li>
    </ul>
  </div>
</div>
<% include '/WEB-INF/includes/footer.gtpl' %>

the include is used to include other groovy templates. Groovy templates lets you embed groovy code by just like we do in JSP and PHP.

#Run the application
$ ./gradlew gaeRun

The application would be running http://localhost:8080/

One can even create a eclipse/intellij project for this by:

#For Eclipse
gradlew cleanEclipse eclipse

#For IntelliJ 
gradlew cleanIdea idea

and then load the project in your IDE.

Once we are done with the development, we can deploy to Google App Engine by using:

$ ./gradlew gaeUpload

but before that you must create an application in your Google App Engine account and update the appengine-web.xml file in src/main/webapp/WEB-INF directory by adding the appid to the XML.

To try out this sample, you need to create a new index.groovy file in src/main/webapp/WEB-INF/groovy folder. Then create index.gtpl in src/main/webapp/WEB-INF/pages. Also dont forget to update the appengine-web.xml file.

Comments

comments

About Mohamed Sanaulla

In his day job he works on developing enterprise applications using ADF. He is also the moderator of JavaRanch forums and an avid blogger.

Trackbacks

  1. [...] our sample Gaelyk application here we stopped at just obtaining the location information. In this post lets update that application to [...]

  2. [...] have seen here and here on creating simple mashup using Gaelyk. In this series of articles lets see how we can [...]

  3. [...] posts list about 61 geolocation APIs. Javabeat has put up usage of one such API in their post on sample gaelyk application. All this is good, but any support out of the box is always recommended and that’s where [...]

  4. [...] posts list about 61 geolocation APIs. Javabeat has put up usage of one such API in their post on sample gaelyk application. All this is good, but any support out of the box is always recommended and that’s where [...]

Speak Your Mind

*

Close
Please support the site
By clicking any of these buttons you help our site to get better