X

Converged Enterprise Applications

Guest Author

by Prasad Subramanian

The February 29, 2008 Tech Tip,
Adding Voice to Java EE With SIP Servlets,
introduced Session Initiation Protocol (SIP),
a signaling protocol that is used to set up, modify, and terminate a session between two endpoints. It also introduced various
SIP-related concepts such as a SIP container -- a server-side container of SIP components or services -- and a SIP
servlet -- a servlet that runs in a SIP container and that supports the SIP protocol. The tip mentioned that together, SIP and SIP
servlets, are behind many popular telecommunications-based applications that provide services such as Voice-over-IP (VoIP),
instant messaging, presence and buddy list management, as well as web conferencing. In addition, the tip presented a sample web
application that uses SIP servlets and HTTP servlets to provide VoIP phone service.

SIP and SIP servlets are also important in the enterprise. Combined with Java EE technology, SIP servlets can be used to add
rich media interactions to enterprise applications. For example, a Java EE-conforming enterprise application that supports SIP
could process voice calls or calls in other media. In such an application, an Enterprise JavaBeans (EJB) technology component
could set up a SIP-related call and a SIP servlet could invoke an EJB component or a connector resource.
The SIP Servlet API v1.1 specification (JSR 289) defines the
contract between SIP servlets and a Java EE-conforming enterprise application. JSR 289 makes it easier for application developers
to use the Java EE model for developing applications that process SIP requests and responses.

One of the concepts introduced in the earlier tip is that of a converged application, that is, an application that includes
both SIP and HTTP servlets. In this tip, you'll learn about converged enterprise applications and how the SIP Servlet API v1.1
specification simplifies the development of converged enterprise applications. You'll also find a
sample converged enterprise application that demonstrates the concepts and techniques covered in this tip.

What's a Converged Enterprise Application?

A converged enterprise application is an enterprise application that has a SIP servlet application bundled within it.
An enterprise application is typically packaged in an enterprise archive file whose extension is .ear. The package
may include an application.xml file, which describes the content of the modules within the enterprise application.
Here, the term module refers to the web application and any EJB or connector archive files bundled within the application.
Note that including an application.xml in an enterprise application package is optional. However, even if an
application.xml file is not included, it is possible to bundle a SIP application within the enterprise application.
In this case, the SIP Application is bundled in the same way as other applications such as web applications or the way
EJB modules are bundled in a descriptor-less enterprise application.

A converged enterprise application is also packaged in an enterprise archive file with a .ear extension.
The bundled SIP application is described as a web module in the application.xml file. The following code snippet
is an example of how a bundled SIP application is described in an application.xml file:




   <?xml version="1.0" encoding="UTF-8"?>
<application version="5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd">
<display-name>ConvergedEnterprise</display-name>
<module>
<web>
<web-uri>ConvergedSipApplication.war</web-uri>
<context-root>/ConvergedSipApplication</context-root>
</web>
</module>
<module>
<ejb>TalkBack.jar</ejb>
</module>
</application>




Converged Enterprise Applications and SIP

As mentioned earlier, the SIP Servlet API v1.1 specification makes it easier for application developers to use the Java EE model
for developing applications that process SIP requests and responses. For example, consider an EJB component such as a Message
Driven Bean (MDB). If the MDB receives a message, it could use the APIs defined in SIP Servlet API v1.1 to invoke a SIP request.
Similarly, a SIP servlet that receives an INVITE request could invoke an EJB component from the SIP servlet's
doInvite() method to do some complex processing logic. Or a connector resource could be invoked from within the
SIP Servlet to access an external subsystem such as
a Home Subscriber Server (HSS) for
authentication or a media server to process media.

Let's examine some aspects of SIP Servlet API v1.1 as it relates to SIP servlets and Java EE components.

SIP Servlet-Java EE Component Interface

The SIP Servlet API v1.1 specification defines the interface between Java EE components and SIP servlet applications.
Typically, you invoke a SIP request from a Java EE component such as an EJB MDB or invoke an EJB or
connector resource from a SIP servlet.

You use the javax.servlet.sip.SipFactory interface to invoke a SIP request from a Java EE component.
This interface provides utility methods to create a SIP request in an enterprise application. The methods are summarized
in Table 1. Note that the methods in bold are the ones that are used to create a SIP Request.





Table 1: SipFactory Methods
Method SignatureDescription
createAddress(java.lang.String addr)Returns an Address object corresponding to the specified string.
createAddress(URI uri)Returns an Address object with the specified URI and no display name.
createAddress(URI uri, java.lang.String displayName)Returns a new Address object with the specified URI and display name.
createApplicationSession()Returns a new SipApplicationSession object.
createApplicationSessionByKey(java.lang.String sipApplicationKey) Returns a new SipApplicationSession object identified by the specified SipApplicationKey.
createAuthInfo() Creates a new AuthInfo object that can be used to provide authentication information on servlet
initiated requests.
createParameterable(java.lang.String s) Creates a new Parameterable object parsed from the specified string.
createRequest(SipApplicationSession appSession, java.lang.String method, Address from, Address to)Returns a new request object with the specified request method, From, and To headers.
createRequest(SipApplicationSession appSession, java.lang.String method, java.lang.String from, java.lang.String to)Returns a new request object with the specified request method, From, and To headers.
createRequest(SipApplicationSession appSession, java.lang.String method, URI from, URI to)Returns a new request object with the specified request method, From, and To headers.
createSipURI(java.lang.String user, java.lang.String host)Returns a new SipApplicationSession object identified by the specified SipApplicationKey.
createURI(java.lang.String uri) Returns a URI object corresponding to the specified string, which should represent an escaped SIP, SIPS, or tel URI.

 

A SipFactory instance is specific to a SIP Application and there can only be one SipFactory instance for
each SIP Application. The SipFactory instance is available in the servlet context of that SIP Application as an
attribute of javax.servlet.sip.SipFactory. Recall that the servlet context as defined in the servlet specification
also applies to SIP servlets. The servlet specification defines specific context attributes that are used to store and retrieve
information specific to SIP servlets and interfaces from the context. In the case of Java EE components such as EJBs and MDBs,
which are outside the scope of the servlet context, the SipFactory is available as a resource. You can inject the
resource into a Java EE component such as an EJB or MJB using the @Resource annotation. The syntax of this injection looks
like this:



   @Resource(name="sip/app-name/SipFactory") SipFactory sf-app;




where app-name is the name of the SIP application whose SipFactory is being injected. Note that there could be more than
one SIP application bundled in the enterprise application. So you need to specify which SipFactory instance
to inject into the Java EE component. The app-name is derived based on certain rules. For a description of the rules
see the blog Sailfin in detail: Part 1 app-name.

A key constraint here is that only SipFactory instances that belong to SIP applications which are co-located
in the .ear file can be injected into a Java EE component.

Let's look at an example. The following code snippet injects the SipFactory instance for the SIP application
whose application.xml file was shown earlier. The SipFactory instance is injected as a resource
into the EJB component in the TalkBack.jar file.




   @Stateless
public class TalkBackBeanBean implements TalkBackBeanLocal {
@Resource(name="sip/ConvergedEnterprise/ConvergedSipApplication/SipFactory")
SipFactory sf;
@Resource(name="sip/ConvergedEnterprise/ConvergedSipApplication/SipSessionsUtil")
SipSessionsUtil ssu;
public String findWho() {
SipApplicationSession sas = ssu.getApplicationSessionByKey("CSA", false);
return (String) sas.getAttribute("newReg");
}




The app-name in the code snippet above is ConvergedEnterprise/ConvergedSipApplication because
there is no explicit app-name defined in the sip.xml deployment descriptor. This follows Case I in the
app-name derivation rules.

Accessing a Java EE component from a SIP Servlet

There are two ways to access a Java EE component from a SIP Servlet. The first way is to use annotations.
Java EE annotations are supported within a SIP Servlet. For instance, you could use an @EJB
annotation to inject an EJB into a SIP Servlet or use a @Resource annotation to inject a connector resource.

The following SIP servlet example demonstrates this approach. Here an @EJB annotation is used to access a bean
defined in the TalkBack.jar file. The syntax of the @EJB annotation in the SIP servlet is the same
as for HTTP servlets. In this simple example, the SIP servlet invokes the TalkBackBean method in the EJB and
returns either a success message or an error message based on the return value from the EJB.




