Sonntag, 24. Februar 2008

The third parts shows how to build a web based administration for the screening application. It is built using the Visual Web JavaServer Faces framework. It provides basic CRUD (Create, Read, Update, Delete) functionality for each of the entities in the database.

Database Contents

The database contains the following entities:

UserData:holds the user id, the name of the used screening profile, the reference to the provider data and the users's Sip Uri.

ProviderDataholds the system specific data, in our case the Sip Uri of the announcement to be played when a call is not allowed.

ScreeningProfileholds the screening data to be checked in blacklists and whitlelists. Each entry consists of a profile name, a blacklist/whitelist indicator and the Sip Uri to be checked itself.

Page Creation

The application consists of a main page which has links to the Users page, the Providers page and the Screening page. The application is modeled according to the tutorial "Modifying Database Table Rows with the Java Persistence API" in http://www.netbeans.org/kb/60/web/web-jpa-part2.html. Do the following steps to build the application:

Right click on the screening application in the project window and select "New-Visual Web JSF Page" for each page.

Right click on the screening application in the project window and select "New-Visual Web JSF Session Bean" once.

Drag and Drop the hyperlinks for users, providers and screening to the main page.

Add the code for three properties userDataList, providerDataList and screeningProfileList to SessionBean1 as well as the corresponding methods to fill this lists from the database (updateUserData(), updateProviderData() and updateScreeningProfile() ) and one helper method findProviderDataById(String providerId).

Page Layout, each entity page contains:

a static text field for the headline

a grid panel with id mainContainer

a table which is bound to the data in SessionBean1

a grid panel with id buttonPanel with 2 buttons, an add-update button and a delete button

a grid panel with name addUpdatePanel with one label and one text field or dropdown list for each field in the entity.

a hyperlink to go back to the main page

Page Flow, open the faces-config.xml file and in the graphical editor

Connect each of the hyperlinks on the main page with the corresponding entity page

Connect the backlink on the entity pages with the main page

Connect the buttons on each entity page with the entity page itself

Binding to Data

Right click the table and select "Table Layout", then select the corresponding list in "Get Data From".Set the id's of the table columns as [property name]Column and the table fields as [property name]Text.

Set the id's of the addUpdatePanel elements as [property name][field or list]

.For the dropdown list for providers in the Users page select it, right click and select "Bind to Data", then choose providerIdList.

For the dropdown list for screening profiles in the Users page select it, right click and select "Bind to Data", then choose screeningNameList

Handling Selection using an addtional radio button in each table row

Add the code for a TableSelectPhaseListener to the java bean for the page as shown in the example code

Add the javascript code for initAllRows() as shown in the example code. This code is specífic for each page because it also updates the addUpdatePanel fields when a table row is selected.

Right click the table and select "Table Layout", then "New" and select Radio Button from component type and click "Up" until the button is on the top of the column. Set the button's id to selectButton.

Select the radio button, right click in the navigator window and select "Property Bindings". Add the bindings for selected, selected value and name. For name enter manually"#{[page name]selectButton.id}". This binds the select button to the TableSelectPhaseListener object.

Select the selectColumn in the navigator window and set the bindings for selectId to"#{[page name]selectButton.id}" and the bindings for onClick to "setTimeout('initAllRows()', 0)".This performs the update of the table when a radio button is clicked.

Select the tableRowGroup in the navigator window and set the bindings for selected to the selectedState property.

Command Handlers

Add persistency to the page by right clicking in the source editor and then select"Persistence->Use Entity Manager".

Add the code for merge() and delete() as shown in the example code. You can delete the generated code for persist().

Doubleclick the "add-update" button and enter the java code as shown in the example code.

Doubleclick the "delete" button and enter the java code as shown in the example code.

Freitag, 8. Februar 2008

The following diagram show the structure of the screening application, the diagram is generated by the build process in the echarts/screening/ech/doc-files folder. From the initial state RECEIVE_INVITE either the state PLAY_ANNO is reached (if screening is applied) or the state CONNECT if screening is not applied. When the connection is successfully established the state TALKING becomes active which handles the call until finish.

Montag, 4. Februar 2008

In this example I will show how to build a simple screening application for Sailfin using the ECharts state machine language. The application checks the dialed number and either let the call proceed or plays an announcement to the caller that the call is forbidden. Each user is assigned a screening profile which contains his screening rules consisting of blacklisted numbers and exceptional whitelisted numbers. A call is forbidden if the dialed number is contained in the blacklist but not in the whitelist. A call is allowed if the dialed number is not contained in any list or in the whitelist only.What is EChartsAccording to the description on the ECharts website (http://echarts.org/) it is a state machine-based programming language for event-driven systems derived from the standardized UML stacharts language. ECharts is a hosted language which means that it is dependent on an underlying programming language such as Java.Benefits of ECharts

It provides a problem oriented language. State machines are a typical method to describe message processing applications and a language whose paradigm fits to the domain makes application development easier.

From an application developers point of view your application has to handle only a single call in contrast to the servlet programming model where you have to deal with all calls handled by the servlet in parallel. The session and dialog management is abstracted by the so called box model.

It allows to build reuseable parts by defining state machines which handle a certain task and can be inserted as a single state in an outer state machine. In the example I will show a Connect machine which builds up a connection to the called party, a Transparent machine which handles the talking state and a PlayAnnouncement machine which plays announcements to the caller.

If on order to use the documentation generator for state machines on Windows you need graphviz from http://www.graphviz.org/. For some strange reasons I had to directly set the path for the graphviz "dot" program in ech2javadoc to make it working.

In the sailfin application server set the following JVM options with the admin console on http://localhost:4848/ by "Application Server->JVM Settings->JVM Options->Add Option".-Dorg.echarts.servlet.sip.messagelog=true-Dorg.echarts.debugging=true-Dorg.echarts.servlet.sip.debugging=true-Dorg.echarts.servlet.sip.logdir=${com.sun.aas.instanceRoot}/echlogs-Dorg.echarts.system.transitionTimerManager.class=org.echarts.servlet.sip.TransitionTimerManager

The sources are available in cvs usingcvs -d:pserver:[your java.net account]@cvs.dev.java.net:/cvs co sailfin/sailfin-testsand then can be found then in community/samples/screening, or send an email to peter.c.klein@siemens.com to get them.

Add the entity classes for UserData, SceeningProfile and ProviderDataand copy their sources from the downloaded cvs sources.

Add the java class for ModelFacade as well as the java class for RegisterSipServlet and copy its sources from the downloaded cvs sources.

Add a java class FSMSupport which contains helper functions called by the state machines and copy its sources from the downloaded cvs sources.

Add antlr.jar, approuter.jar, echarts.jar and echarts-sipserlet.jar in the /lib folder to the projects libraries.

Create a new folder structure echarts/screening/ech in screening/src to hold the echarts sources and copy the *.ech files from the downloaded cvs sources. Add this folder in the project properties to sources.

Add to the build.xml file the properties and targets -pre-compile (for ech2java compilation) and -post-compile (for generating state machine documentation) as in the build.xml file in the downloaded sources.

Add the EChartsSipServlet and the RegisterSipServlet to the sip.xml as shown in the example code. Note that the state machines themselves are no servlets but are called from the EChartsSipServlet. Also add ModelFacade to web.xml

Compile and deploy the application.

Setup the data in the database as shown in the filldata.sql file in the"scenarios/tc-001-basic-ua" folder.

Depending on the dialed number and contents of the screening profile the call will either be connected to the called party or the party defined in the ProviderData.anno attribute.

I the next post I will show the web based admin and some insights how it works.

Notes

The web based admin is already included in the sources but in the moment only viewing works, modify and delete have to be added.

Open the visual web page editor for the created page. Then go to the "Services" tab, connect to the database and select the USERDATA table. Drag and drop it to the editor's canvas. You will see in the navigator window that a Data Provider object and a Row Set object were created.

Drag and drop a table on the canvas. Select the table, right click and select "Bind to Data". Choose the userdataDataProvider which was created before and click OK. The table is now able to display data for users.

Deploy the application and point your browser to localhost:8080/b2bua to view the contents of USERDATA.

Create and Delete

Add a button "Add User" and a button "Save Changes".

Doubleclick the "Add User" button and enter the action code from the sources.

Doubleclick the "Save Changes" button and enter the action code from the sources.

Select the table and open the layout editor. Add a new column and change the type of the column to "Button".

Doubleclick the "Delete" button and enter the action code from the sources.

Deploy the application again. You can now create and delete user data. The changes are stored in the database when you click "Save Changes".

In this part we will add a Sip Servlet for registration (handling the REGISTER message and storing the users contact information in the database) and a Sip Servlet which acts as a B2B User Agent transparently routing between A and B party.Create Servlets

Create a new class ModelFacade in the sip.model package. This class contains the methods UserData findUserDataById(String userId) and UserData updateUserData(UserData user) which are used by the Registration Servlet.

Create a RegisterSipServlet class and a B2BUASipServlet class with "New->Sip Servlet".

The code for both you can copy from provided sources.

In configuration files add the RegisterSipServlet and the B2BUASipServlet to sip.xml and the ModelFacade to web.xml.

Deploy the application.

Prerequisites for Testing

Get a softphone (e.g. X-Lite from http://www.counterpath.com/) and configure its settings (e.g. username to "Bob", domain to "test.com", proxy to localhost:5060).

If you are running the second softphone on the same machine you need a different model as second phone (e.g. 3CX VOIP phone from http://www.3cx.de/voip-telefon/index.html) and configure it for a second user (e.g. Alice)

Test the Application

Start both softphones, on X-Lite you should see "Ready, your username is Bob" on the display

Dial from A party as sip:user@siphost:port, e.g. sip:Alice@localhost:5057