Tech blog to share ideas about ongoing project and discuss interesting stuff related to Communication tech and programming.

Wednesday, April 2, 2008

JSIP and Spring

Last month I started using Spring and my first hands-on experience was a small project that starts a standard JSIP stack inside the Spring Framework. I was really amazed how Spring provide a nice component technology that's simplify the code and takes care in a well structured fashion of component initialization, reference and dependency.

SIP is a P2P protocol this means that every SIP entity acts as client and server, so in order to write a SIP application you need to start a TCP or UDP server listening on a local port. This usually require a good deal of initialization code in your program. Spring takes care to setup everything for you just using an xml file, let's take a look how.

First of all you need a file properties in order to configure the stack, here is an example for the properties file:

javax.sip.STACK_NAME=spring-sipstack
javax.sip.STACK_PREFIX=gov.nist
gov.nist.javax.sip.TRACE_LEVEL=32
gov.nist.javax.sip.DEBUG_LOG=sipdebug.txt
gov.nist.javax.sip.THREAD_POOL_SIZE=4
javax.sip.TRANSPORT=udp

Spring Framework defines all your application component (called Spring Bean) using a xml file with a beans root tag.

The first component we need is a bean that loads the properties from our sip.properties file. Here is the Spring Bean definition

<util:properties id="sipConfiguration" location="classpath:sip.properties"/>

Our component is referenced inside the spring bean registry using the id "sipConfiguration" and will create a java.util.Properties object.

The second component is the standard javax.sip.SipFactory that is needed in order to instantiate the stack.

We obtain an instance of the SipFactory using a static factory method getInstance and we declare that all the other beans referencing sipFactory will obtain the same instance using the scope singleton. We're also specifying a property that allows us to change the JSIP implementation just modifying the spring configuration file. In this case we are using the NIST SIP implementation providing the value "gov.nist" for the pathName property.

<bean id="sipFactory"
class="javax.sip.SipFactory"

method="getInstance"
scope="singleton">

<property name="pathName" value="gov.nist"/>


</bean>



Now let's create and start the stack:

<bean id="sipStack"
bean="sipFactory"

method="createSipStack"
scope="singleton">

<constructor-arg ref="sipConfiguration"/>


</bean>


The stack is created using the factory method createSipStack of the sipFactory bean, the factory method require a java.util.Properties argument and we just provide the reference to out sipConfiguration bean. After the bean creation the standard method start is invoked and the stack is started.

Now the stack is started but in order to perform any operation on the SIP Stack we need to obtain an instance of the SipProvider interface. In order to create a SipProvider we need to setup a Listening Point for the stack, the listening point identify the server socket inside the stack on which we are listening for SIP requests.
To create a listening point we use the factory method createListeningPoint of the SipStack and we configure the transport endpoint ip address, port and protocol.

<bean id="listeningPoint"
bean="sipStack"
method="createListeningPoint"
scope="singleton">


<constructor-arg type="java.lang.String" value="127.0.0.1"/>

<constructor-arg type="int" value="5560"/>
<constructor-arg type="java.lang.String" value="udp"/>

</bean>


Finally let's create our SipProvider using the createSipProvider factory method of the SipStack by passing as argument the listening point bean id.

<bean id="sipProvider" bean="sipStack" method="createSipProvider" scope="singleton">

<constructor-arg ref="listeningPoint"/>


</bean>

This is all you need to setup the stack. Now you just need to register your implementation of the SipListener interface with the SipProvider.
Finally in order to run the stack you have to start the Spring Framework Application Context using your bean definition xml file.

public class SipSpringStart {
private ApplicationContext springContext = null;
private String ctxFilePath = "spring-context.xml";

public SipSpringStart() {
this.springContext = new ClassPathXmlApplicationContext(
this.ctxFilePath);
}

public static void main(String[] args) {
new SipSpringStart();
}

}



No comments: