Friday, January 29, 2010

How to SIP a Coherence soup - Part(I)

A few times a requirement has passed our way to find if Oracle Coherence can be integrated with hand-held devices. Either to get a notification of an Entry or as a task submission unit. The short answer is No and the long answer is Yes. No - because Coherence requires at least a J2SE to be used natively. J2ME platform is not supported. Yes - because there is an architectural pattern called edging. Edging is a pattern of platform integration when a system does not support the protocol of another and we have to create an intermediary system that integrates these two protocols by understanding both. This intermediary system is "edged" or proxied in between. So lets cook this recipe.

Problem Statement: Integrating a cellphone with Coherence.

Ingredients
:

  1. A clean servlet container
  2. Coherence jar
  3. A SIP emulator and,
  4. An IDE as per your taste
For a spicy recipe we have used an Oracle WebLogic Application Server, JDeveloper and Sun's now called Oracle's Java ME Platform SDK.

How to Cook:
  • Download Weblogic Application Server from OTN and install it.
  • Install Java ME Platform SDK from http://java.sun.com, install it and start Java_Platform_ME_SDK under toolbar/bin.
  • While j2me SDK is warming up start JDeveloper and a simple Coherence cluster.
  • If this is the first time you are cooking keep coherence-cache-config pretty simple with a distributed cache "A". If you like a little hotter you can spice the cache configuration up as needed.
  • By now JDeveloper should be boiling. Create a new J2EE project and put the following servlet:

public class SipRequestInitiator extends HttpServlet {

private NamedCache nCache = CacheFactory.getCache("A");
public SipRequestInitiator() {
}
public void init(ServletConfig sc) throws ServletException {
super.init(sc);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
int num = 10;
try {
num = Integer.parseInt(req.getParameter("num"));
} catch (NumberFormatException nExp) {
System.out.println("Wrong number, defaulting to 10");
}
Filter filter =
new LimitFilter(new LikeFilter(new KeyExtractor("toString"),
"news-%", '*', true), num);
Set news = nCache.keySet(filter);
StringBuilder sB = new StringBuilder();
Iterator iter = news.iterator();
while (iter.hasNext()) {
String k = (String)iter.next();
sB.append((nCache.get(k)).toString());
sB.append("\n");
}
res.setContentType("text/plain");
res.setContentLength(sB.toString().intern().length());
res.getWriter().println(sB.toString());
}
}
  • Deploy the servlet with a web.xml. WebLogic plate should be ready now.
  • Once J2ME is hot enough start a MIDP project and cook it with the following Midlet:

public class CohMIDlet extends MIDlet
implements CommandListener, SipServerConnectionListener {

private Display display;
private Form form;
private Command myMessages;
private Command exitCommand; // The exit command
private TextField number;

public CohMIDlet() {
display = Display.getDisplay(this);
form = new Form("Receive Message");
exitCommand = new Command("Exit", Command.EXIT, 0);
myMessages = new Command("Messages", Command.ITEM, 1);
number = new TextField ("No. Of Messages", "10", 3, TextField.LAYOUT_LEFT);
form.append (number);
form.addCommand(exitCommand);
form.addCommand(myMessages);
form.setCommandListener(this);
}

public void startApp() {
display.setCurrent(form);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
notifyDestroyed();
}

public void commandAction(Command c, Displayable s) {
if (c == myMessages) {
Thread t = new Thread() {
public void run() {
getMessages();
}
};
t.start();
}

if (c == exitCommand) {
destroyApp(true);
}
}

private void getMessages() {
int num = Integer.parseInt(number.getString());
HttpConnection hc = null;
InputStream in = null;
String url = "http://localhost:7001/sipinitiator?&num=" + num;
try {
hc = (HttpConnection) Connector.open(url);
in = hc.openInputStream();

int contentLength = (int) hc.getLength();
byte[] raw = new byte[contentLength];
int length = in.read(raw);

in.close();
hc.close();

// Show the response to the user.
String s = new String(raw, 0, length);
form.append(s);
} catch (IOException ioe) {
form.append(ioe.getMessage());
}
}

public void notifyRequest(SipConnectionNotifier arg0) {
}
}
  • put two entries in cache A with keys as "news-$i", where $i is the article number.
  • Choose a Cellphone type as per your choice. I like the good old style flip-phones. Run the emulator. It will deploy the application. Press the Menu button and select Messages. Do you see the following?

In this part we have prepared the soup and tasted it using a Midlet. In part(II) we will try to find how we can SIP it. Enjoy!

No comments: