exploring ruby and java interoperability for building converged web and sip applications

14
Exploring Ruby and Java Interoperability for Building Converged Web and SIP Applications Edin Pjani´ c and Amer Hasanovi´ c University of Tuzla, Faculty of Electrical Engineering Franjevaˇ cka 2, 75000 Tuzla, Bosnia and Herzegovina {edin.pjanic,amer.hasanovic}@untz.ba ABSTRACT KEYWORDS software infrastructure, SIP, converged appli- cations, dynamic languages, interoperability, Ruby, JRuby, Rack, Cipango, Jetty 1 INTRODUCTION In the nineties, software development was mostly focused on desktop applications utilizing tools, libraries and paradigms built around Java and C++, the two most dominant programming languages of that time. During the last decade, this focus started shifting towards Web applications, agile practices and dynamic programming languages [1][2][3]. The Ruby programming language [4] received a lot of attention in the software industry, primarily because of the flexible Web frameworks, such as Ruby on Rails [5] and Sinatra [6], as well as Ruby’s support for the development of domain specific languages (DSL) [7][8]. With the recent rise of social Web applications, there is an increased interest to bring other services to the Web domain, real-time voice and video in particular. Based on the HTTP model, the Session Initiation Protocol (SIP) [9] was developed to support these services. The telecommunications industry has accepted the SIP protocol, which is now widely implemented and used in telecom application servers. While Ruby has excellent support for HTTP, due to the Web frameworks, it lacks the adequate support for SIP. On the other hand, Java has well developed APIs, libraries and tools for the SIP protocol, such as the SIP Servlets [10] and JAIN SLEE [11]. Therefore, it would be beneficial to combine Ruby’s proven agility [3] and Java robustness in a single infrastructure for rapid development of In this paper we present a Ruby infrastructure that can be used for rapid development of Web applications with SIP signaling capabilities. We construct this infrastructure by combining the Java based Cipango SIP/HTTP Servlet Application Server with the Ruby on Rails Web development framework. We provide detailed explanations of the steps required to build this infrastructure and produce a realistic SIP application with an integrated Web interface. The described infrastructure allows Ruby applications to utilize the entire functionality provided by the SIP Servlet API and can be used as a good starting point for the development of Ruby-based domain specific languages for the SIP protocol. We also compare the proposed infrastructure with the existing Ruby frameworks for SIP application development. Furthermore, we present the performance analysis results of the demo application using SIPp, a SIP traffic generator tool.

Upload: ijdiwc

Post on 20-Oct-2015

19 views

Category:

Documents


3 download

DESCRIPTION

In this paper we present a Rubyinfrastructure that can be used for rapiddevelopment of Web applications withSIP signaling capabilities. We constructthis infrastructure by combining theJava based Cipango SIP/HTTP ServletApplication Server with the Ruby on RailsWeb development framework. We providedetailed explanations of the steps requiredto build this infrastructure and produce arealistic SIP application with an integratedWeb interface. The described infrastructureallows Ruby applications to utilize the entirefunctionality provided by the SIP ServletAPI and can be used as a good starting pointfor the development of Ruby-based domainspecific languages for the SIP protocol. Wealso compare the proposed infrastructurewith the existing Ruby frameworks for SIPapplication development. Furthermore, wepresent the performance analysis results ofthe demo application using SIPp, a SIPtraffic generator tool.

TRANSCRIPT

Exploring Ruby and Java Interoperability for BuildingConverged Web and SIP Applications

Edin Pjanic and Amer Hasanovic

University of Tuzla, Faculty of Electrical EngineeringFranjevacka 2, 75000 Tuzla, Bosnia and Herzegovina{edin.pjanic,amer.hasanovic}@untz.ba

ABSTRACT

KEYWORDS

software infrastructure, SIP, converged appli-cations, dynamic languages, interoperability,Ruby, JRuby, Rack, Cipango, Jetty

1 INTRODUCTION

In the nineties, software developmentwas mostly focused on desktopapplications utilizing tools, librariesand paradigms built around Java

and C++, the two most dominantprogramming languages of that time.During the last decade, this focus startedshifting towards Web applications, agilepractices and dynamic programminglanguages [1][2][3].

The Ruby programming language [4]received a lot of attention in the softwareindustry, primarily because of theflexible Web frameworks, such as Rubyon Rails [5] and Sinatra [6], as well asRuby’s support for the development ofdomain specific languages (DSL) [7][8].

With the recent rise of social Webapplications, there is an increasedinterest to bring other services to theWeb domain, real-time voice and videoin particular. Based on the HTTP model,the Session Initiation Protocol (SIP) [9]was developed to support these services.The telecommunications industry hasaccepted the SIP protocol, which is nowwidely implemented and used in telecomapplication servers.

While Ruby has excellent support forHTTP, due to the Web frameworks, itlacks the adequate support for SIP. Onthe other hand, Java has well developedAPIs, libraries and tools for the SIPprotocol, such as the SIP Servlets [10]and JAIN SLEE [11]. Therefore, it wouldbe beneficial to combine Ruby’s provenagility [3] and Java robustness in a singleinfrastructure for rapid development of

In this paper we present a Rubyinfrastructure that can be used for rapiddevelopment of Web applications withSIP signaling capabilities. We constructthis infrastructure by combining theJava based Cipango SIP/HTTP ServletApplication Server with the Ruby on RailsWeb development framework. We providedetailed explanations of the steps requiredto build this infrastructure and produce arealistic SIP application with an integratedWeb interface. The described infrastructureallows Ruby applications to utilize the entirefunctionality provided by the SIP ServletAPI and can be used as a good starting pointfor the development of Ruby-based domainspecific languages for the SIP protocol. Wealso compare the proposed infrastructurewith the existing Ruby frameworks for SIPapplication development. Furthermore, wepresent the performance analysis results ofthe demo application using SIPp, a SIPtraffic generator tool.

user
Typewritten text
597
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

SIP applications. The main concepts ofthis integration were discussed in [12].

In this paper, we demonstrate thesteps required to build the infrastructurewhich allows hosting of Web applicationswith real-time VoIP capabilities entirelyin Ruby. We reuse well-known and testedopen-source components as the basis forthis infrastructure. More specifically, weglue together the code provided by theRuby on Rails Web framework and aJava based Cipango SIP/HTTP ServletApplication Server [13]. We realizethis concept with JRuby [14], a Javaimplementation of the Ruby language.We also provide a detailed explanation ofthe techniques we use for interoperationbetween JRuby and Java. Finally, wecompare our approach with similarRuby infrastructures for SIP applicationdevelopment.

The paper is organized as follows. InSection 2 we shortly outline the relatedinfrastructures and compare them withour approach. In Section 3 we focuson interoperability between JRuby andJava, which is essential for utilizing Javalibraries from within the Ruby code.In Section 4 we discuss the CipangoSIP/HTTP application server architectureand identify the key classes that canbe used to embed the server engineinside a Ruby application. We providean in-depth procedure to construct theproposed infrastructure by buildingan example Web application with SIPcapabilities in Section 5. In Section 6, weanalyze the performance of the demoapplication. Finally, in Section 7 weprovide a conclusion and map a coursefor the future work.

2 RELATED WORK

At the time of writing this paper, we areaware of the two Ruby infrastructuresfor SIP application development. In thissection we give a brief overview of theseframeworks and compare them to ourapproach.

2.1 TorqueBox

TorqueBox [15] is a Ruby applicationplatform that integrates JRuby Webapplications based on Rack [16]frameworks, such as Ruby on Rails,with the JBoss Application Server [17],utilizing the features provided by JBoss.Currently, TorqueBox provides the SIPsupport in the beta versions.

Building converged applicationswith TorqueBox is similar to ourapproach. The main differences are in theapplication deployment and integrationwith the SIP application server. Thisis a direct result of the fact that theTorqueBox uses the JBoss while inour approach we utilize the Cipangoapplication server. Additionally, theTorqueBox application deployer does notsupport all the features provided by theSIP servlet API from within Ruby code.For instance, listener objects are createdand added to the SIP application contextduring the deployment of the application.The classes for these objects are definedin the sip.xml deployment descriptorfile and cannot be Ruby classes.

Application deployment in ourapproach is completely different. Insteadof deploying an application to the server,we incorporate the server inside the Rubyapplication. This means that we canutilize the full stack of the SIP Servlet

user
Typewritten text
598
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

API and control all the features providedby the Cipango application server,including the creation and specificationof listener objects, as shown in the demoapplication. Furthermore, this gives us apossibility to develop and integrate RubyDSLs in order to speed up and simplifyVoIP applications development.

Moreover, the lightweight infrastruc-ture of the Cipango engine allows fasterapplication startup times, which is veryimportant in short development iterationcycles.

2.2 Sipatra

Sipatra [18] is a Ruby DSL for SIPServlets and targets SIP Servlet 1.1compatible application servers. Its syntaxis much like the syntax used in SinatraWeb DSL, but adapted to support thespecific features of the SIP protocol.

Sipatra SIP message handlers aredefined as blocks of code that arecalled when certain conditions aresatisfied. The conditions are specified asregular expressions that must match themessage’s SIP request method, responsecode, URI or headers in order for thehandler to be invoked. There can bemore than one handler for the same SIPmessage type. The handlers are evaluatedin the order they appear in the codeand the first handler that matches thecondition is executed. An example of thesyntax is shown in the Figure 1 listingthat is self explanatory.

Similar to our approach, Sipatra usesthe Cipango application server. However,the application deployment procedure issimilar to the one used in the TorqueBoxproject. Hence, it suffers from the samelimitations discussed in Section 2.1.

invite /sip:.*@sipatra.org/ do...

end

invite /sip:.*@otherdomain.org/ do...

end

invite do...

end

response :INVITE, 200 do...

