Thursday, November 20, 2008

JBoss Seam enhances Sip Servlets

Seam-managed SIP components. How about that? Seam components can now handle real SipServletRequests while taking advantage of the Seam perks - bijection, scoping, transaction management, interceptors and everything else.

Your SIP and HTTP Servlets are running in the same servlet context and they share the same application-scoped components, while the session-scoped components are mapped to the respective SIP and HTTP sessions*. You can work with both EJBs and POJOs, interact with your web-layer, and still build very loosely coupled telco components working on the same messages without being aware of each-other. Seam provides synchronous and asynchronous light-weight message passing through the @Observer-annotated methods, which covers most of the communication needs in converged applications.

How it works?

The Seam 2 core is now mostly independent of HTTP Servlets and JSF. Basically we hooked a controller Sip Servlet and session listeners to the Seam lifecycle to control the context assignment for incoming SIP messages. When a SIP message arrives, we raise Seam events to notify the Seam components subscribed to receive the SIP events. We had to use a small Java reflection hack to reach some protected Seam contexts, but I believe it is safe. We will try to make it more clean.

The setup is straightforward - just add the controller servlet to your Seam application in a Sip Servlets container and it's ready to go. For now you can start with the sample application.

Theoretically this technique can work on any JSR289-compliant container that supports JBoss Seam, but I have only tested it on Mobicents Sip Servlets 0.6/0.7 with JBoss Application Server 4.2.3 and Seam 2.1.0.SP1.

One example

This is simple SIP service which responds to an INVITE and counts the number of messages per session. There is a session-scoped counter, which is incremented on every message. Note how you can subscribe methods to SIP events. You can subscribe as many methods as you like in any Seam component, they all will be notified.

@Name("simpleSeamSipService")
@Scope(ScopeType.STATELESS)
@Transactional
public class SimpleSeamSipService {
@Logger Log log;
@In SessionMessageCounter sessionMessageCounter;

public void incrementMessageCounter() {
sessionMessageCounter.increment();
log.info("Processed SIP messages "
+ sessionMessageCounter.getMessages());
}

@Observer("INVITE")
public void doInvite(SipServletRequest request)
throws Exception {
incrementMessageCounter();
request.createResponse(180).send();
Thread.sleep(100);
request.createResponse(200).send();
}

@Observer("ACK")
public void doAck(SipServletRequest request)
throws Exception {
incrementMessageCounter();
}

@Observer({"REGISTER","BYE"})
public void sayOK(SipServletRequest request)
throws Exception {
incrementMessageCounter();
request.createResponse(200).send();
}

@Observer({"RESPONSE"})
public void sayOK(SipServletResponse response)
throws Exception {
incrementMessageCounter();
}
}
You should keep in mind that the Seam events are application-wide. If you need cross-application messaging use JMS (which accidentally is also effortless with Seam).

And here is the SIP-session scoped component:

@Name("sessionMessageCounter")
@Startup
@Scope(ScopeType.SESSION)
public class SessionMessageCounter {
private int messages;

public int getMessages() {
return messages;
}

public void increment() {
messages++;
}
}
Actually, this component is created and stored in every Seam session, no matter if it's SIP or HTTP. This is a bit inefficient, but has some advantages. Ultimately we would want to have a separate SipSession and SipApplicationSession scopes in Seam and we will probably get there with the user-defined scopes in Web Beans (JSR 299) or a newer version of Seam.

Why use it?
  • All the Seam goodness.
  • Development will be easier, because you can take advantage of the Seam WEB-INF/dev classloader to deploy Seam components faster. Otherwise you have to redeploy the whole war/ear (10-20 secs vs 1-2 secs). This feature is not perfect yet.
  • Testing - Seam provides a great framework for testing based on dependency injection and mocking.
  • Programming model is practically the same as the one you use for Web apps with Seam and similar to the future Web Beans.
  • Potential to integrate with jBPM and JBoss Rules through Seam. (contributors?)

Why not to use it?
  • It is not standards-based.
  • Performance is suffering a bit with Seam.
You can find the sample application in SVN:
http://mobicents.googlecode.com/svn/trunk/servers/sip-servlets/sip-servlets-seam

We will soon provide a kit for integrating this capability in your applications. Until then, use the sample application.



*(We currently have no use for conversation scope in SIP.)

1 comment:

shehanaaz said...

Buy termination routes from international VoIP carriers, or sell your A-to-Z VoIP/TDM routes to a large audience.
------------
shehanaaz
MINUTETRADERS | Voice Exchange - Buy/Sell Wholesale AZ VoIP Termination Routes