A JAIN SLEE beginner's tutorial? That's a question I see frequently in Mobicents forums, and so I decided to write one that examples how to use Mobicents JAIN-SLEE Server and the last tools we made around Apache Maven2. You can call it "Developing a Hello World JAIN SLEE service in 30 minutes or less".
Of course, before we need a working environment, so you need to install Mobicents JAIN SLEE server binary (don't forget to add an environment variable JBOSS_HOME pointing to the jboss-4.2.2.GA directory of the Mobicents install), and for this tutorial you will also need the Eclipse IDE and Apache Maven2. Additionally you will need to setup Mobicents JAIN SLEE Maven Archetypes. Click on the links for instructions on how to do that.
Ready to rumble? Lets start by creating the Maven2 project using Mobicents JAIN SLEE Maven Archetypes.
Part 1 - Creating the Maven2 project
Open a bash/terminal/command line in the Eclipse workspace directory and type
mvn archetype:generate -DarchetypeCatalog=local
The Maven2 Archetype plugin will ask you what archetype you want to use, introduce the number for jain-slee-basic-service. Second it will ask you the values for some properties:
- groupId - introduce org.mobicents.slee.example
- artifactId - introduce hello-world
- version - just press enter to accept default value
- package - introduce org.mobicents.slee.example again
The process will finally build the project, which will be a directory named hello-world.
Part 2 - Create the Eclipse project and import it in the Eclipse workspace
Ensure Eclipse is closed, and in the bash/terminal/command line (Eclipse's workspace directory) do
mvn -Declipse.workspace=. eclipse:add-maven-repo
Maven will add a variable M2_REPO to Eclipse pointing to Maven2 local repository. Now change to hello-world directory and do
mvn mobicents:eclipse
Maven will create the Eclipse project files. Finally open Eclipse, in the File menu select Import, then "General->Existing Projects into Workspace", next and finally browse to the hello-world directory and Eclipse should find a project named ... hello-world, select it and press Finish.
Part 3 - JAIN SLEE coding
Lets start with a short overview of JAIN SLEE. A SLEE is an application server, a container for software components. JAIN SLEE is designed and optimized for event driven applications, also known as asynchronous applications.
A JAIN SLEE event represents an occurrence that requires application processing. Each event has a specified event type (name,vendor and version), and all applications define the event types they want to handle, on the application Xml descriptors. For each event type of interest an event handler method must be provided in the application.
Events occur in a resource, inside or outside of the container. We call "event firing" to the action of posting of an event into the container, and when this happens the container will route the event to all applications interested on it, that is, all application instances (entities) attached to the context of that event, in JAIN SLEE this context is named activity. This attachment can be explicit (lets leave that for another article) or implicit, when the application defines the event type of the event being routed as an initial event. This means that if an application defines an event type as "initial", then all events of that type will be handled by the application.
So JAIN SLEE applications, also known as Services, are pure logic, which is executed by the container when events are fired in the container, which means they don’t have any active resources. In that sense, a JAIN SLEE service is no different than a web page script executed by the browser.
Going deeper, a JAIN SLEE Service is a tree of Service Building Blocks (Sbb), containing one root Sbb which then can declare others as child Sbbs, which then can have their own childs, and so on. Each Sbb is a Java abstract class, and includes the following logic:
- implementation of the event handler methods
- implementation of the interface to be used by other Sbbs who declare it as a child
- implementation of an entity/instance life-cyle
- implementation of methods to manage persistence of instance data
Ok, now what we want for our service is that when it is activated a message "Hello World" will be printed on the console. The Maven archetype we used already made most of the job:
- it created a Service, which is nothing more than a Xml descriptor, that you can find in du/src/main/resources/services/service.xml, that just defines it's id (name,vendor,version) and its root sbb:
<service-name>hello-world SLEE Service</service-name> <service-vendor>org.mobicents.slee.example</service-vendor> <service-version>1.0-SNAPSHOT</service-version> <root-sbb> <description> <sbb-name>hello-world SBB</sbb-name> <sbb-vendor>org.mobicents.slee.example</sbb-vendor> <sbb-version>1.0-SNAPSHOT</sbb-version> </description> </root-sbb> ...
- it created a Sbb that handles an internal event, ServiceStartedEvent, that is fired whenever a service is activated. How is this done you may ask, each Sbb class is packed in jar with a Xml descriptor (you can open it in eclipse please? sbb/src/main/resources/META-INF/sbb-jar.xml), this descriptor defines the Sbb id (name,vendor,version), its Java class and the events it handles, in this case ServiceStartedEvent:
<sbb-name>hello-world SBB</sbb-name> <sbb-vendor>org.mobicents.slee.example</sbb-vendor> <sbb-version>1.0-SNAPSHOT</sbb-version> <sbb-classes> <sbb-abstract-class reentrant="False"> <sbb-abstract-class-name> org.mobicents.slee.example.RootSbb </sbb-abstract-class-name> </sbb-abstract-class> </sbb-classes> <event direction="Receive" event="True"> <event-name>ServiceStartedEvent</event-name> <event-type-ref> <event-type-name> javax.slee.serviceactivity.ServiceStartedEvent </event-type-name> <event-type-vendor>javax.slee</event-type-vendor> <event-type-version>1.0</event-type-version> </event-type-ref> <initial-event-select variable="ActivityContext" /> </event>
public void onServiceStartedEvent( javax.slee.serviceactivity.ServiceStartedEvent event, ActivityContextInterface aci) { try { Context myEnv = (Context) new InitialContext().lookup("java:comp/env"); ServiceActivity sa = ((ServiceActivityFactory) myEnv .lookup("slee/serviceactivity/factory")).getActivity(); if (sa.equals(aci.getActivity())) { // it's this service that is starting logger.info("service activated..."); } // don't want to receive further events on this activity aci.detach(this.sbbContext.getSbbLocalObject()); } catch (Exception e) { logger.error("Can't handle service started event.", e); } }The logic in this event handler looks ugly but it's simple, it retrieves the ServiceActivity of the service from it's JNDI environment, and compares it with the ServiceActivity where the event was fired. If matches it means it's our service that is being activated. Great, now we just need to print the message in the console and in fact it's already printing something, "service activated", so all you need to do is change that code to
logger.info("hello world!!!");
Part 4 - Run the serviceThe end is close, let's start Mobicents JAIN SLEE Server, doing run.sh/run in server/bin folder of the Mobicents directory. Use another bash/terminal/command line window please.
Once it stops go to the window in the hello-world example directory and do
mvn install
Voila, Maven builds the Service's Deployable Unit jar on it's own, copies it to the Mobicents server deploy dir, and you should see the service being deployed on the window where Mobicents is running. In the end you should see
03:04:44,697 INFO [RootSbb] hello world!!!
That's it, have fun with JAIN SLEE specification document (the best knowledge source for sure) and don't forget to leave your feedback here.
A verry nice tutorial Edu ..
ReplyDeletewonderful
ReplyDeletebut how to start or run mobicents?
from src or from binary
i've done it, yeah!
ReplyDeleteFirst, Sorry for my english :).
ReplyDeleteI have some problems with my maven so I couldn't finish the tutorial (Fatal Errors a things like that).
I have read the mobicents examples source code and I have noticed those examples were developed with maven too. My question is how about the eclipse plugin for jain slee and the maven's plugins for eclipse and netbeans?, I'm worried about the deploying of projects developed with those tools because of their project structure, its the same as maven's projects?
Thanks.
Julian.
Hi Ed,
ReplyDeleteHow do I setup the local catalog? I created the archetype-catalog.xml file, but don't know where to place it. Am working on windows xp. The following is the output obtained after executing the mvn cmd,
C:\playground>mvn archetype:generate -DarchetypeCatalog=local
[INFO] Scanning for projects...
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Default Project
[INFO] task-segment: [archetype:generate] (aggregator-style)
[INFO] ------------------------------------------------------------------------
[INFO] Preparing archetype:generate
[INFO] No goals needed for project - skipping
[INFO] Setting property: classpath.resource.loader.class => 'org.codehaus.plexus
.velocity.ContextClassLoaderResourceLoader'.
[INFO] Setting property: velocimacro.messages.on => 'false'.
[INFO] Setting property: resource.loader => 'classpath'.
[INFO] Setting property: resource.manager.logwhenfound => 'false'.
[INFO] [archetype:generate]
[INFO] Generating project in Interactive mode
[INFO] No archetype defined. Using maven-archetype-quickstart (org.apache.maven.
archetypes:maven-archetype-quickstart:1.0)
Choose archetype:
Choose a number: : 1
Choose archetype:
Choose a number: : Choose archetype:
Choose a number: : Terminate batch job (Y/N)? y
Am not sure how to proceed now & the jboss site is under maintenance and am lost. Kindly advice.
Thanks,
Cyril
Hi Ed,
ReplyDeleteWas able to setup the catalog. For those who are new to using maven, here is what I did,
1. I created the archetype-catalog.xml as listed on http://groups.google.com/group/mobicents-public/web/jainslee-maven-archetypes.
2. I then placed this file on C:\Documents and Settings\cyril\.m2
directory and then everything worked as per the tutorial.
Thanks for the tute Ed.
Cheers,
Cyril
Thank you Eduardo! Nice easy tutorial!
ReplyDelete