15 May 2006

InstanceTrackingFilter -- sending JMX notifications

Following on from my previous post, I wanted to explore how-to somehow some form of data baed on Session failovers in Application Server Control (ASC).

Being interested in JMX, one approach that seemed possible was to use the notification support available within JMX to broadcast when session failovers occur and have ASC subscribe to these notification events so that it received them.

In reality, it turned out to be quite easy to do by adding an MBean to the module containing the ServletFilter and calling into it from the ServletFilter.

A simple notification emitter

To emit JMX notifications a very basic MBean can be used.

The MBean interface is defined as:

public interface InstanceTrackingNotifierMBean {
public void notifyFailover(String sessionId,
InstanceIdentifier previous,
InstanceIdentifier current);
}

The MBean implements this interface. It also subclasses the NotificationBroadcasterSupport class provided in JMX to handle the mechanics of adding/removing listener registrations and sending out the notifications.

Here's the full MBean implementation:
public class InstanceTrackingNotifier
extends NotificationBroadcasterSupport
implements InstanceTrackingNotifierMBean {

public InstanceTrackingNotifier() {
}

private String notifications[] =
{
"Request Failover"
};

/**
* @param sessionId
* @param previous
* @param current
*/
public void notifyFailover(String sessionId,
InstanceIdentifier previous,
InstanceIdentifier current) {

sendNotification(
createNotification(notifications[0],
"Session " + sessionId +
" switched from: " + previous +
" to: " + current));
}


/**
* Creates a new notification object.
* @param desc - the message to put into the notification
* @return the notification
*/
private Notification createNotification(String operation, String desc)
{
return new Notification(operation,
this,
System.currentTimeMillis(),
desc);
}

/**
* Informs any interested party what notifications this MBean emits.
* @return the notifications this MBean emits
*/
public MBeanNotificationInfo[] getNotificationInfo()
{

MBeanNotificationInfo[] info =
{
new MBeanNotificationInfo(notifications,
"javax.management.Notification",
"Notification set for InstanceTracking")
};
return info;
}
}


This MBean exposes an operation called notifyFailover which emits a JMX notification that contains a message detailing the affected client session and which hosts are involved in the switch. It's all fired up and ready to go.

Using the MBean from the ServletFilter
Once the MBean has been developed, all that needs to be done is to make use of it from the client.

The ServletFilter init method is used to lookup the MBean and create a working proxy of it which can be used when a failover is detected, thus emitting a JMX notification.


public void init(FilterConfig filterConfig) throws ServletException {
debug("init");
_filterConfig = filterConfig;
try {
MBeanServer mbeanserver = MBeanServerFactory.createMBeanServer();
ObjectName objectname = new ObjectName(":name=InstanceTrackingNotifier");
notifier = (InstanceTrackingNotifierMBean)
MBeanServerInvocationHandler.newProxyInstance(
mbeanserver,
objectname,
InstanceTrackingNotifierMBean.class,
false);

} catch (Exception e) {
e.printStackTrace();
}
}


Once notifier proxy has been created for the MBean, the notifyFailover operation can be called from the ServletFilter when a failover is detected.


} else {
// Is not the same host so upate the InstanceIdentifier
// Log a message, put notification into session
session.setAttribute(SESSION_FAILOVER, Boolean.TRUE);
session.setAttribute(SESSION_IDENTIFIER, currentInstance);
System.out.println("SessionId: " + session.getId() +
" switched from: " + previousInstance +
" to: " + currentInstance + "");
notifier.notifyFailover(session.getId(),
previousInstance,
currentInstance);
}

Hooking it up with ASC
Once the ServletFilter module has been extended to support the emission of JMX notifications for session failover activity, ASC can register to receive the notifications.

Since the MBean is created by a deployed application, it is accessed via the "Application Defined MBean" icon associated with the specific application.

Once the MBean is visible, the notifications can be seen and subscribed to.



Once the subscription has been made, any time a Session failover is detected, ASC will receive a notification which it displays in the notification list.



So there you have it -- rudimentary Session failover detection, JMX notifications and visibility from ASC.

No comments: