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.