   public class InviteServlet extends SipServlet {
@EJB(name="TalkBackBean") private TalkBackBeanLocal tbBean;
//Reference to context - The ctx Map is used as a central storage for this app
javax.servlet.ServletContext ctx = null;
/\*
\* Processes the INVITE request
\*/
@Override
protected void doInvite(SipServletRequest req)
throws ServletException, IOException {
System.out.println("In the INVITE servlet");
SipServletResponse resp = null;
String responseMessage = tbBean.findWho();
// if the bean returns a non null value, then its a success.
if(responseMessage != null) {
resp = req.createResponse(200, "SUCCESS");
} else {
resp = req.createResponse(500, "Error");
}
resp.send();
}




The second way to access a Java EE component from a SIP servlet is to specify the to-be-injected EJB
in the <ejb-ref> element of a sip.xml or sun-sip.xml file.
The sun-sip.xml file is a Sailfin-specific deployment descriptor file, which is functionally equivalent
to the sun-web.xml file for web applications. Recall that Sailfin is the SIP servlet container
implementation in GlassFish being developed in the
SailFin project.
You can also specify a connector resource to be injected in the <resource-ref> element
of these files. This is made possible through the support provided in the sip.xml and
sun-sip.xml files for elements such as <ejb-ref>, <resource-ref>, and
<resource-env-ref>.

The following example demonstrates the second approach. Here an EJB is specified in an <ejb-ref> element
in a sip.xml file. The EJB can then be looked up using the ejb-ref-name in the JNDI context.



   <ejb-local-ref>
<ejb-ref-name>TalkBackBean</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>sample.talkback.TalkBackBeanLocal</local>
<ejb-link>TalkBack.jar#TalkBackBeanBean<




Java EE Annotations in SIP Servlet Classes

The @EJB and @Resource annotations are not the only Java EE annotations that can be
specified in SIP servlet API v1.1 classes. Any of the following Java EE annotations:

  • @RunAs
  • @DeclaresRole
  • @Resource
  • @Resources
  • @EJB
  • @WebServiceRef
  • @PostConstruct
  • @PreDestroy

can be specified in any of the following classes:

  • javax.servlet.sip.Servlet
  • javax.servlet.sip.SipApplicationSessionListener
  • javax.servlet.sip.SipApplicationSessionActivationListener
  • javax.servlet.sip.SipSessionAttributeListener
  • javax.servlet.sip.SipSessionListener
  • javax.servlet.sip.SipSessionActivationListener
  • javax.servlet.sip.SipErrorListener
  • javax.servlet.sip.TimerListener


The Sample Converged Enterprise Application

Accompanying this tip is a zip file that contains NetBeans projects for three
applications:

  • ConvergedEnterprise - A converged enterprise application.
  • ConvergedSipApplication - A SIP application.
  • TalkBack - An EJB module.

The SIP application, ConvergedSipApplication, is bundled in the converged enterprise application,
ConvergedEnterprise. Download the zip file and extract its content. Navigate to the
SampleApp/ConvergedEnterprise/src/conf directory.
You'll see the application.xml file for the converged enterprise application. Notice that the bundled SIP
application and the EJB module, TalkBack, are described in the file. A code snippet of the
application.xml is shown here. Also notice the .ear file
for the converged enterprise application in the SampleApp/ConvergedEnterprise/dist directory.

Navigate to the
SampleApp/TalkBack/src/java/sample/talkback directory, you'll see an EJB component, TalkBackBeanBean.
Notice how the SipFactory instance for the SIP application, ConvergedSipApplication, is injected as a resource.
A code snippet of the EJB component is shown here.

Navigate to the
SampleApp/ConvergedSipApplication/src/java/sample/servlet directory. You'll see a servlet, InviteServlet.
Notice how the servlet uses an @EJB annotation to inject the EJB component named TalkBackBean.
A code snippet of the servlet is shown here.

Running the Sample Converged Enterprise Application

To run the sample converged enterprise application, do the following:

  1. If you do not have Sailfin 1.0 installed,
    download and install it.
  2. If you do not have NetBeans IDE 6.1 (or later) installed,
    download and install it.
    The instructions presented here are for NetBeans IDE 6.5.
  3. Install the NetBeans SIP development and test plugins as follows:
    • In the NetBeans IDE, select the Tools menu, then Plugins. This opens the Plugins dialog box.
    • Select the Downloaded tab. Then click the Add Plugins button. This opens the Add Plugins dialog box.
    • Navigate to the sailfin-install-dir/lib/tools/netbeans directory, wheresailfin-install-dir is the directory where you installed Sailfin 1.0.
    • Select all the files with .nbm extensions and click the Open button.

  4. Ensure that Sailfin is registered in the NetBeans IDE, as follows:
    • Click the Services tab in the NetBeans IDE.
    • Expand the Servers node. You should see Sailfin V1 in the list of servers. If not, register Sailfin V1 as follows:
      • Right-click the Servers node and select Add Server. This opens an Add Server Instance wizard.
      • Select Sailfin V1 in the server list of the wizard and click the Next button.
      • Enter the location information for the server and click the Next button.
      • Enter the admin name and password and click the Finish button.

  5. If you haven't already done so, download the zip file for the sample
    and extract its contents.
  6. Open the converged enterprise application as follows:
    • Click Open Project in the File menu of the NetBeans IDE. This opens the Open Project dialog box.
    • Navigate to the directory that contains the extracted contents for the sample and selectConvergedEnterprise. Select the Open Required Projects checkbox. This should open all the three projects
      for the converged enterprise application: ConvergedEnterprise, ConvergedSipApplication,
      and TalkBack.
    • Click the Open Project button.

  7. Resolve references in the applications as follows.
    • Right click the ConvergedEnterprise project in the Projects window and select Properties.
      This open the Project Properties dialog box.
    • Select the Libraries node in the Categories window. Then select the Add JAR/Folder button.
      This open the Add JAR/Folder window.
    • Navigate to the sailfin-install-dir/lib directory and select the ssa-api.jar
      file.
    • Click the Open button in the Add JAR/Folder window and the O.K. button in the Project Properties window.
    • Perform the same actions for the ConvergedSipApplication and TalkBack projects.

  8. Build and deploy the application as follows:
    • Right-click the ConvergedEnterprise project and select Clean and Build.
    • Right-click the ConvergedEnterprise project and select Deploy. This should start Sailfin and
      deploy the converged enterprise application in Sailfin. You should also see a SIP Test Agent window open in the NetBeans IDE
      as shown in Figure 1. This window is a SIP emulator that can be used to send SIP requests and
      receive responses.

      SIP Test Agent Window
      Figure 1. SIP Test Agent Window
       

  9. Click the New Request button under the Message Creation window. In response, you should see various dialog
    boxes open for a SIP request as shown in Figure 2.

    SIP Request Dialog Boxes
    Figure 2. SIP Request Dialog Boxes
     

  10. Select INVITE in the Method drop-down in the Request dialog box. Then click the Send button below the Message Preview
    window. In response, you should see a response message that includes 200 OK as shown in
    Figure 3. This indicates that the application successfully invoked an EJB from within a SIP servlet.

    SIP Response Message
    Figure 3. SIP Response Message
     


For more information on adding the SIP development and test plugins to NetBeans and adding Sailfin as a server to
NetBeans, see the Hands On Lab,
Adding Convergence
of media to your Java EE Application using NetBeans IDE and Sailfin
. The Hands On Lab also has details on how to use
the SIP Test Agent.

Summary


The SIP Servlet API 1.1 specification formalizes the interfaces and interactions between the SIP servlets and Java EE
applications. It enables users to create converged enterprise applications that can handle voice and data traffic using
SIP servlets.

About the Author

Prasad Subramanian is a staff engineer at Sun Microsystems and is the engineering lead for
Project Sailfin.



2009 JavaOne Conference, June 2-5, San Francisco \*\* Register Now\*\*

Stay on top of everything new and different, both inside and around Java technology. Register by April 22, 2009,
and save $200 off a Conference Pass or Conference Plus Pass. Register now at
http://java.sun.com/javaone.

Join the discussion

Comments ( 3 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha