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 MBeanInfo
s. All MBeans of the same type will be registered with
the same domain part in their ObjectName
s (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
ObjectName
s 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).
SubscriptionLink
s 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 ObjectName
s that the Caplin Platform
registers its MBeans with. This is necessary because the value supplied for a key/value
pair used in the ObjectName
s 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 ObjectName
s 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 useObjectNameLink
s andRelationSet
s.
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.
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
ObjectName
s 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 ObjectName
s they use.
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
AttributeChangeNotification
s, which are sent every time a particular
attribute is updated. Some MBeans will also emit RelationSetNotification
s,
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 AttributeChangeNotification
s 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 AttributeChangeNotification
s. 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.