Sunday Aug 30, 2009

Writing Facebook Applications with Java EE (part 2)

In the first part of this blog, I showed how to register your application with facebook, create a web application and deal with Facebook authentication. In this part, I will show how to write a simple application, that shows the user their own Facebook UID and a list of all their friends. Nothing earth shatteringly useful, because this is just introduce you to the mechanics of writing a simple application.

Step 5: Write the application

Our application user is now authenticated. We can begin to make FQL calls and read/publish information to facebook. Our little sample, will use FQL to know more about the logged in user and the friends list.We told facebook that our application will run as an iframe in Facebook chrome. All we have to do is return some well formed html. We will do the "Hello World" type functionality and also show how to use FQL queries to extract information on all of the user's friends.

We will create a helper class Friend to hold the details of each facebbok user.  Later, I will show how to make this an Entity and store the data periststently, rather than make expensive and slow queries to facebook, repeatedly. The data could get stale and that is another issue to deal with later. Facebook does not encourage data caching.

public class Friend {

    private Long id;
    private String name;
    private String picurl;
    private String phone;

    public Friend() {

    public Friend(Long id) { = id;

    public Friend(Long id, String name) { = id; = name;

    public Friend(Long id, String name, String pic) { = id; = name;
        this.picurl = pic;

   // getters and setters have been omitted for brevity


The authenticated Facebook client is now available as a request attribute. We simply extract it and use it to make Facebook API calls. A helper method auth_getUserId provided by FacebookJsonRestClient extracts the facebook id of the logged in user. We will use this to get information on the user and friends.

 public class Canvas extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            FacebookJsonRestClient fbc = (FacebookJsonRestClient) request.getAttribute("auth.client");

            PrintWriter out = response.getWriter();
            long myUid = 0; Friend me = null;
            try {
                myUid = fbc.auth_getUserId(request.getParameter("auth_token"));
                me = findFacebookName("" + myUid, fbc);
            } catch (FacebookException ex) {
                Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);

            ArrayList<Friend> myFriends = findFacebookFriends(fbc);

// TODO: later in the blog,  show how data is output

The method findFacebookName illustrates basic use of FQL that returns one result object. 

    private Friend findFacebookName(String fid, FacebookJsonRestClient fbc) {
        String name = null;
        String pic = null;
        try {
            String query = "SELECT name,pic FROM user WHERE uid=" + fid;
            org.json.JSONArray fa = null;
            fa = (org.json.JSONArray) fbc.fql_query(query);
            name = fa.getJSONObject(0).getString("name");
            pic = fa.getJSONObject(0).getString("pic");
        } catch (FacebookException ex) {
            Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JSONException ex) {
            Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
        return new Friend(new Long(fid), pic, name);

The method findFacebookFriends illustrates friends_get() that returns an array of Facebook Ids of all the user's friends. 

private ArrayList<Friend> findFacebookFriends(FacebookJsonRestClient fbc) {
        org.json.JSONArray resultArray = null;
        ArrayList friends = new ArrayList();
        try {
            resultArray = fbc.friends_get();
            for (int i = 0; i < resultArray.length(); i++) {
                try {
                    Long fid = resultArray.getLong(i);
                    String query = "SELECT name,pic FROM user WHERE uid=" + fid;
                    org.json.JSONArray fa = null;
                    try {
                        fa = (org.json.JSONArray) fbc.fql_query(query);
                        String pic = fa.getJSONObject(0).getString("pic");
                        String name = fa.getJSONObject(0).getString("name");
                        friends.add(new Friend(fid, name, pic));
                    } catch (FacebookException ex) {
                        Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
                } catch (JSONException ex) {
                    Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
        } catch (FacebookException ex) {
            Logger.getLogger(Canvas.class.getName()).log(Level.SEVERE, null, ex);
        return friends;

Spitting it all out

After getting all the data we need, it is time to output something that will be shown to the end user, as the output a HTML page is shown in an iframe.

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {

            // Data Extraction: See Above
            PrintWriter out = response.getWriter();
            out.println("Your Facebook Id:" + me.getId());

            out.println("Your friends:");
            Iterator it = myFriends.iterator();
            while (it.hasNext()) {
                Friend f = (Friend);
                out.println("<li>Friend Name" + f.getName() + "</li>");
        } catch (Throwable t) {
        } finally {


Deploy the web application to a Java EE server that is visible to the internet and is accessible at the Canvas callback URL you used when the application was registered at Facebook.

The sample application can be accessed directly specifying the Canvas Callback URL specified at registration (  or  It produces output as expected showing my Facebook Id and the names of all my friends. Real applications are of course, going to be a lot more interesting... This should get you, the Java EE developer, going..

Friday Aug 28, 2009

Facebook Applications on Glassfish (part 1)

During this summer, I explored writing Facebook applications using Java EE, something I have wanted to look into for a while, but never got around to. Facebook had stopped official support for it's Java API, in May 2008, which is not so nice to the millions of Java programmers out there. Fortunately, the API has since evolved as Facebook Java API.  It is very usable and there are many blogs and examples on how to get started. After looking at various posts, it was relatively simple to write a basic facebook application and make it run on Glassfish application server. I will share what I have learned along the way.

I used a recent NetBeans Dev build (NetBeans IDE Dev (Build 200908070201))  and GlassFish v2.1, but feel free to use an setup you are comfortable with. The steps should work the same way with Eclipse or GlassFish v3.

Step 1

I am assuming you are a Facebook user. Who isn't these days :-). If not, go sign up first.

The next task is to get yourself facebook developer privileges, which you do by "installing" facebook developer application. The developer application allows you to register your new application, provide some basic details to facebook on where it runs, generate an Application Identifier, API key and Secret Key etc. which identify your application to facebook users and to facebook platform.

To get started, click on Setup New Application at the top of the page. 

Provide a name for your sample, Agree to the Facebook Terms and Save Changes.

After Step 1, facebook assigns an API key that identifies your Application's requests and also a secret key that must be supplied with every request This is what you will see after you hit Save Changes above.

I have whited out the App Id, API Key and Secret code that I obtained. You will see long hex strings. You have taken the first big step already.  There is an application now registered.

Step 2

Now provide some essential information about where your application is hosted, the main canvas page etc. If you are not familiar already, your facebook application will not run on facebook's servers. You have to host it somewhere. You can use a Glassfish or Tomcat hosting provider or do it from home, which is what I do. I use to get a public domain name that points back to my home server or laptop. This is obviously not recommended if your application becomes wildly popular, but it is good enough for this sample!

In Step 2, we will provide some more crucial information about your application.The bits of information that we plan to provide are under Canvas and Connect.

On this page, we will make some important choices.

  1. Canvas Page URL: Choose the common name that you want for your application's users. I chose glassbook. When facebook receives a request for this URL, it will map it to your application.
  2. Canvas Callback URL: Provide the full URL path to where your facebook application will eventually be running. I am hosting my sample on a domain called  The domain is registered at, which offers free DNS services, with some limitations. Note the following:
    1. I used FacebookSample as the context root for my web application that will handle the application logic. You could choose anything you want for this. Just make sure to use the same context root when you develop the web application later.
    2. I declared that the receiver of facebook traffic is a servlet or JSP that is mapped to Canvas. You can use any name you want here and do the corresponding thing while developing the application.
  3. Use the defaults for all others. We will not use FBML in this sample.

 Now, click on Connect on the  left hand panel and supply the same path we provided for Canvas call back URL.

Thats it! You have registered an application. Now all that is left is to write it!

Step 3

Now we will develop the web application, called FacebookSample. In NetBeans, create a new project, called FacebookSample.

Note how I used the context root: FacebookSample

Then I created a servlet called Canvas:

And a ServletFilter called FacebokAuthFilter

 At the point, in NetBeans there should be two source files in the project structure.

You already know that we intend to put the application logic in servlet class.We have not filled in anything there yet. We will return to it soon.

Before we start writing code, need to add some Facebook Java API jar files to your web application. In NetBeans, you can do this by right clicking on the FacebookSample application, choosing Properties and then Libraries. You must add the following 3 jar files:

  1. commons-logging-1.1.1.jar
  2. facebook-java-api-2.1.1.jar
  3. json-20070829.jar

All of these are in the facebook Java API bundle you downloaded at the top of the tutorial.

Macintosh-202:lib Sreeram$ pwd
dhcp-usca14-133-138:lib Sreeram$ ls -l 
total 3568
-rw-r--r--  1 Sreeram  Sreeram   62983 Dec 31  2007 activation-1.1.jar
-rw-r--r--  1 Sreeram  Sreeram  243016 Jan 15  2009 commons-lang-2.2.jar
-rw-r--r--  1 Sreeram  Sreeram   60686 Sep 20  2008 commons-logging-1.1.1.jar
-rw-r--r--  1 Sreeram  Sreeram  137560 May  1 08:26 facebook-java-api-2.1.1.jar
-rw-r--r--  1 Sreeram  Sreeram  278382 May  1 08:25 facebook-java-api-schema-2.1.1.jar
-rw-r--r--  1 Sreeram  Sreeram   89967 Sep 27  2008 jaxb-api-2.1.jar
-rw-r--r--  1 Sreeram  Sreeram  856752 Nov 24  2008 jaxb-impl-2.1.9.jar
-rw-r--r--  1 Sreeram  Sreeram   41829 Dec 31  2007 json-20070829.jar
-rw-r--r--  1 Sreeram  Sreeram   15949 Jan 15  2009 runtime-
-rw-r--r--  1 Sreeram  Sreeram   23346 Sep 27  2008 stax-api-1.0-2.jar

Now we are ready to start coding, but there is one other topic I need to introduce: why do we need That is the topic of the next section.

Step 4: Facebook Authentication

Only registered Facebook users can access your application. We need to authenticate users and force login if necessary. Login is handled by Facebook. Our application will make calls to Facebook APIs in the context of authenticated user.

Our application, may sometimes need permissions to do some things, such as read and publish to a stream. We need to request the user to grant such permissions.

We will use a Servlet Filter for check whether the user is logged in and request necessary permissions. 

Now lets dissect

     \* Init method for this filter
    public void init(FilterConfig filterConfig) {
        this.filterConfig = filterConfig;
        if (this.filterConfig != null) {
            _apiKey = filterConfig.getInitParameter("api_key");
            _secretKey = filterConfig.getInitParameter("secret_key");
            if (debug) {
                log("FaceBookAuthFilter:Initializing filter");

You need to supply the API Key and Secret Key received from facebook in the web.xml, so the Servlet Filter can use then in its requests redirected to facebook. This is what your web.xml would look like. Plugin the API key and Secret code you got from Facebook.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="" xmlns:xsi="" xsi:schemaLocation="">
            <param-value>Your API Key Here</param-value>
            <param-value>Your Secret Key Here</param-value>

Back to the Filter

     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        try {
            FacebookJsonRestClient authClient = getAuthenticatedClient((HttpServletRequest) request,_apiKey, _secretKey);
            request.setAttribute("auth.client", authClient);
            filterConfig.getServletContext().setAttribute("fbc", request.getAttribute("auth.client"));
            chain.doFilter(request, response);
        } catch (FailedLoginException fle) {
            //user not logged in
            request.setAttribute("auth.client", null);
            forceLogin((HttpServletResponse) response);
        } catch (Exception e) {
            //handle exception

We first try to create a FacebookJsonRestClient object. This logic is encapsulated in the getAuthenticatedClient method. We will check the incoming request for the presence of two request parameters: auth_token and session_key. If a session key is present and is valid, the client object is instantiated. If only an auth_token is present, a client is instantiated and a new session created. The facebook session lasts about an hour. Infinite sessions are a different beast and one needs to request the user to grant offline access privileges. I have not played with it yet.

private FacebookJsonRestClient getAuthenticatedClient(HttpServletRequest request, String apiKey, String secretKey) throws FailedLoginException, FacebookException {
        String authToken = request.getParameter("auth_token");
        String sessionKey = request.getParameter(FacebookParam.SESSION_KEY.toString());
        FacebookJsonRestClient fbClient = null;
        if (sessionKey != null) {
            fbClient = new FacebookJsonRestClient(apiKey, secretKey, sessionKey);
        } else if (authToken != null) {
            fbClient = new FacebookJsonRestClient(apiKey, secretKey);
            //establish session
        } else {
            throw new FailedLoginException("Session key not found");
        return fbClient;

If there is no valid session established for the user, a FailedLoginException is thrown and we call forceLogin to cplete the Login process.  Otherwise, the client is objected is inserted into the request attributes for later retrieval.

     private void forceLogin(HttpServletResponse response) {
        try {
            String redirect = "" + "api_key=" + _apiKey + "&connect_display=popup" + "&v=1.0" + "&next=" + "&cancel_url=" + "&fbconnect=true" + "&return_session=true"
        } catch (Exception ioe) {
            //handle exception

I used next= to point to my test program. You will need to change the  next parameter to point to your application canvas URL.

 In the next part, I will walk through the rest of the application, the part that implements the canvas. Won't be long.

Monday Jul 13, 2009

Support for Cloud images of SailFin

If you are looking for support for SailFin AMI, I am told there are currently two issues:

  1. This AMI was packaged with OpenSolaris Just Enough OS (jeOS) and they say it is not supported yet on EC2. I know it has been in use for a while, so they may be close to offering support. I do not know.
  2. The SailFin build is v2b20. The supported release is 1.5

This should not stop you doing a Beta using this AMI.

The PM wants to know which platforms there is demand on. So post a comment or two to let him know what you are looking for.

Thursday Jul 09, 2009

Sailfin in the Amazon EC2 Cloud

Getting Started with SailFin on Amazon EC2

A few SailFin users have inquired about SailFin hosting. I run one out of my garage. It is free but sorry I do not have the additional capacity :-) I had also rented a dedicated server at GoDaddy ($80/mo) to host our demo server. So far it has worked out well and it is quite a reasonable option. There may be other hosting providers there, we do not know about. Do let us know, if you run into anyone.

Sun ISV Engineering guys stepped up to create a rentable ready-to-go Sailfin AMI for Amazon EC2. This is easier to use because it has SailFin and MySQL pre-installed and pre-configured as services. So when the image comes up, you have a running server. All it needs is your service/application. The downside of any cloud image is that everytime you bring it up, it forgets what was configured. So you will have to write some scripts that start up the image and then deploy your application etc. Not a big deal. I will get you started in a moment...

It is always good to know where additional help is, in case you need it. For me, Getting Started document for EC2 & OpenSolaris [1], was all that was needed. I will condense the steps provided there and add some specific details for using SailFin.

  • First, get yourself an account on Amazon EC2, if you have not already done it. EC2 is not free, nor is it super cheap. Be prepared to supply a credit card number for billing. It appears to be reliable. I have not done any performance testing yet.
  • After you sign up you will get a Private Key and a Certificate. You need to save them as separate files with the .pem extension. The location of these two files needs to be set in the environment for the EC2 command line tools to work.
  • The AMI/API command line tools can be downloaded from the following locations:
    After completing the downloads, follow the instructions in the Amazon Getting Started Guide for setting up the tools to make it available or usable. The guide is available from: You will see how to download and configure the EC2 CLI tools in the the early sections of [1].  Here is what I have in my setup:
export EC2_HOME


export EC2_CERT

export EC2_URL

Just how does one fire up an AMI instance?

The AMI  is called: ami-9df312f4. It is SailFin v2, build 20, which has recent bug fixes. This AMI is provisioned with OpenSolaris, SailFin and MySQL all pre-configured.  When you start the AMI, SailFin and MySQL should both have started up as well and ready to use. I suspect when you have your own application on top of it, you will want to automate the deployment of your application also. 

ElasticFox is a very efficient graphical interface for EC2. When beginning, lets use the command line interface, so you get the hang of what is going under the hood. All the commands are in ${EC2_HOME}/bin directory.

  • First, generate a keypair:
ec2-add-keypair mykeypair

This will produce output which you must copy and paste into a file called mykeypair. Save everything between (and including) the "-----BEGIN RSA PRIVATE KEY-----" and "-----END RSA PRIVATE KEY-----" lines. You can generate as many keypairs as you want. You may want to keep one for sailfin usage.

chmod +x mykeypair 

  • Now start up the SailFin 2.0b20 AMI, for example:
ec2-run-instances ami-9df312f4 -k mykeypair
The output should be something like this:

RESERVATION    r-c73171ae    609350199924    default
INSTANCE    i-dfa197b6    ami-9df312f4            pending    mykeypair    0        m1.small    2009-07-09T22:00:03+0000    us-east-1d    aki-6552b60c    ari-6452b60d        monitoring-disabled

  • It does take a while for the instance to fire up. Check status with the instance id reported above:
ec2-describe-instances | grep i-dfa197b6

INSTANCE    i-dfa197b6    ami-9df312f4            pending    mykeypair    0        m1.small    2009-07-09T22:00:03+0000    us-east-1d    aki-6552b60c    ari-6452b60d        monitoring-disabled

Eventually (5 minutes or less) it will enter running state and is usable. You will then see a public DNS address for the active instance:

INSTANCE    i-dfa197b6    ami-9df312f4    ip-10-244-15-112.ec2.internal    running    mykeypair    m1.small    2009-07-09T22:00:03+0000    us-east-1d    aki-6552b60c    ari-6452b60d        monitoring-disabled

You can see the DNS name of the instance in the command output, in this case: Also note the instance identfier, in this case i-dfa197b6.

Opening Ports

The typical SailFin server needs to open some critical ports for traffic and administration. You can authorize ports explicitly. This profile definition is persistent. Here we use the default security profile.

    • ec2-authorize default -p 22 (opens up SSH port. Otherwise, ssh command above would not work)
    • ec2-authorize default -p 8080 (HTTP traffic)
    • ec2-authorize default -p 4848 (Admin Server Port)
    • ec2-authorize default -p 5060 (SIP Traffic).

    • To allow UDP SIP traffic, ec2-authorize default -p 5060 --protocol udp

Explore the running image

To login, you could use the DNS name of the instance in configuring the SIP phones. I used DynDNS service to point a domain to this Amzon instance. The IP address of the instance is encoded in the DNS name. For example,  the external IP Address of is

You can ssh to our instance. Use the DNS name that was reported by ec2-describe-instances (above)

ssh -i mykeypair -l root

Macintosh-202:ec2-api-tools-1.3-36506 Sreeram$ ssh -i mykeypair -l root
The authenticity of host ' (' can't be established.
RSA key fingerprint is 15:3a:03:d1:b9:3e:2d:37:7f:77:41:05:a2:1e:9a:d6.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ',' (RSA) to the list of known hosts.
Last login: Thu Jul  9 22:47:48 2009 from sca-ea-fw-1.sun

Sun Microsystems Inc.   SunOS 5.11      snv_101b        November 2008

Welcome to an OpenSolaris on Amazon EC2 instance

Use of this OpenSolaris instance is subject to the license terms found at and in /etc/notices/LICENSE.

Users are advised to protect their MySQL database by following guidelines
mentioned within MySQL 5.1 database documentation

Additional software packages from the OpenSolaris Package Repository are
governed by the licenses provided in the individual software packages which can
be viewed using the package manager graphical user interface.

OpenSolaris 2008.11 AMI contains temporary fix for bug id #6787193 and
For details refer to

For important security information, and image usage instructions please review
the files in /root/ec2sun.

For latest updates and late breaking information, please visit the OpenSolaris
on EC2 blog at

Register at to receive latest
news on OpenSolaris AMIs

For technical questions:
You have new mail.
root@ip-10-244-159-143:~# ls
root@ip-10-244-159-143:~# cd ec2sun
root@ip-10-244-159-143:~/ec2sun# ls
DTrace.README  README  mysql.README  sailfin.README  sysbench.README

Be sure to look at the README files once before you start using the instance. You should see an instance of MySQL and SailFin already running. To check the status you can use:
root@ip-10-244-159-143:~/ec2sun# svcs -a | grep -i mysql
online         22:41:31 svc:/application/mysql:default
root@ip-10-244-159-143:~/ec2sun# svcs -a | grep -i domain1
online         22:42:33 svc:/application/SUNWappserver/domain1:default

You can also point your browser to the administration server: http://<DNS-address>:4848 

For your convenience, as database connection pool and JDBC resource has been configured in SailFin. You can see it by going down to explore JDBC Resources in the Admnin console. Ping the Connection pool named mysql and it should be succesful. Now run your usual asadmin scripts that deploy the service to the SailFin.

Stopping the Instance 

    You can terminate the instance as follows:

    ec2-terminate-instances i-<something>

    Using ElasticFox

    ElasticFox and SailFin

    ElasticFox is a a free FireFox plugin that simplifies dealing with the EC2 cloud. You can search for images, start them up, configure and do most of the management. Download details for ElasticFox are at AWS website. Documentation is great, and you will figure it out quite easily.

    Thursday Feb 12, 2009

    Designing scalable, reliable, and efficient systems

    Designing Scalable, reliable and efficient systems is the goal of systems engineering. We see that in the way Google scales their services to billions or the Amazon cloud. But before the internet big boys, this used to be the sole domain of the telecom guys. Well, it still is their domain because there are nearly 4 billion cell phones and god knows how many landline phones in operation. Switches that set up all these calls are quite hard to build.

    Today, Andreas Burmester sent a link to a paper that appeared in Ericsson Review. It describes how they built a full system for delivering continuous services using only open source components. Notable how they depend on Java EE and GlassFish Communications Server in the middleware tier. They used Open SAF and Linux clustering at the lower levels.

    Tuesday Dec 23, 2008

    Introducing GlassFish Communications Server

    This is the big blog that goes over what is Project SailFin.  I hope it is an interesting read and I hope to receive your comments.


    Convergence at happening at various levels in communication industry. Carriers seek to consolidate fixed and mobile services. There is operator consolidation due to acquisitions. When two operators merge, they need to rapidly combine subscriber databases, CRM and billing systems, to reap the cost savings benefits. So carriers find that moving to a standards-based network and software infrastructure is good for them. It allows them to be agile and and keep costs low. Increasingly you hear about a Services Delivery platform (SDP), one universal platform for network facing functions, operating consumer portals, running CRM applications, integration with OSS/BSS and even service exposure through gateways. We wanted to drive GlassFish adoption in this challenging segment: if it is good enough for carriers, it is more than good enough for enterprises.  Project SailFin started with this vision in June 2007. There is a lot of magic that goes into delivering reliable digital television and home phone services, besides an application server, however good and extensive it may be. Carriers and Network Equipment Providers are good at building SDPs.We just want to be a part of it with GlassFish.

    Services Delivery platforms are mission critical. Lets face it, software bugs and hardware failures are unavoidable. So the game was about detecting failures, rapid recovery, and keeping downtime to a minimum. Clusters need to expand and shrink with demand fluctuations. Upgrades need to be performed without downtime. A lot of the work that happened this past year went into integrating a JSR289 compliant SIP Servlets Container in GlassFish, adding a converged load balancer and session data replication system. Well, we are done and about ready to make it generally available. The official name is GlassFish Communications Server (GlassFish CS), because it is based on GlassFish Enterprise. We may also use the nickname SailFin to refer to the same thing.

    GlassFish CS is an open-source applications server that supports Java EE 5 specification and SIP Servlets 1.1 API (figure 1). It is based on the GlassFish v2.1 and so it inherits much of the core architecture and administrative infrastructure. Onecan deploy Java EE Applications, pure SIP applications and converged applications that mix all of the above. In addition, SailFin includes a novel built-in converged load balancer, support for session data high availability, support for integration in SAF API based deployments, choice of Application Routers and IMS/Diameter support in future release. Since GlassFish Communications Server is built on GlassFish Enterprise Server v2.1, it puts fresh and powerful technology in the hands of developers for creating next generation services. Developers can mix SIP Servlets technology with technologies like EJB, Java Persistence API, JDBC, Web services, and reuse container services like JNDI, JMS, Dependency Injection, Security, Transaction management.

    Sailfin sub systems
    Figure 1 GlassFish: An Integrated Execution Platform for Converged SOA, SIP, and Java EE Services

    SIP Protocol Stack and SIP Servlets

    GlassFish CS integrates a high-performance SIP protocol stack implemented using Grizzly. Incoming requests pass through a chain of handlers that perform specific functions. For example, the Overload Handler, if enabled, would send an appropriate error response, if the server is overloaded. The optional load balancer, if enabled, would apply the specified sticky load balancing logic and forward the request to the appropriate instance in the cluster, or pass it up the stack. Initial requests are matched with deployed applications and appropriately routed. Optionally, the default or user deployed Application Router is consulted to make the initial routing decisions. Many SIP listeners can be configured to accept TCP and or UDP traffic on multiple network interfaces. SIP over TLS is supported.

    Figure 2: Sip Protocol and Request Processing Stack in GlassFish

    Web Services

    Network Services like dialing, SMS and service enablers like location are often exposed to developers using web services gateways. Web Services are mechanism to mash-up services from simpler building blocks. SailFin includes Metro Web Services stack. Metro implements important WS-\* standards and WS-I standardized interoperability profiles in order to assure interoperability between Java and .NET web services. Metro web services is a popular stack reused by many and well tuned for performance. It is likely to be of great interest to Carriers who are looking to build service gateways.

    Figure 3: Metro Web Services Stack in GlassFish

    JBI and Open ESB Support

    GlassFish has built-in support for Open ESB, by including the implementation of Java Business Integration (JBI) specifications. JBI as specified in JSR 208. This is a Java standard for structuring business systems according to a service-oriented architecture (SOA). In JBI approach to SOA, a composite application is assembled from distinct services, where each service performs one or more business-related processes. JBI gives an enterprise a lot of agility in building composite applications because services and data that are used in one application can be shared and reused in other applications.

    Open ESB runtime hosts a set of pluggable component containers, which integrate various types of IT assets. These pluggable component containers are interconnected with a fast, reliable, in-memory messaging bus called the Normalized Message Router (NMR) also referred to as the JBI Bus. Service containers adapt IT assets to a standard services model, based on XML message exchange using standardized message exchange patterns (MEP) based on abstract WSDL. This improves interoperability and allows a mix-and-match of technologies from various vendors. When sending and receiving messages outside the JBI environment, the engine component containers communicate using the in-memory NMR messaging infrastructure and pass messages out to the client through an appropriate binding component container. When communication is entirely within the JBI environment, no protocol conversion, message serialization, or message normalization is necessary because all messages are already normalized and are in standard abstract WSDL format. JBI standardizes the way composite applications are packaged.

    GlassFish is Open ESB ready, because it contains the Normalized Message Router and a Java EE Service Engine that is used to expose any EJB or Web Service End Points on the JBI bus, optionally. With this basic infrastructure SGCS instance can host service engine and binding components for any protocol, participate in workflows and integrate with billing, provisioning or network element management systems.

    Management and Monitoring 

    GlassFish management framework allows an administrator to configure and monitor instances and clusters securely and remotely, from a web-based central administration console. Administration in a carrier deployment environment can be automated in many ways. The command line interface (CLI) can be used to script and automate processes. A stable JMX API is made available to programmatically monitor the server, query configuration and change configuration data.

    Figure 4: Centralized Administration

    GlassFish administration infrastructure, based on Domain Administration Server (DAS) and Node Agent (NA) is carried over. DAS performs aggregate actions such as starting and stopping clusters and instances, propagating configuration changes and distributing deployed applications, to affected instances. DAS also manages the central repository where all deployed applications, libraries and configuration data is stored. The repository can be automatically backed up and restored, to revert to a previous configuration after failure. The DAS is not necessary to be up and running for normal operation of services in a domain. Node Agents assist the DAS in managing the lifecycle of instances and watchdog restart service for instances. Communication between the DAS, NA and instances is always secure.

    Monitoring is supported through JMX and SNMP interfaces. Monitoring level may be varied dynamically from OFF to LOW and high, changing the amount of information that is collected. Monitoring level can be controlled at fine-grained level to watch only the desired sub-systems making it suitable for production deployments where performance degradation of running services is not desirable. Similar to monitoring, logging can also be enabled and disabled dynamically for any sub-system, log verbosity level controlled and log files automatically rotated for field serviceability. Additional log filters can be installed on the field for customization.

    Administration Web console is commonly used to administer and monitor GlassFish Communication Server. The web console provides an intuitive interface to navigate the complex configuration elements and wizards for completing common tasks like deploying applications, creating clusters and configuring high-availability and load balancer.

    Figure 5: GlassFish Web Administration Console

    GlassfIsh provides a Self Management Framework. System administrators, responsible for monitoring the application server for unpredictable conditions and apply corrective actions, no longer have to watch for these conditions manually. This feature enables prevention of failures by detecting emerging problems rapidly and preemptively addressing them, thus improving availability through self-healing. A self-management rule is an association between an event and actions. Events and Actions are performed by MBeans. Rules can be created to act on pre-defined events or new event types. Some pre-defined event sources are:

    •    Lifecycle events: Event is generated when an instance is ready, shutdown or abruptly down
    •    Monitor event: Monitor any statistic and generate an event when a threshold is crossed
    •    Log events: When a log message is produced at a certain level from a specified logger
    •    Trace events: configured to emit an event when a specified EJB or Servlet is entered/exited
    •    Timer events: used to perform actions at pre-determined times
    •    Notification events: Generic JMX notification event

    Carrier Grade Service Execution

    In this section, we will look at how SailFin provides high quality and continuous service. High availability requires that:

    •    System operates at the desired latency levels even when above the engineered capacity
    •    System throughput is steady and is stable under increased loads 
    •    Hardware and software failures are tolerated
    •    Service failover is reliable, fast and invisible to the clients
    •    Client’s application state is persisted across recovery
    •    System and services are designed to scale horizontally
    •    Adding/Removing capacity to/from the platform should not affect running services and clients
    •    Spread the load evenly based on simple and configurable criteria
    •    Configuration must be allowed to change dynamically without needing restarts
    •    Detect and correctly handle load spikes and overloaded resource conditions

    GlassFish Communication Server is designed to provide carrier grade service execution environment for web and converged SIP applications.

    Active and Fully Replicated Services

    Java EE and SIP Container services are replicated in every instance in a cluster. Each server instance has a local JNDI service that is kept synchronized with global namespace maintained on the Domain Administration Server, local Java Message Service, Transaction Manager, Timer Service and so on. There are no specially designated instances that perform special functions. This eliminates all single points of failure. Since services are available locally in every instance, default service invocation is local and optimized to be fast. Services scale naturally as more instances and capacity is added.

    GlassFish uses Active/Active approach to high availability. All deployed applications are available at every instance in the cluster and the load balancer can send request to any of them. There is no need to configure an active primary and standby secondary. All servers actively handle traffic. There is no need to configure passive stand-by servers for the uncommon failure scenario. Hardware investment is efficiently utilized.

    Cluster health is actively monitored by a heartbeat service that detects when an instance goes down and triggers appropriate recovery actions from neighboring instances. For example, when a server crashes, in-flight distributed transactions are arranged for automatic recovery by another instance, to prevent database row locking from freezing the application for other users.  If the failed instance tries to come up during the recovery, it is paused until recovery is completed and then allowed to join the cluster and process traffic.

    Performance: Low Latency and Consistent Throughput

    Using the SipInviteProxy performance test with immediate call tear down (Call Length is 0 seconds), GlassFish Communications Server is benchmarked at 900 CPS on a dual processor 2-core (2.8GHz AMD) system using SuSE Linux and Sun JDK 1.5u12. Average latency is 13.67ms. 99.86% percent of calls complete in under 120ms in this stress load. Since this is based on GlassFish, all other containers are also well tuned for performance. GlassFish was used to publish very impressive SPECjAppServer2004 benchmarks scores.

    Overload Protection

    SIP is an asynchronous Peer-to-Peer protocol. SIP requests are retransmitted, if responses are not received in time. When a server falls behind in handling traffic, retransmissions are inevitable. This can lead to snowball effect of increasing traffic, spiraling degradation in quality of service and even total service failure. GlassFish Communication Server employs Overload Protection features that constantly monitor the system CPU utilization and Java Heap memory utilization to trigger traffic throttling logic. New incoming requests are replied with 503 Service Unavailable responses, until the system returns to operating in safe and sustainable condition. Clients may choose to try another server or try again after some time. Existing clients and traffic is ensured with consistent service levels.

    Converged Load Balancing

    Communications service delivery platforms run on horizontally scaled blade servers. It is important to distribute traffic uniformly across all the blades. It is more efficient to route the subsequent messages to the same target server where the session state is cached in memory. In converged collaborative applications, one or more users may interact with the same service and use different protocols like SIP and HTTP concurrently. Converged Load Balancing refers to a unique feature in GlassFish Communications Server that recognizes if the incoming SIP and HTTP messages belong to the same executing application session instance and route them coherently to the same target server.

    Converged Load Balancing (CLB) function can be enabled in any GlassFish cluster. When enabled for self-load balancing function, each instance can act as a load balancer in addition to handling traffic.Customers save money because they can use a simple L3 load balancer and do not need the more expensive SIP capable load balancers from third parties.

    Figure 6: Horizontal Scaling with Converged Load Balancer

    It is possible to use GlassFish clusters without self-load balancing and use an external SIP aware hardware load balancer. When load-balancing logic is done inside the server instance, a simple L3 load balancer will suffice to distribute incoming packets to any instance in server.

    The default CLB policy performs sticky round robin load balancing on SIP and HTTP traffic. Since many SIP clients and proxies may not preserve all headers, no additional SIP headers are added. The load balancing decision consumes SIP from-tag, to-tag, and call-id parameters of the request. HTTP requests are load balanced using the session identifier, in this mode.

    As additional hardware capacity is added to the cluster it is important that the benefit is made immediately visible to all clients, both old and new. CLB monitors cluster size increase and incorporates them into the load-balancing table. Requests that are not already sticky to target servers are directed to the new server instances. Server capacity can also be reduced and user sessions and requests are migrated to remaining load processing servers. The dynamic clustering capability enables planned downtime and service upgrades without disrupting the entire service. Blades can be brought down one by one, for maintenance and restarted to resume function. This functionality is based on applying a consistent hashing scheme to configurable headers or parts of incoming requests.

    Data Centric Rules

    The default SIP and HTTP load balancing policies suitable for many scenarios and provide sticky load distribution. However, in many IMS scenarios it may be necessary to look inside different SIP headers and URL fields or even translate URI domains. HTTP load balancing may need to consult custom cookies and headers. GlassFish Communications Server provides a facility for the administrator to customize the load balancing to be based on data embedded in SIP and HTTP messages. The consistent-hash algorithm is applied to these administrator specified filed. For example, pne may specify SIP and HTTP rules as: if a Conference-Name header is available in a SIP message load balancing is performed on that, otherwise use the user part of the From: SIP header. For HTTP requests, look for a parameter called Conference-Name in the request or use the Host: header.

                               <header name="Conference-Name"

                          <else return="" />

                            <request-uri parameter="ConferenceName" 

                          <else return="request.Host"/>

    Session Data Availability

    While CLB assures service availability, even load distribution, fail over of requests and fail back. But the data associated with user sessions must be restored after a failure. GlassFish employs a Peer-To-Peer in-memory replication system to save critical container and user interaction state and ensure data availability. All active SIP dialogs have container state: dialog state represented as Dialog Fragments, Session object(s) comprising of SipSession, SipApplicationSession and HttpSession, and associated timers. Modified state objects are replicated to a peer, at the end of every SIP transaction or after a web request is completed. Just like the CLB, the replication management sub-system also runs inside the GlassFish server instance. It is responsible for making replicas and saving them to its replica peer, and acting as a replicating peer to another instance in the cluster. It is also responsible for delivering requested replicas acquiring replicas, during fail over and cluster healing.  

    Figure 7: Session Data Replication in GlassFish

    The diagram above shows a healthy four-instance GlassFish cluster running is highly available mode with CLB and session data replication enabled. For illustration, we show two SIP user agents and a HTTP browser interacting with the converged service. The CLB has directed this traffic collectively to Instance 4. The state for the interaction consists of one SipApplicationSession, two SipSession objects, one HttpSession object and possibly many SipTimer objects. These objects are transparently replicated to the peer, Instance 1.

    When a failure occurs and Instance 4 does down, the CLB performs request rerouting. For illustration lets assume that this group of requests are now sent to Instance 3. This instance does not have the necessary session data and when the request is received that touches this data, a query is sent to locate the replica. Instance 1 responds to this query and delivers the network of dialog state and session data to Instance 3. The session data ownership is now migrated to Instance 3 and it will maintain replicas on its replication partner. When instances leave or enter the cluster, replication relations are recalculated to always ensure that there is always one replica available in the cluster.

    2008 is over and SailFin is getting ready to leave the station

    My last post was exulting about JSR289 passing the vote way back in July. We have been moving along since then. I thought SailFin would be the first to pass the JSR289 compatibility tests. But Oracle made sure that they already passed the TCK by the time it was made public! And then we found that there were issues in the TCK that needed discussion with the Spec lead. Thanks to Mihir, we got past all of that and had a clean run in November.

    The economic turmoil and U.S presidential election have taken their share of headline news. It has been a less sensational and productive year for SailFin community. Some major accomplishments:

    • Community membership crossed 200, with over 45 with developer status.
    • Found early adopters through the community. Great interest seen from companies building unified communications solutions and conferencing systems for enterprises and SMBs.
    • Ericsson has been a tremendous partner all along. Ericsson Service Development Studio 4.1 is an Eclipse based IDE that includes SailFin by default.
    • IPTV live field trials with GlassFish and SailFin with Sonaecom in Portugal. I am told some more such things are in progress.
    The GA release of SailFin is planned January 2009. As we approach this big date, there will be many more informative blog entries on the performance, unique features, and the team behind SailFin.

    Thursday Jul 24, 2008

    JSR-289 passes JCP Exec Committe Vote

    The JCP Executive Committee has approved the JSR 289 Final Approval Ballot. Congratulations to the EG and Spec Leads! We had many along way, so it is good to name them all. Nasir Khan, Jarek Wilkiewicz, Mihir Kulkarni and Yannis. JSR-289 standardizes the converged SIP Servlets and Java EE application model which is a great step forward and keeps up the momentum. We just got a TCK preview. Hope to get the final version of TCK soon. Look for more news on SailFin release dates with JSR-289 compatibility, high availability and everything else we are working on.

    Monday May 21, 2007

    Adding Voice to Java Web Applications - Samples

    We just posted our slides for the Java One talk (TS-4919: Adding Telephony to Enterprise Java Applications) on sailfin website. During the talk we described two samples. A simple Click-To-Dial applications that lets two logged in users have a conversation and a full-blown multi-uaser collaboration application Conference Manager with live voice mixing. The source code for the latter is coming soon. Enjoy the Click-To-Dial sample and let us know how it works for you.

    Tuesday May 08, 2007

    Project SailFin launches in GlassFish Community


    After last JavaOne I started looking at a completely different area, Java and Communications. After tinkering to see how I could add voice to a Java EE web application, it seemed like there was no easy and portable way to do this. I looked around to see what was already there and was close enough to Java EE, and could be accepted by enterprise developers. The answer seemed to be SIP Servlets. Sun joined the JSR-289 expert group and focused on the proposed application model that combines SIP and Java EE. JSR-289 is in Early Draft Review stage. Take a look and get involved.

    We were also lucky to find a great partner in Ericsson. By the end of the 2006, we had Ericsson's SIP Application Server running alongside GlassFish. We were able to inject Java EE services like EntityManager inside Sip Servlets and initiate calls from inside web applications. One thing led to another and here we are at another JavaOne! SailFin is live today as the first open source SIP Servlets technology project, in the GlassFish Community. Visit us to see the sources and build instructions.

    We sent around an evaluation kit inside Sun and the people at Sun Labs built an amazing fully Java EE and JSR-289 based Conferencing application on top of SailFin. Jonathan Kaplan from the Labs and I have a talk about this on Thursday (TS-4919: Adding Telephony to Java Technology Based Enterprise Applications, 4:10-5:10pm, Hall E, Rm 134). Also visit us at the Pod (# 968) to see the demo.

    An intersting tidbit: The Surfing Duke image on SailFin project web page was designed by James Gosling. Thanks James.

    Friday Jun 30, 2006

    JavaOne 2006 Technical Sessions are now online

    What? You could not attend JavaOne in person? Do not despair. All the JavaOne 2006 Technical Sessions are online now for those who missed the live action.

    They have done a fantastic job this year and very quickly too. Thanks to Annette Vernon and Ralph Crawford (the amazing duo behind JavaOne content planning at Sun

    ) All you need is a Sun Developer Network Login account, which is free. Look for Join SDN link at the top.

    The audience feedbacks also came back very quickly this year. We in the Program Committee were very gratified to see the quality ratings climb significantly this year, from last year. Both Core Enterprise and Web Tier crossed the 4.0 average. Since both cover a lot of terrain, crossing the 4.0 quality average barrier was very signficant. The Top 20 awards should be out there soon...

    For us folks at Sun, the conference was largely about expanding focus on Project GlassFish and Java EE 5 launch. If you want to learn about or get invoved in Java EE platform development, GlassFish Talk talk is worth checking out..

    Wednesday Apr 05, 2006

    JavaOne 2006

    I have been away from blogging for a long time now. Been busy travelling on business and getting some projects around Glassfish off the ground. Expect to see me writing a lot more in the coming weeks.

    Well, JavaOne is almost upon us. This year it is in May, not June. I was on the program committee again this year, responsible for co-ordinating content selection on the core enterprise track. KNowing how much work it was last year, this year I was prudent enough to ask my manager for additional help.

    First we were worried that our Call For proposals which was out in December 2005, was too early and we would not get enough enough proposals. Well, it turned out that our fears were quite unnecessary. The number of proposals in Core Enterprise (Java EE) track were about the same as last year. We have nearly 425 proposals just in this track!

    We had a a budget of 28 talk slots in this track. Waded through nearly 350 proposals for technical sessions. You can see how the odds are? 1 in 12 talk prospoals gets accepted. If your proposal got accepted, congratulations. You now know how hard it is.

    Usually we have the same number of BOFs as Technical Sessions, in each track. But a majority of proposals are for Technical Sessions. We look for the richness of topic and abstract and convert some technical session proposals to BOFs. So if you had a TS proposal, but you got a BOF instead think about your abstract and talk flow in your proposal next year.

    For the first time at JavaOne 2005, we passed around pencils and bubble sheets for audience feedback on each talk. We got thousands of feedback entries, audience ratings. They even scanned the scribbled comments at the bottom and got PDF. All this feedback was unprecedented. We learn a lot about what people like and why. We also learned why some speakers did not quite get it right and connect with audience. The feedback has been shared with the speakers confidentially. Based on attendance counts and quality ratings, we were also able to announce the Top 20 talks awards for 2005.

    All in all the feedback is wonderful and very useful. You can expect the same thing to happen again this year. Keep the feedback coming and help us to make the conference better.

    Oh, one other thing. We did a minor clean up of track titles. We now have an abstract track called "Java EE". Web Tier and Core Enterprise are the real tracks. The major tracks are Java SE (Core Platform), Java EE (Enterprise) and Java ME (Mobility), as you have already guessed.

    resource consumption management in glassfish

    One of the nice things I like in my job at Sun is that I get to meet really demanding customers at our Executive Briefing Center. We get to talk with some really good technical guys, who are thinking ahead and seeing around the curve. Last year we were talking to a couple of guys in a major financial company on the east coast. They had heard about Solaris Containers aka Zones and were wondering how it could ease management of the dozens of J2EE applications they now have to manage.

    Zones give a fairly lower virtualization of system resources. Each zone has a distinct IP address and hostname and root file systems. You can automate and recreate a similar looking zone on a different machine. One could put a J2EE application server and one business application in each zone and you could do very well isolating and managing resources consumed by each of the apps. In fact we found that this was exactly the model followed at another major financial house that is moving to Solaris 10.

    But Zones are only on Solaris 10 and upwards. What about Linux and Windows? What if the applications were numbering in dozens or hundreds and had a fairly limited usage? Would it not be nice if you could deploy them all as you would normally do, one one Application Server, but still be assure Quality of Service? Things I heard mentioned were:

  • Be able to reserve a specific percentage of request processing capability for a particular business service. OS level resource management capabilities are usually too low level.
  • be able to specify ceilings on resource utilization so that heavier than expected traffic to one application, does not adversely affect other co-redident applications.
  • Then it got a bot more esoteric. Be able to give priority access to one application user over another, when accessing some manager resource, say a database connection pool. Web Identity based resource allocation policies are all but impossible at OS level.
  • So we got thinking and did some thing pretty interesting in project Glassfish. We found out that by placing a policy engine that examines incoming service requests and assigning them to worker threads based on the policy file, gave us a coarse but fairly accurate control on overall resource consumption. We could restrict no more than say 20 users to a particular web application, at any time. We could set aside some request processing threads, so that users of an important time-sensitive application always received good service, even if there was an over abundance of users for some other co-resident applications. Pretty neat. Jeanfrancois implemented this logic on top of Grizzly, the high performance all Java HTTP engine we have under Glassfish Application Server (Happy to to say that it beats some of the best C++ based HTTP engines out there for latency and throughput!). Me and jeanfrancois have a BOF coming up at the upcoming JavaOne on this topic. Jeanfrancois will be blogging about this soon, so you can look at the code and give us feedback. This is an experimental feature right now. We want to get community feedback and contribution before roling it in as a supported feature.

    If you havent already looked at Glassfish, go take a look at The code is already checked in.

    Sunday Jun 26, 2005

    Java One, San Francisco and MOMA

    JavaOne 2005 is finally here! Been working frantically the past few weeks going over slides from all the accepted talks in core enterprise track. We had the biggest track, nearly 30 talks. Working with the reviewers and speakers was a great experience. Had great reviewers and the Speakers went to great lengths to accomodate the feedback. The talks aappear more balanced, cleaner and deeper. The core track team is hoping that the attendees would notice the hardwork. We do track attendee responses to the surveys. Do fill out yours. We actually read them! Some of it goes back to the speakers. Everyone wins. Went to Moscone early in the afternoon. Great weather. Registered early (a very good thing to do!). My talk (TS-7123, Sun Application Server 9.0 and the Java EE SDK) in on tomorrow. My co-speakers showed up, as we signed up for speaker coaching. Last I had speaker coaching was in 1999 (Java HotSpot VM launch, great memories) and my rusty style got a good tuneup. Highly recommend it. It is free. Dropped in at the NetBeans day event at the Argent. Nice crowd. The talks were packing the rooms. Ludo was buzzed about NetBeans 4.1 and 4.2. Parking was easy today at the 3rd Street Moscone garage. I am sure it will not be that easy tomorrow. The MOMA cafe looked very inviting, but I will be back for four more days

    Tuesday Mar 01, 2005

    JavaOne 2005 - Core Enterprise Track Progress Report

    Designing the Core Enterprise Track planning has been a great deal of fun. First of all we ended up with over 440 submissions just for this track. This is actually a small improvement over last year, despite the shorter CFP period this year. Quite heartening.

    As expected we have a great deal of submissions in the SOA space. Not surprising. So as to not fill the agenda with SOA alone we decided on some key buckets and themes and made sure we had a balanced track. These are the "buckets" within this track for 2005:

    \* Interesting experiments on/around J2EE
    \* Diverse Opinions
    \* Whats cool in App Server X
    \* J2EE 5.0
    \* Service Oriented Architecture
    \* Performance
    \* Security/Identity
    \* Exploiting J2EE APIs better

    The selection process for technical sessions is coming to an end. We will be notifying the selected presenters soon. We have an engaging set of speakers, and a diverse topic set to look forward to.

    Various things I do at Sun Microsystems.


    « July 2016