Caplin DataSource JMX SDK 8.0.3-290770-7760911e

The Caplin DataSource JMX SDK is an API designed to allow the Caplin Platform components to be managed using Java Management Extensions (JMX) technology. Every application built with Caplin's DataSource SDK can enabled for management, including the Caplin Liberator, Caplin Transformer and all standard DataSource products.


Terminology

The terms monitor and manage are often used interchangably throughout this document. Although they are distinct (as detailed by the definitions below), this has been done for the sake of brevity.

Monitoring

Monitoring is defined as the observation of the current state of the system. As such, the process of observation will have no impact on the system. The majority of the functionality provided by the SDK falls into this category. For example the current value of an attribute can be retrieved, and a listener can be added to be notified of all changes to that attribute.

Management

Management is defined as the performing of an operation that can modify the state of the system. For example, a Liberator user's session could be ejected, or their permissions to view data could be re-evaluated.

MBean Type

The term MBean Type used within this document does not refer to the actual class of the MBean (in fact, all MBeans exposed by this API are represented by the same class, GenericDynamicMBean). Instead it refers to the groups of MBeans that expose indentical MBeanInfos. All MBeans of the same type will be registered with the same domain part in their ObjectNames (e.g. all MBeans that represent DataSource peers will have the domain server.peers).


Target Audience

This document is aimed at developers who wish to monitor and/or manage one or more Caplin Platform components using JMX. It covers everything that will be required to write a new application that monitors the Caplin Platform components, or to upgrade an existing JMX enabled application. This document may also be referenced by developers creating their own views for the Caplin Management Console (CMC). See the Customising the CMC document included in the Caplin Management Console kit for more information.


Additional Resources

Other documents that may be of interest are provided with the Caplin Management Console kit. These are:

  • Getting Started Guide - explains how to enable JMX monitoring for the Caplin Platform components, and how to run the Caplin Management Console.
  • Monitoring Overview - covers the overall JMX process and how it has been implemented by the Caplin Platform Components.
  • Customising the CMC - explains how a custom view can be added to the Caplin Management Console.

The Sun Systems™ website also contains a number of documents that will aid the development of a JMX enabled application. Links to several of these pages are provided below:


JVM Compatibility

The Caplin DataSource JMX SDK requires Java version 1.5.


Overview

Follow the links on the table below for information on the following topics:

Topic
Connecting To The Caplin JMX Server
Caplin JMX Extension JAR
Examples Provided
The SERVERTYPE Singleton Bean
MBean Overview And List Of Current MBeans

Connecting To The Caplin JMX Server

To connect to a Caplin JMX Server, the client will need to know the name or address of the machine running the JMX Server, and which port the RMI registry that contains the server stub is running on (this is defined by the rmi-registry-port configuration option within etc/jmx.conf file for the server component).

Using this information, the application can connect to the JMX Server using JMX remoting. JMX remoting is defined by Java Specification Request (JSR) number 160. It defines a mandatory connector based on RMI (supporting both RMI/JRMP and RMI/IIOP), and an optional one based on sockets and Java serialization (JMXMP).

JMX Service URL

An instance of JMXServiceURL must be created to establish a connection. This should be constructed with the following format: service:jmx:rmi:///jndi/rmi://<server-name>:<rmi-registry-port</datasrc. The example below shows how a JMXServiceURL can be created that will connect to the server called mydatasource and the port 10000.

         JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://mydatasource:10000/datasrc");
         JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
         MBeanServerConnection mbeanServer = jmxConnector.getMBeanServerConnection();

Connection Credentials

A client side application will typically be required to supply a username and password in order to successfully connect to a Caplin JMX Server. These credentials must be included in the environment Map passed into the JMXConnectorFactory.connect(JMXServiceURL url, Map environment) method. The credentials are specified in a String array with the key JMXConnector.CREDENTIALS. The example below shows how the code snippet from before can be modified to connect with the credentials "admin-user" and "admin-password".

         JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://mydatasource:10000/datasrc");

         HashMap environment = new HashMap();
         environment.put(JMXConnector.CREDENTIALS, new String[] { "admin-user", "admin-password" });

         JMXConnector jmxConnector = JMXConnectorFactory.connect(url, environment);
         MBeanServerConnection mbeanServer = jmxConnector.getMBeanServerConnection();

Caplin JMX Extension JAR

A Java archive (JAR) file, common-jmx.jar, is provided that contains classes specific to the Caplin DataSource JMX implementation. It is important for an application connected to the Caplin JMX Server to have access to this JAR, otherwise it will be unable to interpret important attribute values and notifications of changes to these values.

The following subsections describe the most important classes provided by common-jmx.jar.

ObjectNameLink Data Type

The ObjectNameLink class is used to represent both "one to one" and "many to one" links from one MBean and another within the monitoring system. The getLinkName() and toString() methods return a human readable name for the linked MBean. The getObjectName() method will return the actual ObjectName the linked MBean was registered with.

The table below shows some examples of what the link names and the corresponding ObjectNames look like:

Link Name Object Name
0A8BGF rttpd.client.session:client-address=192.168.201.114,session-id=0A8BGF,application-id=RTSL,username=demouser
/DEMO/L2/MSFT rttpd.cache.object:base-name=MSFT,dir-name=/DEMO/L2,object-name=/DEMO/L2/MSFT

SubscriptionLink Data Type

The SubscriptionLink class is a subclass of ObjectNameLink that represents a user sesssion's subscription to an cached object. In addition to providing a human readable name, and the ObjectName of the related MBean, a SubscriptionLink provides methods to get information specific to a subscription, such as its id and name, as well as the ObjectName of a helper MBean that can be used to get additional information about the state (e.g. the time the subscription was made, or when how many updates have been sent).

SubscriptionLinks will always be contained within a RelationSet (see below). A particular user session can have many subscriptions to cached objects, including multiple subscriptions to the same underlying cached object. Similarly, a cached object can have many subscriptions from user sessions, including multiple subscriptions from the same user session.

The table below shows a simple example of the "many to many" relationship represented by subscriptions. In this example, the user session 012345 has requested three cached objects, /DEMO/MSFT, /DEMO/DELL and /DEMO/CSCO, whilst the session 098765 has requested a single one, /DEMO/MSFT. From the cached object perspective, /DEMO/MSFT has two subscriptions, one from the user session 012345, and the other from 098765. Both /DEMO/DELL and /DEMO/CSCO have a single subscription from the session 012345.

Username Session Id Sub. Id Sub. Name Cached ObjectName
demouser 012345 0001 /DEMO/MSFT /DEMO/MSFT
demouser 012345 0002 /DEMO/DELL /DEMO/DELL
demouser 012345 0003 /DEMO/CSCO /DEMO/CSCO
admin 098765 0001 /DEMO/MSFT /DEMO/MSFT

RelationSet Data Type

The RelationSet class is used to represent both "one to many" and "many to many" links from an MBean to many others. The elements within a RelationSet will be instances of ObjectNameLink.

RelationSet implements the java.util.Set interface, and can be handled as a standard set. It also provides helper methods that enable its state to be kept up to date. The getNotificationListener() method returns a notification listener that can be registered with the JMX Server to update the contents of the RelationSet whenever a notification that an element should be added or removed is received. The getNotificationFilter() method returns a filter that discards all notifications that do not apply to this RelationSet. The addUpdateListener(RelationSetUpdateListener) method should be used to register a class that implements the RelationSetUpdateListener interface to receive all the updates that are made to the RelationSet.

ObjectName Encoding

The ObjectNameEncoder package provides helper classes that should be used to encode and decode the ObjectNames that the Caplin Platform registers its MBeans with. This is necessary because the value supplied for a key/value pair used in the ObjectNames generated by the Caplin Platform may contain illegal character(s), such as equals (=), colon (:) and question mark (?). Without the encoding, a MalformedObjectNameException will be thrown, whilst without the decoding, the ObjectName may not be displayed in a particularly user friendly format. All ObjectNames generated by the Caplin Platform components will have been encoded using the ObjectNameEncoderAccessor.getObjectNameEncoder().

The following code demonstrates how an ObjectNameEncoder can be used to encode a value used to construct an ObjectName and to decode the username key value stored within an ObjectName.

         private final static ObjectNameEncoder OBJECT_NAME_ENCODER = ObjectNameEncoderAccessor.getObjectNameEncoder();
         ...
         public ObjectName encodeSessionObjectName(String username, String sessionId, String applicationId, String address)
                throws MalformedObjectNameException, NullPointerException
         {
            Hashtable sessionDetails = new Hashtable();
            sessionDetails.put("username", OBJECT_NAME_ENCODER.encodeValue(username));
            sessionDetails.put("session-id", OBJECT_NAME_ENCODER.encodeValue(sessionId));
            sessionDetails.put("application-id", OBJECT_NAME_ENCODER.encodeValue(applicationId));
            sessionDetails.put("client-address", OBJECT_NAME_ENCODER.encodeValue(address));
            return new ObjectName("rttpd.client.session", sessionDetails);
         }
         
         public String decodeSessionUserName(ObjectName objectName)
         {
            String username = objectName.getKeyProperty("username");
            if (username != null)
            {
               username = OBJECT_NAME_ENCODER.decodeValue(username);
            }
                return username;
         }

Example Classes

Four example classes are provided with the SDK demonstrating how it should be used. These are:

  • examples.attributes.VersionExample - gets the version number of the Liberator being accessed.
  • examples.operations.DebugLevelExample - modifies the debug level of the event log on the Liberator.
  • examples.notifications.CpuMonitoringExample - registers a listener to monitor changes in CPU level of the machine running the Liberator.
  • examples.console.RemoteJMXConsoleExample - a terminal based console capable of running queries to find out which MBeans have been registered with the JMX server, getting attribute values and invoking operations. It also demonstrates how to use ObjectNameLinks and RelationSets.

These examples cover all the basic areas of interacting with a JMX server, including:

  • Querying a JMX server to find out the MBeans that have been registered with it.
  • Finding out what attributes, operations and notification are available for a specific MBean.
  • Getting the value for a particular attribute (or attributes) from an MBean.
  • Invoking an operation on an MBean.
  • Adding notification listeners to, and removing them from, an MBean.

TOP


The SERVERTYPE Singleton Bean

The SERVERTYPE MBean defines a list of all the JMX enabled Caplin Platform components that are available within the JMX Server. It provides two attributes, defined in the table below, that describe the type of each component and the ObjectName domain prefix used for all the MBeans registered by that component. The SERVERTYPE MBean itself is always registered with the ObjectName SERVERTYPE:Server Type=default.

Please note that typically only a single component will be available within a JMX server. However, future releases of the Caplin Platform components may register multiple components with a single JMX server.

Name Data Type Description
server-type String Array An array of the different types of components that are registered with the JMX server, such as "liberator", "transformer" and "datasrc". The component type can be used to identify what types of MBeans will be available; for example, the Caplin Management Console uses this value to define which views are available (e.g. the Users view is only displayed for a Liberator).
root String Array An array of the prefixes that must be applied to the domain part of the ObjectName for all MBeans that were registered by a particular component. The elements in this array correspond to the component with the same index defined within the server-type array.

Using the root Attribute

Each distinct type of MBean is registered with a domain for its ObjectName that indentifies its type. For example, all DataSource peers are registered with the domain server.peers, whilst all log files use the domain server.logging. Unfortunately this is not enough to create unique ObjectNames if there are multiple components registered with the JMX server. The root attribute described above is used to provide a prefix to the standard domain name for a particular MBean type for a specific server component.

For example, if a particular JMX Server provides MBeans to monitor for two separate Liberators, the server-type attribute will have the value { "liberator", "liberator" } and the root attributes might have the value { "primary", "backup" }. In this case, all DataSource peers for the first (primary) Liberator will have the domain primary.server.peers, whilst those for the second (backup) Liberator will have the domain backup.server.peers. Similarly the log files will have the domains primary.server.logging and backup.server.logging respectively.

The following code example demonstrates how the SERVERTYPE MBean can be used to get the domain prefix for the first server component:

         MBeanServerConnection mbeanServer = getJmxConnection();
         ObjectName objectName = new ObjectName("SERVERTYPE:Server Type=default");
         String[] rootPrefixes = (String[]) mbeanServer.getAttribute(objectName, "root");
         String firstPrefix = rootPrefixes[0];

