Thursday, March 19, 2009

Messaging With GWT (AJAX)

"Writing web apps today is a tedious and error-prone process. Developers can spend 90% of their time working around browser quirks. In addition, building, reusing, and maintaining large JavaScript code bases and AJAX components can be difficult and fragile. Google Web Toolkit (GWT) eases this burden by allowing developers to quickly build and maintain complex yet highly performant JavaScript front-end applications in the Java programming language." --Quoted from "http://code.google.com/webtoolkit/".

Since version 6.x, Netbeans included plug-ins for GWT/AJAX web application development. This makes writing GWT/AJAX applications a pleasant experience. With just a few clicks, the required GWT/AJAX web application skeleton files are automatically created. A complete war file is also generated when the (GWT/AJAX) web application is successfully built. The Netbeans/GWT tutorial to create a GWT web application is fairly simple to follow:

http://www.netbeans.org/kb/60/web/quickstart-webapps-gwt.html

The GWT quick start guide is at the link here:

http://code.google.com/webtoolkit/

This article provides a simple (GWT/AJAX) code example to send/receive text messages from a browser. A JMS TextMessage sent to a specific (JMS) destination can be received by the AJAX script running in the browser. The example can be modified to receive GWT supported serializable objects. The example looks like (Figure 1) after launched. The text entered in the lower text area is sent to a queue ("myqueue") when the Send button is clicked. The text is then (concurrently) received from the same queue and displayed in the upper text area.










(Figure 1)

The example assumes that you know about 2% of GWT and 0.1% of AJAX. The 2% means you know how to create and write a Hello-World GWT application and how "GWT RPC" works. No AJAX knowledge is required. You do need to know Java and JMS.

The code example is created with Netbeans IDE 6.5 with GWT plug-ins. The example is divided into the following components. AJAX and HTML files generated from GWT compiler and Netbeans IDE are not included here.
  • Creating services (interfaces)
  • Implementing services (interfaces)
  • Making the service calls
1. Creating services.

The interface defined in GWTService allows AJAX clients to send/receive messages on the specified destination name.

GWTService.java

package com.em.gwt.client;
import com.google.gwt.user.client.rpc.RemoteService;

//RPC interface for client to send/receive messages from destination name "destName".

public interface GWTService extends RemoteService {

public String receive (String queueName) throws IllegalStateException;

public void send (String queueName, String msg);
}

GWTServiceAsync.java

package com.em.gwt.client;
import com.google.gwt.user.client.rpc.AsyncCallback;

public interface GWTServiceAsync {

public void receive (String queueName, AsyncCallback callback);
public abstract void send(String queueName, String msg, AsyncCallback asyncCallback);
}


2. Implementing services (interfaces).

The service is implemented with Open Message Queue. So you need to include imq.jar, jms.jar in the IDE project library.

GWTServiceImpl.java

/*
* GWTServiceImpl.java
*
* Created on March 17, 2009, 2:02 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/

package com.em.gwt.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.em.gwt.client.GWTService;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.servlet.ServletException;

/**
*
* An example GWT service implementation to receive messages from
* specified JMS destinations.
*/
public class GWTServiceImpl extends RemoteServiceServlet implements
GWTService {

private ConnectionFactory factory = null;
private Connection connection = null;

/**
* This is an example implementation. No connection pooling.
*/
@Override
public void init() throws ServletException {

try {
//get conn facory
factory = new com.sun.messaging.ConnectionFactory();

//create jms connection
connection = factory.createConnection();
//start the connection
connection.start();

log ("Connection started.");
} catch (Exception e) {
log (e.getMessage(), e);
throw new ServletException (e);
}

}

/**
* Receive a message from the specified queue destination name.
*
* The performance can be improved if the session/consumer
* are cached.
*
* @param qname the queue name.
* @return The body of the text message.
*
* @throws java.lang.IllegalStateException if any internal error occurred.
*/
public String receive (String qname) throws IllegalStateException {

String msg = null;
Session session = null;

try {
//create a session
session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//get the queue reference
Queue queue = session.createQueue(qname);
//create a consumer
MessageConsumer consumer = session.createConsumer(queue);

//receive with 10 seconds timeout
Message m = consumer.receive(10000);

//get the body of the message
if (m != null && m instanceof TextMessage) {
msg = ((TextMessage)m).getText();
}

} catch (Exception e) {
msg = e.getMessage();
throw new IllegalStateException (e);
} finally {
close(session);
}

return msg;
}

public void send (String qname, String msg) {

Session session = null;

try {
//create a session
session = this.connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//get the queue reference
Queue queue = session.createQueue(qname);
//create a consumer
MessageProducer producer = session.createProducer(queue);

TextMessage tm = session.createTextMessage();
tm.setText(msg);

producer.send(tm);

} catch (Exception e) {
throw new IllegalStateException (e);
} finally {
close(session);
}

return;
}

/**
* close the specified session.
* @param s the session to be closed.
*/
private void close (Session s) {
try {
s.close();
} catch (Exception e) {
log (e.getMessage(), e);
//throw new IllegalStateException (e);
}
}

/**
* close connection when servlet is destroyed.
*/
@Override
public void destroy() {

try {
this.connection.close();
} catch (Exception e) {
log (e.getMessage(), e);
}
}
}


3. Making service calls.

The entry point of the GWT client application. Each message received is updated in the TextArea.

maasEntryPoint.java

package com.em.gwt.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.Date;

public class maasEntryPoint implements EntryPoint {

private VerticalPanel vp = new VerticalPanel();

private TextArea recvTextArea = new TextArea();

private TextArea sendTextArea = new TextArea();

private Button btnSend = new Button("Send");

private Label recvLabel = new Label ("message received:");

private Label sendLabel = new Label ("message sent:");

private AsyncCallbackRecvImpl recvCallBack = new AsyncCallbackRecvImpl();
private AsyncCallbackSendImpl sendCallBack = new AsyncCallbackSendImpl();

private GWTServiceAsync service = null;

private static final String MYQUEUE = "myqueue";

/** Creates a new instance of maasEntryPoint */
public maasEntryPoint() {
}

/**
* The entry point method, called automatically by loading a module
* that declares an implementing class as an entry-point
*/
public void onModuleLoad() {

vp.add(recvLabel);

recvTextArea.setCharacterWidth(70);

vp.add(recvTextArea);

vp.add(sendTextArea);

btnSend.addClickListener(new SendBtnListener());

vp.add(btnSend);

vp.add(sendLabel);

RootPanel.get().add (vp);

service = getService();

receive();
}

private void receive() {
service.receive(MYQUEUE, recvCallBack);
}

public static GWTServiceAsync getService(){
// Create the client proxy. Note that although you are creating the
// service interface proper, you cast the result to the asynchronous
// version of
// the interface. The cast is always safe because the generated proxy
// implements the asynchronous interface automatically.
GWTServiceAsync service = (GWTServiceAsync) GWT.create(GWTService.class);
// Specify the URL at which our service implementation is running.
// Note that the target URL must reside on the same domain and port from
// which the host page was served.
//
ServiceDefTarget endpoint = (ServiceDefTarget) service;
String moduleRelativeURL = GWT.getModuleBaseURL() + "gwtservice";
endpoint.setServiceEntryPoint(moduleRelativeURL);
return service;
}

class AsyncCallbackRecvImpl implements AsyncCallback {

public void onFailure(Throwable caught) {
recvTextArea.setText("receive failed: " + caught.getMessage());

caught.printStackTrace();
}

public void onSuccess(Object result) {

if (result != null) {
recvTextArea.setText("Received msg = " + (String)result);
}

receive();
}

}

class AsyncCallbackSendImpl implements AsyncCallback {

public void onFailure(Throwable caught) {

sendLabel.setText(new Date() + ": send failed.");

caught.printStackTrace();
}

public void onSuccess(Object result) {

sendLabel.setText(new Date() + ", sent message = " + sendTextArea.getText());

}

}

class SendBtnListener implements ClickListener {

public void onClick(Widget sender) {
String msg = sendTextArea.getText();
if (msg == null || msg.isEmpty()) {
Window.alert("No message entered in send text area.");
} else {
service.send(MYQUEUE, msg, sendCallBack);
}
}

}

}

Wednesday, March 11, 2009

Messaging, a brief review

There are various semantics when the term messaging is used. Such as e-mail, which is primarily used for communication between people, is also referred to as messaging.

The term messaging discussed in this blog space is scoped as follows.

The scope.


Messaging is a communication model. It is usually made possible by a messaging system. A messaging system is commonly referred to as a message oriented middleware (MOM).

A messaging system provides API, messaging agents, and routing services to facilitate software components to create, send, receive, and read messages.

A major characteristic of messaging is to communicate asynchronously. This is in contrast to RPC or RMI style communications.

Software components that communicate with messaging style are usually distributed and loosely coupled. The communication parties (producers and consumers) are not required to be active (running) simultaneously. They are not required to know each other's existence or implementation. And they are not required to use the same communication protocol to send and receive messages.

Messaging can be categorized into two domains. Point-To-Point messaging domain and Publish-and-Subscribe messaging domain.

A destination within the Publish-and-Subscribe messaging domain is called a topic. A destination within the Point-To-Point domain is called a queue.

A topic is a destination from which all the attached subscribers will receive a copy for each message published to it.

A queue is a destination from which only one consumer will receive each message sent to it.

With messaging, software components communicate with each other through a destination. The communication parties only require to know the destination and the format of the message to communicate effectively.


Java Message Service (JMS)

In 1998, Sun and a majority of messaging vendors defined a set of Java API and message routing behavior for the above messaging scope. The JMS messaging service is commonly used by the corporate IT systems.

The JMS messaging service is also commonly used as the back-bone routing service for the Service-Oriented Architecture (SOA) implementation.

Almost all major messaging providers today support and implement the JMS specification.

For JMS, the communication protocols between messaging clients and a messaging provider are vendor dependent. JMS does not define protocols between JMS clients and a messaging provider. The JMS communication protocols are transparent to the applications but are not compatible among messaging providers.


The transition


As the programming environment has moved to the Internet, the messaging model is also evolving. The boundaries between enterprise messaging and the web are often required to be crossed.

Since 1999, there are specifications been developed to address and attempt to resolve messaging issues across the web and corporate boundaries. Such as ebxml messaging service (ebMS), WS-Reliability, and WS-ReliableMessaging . Each of the specification was based on SOAP and defined sophisticated rules for the messaging behavior, reliability, and security requirements.

But the level of complexity and compatibility issues were among the challenges for the mass adoption for these specifications and implementations.

With Software as a Service (SaaS) becomes a reality, the concept of Messaging as a Service (MaaS) is also a part of the transition.

The JMS messaging service are naturally adopted and served as the back-bone routing service for the implementation of a MaaS due to its solid foundation and widely availability.

As of today, the RESTful architectural style has become a popular design choice for the new generation of web services. It is thus a natural transition to present MaaS in a RESTful way. This makes it much simpler to participate in messaging for a web capable software component.

In the mean time, the cloud computing is also gaining its momentum. The combination of MaaS and cloud seems to be a good fit. The messaging in the cloud development is on-going. The pay-per-use messaging concept is becoming an alternative option to corporate IT and start-ups.

Wednesday, March 4, 2009

Stateless

The term "stateless" has been discussed a lot lately. It is about the stateless constraint imposed on the REST architectural style. In the famous dissertation of Fielding, section 5 (Representation Style Transfer), the stateless constraint stated as follows.

"communication must be stateless in nature, as in the client-stateless-server (CSS) style of Section 3.4.3 (Figure 5-3), such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client."
(http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm)

And the benefits of statelessness "induces the properties of visibility, reliability, and scalability".

The benefits are not difficult to understand. But some consequences are also derived from the nature of statelessness.

One of the consequences of the stateless behavior is the "transient" server resource availability, such as a transaction. How can this stateless design be implemented such that it can fulfill the "web scalable" requirement? As some said, "just add another server and the system is automatically scaled".

For example, if a RESTful application client is in the middle of a transaction on server (A). But the next request was "load balanced" by a less-intelligent load-balancer to a different server (B). To achieve the claimed (stateless) benefit, the transaction processing must proceed as if the request were on the original server (A).

The previous article "Meet The Web, Part 2 (with transaction)" is a typical RESTful transaction scenario to face this challenge.

There are solutions to address the stateless implementation issues.

For example, the following are some possible solutions to handle the stateless nature for a "transient" resource (such as a transaction).
  1. Client includes accumulative information (including previous requests related to the transaction) in the request message.
  2. Mirror a resource state (such as a transaction) in all servers.
  3. Introduce a new (shared) service layer to handle the resource. Such as a transaction service, on a separate machine, to handle transactions. When a transactional request is received, the request is forwarded to the transaction service layer.
  4. Use an intelligent load-balancer.
There are other solutions not mentioned. So the issue is not due to "lack of solution" to implement a stateless behavior. The challenge is that, if attempts to change the existing system to fulfill the constraint, it takes efforts to redesign and rearrange the "guts" in the current design and implementation. And it also takes time to get adjusted to the new design style.