end

Figure 1. Example of the Sipatra syntax.

3 JRUBY AND JAVAINTEROPERABILITY

Matz’s Ruby Interpreter or RubyMRI is the reference implementationof Ruby, written in C by YukihiroMatsumoto. However, this is not theonly implementation of Ruby. Oneespecially successful open sourceimplementation, called JRuby, is writtenfor the Java Virtual Machine. Whilebeing fully compatible with RubyMRI, it offers certain advantages. First,since it is implemented on top of theJava Virtual Machine (JVM), JRubythreads are mapped to the kernel threads,and Unicode strings are automaticallysupported in JRuby. Second, JRubycan seamlessly interoperate with Java.Meaning, that we can use Java objectsas normal Ruby objects, and vice versa.Hence, we can exploit the wealth of Javalibraries, using the power of Ruby’sflexible syntax. To demonstrate theinteroperability between JRuby and Java,we use the Java listing shown in Figure 2,in which we define the Foo Java class.

We compile the class and put it inthe example.jar library. Now, wecan use the Foo class in JRuby. To

user
Typewritten text
599
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

package org.test;public class Foo {

private int var = 0;public void setVar(int v) {

var = v;}public int getVar() {

return var;}public void method1() {

System.out.println("In Java "+var);}public static void method2(Foo obj) {

obj.method1();}

}

Figure 2. The example Java class Foo, used to demon-strate the interoperability.

demonstrate this, we write the Rubyprogram ’test program.rb’, shown inFigure 3.

Since the native Java classes in JRubyare wrapped inside the java module, weinclude this module in the first line of thescript. To access the Foo class, we re-quire example.jar as a Ruby module,and include the class from it’s packagein lines 2 and 3. Next, we define a Rubyclass, called Bar, by subclassing the Fooclass. In the Bar class code, we overridemethod1 to print a Ruby message.

We create the two Rubyobjects, named java_object andruby_object, in lines 9 and 10. Inline 11, it looks like we are directlysetting the var field of ruby_object.This however is not allowed, since wedon’t have access to the private fields ofthe base class. JRuby instead, calls theprovided Java setter method setVar,inherited from Foo, and passes value 10to the method. Similarly, JRuby calls thegetter method getVar when we try toread from var in line 6. Finally, we sendthe two objects to the static Java methodof the Foo class, in lines 12 and 13.

[ 1] require ’java’[ 2] require ’example.jar’[ 3] include_class ’org.test.Foo’[ 4] class Bar < Foo[ 5] def method1[ 6] puts "In Ruby "+var.to_s[ 7] end[ 8] end[ 9] java_object = Foo.new[10] ruby_object = Bar.new[11] ruby_object.var = 10[12] Foo::method2 java_object[13] Foo::method2 ruby_object

Figure 3. The code of the ’test program.rb’script.

When we execute the program, it printsthe following output:$ jruby test_program.rbIn Java 0In Ruby 10

We can see that during the secondcall, when we send ruby_objectto the Java world, the Ruby version ofmethod1 gets called inside the code ofthe Java class.

We use the described interoperabilityfeatures extensively to embed, configureand manipulate a Java SIP applicationserver inside the code of a convergedWeb and SIP JRuby application.

4 CIPANGO SIP APPLICATIONSERVER

In the telecom Next GenerationNetworks paradigm, SIP is one of thecore protocols used in the ServiceDelivery Platforms. These platformscan be built around Java EnterpriseEdition (EE) [19] servers, extended tosupport SIP Servlet specification [10].Using these extensions, applicationsthat support SIP services can be built inJava with SIP servlets, in a similar wayWeb applications are built with HTTP

user
Typewritten text
600
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

servlets. Applications are deployed toJava EE servers in the war archives. Theserver unpacks the archive, initializesthe application and invokes it when anappropriate HTTP or SIP message isreceived, or when a certain event occurs.Technique similar to this is used in theopen source TorqueBox project [15]to deploy JRuby applications to theMobicents SIP application server [20].However, with this approach it can bedifficult to access from JRuby somefeatures provided by the applicationserver. For instance, creating andcontrolling the SIP servlet timers.

In this paper, we use anotherapproach. The open source CipangoSIP/HTTP Servlet Application Server,built on top of the Jetty Web Server [21],supports an interesting option ofembedding. Using this option, instead ofdeploying an application to the server,we incorporate the server engine in ourapplication and control it completely.

The Cipango engine consists of thecore classes that are shown in Figure 4.To embed the engine, we need to createthe following Java objects in a JRubyapplication:

– one Server instance,– a number of connector instances that

specify the sockets used for commu-nication,

– at least one SipAppContext thatrepresents a context in which we addSIP and HTTP servlets, and finally,

– a number of SipServlet andHttpServlet instances that weuse inside the context to handle thespecific HTTP and SIP requestsand/or responses.

Figure 4. Core Cipango classes

5 THE DEMO APPLICATION

When a SIP VoIP client starts up, it sendsa SIP REGISTER request to the SIP reg-istrar server. The request has a dual pur-pose. It is used to authenticate the user,and provide the server with the current IPlocation of the user. The user’s current IPaddress is then saved in a database. As-sociation between the user’s username, orhis SIP URI, and the IP address of the ma-chine where the user’s SIP client is run-ning is called binding. Proxy servers usebindings in order to forward requests toSIP clients.

SIP proxy servers have several rolesin the SIP infrastructure, such as check-ing validity of the SIP requests, checkingthe user’s credentials for certain requests,routing the requests to other proxies or tofinal recipients. If the proxy is responsiblefor the final recipient’s domain, it checksthe location database for his current IP ad-dress and proxies the request to that loca-tion in order to deliver the request to thedestination.

In this paper, we build a simpleregistrar and proxy application, usingonly Ruby. Besides processing the SIPREGISTER and INVITE messages,the application provides a simple Webinterface for administration purposes.

user
Typewritten text
601
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

We first prepare the Web interface,by using the Rails framework. Then,we create the application in which weembed the Cipango SIP engine. Insidethe application code, we configurethe Cipango engine to host the Railsgenerated Web interface, and to handleREGISTER and INVITE SIP messagesusing the SIP servlet defined in theapplication.

5.1 Building the Database and WebInterface

We start building the application bydownloading the latest JRuby distributionarchive from the JRuby Web site [22].After uncompressing the archive, weadd the bin directory of the JRubydistribution to the system path, since weuse the command line interface to buildthe application.

Next, using the gem infrastructure,we install the Rails framework and theSQLite3 database adapter.$ jruby -S gem install rails \

activerecord-jdbcsqlite3-adapter \--no-ri --no-rdoc

The previous command installed thelatest Rails framework to the JRubydistribution, but without the defaultdocumentation.

To build the Web interface fromscratch we use the Rails code generators,which we invoke from the command line.For the deeper understanding of thesecommands, we direct the reader to [23]and [24].

We first build the skeleton Railsproject called registrar by issuingthe following command:$ jruby -S rails new registrar \

--template http://jruby.org

Based on the template for JRubyRails applications, this created theregistrar project directory, togetherwith the subdirectories that hold thedefault Rails project infrastructure.

Next, in the project’s directory, inorder to construct the Web interfacefor user administration, we execute thegenerate scaffold command:$ jruby -S rails generate scaffold \

sip_user user_name:string \first_name:string last_name:string

As described in [23], Rails is basedon the MVC design pattern. The previouscommand created the model, view andcontroller classes for the sip_userresource with the following threefields of the string type: user_name,first_name and last_name.

Now we need to create an additionalclass that models the SIP registrationbindings. The model class has to havea field for the current location ofthe user and a reference to the userwhich the binding belongs to. Hence,we create the registration model witha field location and a referenceto the sip_user model by issuingthe following generate modelcommand:$ jruby -S rails generate model \

registration location:string \sip_user:references

The previous generators createSipUser and Resource classes .The Resource class is associatedwith the SipUser class usingthe ActiveRecord’s belongs_toassociation. This is equivalent to aforeign key relationship in relationaldatabases. Now, we need to create theother side of the association by changingthe generated SipUser class definition,

user
Typewritten text
602
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

saved in the file ’app/models/sip user.rb’,to read:class SipUser < ActiveRecord::Basehas_one :registration,

:dependent => :destroyend

This definition means that instance ofthe SipUser class can have only oneinstance of the Registration class.Additionaly, deletion of the SipUserinstance will initiate deletion of therelated Registration instanceautomaticaly. The association betweenthose two classes is depicted graphicalyin Figure 5.

Registrationlocation

SipUseruser_namefirst_namelast_name

1 0..1has one belongs to

Figure 5. Class diagram of the models.

Before we can access the resourcesthrough the Web interface for CRUD(create, read, update and delete)operations, we need to build the databaseto hold the resource data. The previousgenerate commands have alsogenerated the migration scripts, whichwe use to create the SQLite database withthe appropriate schema that describesthe resources. To start the migrationprocess and generate the productiondatabase, we execute the following Rakedb:migrate command.$ jruby -S rake db:migrate \

RAILS_ENV=production

We are done building the databaseand Web interface, which is shown inFigure 6. Now, we need to add therequired Java libraries to the registrarproject in order to provide the SIPprotocol support for our application.

Figure 6. Rails generated Web interface.

5.2 Adding the Java Libraries

We download the Cipango applicationserver distribution, version 1.0.0, fromits Web site [13]. After we uncompressthe Cipango distribution, from thedistribution’s lib directory, we need thefollowing jar files: cipango, jetty,jetty-util, servlet-api,sip-api, and also cipango-darfrom the lib/ext folder. In the Railsregistrar project directory, we createthe jars folder. This is where we copythe required jar files from the Cipangodistribution.

To host the Rails generated Webinterface, we also need the JRuby-Racklibrary [25]. This library was developedspecifically to enable the hosting ofJRuby Web applications, inside JavaEE-compliant servers. We use theJRuby-Rack library to connect the Railsgenerated code with the embeddedCipango server. The library is providedin a single jar file, which we obtainfrom its Web site [25]. We copy thedownloaded JRuby-Rack jar file to thejars directory of the registrarproject.

user
Typewritten text
603
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

[ 1] require ’java’[ 2] Dir["jars/*.jar"].each { |jar| require jar }[ 3] require ’my_factories’[ 4] require ’my_sip_servlet’[ 5]... < include the necessary Java classes > ...[19][20] cipango = Server.new[21] context_collection = SipContextHandlerCollection.new[22] cipango.handler = context_collection[23]... < setup TCP and UDP connectors > ...[29][30] context = SipAppContext.new[31] context.resource_base = "."[32] context.context_path = "/"[33] context.add_servlet( ServletHolder.new( DefaultServlet.new), "/*" )[34] context.init_params = HashMap.new([35] ’org.mortbay.jetty.servlet.Default.relativeResourceBase’ => ’/public’,[36] ’rackup’ => File.read(’config.ru’),[37] ’jruby.max.runtimes’ => ’1’[38] )[39] context.add_filter("org.jruby.rack.RackFilter", "/*", Handler::DEFAULT)[40] context.add_event_listener( MyListener.new )[41] my_sip_servlet = MySipServlet.new[42] context.add_event_listener( my_sip_servlet )[43] context.add_sip_servlet( SipServletHolder.new(my_sip_servlet) )[44] context_collection.add_handler(context)[45] cipango.start[46] cipango.join

Figure 7. Ruby application which embeds the Cipango server.

5.3 Creating the ConvergedApplication

To glue the entire project together, wecreate the JRuby application in a filecalled ’application.rb’, which we savein the top level directory of the Railsregistrar project. The applicationcode is shown in Figure 7.

In line 2 of the Figure 7 listing, inorder to gain access to the Java classes,we require all the jar files stored inthe jars directory relative to thecurrent path. We include the Java classesfrom their packages in lines 5-19,which are omitted from the listing forsimplicity. We later explain the purposeand content of ’my factories.rb’ and’my sip servlet.rb’, the files we requirein lines 3 and 4.

In lines 20-22, we start embeddingthe Cipango engine by creating theServer instance and assigning ahandler to the server. The handlerprocesses the SIP and HTTP messagesreceived by the server. Next, we defineand configure the two server connectors,the UDP connector for the SIP traffic andthe TCP connector for the HTTP traffic,with the corresponding ports 5060 and3000. For simplicity, we omitted the codeof the connectors setup from the listing.

We create the converged applicationcontext in line 30, and configure it inlines 31-38. More specifically, in lines31-32, we set the current directory asthe resource base for the convergedapplication, and map the application tothe root URL of the server. Next, inline 33 we add the default Jetty servletto the application context. We use it to

user
Typewritten text
604
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

handle the requests for static contentof our Web interface. Therefore, inline 35, we initialize the Jetty servletresource base to the public directoryof the registrar project, where westore the static content of the Railsapplication. We incorporate the entireWeb interface, generated with Rails, byadding the servlet filter to the convergedcontext in line 39. We use the servletfilter class called RackFilter, whichis provided by the JRuby-Rack library.This servlet filter detects if an HTTPrequest matches a dynamic URL handledby the Rails generated interface. If therequest is matched, the filter uses theRails framework to process the request.Otherwise, it just passes the requestto the other servlets in the convergedcontext. Therefore, if the request isfor static content, such as images, cssand javascript files, the filter passes therequest to the default Jetty servlet, whichwe previously added to the context.

We now need to modify the defaultbehaviour of the JRuby-Rack library.The library usually operates in the modewhere a Rails application is deployed toa Java EE server in a single war archive,together with the complete Ruby on Railsand JRuby distributions. Since there isno JRuby runtime in the server’s JVM,JRuby-Rack creates the runtime andinitializes it with the Rails environment.The library then starts the servlet filteroperations and connects the createdruntime with the Java server using theRackFilter object. Since we arerunning the Cipango server embeddedin a JRuby application, we override thedefault behaviour and force JRuby-Rackto use the application’s JRuby runtime,instead of creating a new one. We do thisin line 40, by providing the converged

application context with a custom listenerobject of the MyListener class.MyListener class is defined in the’my factories.rb’ file shown in Figure 8.

%w[org.jruby.rack.DefaultRackApplicationFactoryorg.jruby.rack.SharedRackApplicationFactoryorg.jruby.rack.RackServletContextListenerorg.jruby.Ruby].each {|c| include_class c }

class MyFactory<DefaultRackApplicationFactoryfield_accessor :rackContextdef newRuntimeruntime = Ruby.get_global_runtime$servlet_context=rackContextrequire ’rack/handler/servlet’return runtime

endendclass MyListener<RackServletContextListener

field_reader :factorydef newApplicationFactory(context)if factory

return factoryelse

return (SharedRackApplicationFactory.new(

MyFactory.new))

endend

end

Figure 8. The code of the ’my factories.rb’ file.

We can see that inside theMyListener class we overridethe newApplicationFactorymethod, inherited from theRackServletContextListenerJava class. We implement this method toreturn a custom factory object, which isused for JRuby runtime creation whenthe converged application context isinitialized. The custom factory object isof the MyFactory class. We definethis class inside the same file. In thisclass we only override the inheritednewRuntime method. We change themethod so that, instead of creating andreturning a brand new JRuby runtime,

user
Typewritten text
605
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

it returns the current runtime in whichthe application is already running.Furthermore, we perform the necessaryinitialization of the application’s runtimeto prepare it for the RackFilteroperations.

In line 36, we configure theJRuby-Rack library to load ’config.ru’,a Web application configuration filegenerated by Rails in the top leveldirectory of the project.

To handle the SIP traffic, wecreate and add a SIP servlet objectto the converged application context,in lines 41-43 of the Figure 7 listing.This object is an instance of theMySipServlet class, which we definein ’my sip servlet.rb’ file, shown inFigure 9.

Finally, in line 44 of the Figure 7listing, we add the application context tocontext_collection of the server,and start the server in line 45.

SIP functionality is implementedin the Ruby SIP servlet classMySipServlet, shown in Figure 9.

In the Ruby SIP servlet, we definetwo methods: doRegister anddoInvite.

By defining the doRegistermethod of the SIP servlet, we enable theprocessing of SIP REGISTER requests.Inside the method, from the received SIPrequest, we first extract the user name,as well as the remote IP address andport of the SIP client the request is sentfrom. Next, by using the Rails generatedmodel class SipUser, we query thesystem database for a valid user withthe extracted user name. If we find theuser in the database, we return the 200’OK’ response, meaning that the current

%w[javax.servlet.sip.SipServletjavax.servlet.sip.SipSessionListener].each {|c| include_class c }

class MySipServlet < SipServletinclude SipSessionListener

def doRegister(request)username = request.from.uri.useraddress = request.remote_addrport = request.remote_portremote_uri =

"sip:#{username}@#{address}:#{port}"

user = SipUser.find_by_user_name(username)if user

exp = request.get_header(’Expires’)if !exp

c = request.get_header(’Contact’)c.grep(/expires=(\d+)/)exp = $1

endexp = exp.to_iif exp == 0

reg =Registration.find_by_sip_user_id(user.id)

reg.destroy if regelse

reg =Registration.find_or_create_by_\sip_user_id_and_location(user.id, remote_uri)

reg.location = remote_urireg.save

endrequest.create_response(200).send

elserequest.create_response(404).send

endend

def doInvite requsername = req.get_to.get_uri.get_useruser =

SipUser.find_by_user_name(username)reg = user.registrationif reg

factory =servlet_context.get_attribute(’javax.servlet.sip.SipFactory’)

uri = factory.create_uri(reg.location)req.get_proxy.proxy_to(uri)

elsereq.create_response(404).send

endend

def sessionCreated(event)... < handle the event > ...

endend

Figure 9. Ruby SIP servlet which acts as a SIP registrarand proxy server.

user
Typewritten text
606
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

user has successfully registered, and savehis location to the database using theRegistration model. Otherwise,we send the 404 ’Not found’ (User notfound) response. When a user registers tothis registrar, the binding is kept in thedatabase until the explicit request forremoval is received or the user is deletedthrough the Web interface.

According to the RFC 3261 [9], abinding removal request is performedby sending a SIP REGISTER messagewith the expires parameter of theContact header field value or theExpires header value specified as 0.Our example application checks thesevalues and performs the binding removalwhen it is appropriate.

For simplicity, we omit other opera-tions a normal registrar server wouldperform, such as user authentication andregistration expiration. Additionaly, weignore the domain part of the user’s SIPURI.

In the doInvite method weimplement the proxy behaviour of ourapplication. When the INVITE SIPrequest is received, we first extract theuser name of the recipient and check forits binding. If the binding is found, therequest is proxied to the user’s location,as shown in Figure 10. Otherwise, theresponse 404 (User not found) is sentback as a response to the original request,as shown in Figure 11. For example, ifAlice wants to talk to Bob, she wouldcall him from her SIP client using Bob’suser name. SIP proxy would consult thelocation database to check for his bindingand proxy the request to Bob’s currentlocation.

We can execute the application usingthe following command:

$ jruby application.rb

Once the application is fully initial-ized and running, we can create, updateand delete the users of the registrar serverthrough the Web interface on port 3000,and the URL shown in Figure 6.

Furthermore, we can configure a SIPVoIP client to register with our applica-tion and use it as an outbound proxy byproviding: a valid user name, port 5060,and the IP address of our application, or afully qualified host name.

BobAlice Proxy

INVITE bob

Proxy checks db and finds bob's binding.

200 OK

ACK

INVITE bob@binding-addr

200 OK

ACKBYE

BYE

200 OK200 OK

Figure 10. Binding found – the request is proxied to theuser’s current location.

Alice Proxy

INVITE bob

Proxy checks db and does not find bob's binding.

404 Not found

ACK

Figure 11. Binding not found – the 404 response is sentback to the caller.

user
Typewritten text
607
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

By utilizing the approach presentedin this paper, Ruby objects can alsobe registered as handlers to specificevents generated by the server.To demonstrate this feature, as anexample, MySipServlet classimplements the SIP Servlet APIinterface SipSessionListener.The Ruby servlet object is registeredwith the application to receive eventsin line 42 of the Figure 7 listing. Whensession creation event is generatedby the server, the application invokesthe sessionCreated method onthe servlet object. Other events can beprocessed in a similar manner.

6 PERFORMANCE ANALYSIS OFTHE DEMO APPLICATION

Using the methodology we presentedin [26], the performance analysis isperformed for the proxy part of theexample application. This proxy servereither terminates the call by sending backa 404 Not found message in the case thebinding of the callee is not found in thedatabase, or it sends an INVITE requestto the callee SIP client if the binding isfound, as depicted in Figures 10 and 11.

The performance was done usingSIPp [27], a tool released under the GNUGPL licence. It is available on allmost allUNIX platforms. Furthermore, there is aport for the Windows operating system.

SIPp is a command line performancetesting tool for the SIP protocol. It canact as a user agent client (UAC) or a useragent server (UAS). SIPp establishes andmaintains multiple calls by generatingstandard SIP requests and responses.There are several scenarios integrateddirectly in the SIPp executable.

Additionaly, it is possible to create acustom scenario. The custom scenariosare saved in XML files and are, togetherwith other options, passed to SIPp ascommand line parameters. It is possibleto inject data from one or more externalCSV files.

For the performance analisys of ourdemo application, a custom scenariois created. There are two parts of thescenario: the UAC and the UAS part.The UAC part of the scenario willgenerate calls against the applicationserver, retrieving the callee URIs fromthe external CSV file. The applicationwill either respond with the 404 responseto the UAC or proxy the request to theUAS. The UAS part of the scenario willrespond to the proxied INVITE message,according to the algorithms shown inFigure 12.

UAC

BEGIN SCENARIO

100

INVITE

ACK

BYE

404

200

ACK

END SCENARIO

INVITE

100 Trying

200 OK

ACK

BYE

200 OK

UAS

BEGIN SCENARIO

END SCENARIO

200

Figure 12. Algorithms of the UAC and the UAS partsof the scenario

user
Typewritten text
608
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

Table 1. Performance test results

Ela

ps

ed

tim

e

Ta

rge

t ra

te (

cp

s)

Ca

ll r

ate

(c

ps

)

Ca

ll l

en

gth

(s

)

00:30 2 1,97 59 59 0 0,118

01:00 3 2,97 89 89 0 0,042

01:30 4 3,97 119 119 0 0,076

02:00 5 4,97 149 146 0 0,105

02:30 6 5,97 179 175 3 0,253

03:00 7 6,97 209 186 20 0,628

03:30 8 7,97 239 209 28 0,587

04:00 9 8,97 269 218 46 0,972

04:30 10 9,97 299 247 58 1,056

05:00 11 10,97 329 307 26 0,352

05:30 12 11,97 359 326 24 0,416

06:00 13 11,93 358 308 60 0,946

Ou

tgo

ing

ca

lls

(c

all

s p

er

pe

rio

d)

Su

cc

es

sfu

l c

all

s

(ca

lls

pe

r p

eri

od

)

Fa

ile

d c

all

s(c

all

s p

er

pe

rio

d)

Performance tests were conductedagainst the application installed ona dual core AMD based 2.3 GHzdesktop machine with 2 GB of RAM. Itsresponses were measured using the SIPpwith the call rates starting from 2 callsper second (cps), and increasing by 1 cpsevery 30 seconds, up to 13 cps.

The results of the performance testsare presented in Table 1. The table showsthat the application could handle requestswithout the failed calls at the rates of upto 5 calls per second. After that rate thecall legth starts to increase which is a di-rect result of slow application servers re-sponses. As a consequence, the applica-tion cannot handle all requests sent by theUAC, hence failed calls appear.

The registrar and proxy applicationwe presented does not include theauthentication and other standardfeatures. But even in this simple form, itcan be utilized in real life where thesefeatures are not required, such as theVoIP systems in small or middle sizeorganizations.

7 CONCLUSION AND FUTUREWORK

In this paper, we have presented aninfrastructure that supports developmentof full featured converged Web andSIP applications entirely in Ruby. Theinfrastructure is based on an embeddedCipango SIP/HTTP Servlet ApplicationServer, a lightweight SIP/HTTP serverbased on the Jetty Web Server. We havepresented a simple demo applicationas an example on how to use thisinfrastructure. By adding handcraftedRails code, and redefining inheritedservlet methods of the MySipServletclass, we could extend our applicationfurther. For instance, we could easilyprovide a Web page where a user couldexamine the currently registered users,and start a voice communication, byclicking on the appropriate links.

The Ruby application shown inFigure 7 is flexible enough so that wecould use it to serve a different Railsapplication, without any modificationsof the code. Furthermore, by changingthe ’config.ru’ file loaded in line 36of Figure 7, we could incorporate aWeb interface developed with anotherRack-compatible Web framework, suchas the Sinatra.

Performance testing results show thateven a standard desktop machine is ca-pable of handling enough call rates to beaplicable for real life applications.

To handle the SIP signaling in JRuby,we relied on the Java SIP servlet API, asimplemented by the Cipango engine.This is adequate for a simple application.However, for the more complex SIP callflows, it would be beneficial to develop,on top of the described infrastructure, a

user
Typewritten text
609
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)

custom Ruby DSL for SIP handling. ThisDSL could provide the Ruby languagea flexible SIP service support similar tothe one the Rails framework providesfor Web services. This infrastructurecan be used as a good starting base fordevelopment of DSLs and other facilitiesfor VoIP application developmentutilizing the full potential of SIP ServletAPI and Ruby programming language.

REFERENCES

1. Tratt, L.: Dynamically Typed Lan-guages.Advances in Computers 77, 149–184(2009)

2. Paulson, L.D.: Developers Shift to Dynamic Pro-gramming Languages. Computer 40, 12–15 (2007)

3. Tate, B.: Beyond Java. OReilly Media (2005)4. Flanagan, D., Matsumoto, Y.: The Ruby Program-

ming Language. OReilly Media, 1 edn. (2008)5. Bachle, M., Kirchberg, P.: Ruby on Rails. IEEE

Software 24, 105–108 (2007)6. Mizerany, B.: Sinatra, http://www.sinatrarb.com7. Ghosh, D.: DSLs in Action. Manning Publications,

1 edn. (2010)8. Gunther, S.: Multi-DSL Applications with Ruby.

IEEE Software 27, 25–30 (2010)9. Rosenberg, J., Schulzrinne, H., Camarillo, G.,

Johnston, A., Peterson, J., Sparks, R., Handley,M., Schooler, E.: SIP: Session Initiation Pro-tocol. RFC 3261 (Proposed Standard), updatedby RFCs 3265, 3853, 4320, 4916, 5393, 5621,http://www.ietf.org/rfc/rfc3261.txt

10. Cosmadopoulos, Y., Kulkarni, M.: SIP Servletv1.1. JSR 289, http://jcp.org/en/jsr/detail?id=289

11. Ferry, D.: JAIN SLEE (JSLEE) v1.1. JSR 240(2008), http://jcp.org/en/jsr/detail?id=240

12. Hasanovic, A., Suljanovic, N., Mujcic, A., Sernec,R.: Dynamic Languages Integration Path for Tele-com Applications. In: The Fourth InternationalConference on Digital Telecommunications, pp.133–137, Colmar, France, (2009)

13. Cipango - SIP/HTTP Servlets Application Server,http://cipango.org

14. Nutter, C.O., Enebo, T., Sieger, N., Bini, O., Dees,I.: Using JRuby: Bringing Ruby to Java. PragmaticBookshelf, 1 edn. (2011)

15. TorqueBox, http://torquebox.org16. Rack: a Ruby Webserver Interface,

http://rack.rubyforge.org17. JBoss, http://jboss.org18. Broeglin, D.: Sipatra,

http://confluence.cipango.org/display/DOC/Sipatra19. Java Platform, Enterprise Edition (Java EE) Tech-

nical Documentation,http://download.oracle.com/javaee

20. Mobicents, http://www.mobicents.org21. Jetty - Servlet Engine and HTTP Server,

http://www.eclipse.org/jetty22. JRuby, http://jruby.org23. Viswanathan, V.: Rapid Web Application Develop-

ment: A Ruby on Rails Tutorial. IEEE Software25(6), 98–106 (2008)

24. Ruby on Rails Guides,http://guides.rubyonrails.org

25. Sieger, N.: JRuby-Rack,https://github.com/nicksieger/jruby-rack

26. Pjanic, E., Hasanovic, A., Suljanovic, N., Mujcic,A., Sernec, R.: Telecom Applications Based onDynamic Languages: Development and Perfor-mance Testing, In: Proceedings of the EighteenthInternational Electrotechnical and Computer Sci-ence Conference – ERK 2009, vol. A, pp. 180–183, Portoroz, Slovenia (2009)

27. SIPp, http://sipp.sourceforge.net

user
Typewritten text
610
user
Typewritten text
International Journal of Digital Information and Wireless Communications (IJDIWC) 1(3): 597-610 The Society of Digital Information and Wireless Communications, 2011(ISSN 2225-658X)