Ivelin Ivanov introduces the JAIN SLEE server spec built for high-availability VoIP servers, and its open source implementation, the Mobicents project.
The foundations of a VoIP server
VoIP services depend on high-performance, low-latency servers that can manage the activity of thousands of users logging in, logging out, starting connections with each other, etc. JAIN SLEE is a Java spec for such a system, and java.net's Mobicents project represents its first open source implementation. Ivelin Ivanov introduces JAIN SLEE design and the Mobicents implementation.
VoIP, as many have said, is more than merely voice over IP. Recent years have seen several highly popular applications like Skype , Google Talk , and MSN Messenger . All of them combine voice, instant messaging (IM), and other modes of communication into unified clients and greatly enhance the user experience. Previously, these means to communicate were islands--largely isolated from each other. However, engineers visited them and found large areas of community between these different modes of communication, resulting in integrated clients that have changed the way in which we communicate and conduct business.
What kind of server support needs to be provided for these applications? An examination of the structure of such applications indicates that there are two parts to the application: the signaling part and the media part. The signaling part is an event-oriented activity. Network endpoints exchange one-way messages through various servers and signal the establishment of a session. Interesting services can be built by placing fragments of code, or "event handlers," in the signaling path at the server. Furthermore, service providers may speed up their innovation processes and quickly launch new services if they use a standards-based component model and container architecture. And this is what JAIN SLEE (JSLEE) is all about: it is an event-oriented application middleware standard and Mobicents is an implementation of it.
That's the higher level--now the details.
The primary goal of Mobicents is to produce a quality open source implementation of the JSLEE standard (JSR 22) that integrates seamlessly with enterprise and web applications. The founding team believes that the existence of such a platform will unleash an inevitable surge of R and D and creativity. The same developers who write web applications should be able to write VoIP services using familiar tools and familiar execution environments, leveraging on their existing expertise. The Mobicents project has already demonstrated successfully that J2EE archives and JSLEE archives can be deployed and run smoothly side by side in the same virtual machine. Mobicents developers can use Eclipse , NetBeans , or any other favorite Java IDE to write and deploy SLEE applications, just as they would with J2EE.
Event-Oriented Programming and JSLEE
First some preliminaries: JAIN SLEE or JSLEE. JAIN is a Sun-invented acronym for "Java APIs for intelligent networks ." JAIN aims for an enabling set of Java APIs to develop and deploy service-driven network applications. JAIN is an industry framework designed and specified by groups of industry partners and experts. SLEE is an acronym for "service logic execution environment."
So what's a JSLEE? JSLEE is an application execution framework analogous to the J2EE environment. However, JSLEE's design principles explicitly aimed for low latency (<100 ms) and high throughput (thousands of events per second) environment optimized for asynchronous event processing, including transaction handling, high reliability, a distributed component model, and a standardized framework. JSLEE's standardization finished in March 2004 (JSR-22 ) with JAIN SLEE version 1.0, and continues in JSR-240 , aiming at JAIN SLEE version 1.1. Initially, JSLEE was designed for network signaling environments. However, the whole architecture proved to be generic enough to allow for other application areas as well.
Why a JSLEE?
Just another execution environment? Why? There are both architectural and performance reasons for inventing it. JSLEE inherits some concepts from J2EE, yet does not replace or contradict the J2EE environment. JSLEE is a complementary platform addressing very specific and special requirements not covered by J2EE as of today. Communications applications have unique requirements for performance and availability that are not addressed in J2EE. However, the integration between both platforms is explicitly foreseen by the standards. The invention of JSLEE was motivated by the telecommunication industry's trend towards component-based architectures realized in open, standardized, off-the-shelf platforms. JSLEE is standardized and hence helps reduce time to market and development costs. Furthermore, JSLEE allows multi-vendor environments, even in the service layers of telecommunication providers. Being Java-based, the paradigm of "write once, run anywhere" is supported and allows portable standards-compliant applications. Besides, JSLEE introduces network abstraction by the means of resource adaptors. JSLEE is a solid foundation with a robust component model and scalability characteristics designed for high-volume, low-latency signaling. It is published as an open standard via the Java Community Process .
The Building Blocks: Framework, Resource Adaptors, and SBBs
Looking under the hood, JSLEE consists of four main areas: management, framework, resource adaptors, and the Component model, as illustrated by Figure 1.
Figure 1. Overview of JAIN SLEE's standardized architecture
The management entities allow the whole JSLEE environment to be managed through JMX -MBeans. The various entities in the framework support the business logic implemented in distributed components, the so-called service building blocks, or SBB. The trace entity allows a centralized and single point for logging, alarms inform external management systems, timers invoke components in pre-defined intervals, and profiles provide the business logic with information and data during execution. Among them, the event router routes incoming and newly created events to previously registered SBBs and resources. The event router is more or less the heart of JSLEE's event routing system.
Resource adaptors bridge the component model and the underlying event infrastructure. The event source could be anything emitting events, implemented in any language or environment. The resource adaptor converts incoming protocols and network-specific events into generic, semantically equivalent Java events and fires them into the JSLEE application server for further processing. So the application and the source of events are logically decoupled: applications execute on any network. This relationship is shown in Figure 2.
Figure 2. Event processing through resource adaptors and the event router
The Component model defines how components interact with each other and with the environment, the bundling of services, and their deployment. The JSLEE environment invokes SBBs according to a standardized lifecycle model for SBBs, comparable to EJBs' lifecycle. The runtime environment secures and manages event processing and framework invocation with transactions. Doing so, the JSLEE application server remains in a defined and consistent state even in case of failure.
A service is essentially a management artifact in JSLEE and is bundled as a .jar file. A JSLEE container may simultaneously house several services. Each service is a logical grouping of functionality and consists of several SBBs. Among them, there is a distinguished SBB called the root SBB that is automatically instantiated by the JSLEE container. If appropriate, this root SBB instantiates child SBBs and routes events to these children.
Incoming events emitted by external sources reach the JSLEE application server through resource adaptors, which in turn fire Java events towards the event router. The event router routes them to SBBs following predefined prioritizations. Related events are clustered as ,em>activities. Events of one activity share a common state: the activity context. An example of an activity is a phone call with the sequenced events
Figure 3 shows the simplified process of event processing. A network-generated signal to set up a telephone call is handed over to the resource adaptor. The resource adaptor generates a Java event and hands it over to the event router. Being the first event in a sequence to set up a call, the event router generates a new activity context. This context and the event itself are handed over to the event-processing logic in the SBB. After processing the logic, the SBB invokes the resource adaptor and makes it produce an answer for the network.
Figure 3. An example of event processing in JSLEE
The JSLEE follows a typed event model: each resource adaptor (RA) is thought of as an event source that produces a stream of typed events, and each SBB is an event sink that consumes the stream of typed events. An event,
XXX, is consumed by the container invoking a user-written
onXXX() method with the appropriate signature on the SBB. SBBs may also fire events on activity contexts. In concrete terms, a resource adaptor is a wrapper around a protocol stack (e.g., the SIP stack). Its job is to react to incoming messages on the wire, and generate a typed stream of events that it feeds to the event router. The event router, in turn, starts appropriate transactions, possibly creating root SBBs of service instances and routing events to such SBBs. Now let us drill down into some of these details.
First, let's examine how the JSLEE instantiates services.
- An event (for example, an incoming SIP message) arrives on an activity and is fielded by the container via a resource adaptor.
- The JSLEE container creates an activity context for the activity, if needed.
- The container searches through the installed services to discover if there is one or more services that are interested in the incoming event.
How does this work? Each active installed service advertises a "convergence name," which is consulted for a match. If a match is found, the container automatically creates the root SBB of the service (if not already instantiated), attaches the root SBB to the activity context, and routes the event to the root SBB via the activity context.
The JSLEE execution model defines transactional boundaries for so-called "SLEE-originated invocation sequences." As in EJB terminology, a transaction is an atomic resilient unit of work. However, unlike EJBs, transaction boundaries are not directly visible. Transactions are started by the system at the beginning of JSLEE-originated sequences, and committed at the end of such sequences. Application errors and exception conditions result in the rollback of the enclosing transaction. Concurrently executing SBBs have a serializable view of the world and are isolated from each other. That is, the final outcome of concurrent execution is some serial ordering of the execution sequences.
The JSLEE does not mandate a specific implementation of the concurrency model. For Mobicents, we have chosen to implement pessimistic concurrency control. In the implementation, we use a thread pool and assign an executor per activity context. This is a reasonable choice because an activity context is an event bus and events on that bus should be consumed in FIFO order.
The JSLEE derives some of its efficiency by relaxing disk persistence requirements. Very few data structures need to survive a full JSLEE restart. Most sensitive structures can simply be replicated across the cluster rather than persisted to disk. We use JBoss Cache technology to achieve this. JBoss Cache is tightly coupled with the JBoss Transaction Manager and provides in-memory replication services across the cluster. Structures in the implementation that need to be replicated by placing them in the cache include activity contexts, SBB entities, and service instances. However, we do not, in general, need to replicate the event queue. The final point is a subtle one that works under the assumption that the endpoint will retransmit the message. This gives the SLEE a significant performance advantage over JMS. Indeed, for most applications, there is little traffic across the cluster after the initial activity has been set up and the service instantiated.
The use of the JBoss modular J2EE architecture results in a nice and cleanly separable architecture for the implementation. Each management (JMX) interface mandated by the SLEE is installed as logically separate JBoss service. The JBoss microkernel architecture allows Mobicents to work with a minimal set of installed JBoss services, thus making for a nicely integrated, extensible, and modular architecture.
Mobicents will continue to closely track the JSLEE standard and remain compliant with its latest official releases. The project will also expand its suite of resource adaptors and standard SLEE services to further commoditize communications infrastructure, thus stimulating innovation in new-generation intelligent services. High availability, performance, and scalability are other areas standing high on the task priority list.
We believe that before long, J2EE developers will be as comfortable writing with JSLEE as they are with J2EE. Next-generation application developers will be fluently crafting triple-play applications that best serve their end users.
Mobicents is a community project and it exists by and large due to the voluntary effort of a core team of developers (listed on the Mobicents home page).
Mobicents has advanced through incorporating code released by the National Institute of Standards and Technology (NIST) into the public domain. Mobicents includes contributors from academia and top-tier telecommunication companies. Notable contributions have been made from University of Genoa, Portugal Telecom Inovacao, Lucent Technologies, Open Cloud, Vodafone, and Aepona.
width="1" height="1" border="0" alt=" " />