To provide a stateless solution for the case in "Meet The Web, Part 2 (with transaction)", the solution #4 above would probably be a logical choice. All transactional service requests are delegated to the shared transaction service layer. This would meet the stateless constraint challenge for the transient server resource availability. But changes would be required to rearrange the server/service implementation and move some portion of implementation to a separate location (transaction service layer).

When software development model moved from component (such as beans) to service (such as web services), the thinking and design patterns are also evolving. The concept of "software as a service" (SaaS) seems to fit into the RESTful architectural style nicely. And statelessness may likely become a popular "design pattern" for the coming generation of web services.

There are disadvantages about the stateless design as Fielding pointed out below. Especially the performance impact may not be easy to address. But that's the fun part for the fine engineers to resolve.

"Like most architectural choices, the stateless constraint reflects a design trade-off. The disadvantage is that it may decrease network performance by increasing the repetitive data (per-interaction overhead) sent in a series of requests, since that data cannot be left on the server in a shared context. In addition, placing the application state on the client-side reduces the server's control over consistent application behavior, since the application becomes dependent on the correct implementation of semantics across multiple client versions."

Monday, March 2, 2009

XML

Its an old topic. But watch out, it is just the beginning ...

1. The Got Milk Commercial


Imagine a Got Milk Commercial as follows.

"A grandma walking slowly in a super market with a shopping cart. Suddenly her cell phone rings. She pulls up the cell phone out of her pocket and flips the phone. The camera rooms in on the cell phone screen. It shows the message 'Got Milk?' with signature from the refrigerator."

It is a got milk commercial. But it also shows that we have entered the era of mass messaging. Every device with a network pulse can and wanted to communicate with each other effectively. The grandma's cell phone detected itself is in the super market, so it sends a message (through some messaging service) back home to the refrigerator. A few seconds later, the refrigerator sends back a message with the "Got Milk?" message.

What does the above has anything to do with XML? And why does the weird looking data format so attractive to almost every industry to store, present, and exchange information with it?

In short, it is due to the claimed (and accepted) advantage -- simple, open, extensible, and interoperable.

The message format in exchange for the Got Milk Commercial above is likely to be in the XML format.

So it would be politically incorrect to not stress the importance of considering XML as the packaging mechanism in the web messaging environment. Such as when exchanging messages in "Messaging in the Cloud" environment, the message itself would be more "open" if each message is packaged in the XML format.

"XML provides a basic syntax that can be used to share information between different kinds of computers, different applications, and different organizations without needing to pass through many layers of conversion."
-- wikipedia (http://en.wikipedia.org/wiki/XML).

XML has been widely used for the web. Such as HTML pages, RSS , and the Atom Syndication Format, etc.

For messaging in web environment, restful or not, XML should be evaluated and considered as the message packaging format until a better mechanism is developed.


2. Security Revisited.

In the previous article Security Made Easy, we showed some Java API to sign and encrypt a piece of data. We did not address how the pieces of information should be packaged. By now, you probably have thought about how the information can be packaged.

A high level rule is to have all the security information (message meta data), such as algorithms, parameters, secret key, signature value, encoding rule (for signature and encrypted data), etc. set as the child elements of the "header" element of the message.

And the encrypted (and encoded) data be set as a child element of the message "body" element of the message.

The "piece of data" to be signed and encrypted can (should) be isolated into a byte[] to avoid any XML canonicalization issues.

Specifications for XML signature and encryption are developed for quite sometime. But in practice, you may choose to define some simple elements as mentioned above to avoid issues (such as canonicalization) described at the links below.

http://en.wikipedia.org/wiki/XML_Signature
http://www.cs.auckland.ac.nz/~pgut001/pubs/xmlsec.txt


3. Base64 Encoding.

The XML signature or encryption output is often produced as a byte[]. The byte[] requires to be encoded before it is set as the value of an XML element. Base64 encoding/decoding is often used to "translate" a byte[] into a String and vice versa.

Java does not provide a public/supported implementation. The following are links to source code from JXTA.

Base64Encoding for Java:
https://jxta-jxse.dev.java.net/source/browse/jxta-jxse/trunk/impl/src/net/jxta/impl/util/BASE64OutputStream.java
https://jxta-jxse.dev.java.net/source/browse/jxta-jxse/trunk/impl/src/net/jxta/impl/util/BASE64InputStream.java


4. Summary.

XML provides the mechanism to package a message into a self-contained message. When a message is self-contained, the message can travel through "the cloud" without losing any required information to process the content of the message.

A self-contained message can live much longer than one that's not.