examples.common.BaseExample provides a simple demonstration of how the SERVERTYPE MBean can be used. All the other examples are dependant on this class to correctly prefix the ObjectNames they use.

TOP


MBean Overview And List Of Current MBeans

Every MBean within the JMX server defines the set of attributes that can be queried for it, the operations that can be invoked on it, and the types of notifications that it emits.

Attributes And Notifications

The attributes and notifications are typically used to monitor the server. An attribute usually represents a particular part of the state of the server, such as the number of updates that have been sent, or the current update rate. Most MBeans emit AttributeChangeNotifications, which are sent every time a particular attribute is updated. Some MBeans will also emit RelationSetNotifications, which are emitted whenever an element is added or removed from a RelationSet.

The following code snippet demonstrates how the CPU usage of the server can be a obtained via an attribute, and how changes to its value can be monitored by registering a NotificationListener (note: for simplicity this example does not use the SERVERTYPE MBean to get the domain prefix):

         MBeanServerConnection mbeanServer = getJmxConnection();
         String cpuUsageAttributeName = "cpu-usage";
         ObjectName objectName = getObjectName("rttpd.server.system:System=default");
         
         // first, get existing attribute value
         Object cpuUsage = mbeanServer.getAttribute(objectName, cpuUsageAttributeName);
         System.out.println("CPU usage is currently: " + cpuUsage);
         
         // next, create a filter, and then register a NotificationListener
         AttributeChangeNotificationFilter filter = new AttributeChangeNotificationFilter();
         filter.disableAllAttributes();
         filter.enableAttribute(cpuUsageAttributeName);
         
         mbeanServer.addNotificationListener(objectName,
                                             new CpuMonitoringNotificationListener(),
                                             filter,
                                             null);

Source code for the CpuMonitoringNotificationListener class used in the code snippet:

         class CpuMonitoringNotificationListener implements NotificationListener
         {
            public void handleNotification(Notification notification, Object handback)
            {
               if (notification instanceof AttributeChangeNotification)
               {
                  AttributeChangeNotification acn = (AttributeChangeNotification) notification;
                  System.out.println("CPU usage is now: " + acn.getNewValue());
               }
            }
         }

Operations

The operations are usually used to manage the server. Invoking an operation can modify the state of the system, such as ejecting all the users from a Liberator, or changing the debug level used to log messages to a particular log file. Every operation returns a String which contains the result of the operation.

The following code snippet demonstrates how the log level of the event log can be modified (note: for simplicity this example does not use the SERVERTYPE MBean to get the domain prefix):

         MBeanServerConnection mbeanServer = getJmxConnection();
         ObjectName objectName = new ObjectName("rttpd.server.logging:name=event_log");
         
         Object result = mbeanServer.invoke(objectName,
                                            "set-debug-level",
                                            new Object[] { "info" },
                                            new String[] { "java.lang.String" });
         System.out.println("set-debug-level returned: " + result);

The set-monitoring-interval Operation

Several different types of MBean, including server.peerstats, client.session and cache.object, specify an operation called set-monitoring-interval. This operation can be used to fine tune how frequently AttributeChangeNotifications are emitted by an MBean. It accepts a java.lang.Float as an argument, which is the minimum number of seconds between notifications (i.e. if the interval is set to 5 seconds, a notification will only be sent out every 5 seconds, even if the attribute has changed value more frequently). This prevents the server from being overloaded trying to send notifications for every change to each MBean's state. If the monitoring interval is set to 0, the MBean will stop emitting AttributeChangeNotifications. The default interval for most MBeans is 0.

The following code demonstrates how to set the monitoring interval for a particular DataSource peer (note: for simplicity this example does not use the SERVERTYPE MBean to get the domain prefix):

         MBeanServerConnection mbeanServer = getJmxConnection();
         ObjectName objectName = new ObjectName("rttpd.server.peerstats:identifier=0");
         mbeanServer.invoke(objectName,
                            "set-monitoring-interval",
                            new Object[] { Float.valueOf(5.0) },
                            new String[] { "java.lang.Float" });

MBean Types

A comprehensive list of the different MBean types provided by the Caplin Platform components is available from the following page. This provides a description of each type of MBean, and defines all the attributes and operations available for that type. Where appropriate the types have been grouped together. Click here to access the page.

TOP