You are on page 1of 5

Neil Kolban – 2014-09-07 – Extract from next release of PDF

Sending an email which includes response buttons


Another permutation that is of interest to us is the notion that we might want to send an email to
someone and within the body of that email there are immediate response buttons. Here is a mockup of
what an email may look like when it is received by a user:

The body of the email will contain sufficient description for the reader to understand how to handle and
all they need do is click either "Approve" or "Reject" to indicate the outcome. How then can we model
and implement such a story?
There are likely going to be many ways to achieve this effect and here is one.
From a high level process perspective, our modeled process will have the following design:
A process (shown at the bottom) will send an email to a user. It will then wait for a response. The user
will then see the sent email in their email in box and will either approve or reject. The act of clicking
the Approval or Rejection button will result in the wake up of the BPM process which will now know
the choice made by the user and the process may continue.
Now we need to start breaking this design down into its constituent components.
The first is sending the email. That has been covered in depth elsewhere in this book however there is
now going to be a relationship between what is contained in the email and the wake up of the process.
When an email is received by a user, the body of the email can be encoded as either plain text (simple)
or as HTML. It needs to be noted that the message viewing area of an email client should not be
confused with that of a simple browser. Either the viewing area constrains what can be shown or else
the email client "re-writes" the body to permit only a small subset of the possible HTML that could be
shown in a real browser. This is to prevent obvious security exposures. Imagine that I sent you a
malicious email who's body contained HTML that was undesirable. It could contain inappropriate
images, or JavaScript or any number of ugly items. Commonly, before one looks at the body of an
email, one has very little knowledge of precisely what is contained within it. As such, email clients
typically constrain what may be done.
However, the key to our story is that one specific useful function is allowed … namely, the hypertext
link. An email body can contain explicit links to other web pages. When the email user clicks such a
link, a new browser is opened to that page. Since this requires an explicit act from the email user,
opening a new link is not considered a security exposure. Rather, it is considered a useful and
necessary function. Imagine that you receive an email which says "Have a look at this new offering
from our partner …" … it would be great to embed a link to the corresponding web page that would
take the reader to the desired page with the minimum of fuss.
When a hyper-link is followed, from a technical perspective, that is actually an HTTP GET request
targeting a web server. It is commonly expected that request will return HTML that will be rendered
within the browser. However, using the REST paradigm, an HTTP GET request can also be considered
a Web Services call using the REST pattern.
Putting these pieces together, we can envisage a design that might look as follows:
This takes a little explanation. Let us follow the story from a bottom up perspective.
From within a process, we have a BPM activity that is blocking waiting for an event. In BPM these
events are unfortunately called "UCAs". The BPM process will not wake up until and unless a UCA
event occurs. Within a BPM process, we can trigger the arrival of a UCA event from within another
process or service, but that doesn't help us here. However, we can also trigger a UCA event through a
BPM REST service called "sendMessage". This is a REST service that is exposed from BPM that,
when called with the correct parameters, will cause BPM to fire the corresponding UCA event. If we
start to factor these items out, we see that if BPM receives a "sendMessage" REST request, the
blocking BPM process will wake up. Unfortunately, we can't make that call directly from an email
client as the format of the request isn't similar to that of a HTTP GET caused by a hyper link traversal.
Instead, we introduce a simple Java EE application that listens for an incoming REST request (the
HTTP GET from the button click) and, upon receipt of that request, forwards out a BPM REST
"sendMessage" event to the target BPM server.
Although at first glance, this may seem to add more complexity, the reality is that it additionally solves
a number of other problems such as the security exposures of making BPM available directly to the
Internet.
If we look at all the pieces, the one that we don't yet have is the Java EE application. Fortunately, it is
extremely easy to build such a thing. Java EE provides an implementation of the specification known
as JAX-RS which, via simple annotation, exposes REST Web Service with ease.
Here is an example of a simple handler for an HTTP GET request from an email message body:
package com.kolban.bpm.events;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;

@Path("/approve")
public class ApproveEvent {
@GET
public String approve(@QueryParam("instance") String instance, @QueryParam("outcome") String
outcome) {
System.out.println("Approval called: instance=" + instance + ", outcome=" + outcome);
SendEvent.sendMessage("EBC", "c943b980-e320-4d16-804f-a117199ba402",
"<parameter><key>instance</key><value>" + instance +
"</value></parameter><parameter><key>outcome</key><value>" + outcome + "</value></parameter>");
return "Approval registered: Your outcome was: " + outcome;
}
}

The way to read this code fragment is that when an incoming GET request arrives at the relative URL
of "/approve", extract the query parameters called "instance" and "outcome". So, for example,
a REST request to:
http://<host:port>/approve?instance=123&outcome=approve

will trigger this code fragment. The body of the code calls a method called "sendMessage" which
sends a REST request to BPM to trigger the UCA. The body of THAT method looks as follows:
package com.kolban.bpm.events;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

import com.ibm.ws.util.Base64;

public class SendEvent {

public static void sendMessage(String processApp, String eventName, String message) {


try {
URL url = new URL("http://localhost:9081/rest/bpm/wle/v1/process");
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
String wasUserName = "kolban";
String wasPassword = "password";
String authorization = "Basic " + Base64.encode((new String(wasUserName + ":" +
wasPassword).getBytes()));
httpUrlConnection.addRequestProperty("Authorization", authorization);
httpUrlConnection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
httpUrlConnection.addRequestProperty("X-HTTP-Method-Override", "POST");
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setDoOutput(true);

String payload = "<eventmsg><event processApp='" + processApp + "'>" + eventName +


"</event><parameters>" + message + "</parameters></eventmsg>";
String data = "action=sendMessage&message=" + payload;
OutputStreamWriter wr = new OutputStreamWriter(httpUrlConnection.getOutputStream());
wr.write(data);
wr.flush();

InputStreamReader inReader = new InputStreamReader(httpUrlConnection.getInputStream());


BufferedReader br = new BufferedReader(inReader);
String line = br.readLine();
while (line != null) {
System.out.println("Line is: " + line);
line = br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

The construction of the sending of the email could look as follows:

It is unlikely that you will want to simply have hyper-links in place of buttons. Fortunately, some CSS
styling can take care of that for you. A great resource on the web for building buttons is as follows:
Bulletproof Email Buttons
From there, you can enter your desired button look and feel plus the URL to the WAS REST service
and the HTML that is to be inserted into your email is generated for you.
All that remains is to build a BPD and test it out:

There are many tweaks that can be made to this story, some of the more obvious ones include:
• Generation of process "keys" instead of exposing the process instance Ids which are guessable.
This would prevent a hacker from attempting to approve or reject processes.
• Instance state management in a database such that an attempt to approve or reject a request that
was already approved or rejected would be indicated.
• Form data entry in the email body such that more than a button outcome could be recorded. For
example, a reason for rejection.

You might also like