Thursday, May 31, 2012

Local Lync client presence on a web page

We've staged up an example off of our website of a simple test for invoking some functionality from a user's local Lync client installed on their machine using JavaScript. This of course requires Internet Explorer 8+ and a Lync client that is running. The JavaScript itself is very straightforward, and I'll include it below with the link.
var Instant = {
    sipUri: "",
    // Load up the NAME.dll functionality
    nameCtl: new ActiveXObject('Name.NameCtrl.1'),
    // Watch status changes
    onStatusChange: function (name, status, id) {
        //alert(name + ", " + status + ", " + id);
    },
    // Shows the Lync widget UI
    showOOUI: function () {
        Instant.nameCtl.ShowOOUI(Instant.sipUri, 0, 15, 15);
    },
    // Hides the Lync widget UI
    hideOOUI: function () {
        Instant.nameCtl.HideOOUI();
    },
    // Opens the full Lync widget menu
    openInfoPane: function () {
        Instant.nameCtl.DoAccelerator();
    },
    // Builds the Lync widget
    // This creates a HTML <span> element with all of the necessary Lync functions built in as
    // onmouseout, onmouseover, onclick selectors.
    buildWidget: function () {
        var lyncWidget = document.createElement("span");
        var container = $("#lync-widget");
        lyncWidget.setAttribute("onmouseover", "Instant.showOOUI()");
        lyncWidget.setAttribute("onmouseout", "Instant.hideOOUI()");
        lyncWidget.setAttribute("onclick", "Instant.openInfoPane()");
        lyncWidget.setAttribute("style", "border-style:dashed;border-width:1px;border-color:#ccc;padding:5px;");
        lyncWidget.setAttribute("id", "presence-widget");
        $(lyncWidget).appendTo(container);
        $("#presence-widget").text(Instant.sipUri);
    }
};
The link to our example page can be found here: http://instant-tech.com/examples/lync-presence

Simply add a SIP URI (formatted: johndoe@acme.com) into the box and hit start. If you hover over the users name, it should show the full Lync widget.

Friday, May 25, 2012

Web Client for Microsoft Lync 2010

This week, we have spent some time exploring options to provide a web client for Microsoft Lync 2010.  As we started to explore this area, we anticipated that we would simply use a Lync web client SDK from Microsoft.  However, with Lync 2010, there is no default web client or web client SDK.

So, we have explored a few options during this assessment
  1. Leverage the Lync web client that can be configured to run as part of an Exchange 2010 OWA deployment
  2. Deploy an internal web client proxy service that uses the UCMA api and a custom web client
  3. Integrate with the name.dll component that is installed as part of a Lync 2010 client installation

Initially, we thought that we might be able to extend, and possibly use, the Lync web client that is provisioned as part of a Microsoft Office 365 configuration.  Apparently, this web client can also be configured as an extension to an Exchange 2010 installation with the addition of the OWA and OCS 2007 R2 web client installation.  After some low level investigation with Fiddler we decided that a more structured, and open, approach would be better option.

Here is the Office 365 Lync client:


Here is a link to a good article on integrating Lync and Exchange: http://blog.schertz.name/2010/11/lync-and-exchange-im-integration/

While the integration provided with the Exchange 2010 OWA looked promising, it was a bit too heavy for what we wanted.  So, we continued our investigation and located a few promising projects on Codeplex. 

Specifically, this Codeplex project is very interesting:
http://lyncwidget.codeplex.com/

This project provided a nice base platform for developing a customized web client for Lync 2010.  After a bit of work, and some modifications on our side, we had a nice looking web client for Lync 2010. 

In terms of our modifications, we externalized some of the configuration - to allow for manually configuring the Lync server details.  We also migrated the Lync end point from using application end point to an end point that acts as a simulated SIP user.  We typically experience a high level of success (mostly with presence based API calls) when we use a end user end point - as opposed to the application end point.

Here is the presence example on a page:
Starting a chat:

With the Lync client on the other side of the conversation:


Our next steps will focus on some additional wiring to pass the end user's credentials to the the client (using Windows pass thru authentication) as well as some other configuration options.

Detecting presence of a local Lync client

Another interesting facet of a web-based Lync client, is that we are able to detect whether a Lync client is already running on a user's desktop, and if it is, rather than surfacing a web-based Lync client, we could bring up the users native Lync client running locally on their desktop. There are a few requirements for this functionality:
  1. Internet Explorer must be used when navigating the site. It's the only way to interface with the necessary DLLs to call the local Lync client.
  2. Office 2007 or 2010 must be installed. This places down the proper Lync presence/integration DLLs for us to use through the web.
  3. Lync client must be installed (running too if you expect to get the Lync client and not the web client).
We'll be using JavaScript to perform these tasks, and to get a basic example, it's really minimal code. First, let's make a simple JavaScript library that we can use to access some functions from the name.dll that we'll be manipulating for Lync.
var Instant = {
    sipUri: "eric_lync@instant.local", // Change this to the user's SIP URI you want to chat with
    nameCtl: new ActiveXObject('Name.NameCtrl.1'),

    onStatusChange: function (name, status, id) {
        alert(name + ", " + status + ", " + id);
    },

    showOOUI: function () {
        Instant.nameCtl.ShowOOUI(Instant.sipUri, 0, 15, 15);
    },

    hideOOUI: function () {
        Instant.nameCtl.HideOOUI();
    }
}
Our code here builds an object called nameCtl out of the name.dll NameCtrl control that is enabled with Lync and Office 2007+. This object opens up some other properties and functions that we can use to show information about the user, and track status. Our 'onStatusChange' function tracks a user's presence, it polls for the users current settings, and alerts it. The 'showOOUI' function will show an interactive display when called (more on that in a bit) and the hideOOUI function removes it. Let's build a page now that we can use to test our library.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Lync Presence Test</title>
    
    <!-- le JS -->
    <script type="text/javascript" src="assets/js/instant-presence-0.0.1.js"></script>
    <script type="text/javascript">
        if (Instant.nameCtl.PresenceEnabled) {
            Instant.nameCtl.OnStatusChange = Instant.onStatusChange;
            Instant.nameCtl.GetStatus(Instant.sipUri, "1");
        }
    </script>
</head>
<body>
<span onmouseover="Instant.showOOUI()" onmouseout="Instant.hideOOUI()" style="border-style:solid;">Eric Richards</span>
</body>
</html>
Our page above includes our JavaScript library (instant-presence-0.0.1.js, in this case), and includes a span with some onmouseover and onmouseout functions that will get called from our library. When the page loads, we reference Instant.nameCtl.PresenceEnabled, which checks to see if the Lync client is currently running, if it is, we start checking status with Instant.onStatusChange. Now if we were to hover over the span, we would see a full Lync menu like the screenshot below.
  

From this menu, we can chat, call, video call, meet, etc. We have the full capacity of the local Lync client, all with just a few lines of HTML/JavaScript!


Getting the availability of a Queue using JavaScript

When utilizing Queue Manager as a click-to-chat platform, it's important to be able to accurately know the current state of the Queue. You wouldn't want end-users trying to chat if the queue was offline, this would lead to user disappointment and dissatisfaction. You also may want a way of displaying how many experts are currently online, available, and ready to chat, to show the strength of your 'support-force'. Our Queue front-end has had support for these sort of requests for sometime, but in our most recent release, we've made these activities easier to perform. Let me walk you through a typical scenario, and I'll show you how easy it is.

Scenario: You want to check the status of the queue on a simple web page button press.

To achieve this functionality, we'll do a few things in JavaScript, but the code itself is very straightforward. To do this we'll be using the following (new!) Queue Manager API call to get the status of the queue:
Replace the fields necessary with your environment, the Queue login ID would be something like 'Demo Support' or 'support@instant-tech.com' depending on how the Queues are set up in your deployment.

We'll make a simple JavaScript call to call this, and return the Queue status. The function below shows how the code would look to perform this task. It's a mixture of JavaScript and jQuery, so you'd need to make sure the page you are testing with is using jQuery for this example to work.
var Instant = {
    getQueueStatus: function (queueID) {
        var url = "http://192.168.1.214:8080/ITFramework/webclient?getSTStatus=" + queueID;
        
        $.ajax({
            url: url,
            type: "GET",
            complete: function(result){
                status = $.trim(result.responseText);
                if (status === "na") {
                    console.log("Queue is offline, or doesn't exist."); // Log the message out to the Chrome/Firefox/Firebug console
                }
                else if (status === "STATUS_ACTIVE") {
                    console.log("Queue is online."); // Log the message out to the Chrome/Firefox/Firebug console
                }
                else if (status === "STATUS_AWAY") {
                    console.log("Queue is unavailable. All experts are unavailable/offline."); // Log the message out to the Chrome/Firefox/Firebug console
                }
                else {
                    console.log("Queue may be available, check it's status in Sametime."); // Log the message out to the Chrome/Firefox/Firebug console
            }              
        });
    }
}
In the code above, we've created a function getQueueStatus inside our Instant object that takes the Queue ID as a parameter. We build a 'url' variable with the FQDN to our Queue Server, and the Queue ID that we passed in. Once we have that, we do a simple AJAX GET request to the url variable we built. Once we get the response, our code with run through the 'complete:' section of our code and it will assess what the server has returned. We use jQuery's $.trim() function to strip any '\n' line breaks that may be returned with the data. The API call could return up to 12 responses, but we are only really concerned with 3.
  • If we get 'na' as a response, the Queue is offline in Sametime, or it isn't a valid queue. This means our server can't see it. For this we are writing out to the Chrome/Firebug console Queue is offline, or doesn't exist. 
  •  If we get 'STATUS_ACTIVE', our server can see the queue, it's online. For this we'll write out Queue is online.
  • The other response we'd want to check for this the 'STATUS_AWAY' response, this means that the queue is online, but that all experts are currently busy. 
 Inside these if statements, you could write your own code to execute when these status' are returned. You could have this function load with the page, and if the server returns 'na' you could disable the chat button and give a message the the chat feature is currently disabled.

The other API call which we have surfaced is a way for you to get the number of available experts in the requested Queue. The code itself is almost identical to the code above, except we are requesting a different API endpoint URL:
The JavaScript below lays out this API call simply.
getAvailableExpertCount: function (queueID) {
    var url = "http://192.168.1.214:8080/ITFramework/webclient?getQueueExpertsReady=" + queueID; // Change this to the FQDN of your IQM server

    $.ajax({
        url: url,
        type: "GET",
        complete: function(result){
                count = $.trim(result.responseText);
                console.log("Experts available: " + count);
        }
    });
}
Just like the first block of code, we set a URL using our FQDN and Queue ID, and perform a simple AJAX GET to the URL that we built. We trim the response, and console out the number of experts that we have in the Queue available. This response could be set into a variable itself, which maybe you would want to include in a counter somewhere on the page to show visitors how many agents are there to help. Because this is all JavaScript, it is very flexible to wire these API calls into your website to perform some basic to advanced tasks.

Tuesday, May 8, 2012

Using JMX to Investigate Queue Manager and Java on Linux

Recently, we have been involved in a rather large Queue Manager deployment running on a Linux environment.  During this process, we have been reviewing various tools and techniques to help analyze and detect issues in a remote production environment.  As part of this process, we discovered the value of JMX, VisualVM, and the tools associated with debugging Java applications.  Most of these practices are useful on both Linux and Windows deployments. 

As a bit of background, our Queue Manager for Sametime application is built using Java and a collection of Java libraries.  Queue Manager leverages the Sametime Java API for access to the core Sametime services, it uses the Domino libraries for accessing Lotus Notes/Domino services, and Queue Manager uses Spring as the main application framework.  So, at a high level, Queue Manager is a Java Spring application running under Tomcat. 

Typically, we deploy Queue Manager on a Windows OS.  However, during a recent deployment, we configured Queue Manager to run on a Linux server.  As part of this deployment, we wanted to remotely monitor the thread activity of the application, the CPU usage of the application, and identify any issues related to either thread usage or memory management.

While there are some very useful tools (typically command line) to help with this type of analysis, we particularly like JMX and VisualVM.  After enabling JMX on the server hosting Queue Manager, our application developers then connect to the JMX monitoring system using VisualVM.  This allows our developers to monitor the performance, health, thread usage, and memory usage in real-time - using a very nice graphical display.  The added advantage is that we can use VisualVM to both remotely monitor a variety of internal servers, as well as use VisualVM to review thread dumps and heap dumps (memory allocation dumps) from a remote production environment. 

Here is a screen shot of VisualVM monitoring an internal Linux instance of Queue Manager:


VisualVM is also very useful during extended periods of load testing and stress testing.  Our internal developers created a variety of load testing tools in order to simulate the various Queue Manager  users and systems.  Our load testing suite includes the ability to scale the number of inbound Sametime IM seekers (people looking for help), the number of experts in a queue, the number of web service requests to the system, as well as experts entering and leaving various queues.  During these load tests, VisualVM provides a real time display of the threads, memory, and CPU usage for the system.

In addition to high level monitoring, VisualVM enables the ability to sample (collect) data over a specific period of time.  So, during certain load testing cycles, we can enable VisualVM to sample the activity of the system and then we can review the data to inspect threads, CPU usage across threads, and memory allocation.

View CPU usage by thread:


One of the most useful tools in VisualVM is the ability to dump threads.  To create a thread dump, right click on the JMX instance and select Dump Threads...

Snapshots and System Sampling:

While the ability to capture a thread dump is useful, we have found the ability to save and export a snapshot of the system, using the sampling module, to be incredibly valuable. The 'sampler' area of VisualVM provides the ability to 'snapshot' the current system state and then export this information.
Navigate to the Sampler tab and enable sampling:

Click the Snapshot button

Export the snapshot


Save the snapshot as a file (so it can be shared)


The exported snapshot may then be transferred to another machine and opened using VisualVM.  The ability to save profile snapshots, transfer these snapshots, and then inspect the snapshots using VisualVM has proved extremely valuable.

We have found JMX and VisualVM to be invaluable tools during both our internal load testing and remote performance tuning and analysis efforts.  JMX is a standard component of the Java environment, and the addition of VisualVM provides a compelling, and powerful, collection of debugging and analysis tools.

Here are some helpful links that we have collected during this process:

VisualVM and JMX
Pretty good Spring presentation on JMX and other useful topics:

Getting started with VisualVM:

20 Linux System Monitoring Tools Every SysAdmin Should Know:
Tomcat Related Links:

Reviewing Tomcat Configuration and Tuning:

Presentation by Mark Thomas on Tomcat Tuning:

Mulesoft article on Tomcat performance tuning:

Misc:
Checking for looping code:

Friday, May 4, 2012

IMtegrity 5 Product Launch - Continued Commitment to IBM Sametime

At a time when many of our competitors are exiting the IM compliance and e-discovery market, Instant Technologies is continuing to invest, innovate, and extend our product offerings for IBM Sametime.  Yesterday, we announced the immediate availability of IMtegrity 5.  IMtegrity 5 continues to build on the outstanding platform that we have developed for compliance, archiving, and e-discovery for IBM Sametime. 

IMtegrity 5 is a major product release for Instant and represents our commitment to our customers and the IBM Sametime user community.  In addition to adding native support for Sametime 8.5, IMtegrity 5 includes two significant features that have been requested across a large community of our install base.  First, IMtegrity 5 adds the ability to create ethical IM firewalls within an organization.  By providing a real-time monitoring service for IBM Sametime, IMtegrity now has the ability to detect, and optionally prevent, Sametime IM conversations between individuals and groups.   The ability to support ethical walls has been requested for many years and we are excited that we can now deliver this level of functionality to our customers.

In addition to ethical firewalls, IMtegrity 5 adds support for configurable IM disclaimers.  These disclaimer notifications are designed to notify chat participants whenever new IM conversations are initiated.  Disclaimer text may be customized for the local language and may be triggered based on a set of rules or actions.  Many of our large customers have been requesting individual IM based disclaimers and we anticipate that this additional feature will help IMtegrity continue to gain momentum into new markets.

IMtegrity has always been based on simplicity of design, the ability to scale within large deployment, and the development of a stable platform for compliance and e-discovery.  This latest release of IMtegrity continues this tradition of design and simplicity and includes a seamless installation process for Sametime 8.5 servers, a highly scalable archiving engine, and new features that will enable the IMtegrity platform to meet the demands of new and existing customers.

Our customer base for IMtegrity continues to grow as does our investment in the core IBM Sametime platform.

Peyton McManus
May 4, 2012

Thursday, May 3, 2012

Good Presentation on Installing Sametime 8.5.1

This is a pretty concise presentation (converted to a pdf) detailing the steps to install Sametime 8.5.1.  The presentation is from Lotusphere 2011 and was presented by Frank Altenburg and Volker Juergensen.



Tuesday, May 1, 2012

Apache Tomcat 6 Shutdown Failure Resolution on SUSE Enterprise 11

Recently, in a development environment, and customer site production environment we noticed some issues shutting down Apache Tomcat for our Queue Manager product running on SUSE Enterprise Linux 11. Running './catalina.sh stop' appeared to work fine, but upon further inspection, it failed to stop it's running Java process, and it left its PID file behind (/var/run/tomcat6.pid). Running the '/etc/init.d/tomcat6 stop' command showed us that, in fact, there was an error in the shut down process.


Review of the catalina.out log file revealed a permissions error writing one of the logs. The log entry itself wasn't terribly helpful, but the implications of a permissions issue were intriguing. It's important to mention that we installed Tomcat 6 using SUSE's YaST tool, we hadn't built it from source, so permissions problems shouldn't be an issue. After inspecting Tomcat's directories, I decided to explicitly give group execution privileges to the folders. The folders were already set to attributes 755, so that didn't appear to be an issue. I used the commands below for the Tomcat directories.


Before starting Tomcat again, I removed the PID file (/var/run/tomcat6.pid), killed the left behind Java process (using kill), and cleared out our logs. Once Tomcat was started, and everything was running smoothly, we sent the shutdown.


This time it shut down fine. Upon further inspection the spawned Java process that had lingered before was gone, as was the PID file. Further inspection of the logs showed no further errors with Tomcat's shut down either.