JSR 289: SIP Servlet 1.1 Provides Significant Benefits for SIP Application Developers It's official SIP Servlet 1.1, finalized in late August, introduces a powerful new application selection model, enables SIP/Java EE convergence, and adds additional enhancements to SIP Servlet 1.0. We outline what these changes will mean to SIP application developers. by Steve Apiki SIP Servlet 1.1 (JSR 289) paves the way for more ambitious, more interconnected SIP applications built from next-generation SIP servlet based applications. The new SIP Servlet specification clarifies the intentions of SIP Servlet 1.0 and codifies the industry practices that have grown up around it. It also takes a big step forward in creating a robust mechanism for composing SIP services from collections of servlet applications, and in allowing SIP servlets to work in concert with other Java EE components. In many ways, SIP Servlet 1.1 represents a maturing of the SIP Servlet spec, and that's great news for application developers. On the day-to-day side, it means easier management of protocol sessions, and the end of some repetitive boilerplate code that now moves into the framework. From a long-term view, it means new ways of structuring SIP applications to make them more modular and better integrated with other services. Getting the most out of these enhancements will take some up-front planning. In this article, we'll describe some of the most important changes between SIP Servlet 1.1 and SIP Servlet 1.0 to get you going. We'll start with the related changes to the way SIP requests are routed and the way applications are composed from servlets, arguably the most significant difference between the two versions. Application Selection and Composition In a SIP Servlet 1.0 container, servlets in a single application (SAR file) are tightly connected to that application deployment unit. It's difficult for servlets to reach across application boundaries to work with one another. SIP requests are handled by the container, which finds the target servlet by considering each application's deployment descriptor in turn. If the deployment descriptor matches the incoming request, the request is passed to the target servlet; if not, the container moves on to the next deployed application. When a servlet handles a request, it may proxy the request back through the container to other downstream servlets. Depending upon vendor platform, the application developer may or may not have fine-grained control over the order in which applications are considered, so there may not be a reliable mechanism for composing services from servlets in different SAR files. Figure 1 shows request routing in a SIP Servlet 1.0 container.
Figure 1. SIP Servlet 1.0 request routing. In SIP Servlet 1.0, requests are routed by the container, which finds the target servlet by consulting each application's deployment descriptor file in sequence. In (a), a request arrives at the container; the container checks the request against the first application's XML file and finds that this application doesn't handle this request type, and the request is delivered to App 2. In (b), App 2 proxies the request back to the container, which continues down the line to check application 3, which accepts the request. In (c), App 3 completes its handling of the request and the request is sent externally. The new JSR-289 application selection model introduces a new entity called an Application Router (AR). The Application Router sits alongside the container and is responsible for routing SIP requests to applications. When the container receives a new request, it calls the Application Router; the AR determines which application should be selected and returns the name of that application to the container. The container passes the request to the selected application (within an application, the request always goes to a designated "main" servlet, which may dispatch the request to the correct servlet internally). The application can proxy the SIP request back out to the container, where it will again be passed to the AR to find the next application in the chain. The AR can tell from the request context passed to it by the container whether a request is new, or whether it has already been handled by one or more applications. When the AR decides that all the intended applications in the chain have seen the request, it reports that there are no additional applications (by returning a null application name). The container then sends the request off to its external target. Figure 2 is an illustration of request routing in JSR 289.
Figure 2. SIP Servlet 1.1 request routing. The Application Router is responsible for determining target applications. In (a), the container receives a request and queries the AR with the request; the AR returns "App 2", the target of the request. In (b), App 2 proxies the request back to the container; the container again queries the AR with the new request, this time receiving "App 3", so the request is sent to App 3. In (c), App 3 sends a request out through the container; the container queries the AR and finds there are no additional applications in this chain, so the request is sent externally. The Application Router acts as an up-front application selector for all SIP requests, whether initial requests from external servers or proxied requests from applications within the container. It's tempting to call the AR a request "dispatcher," but that would be inaccurate. Requests don't pass through the AR on their way to selected applications. This is by design, so that there's no way for the AR to modify requests or to otherwise become entangled with application logic. Part of the power of the new model comes from moving away from static XML configuration files to the Application Router, which will be a Java class that implements a service provider interface. (It should be understood that the specification doesn't define how this service provider interface is to be implemented just that one has to exist.) The AR knows what applications are deployed on the container, and it knows the request and the request context. Internally, the AR can use this information, external data sources, and whatever site-dependent logic it requires to return the chain of applications that logically compose a larger service. The other strength of this model is the placement of the AR outside of the application chain and outside of the container itself. With this architecture, the AR is free to select any application for any request, with no dependency on deployment order. The AR can even specify that a request should go to another container by returning an external route. For the servlet developer, each servlet can receive, send, or proxy SIP requests independently without concern for its position in the application chain. Broadening "Convergence" JSR 289 provides a new, standard mechanism for composing SIP servlets and arbitrary Java EE components (such as EJBs) into a single application (packaged as an EAR file). This is a broadening of the support for converged applications as provided by SIP Servlet 1.0, which supported only the combination of SIP servlets and HTTP servlets into a SAR or WAR file. Application developers can now integrate SIP applications within larger enterprise applications on the Java EE platform without relying on proprietary or custom methods.
In a converged application, other components work with the SIP servlet (for example, using it to generate SIP requests) primarily through the SIP servlet's SipFactory interface. The SIP and HTTP convergence model of SIP Servlet 1.0 relied on the HTTP servlet having access to the shared servlet context to find the SipFactory, but that design doesn't extend to non-servlet components. So JSR 289 instead uses an @Resource annotation to instruct the container to inject a SipFactory resource in other components within the same EAR file. In addition to the SipFactory, other components may need access to the application session. The application session is a logical grouping of related protocol sessions (connections) that stores application-specific state information related to that session. A conferencing application, for example, might link several SIP connections into a single application, or a click-to-call application might have an application session that links a SIP protocol session with an HTTP protocol session. As with SipFactory, an @Resource annotation can be used in SIP Servlet 1.1 applications to inject a SipSessionsUtil object, which can be used to look up an application session. Annotations for Metadata As described above, JSR 289 makes use of annotations and resource injection to wire up SIP servlets with other components in a converged application. The SIP Servlet 1.1 Specification also uses annotations to replace external metadata that would otherwise need to be placed in the deployment descriptor file. By moving metadata "inline," out of the deployment descriptor file, annotations make metadata easier to specify and easier to maintain by keeping it all in a source file. Because JSR 289 relies on annotations and resource injection, which are Java 5 language features, Java 5 is the minimum supported version. JSR 289 defines a number of annotations that may be used to replace elements of the deployment descriptor. Table 1, reproduced from table 18-1 in the JSR 289 specification, shows these annotations. Table 1: Annotations in JSR 289 and the entries they replace in the sip.xml file (reproduced from the JSR 289 specification). Item Icons Deployment Descriptor small-icon or Annotation Element @SipApplication smallicon or largeicon large-icon Display Name display-name @SipApplication displayname Description description @SipApplication description Context parameters context-param, Not applicable. param-name, param-value Listener listener-class @SipListener Servlet name servlet-name @SipServlet name Application name app-name @SipApplication name Servlet class servlet-class @SipServlet Initialization init-param, Not applicable, suggested to use constants. parameters param-name, param-value Startup order load-on-startup @sipservlet loadonstartup Proxy timeouts proxy-timeout @SipApplication proxytimeout Session timeouts session-timeout @SipApplication sessiontimeout Resources resource-* @Resource, @Resources
Security Roles security-role-* @DeclaresRole EJBs ejb-ref-* @EJB Run as run-as * @RunAs Web Services Not applicable @WebServiceRef For example, the @SipServlet annotation can be used with a name parameter to replace the servlet-name element. Using this annotation also eliminates the need for the servlet-class in the descriptor file, since the annotation is created where the class is defined. B2BUA Helper Class A B2BUA (Back-to-Back User Agent) is any SIP application that sits in the middle of a SIP call, relaying and optionally transforming requests from a UA on one side to the UA on the other. All SIP requests, including setup and termination, pass through the B2BUA, giving it full control of the call. B2BUA is a common pattern for SIP applications, including those that provide services such as third-party call control, usage tracking, and billing. In SIP Servlet 1.0, each B2BUA needs to provide its own glue to connect the two or more SIP protocol sessions that make up the call. SIP Servlet 1.1 provides a new B2buaHelper class that makes the implementation of a B2BUA easier and less error-prone. Among its other functions, the B2BUA helper can clone SIP requests from one side of the application to the other, managing SIP To and From headers appropriately and automatically preserving unknown headers so as not to interfere with application-specific data exchanged between the two remote endpoints. B2buaHelper can also automatically maintain links between SIP sessions on both ends of the B2BUA, freeing the application developer from needing to track the relationships between these sessions. Making the Transition Backward compatibility with SIP Servlet 1.0 was an important goal of the JSR 289 expert group. You can expect most existing SIP Servlet 1.0 applications to load and run without modification on SIP Servlet 1.1 containers. However, because the spec was tightened up between the two versions, there may be issues with some 1.0 servlets that are no longer well-behaved according to SIP Servlet 1.1's better-defined rules. There's a short list of compatibility issues in appendix A.1 of the JSR 289 final specification. With SIP Servlet 1.1 in final release, the time is now for application developers to start thinking about how to architect future applications to get the most from the new application composition model, from Java EE convergence, and from the other new features of the 1.1 container. Steve Apiki is senior developer at Appropriate Solutions, Inc., a Peterborough, NH consulting firm that builds server-based software solutions for a wide variety of platforms using an equally wide variety of tools. Steve has been writing about software and technology for over 15 years.