Listening To XMPP Subscribe Requests

The following sample code demonstrates how to listen for incoming XMPP subscription requests. A subscription request to App Engine occurs when another XMPP client has granted access to its presence information (whether that client is available to chat or not).

This function reads in the incoming XMPP request, extracts the user name of the client and the subscription type, then records the request into logging. In a production application this code could be modified to store subscription requests into the datastore, creating a list of XMPP users interested in talking to the application.

public void doPost(HttpServletRequest req, HttpServletResponse resp)
        throws IOException {
    //Acquire access to GAE's XMPP service.
    XMPPService xmpp = XMPPServiceFactory.getXMPPService();
    //Parse the user's subscription from the HTTP request.
    Subscription subscribe = xmpp.parseSubscription(req);
    JID from_jid = subscribe.getFromJid();
    SubscriptionType subscribe_type = subscribe.getSubscriptionType();
    //Log the subscription type.
    System.out.println(from_jid + " has subscription type " + subscribe_type);
}//end doPost

Remember to import App Engine’s XMPP package:

import com.google.appengine.api.xmpp.*;

App Engine 1.8.6 Rollout

App Engine recently upgraded to version 1.8.6 in production, and the most obvious change is the errors summary screen.

Here’s the Errors screen prior to 1.8.6:

The current 1.8.6 Errors screen breaks down the errors into client and server-caused issues:

The newly added Error Details graph shows when different errors occur. For instance, this graph shows a client error (an incorrect request) about 19 hours ago:

Enabling XMPP Services

The following XML snippet enables an application to receive XMPP messages. Insert it into the middle of the appengine-web.xml file in the /war/WEB-INF/ folder:

<!-- Enable all inbound services. -->
<inbound-services>
    <service>xmpp_message</service>
    <service>xmpp_presence</service>
    <service>xmpp_subscribe</service>
    <service>xmpp_error</service>
</inbound-services>

Task Queue Generating TransientFailureException

Task queue operations may rarely generate a TransientFailureException, which will look similar to this:

com.google.appengine.api.taskqueue.TransientFailureException:
    at com.google.appengine.api.taskqueue.QueueApiHelper.translateError(QueueApiHelper.java:106)
    at com.google.appengine.api.taskqueue.QueueApiHelper.translateError(QueueApiHelper.java:153)

In general this exception indicates a temporary issue with the underlying App Engine infrastructure, not a failure of the application code. This problem should fix itself shortly.

To mitigate this exception, catch it with a try/catch block and attempt to requeue the task. If that fails, insert a delay of a few seconds before attempting to requeue the task. Redeploying the application may also help.

Aliasing Imports In Golang

A quick note: Go allows the aliasing of imports. For instance, the below line of code imports the appengine/datastore package under the name aedatastore :

import aedatastore "appengine/datastore"

Then the application can call datastore services under the alias name:

aedatastore.Get(c, key, &entity)

This aliasing is particularly useful when package names collide. Assume that an application needs to import the Go image and appengine/image packages. Since both packages are named image, the Go compiler will issue an image redeclared as package name error if both are imported. To avoid this, alias one of the imports:

import "image"
import aeimage "appengine/image"

Webmaster Tool Has Not Been Enabled

While configuring a new Google Apps account for a customer, I encountered the error below:

Here’s how to fix this. First, go to the Users tab, then click Services :

Type in Webmaster Tools in the search box directly under the Services tab:

Click the On button next to the Webmaster Tools label:

Remember to save your changes:

Retrieving The User’s IP Address

Retrieving the originating IP address of the request is simple in most languages.

Here’s how to retrieve the IP address in Java ( req represents a javax.servlet.http.HttpServletRequestreference ):

String ip = req.getRemoteAddr();

Here’s the same line in Go ( r represents http.Request ):

ip := r.RemoteAddr

In PHP, the originating IP can be retrieved from the predefined variable SERVER :

$_SERVER['REMOTE_ADDR']

Handling Form Data In Go

Here’s how to retrieve the value of a form element named comment ( r represents http.Request ):

comment := r.FormValue("comment")

Suppose the form value is an integer. Here’s how to extract the value from the request and convert it from a string to an integer (if an error occurs when converting, the value -1 is stored):

index, err := strconv.Atoi(r.FormValue("index"))    
if err != nil {
    index = -1
}

If needed, the submitted form value can be written to logging by calling:

c := appengine.NewContext(r)
c.Infof("Submitted Value: %v", index)

Templating In Go

The Go language contains an extremely powerful templating engine which simplifies the creation of web pages. Here’s a quick overview of how it works.

First of all, create a set of template HTML files. Wherever dynamic content should be added, add a {{.name-of-property}} annotation. Here’s an example:

<div class="row">
    <div class="span12">{{.propertyone}}</div>
    <div class="span8">{{.propertytwo}}</div>
</div>

In the above example, propertyone and propertytwo represent keys which will be replaced by values later on.

Next, make these template files available to the Go application. This line of code pulls in an entire folder of template files (assuming that templates is a root level directory):

var templates, templates_err = template.ParseGlob("templates/*")

Alternately, a set of templates can be called in by name:

var templates = template.Must(template.ParseFiles("templates/one.html", "templates/two.html", "templates/three.html"))

Using template.Must ensures that all the templates files are loaded in – if it is unable to find a named template file, template.Must sets off a panic.

Next, create a map of strings to display on the page. We associate the keys (which were set within the HTML of the template file) with values that will replace the annotations:

//This map holds the data to display on the page.
display_data := make(map[string]string)
display_data["propertyone"] = string_one
display_data["propertytwo"] = string_two
display_data["propertythree"] = string_three

Finally, execute the template. W represents a http.ResponseWriter reference to write the completed template to, one.html represents the name of the template to use, and display_data is the map that defines the values to use when replacing the annotations:

//Put the data into the template and send to the user.
templates.ExecuteTemplate(w, "one.html", display_data)

Remember to import the html/template package before using this code.