<-- %W --> Cascading over JMX[tm] Remote API Connectors Provides the classes that implement cascading over JMX Remote API connectors. Several implementations of cascading (proxy-based, interceptor-based) may coexist.

A proxy-based cascading agent is implemented in the {@link com.sun.jdmk.remote.cascading.proxy} package.

Overview

The cascading service proposed in this package makes it possible to mount a partial view of a source MBeanServer into a target MBeanServer. The source MBeanServer is also sometimes called the cascaded MBeanServer, while the target MBeanServer is called the cascading MBeanServer.

The Java DMK cascading API introduces the notion of a domain path. An ObjectName is thus decomposed into three parts:

 <domain-path><domain-base-name>:<key-property-list>
    
The domain path is a hierarchical name similar to a UNIX path name, and uses the character `/' as separator.
The Java DMK cascading API provides the ability to mount MBeans from a source MBeanServer under a target domain path in a target MBeanServer.
For instance, this makes it possible in a target MBeanServer to: The content of that target MBeanServer as returned by queryNames(null,null) would then appear as:
 [...]
 java.lang:type=Compilation                    (local MBean)
 java.lang:type=Threading                      (local MBean)
 [...]                                         ...
 server1/instance1/java.lang:type=Threading    (mounted from sugagent 1)
 server1/instance1/java.lang:type=Compilation  (mounted from sugagent 1)
 [...]                                         ...
 server1/instance2/java.lang:type=Threading    (mounted from sugagent 2)
 server1/instance2/java.lang:type=Compilation  (mounted from sugagent 2)
 [...]                                         ...
 

See The File System Analogy below.

CascadingServiceMBean

The cascading service proposed in this package is based on a simple MBean class:

This package provides a default {@link com.sun.jdmk.remote.cascading.CascadingService} class which implements the {@link com.sun.jdmk.remote.cascading.CascadingServiceMBean} interface. This default CascadingService implementation relies on proxy-based cascading and implements the mount operation by instantiating behind the scene a {@link com.sun.jdmk.remote.cascading.proxy.ProxyCascadingAgent}.

The File System Analogy

As explained in the Overview, The Java DMK cascading API introduces the notion of a domain path. This domain path is a hierarchical name similar to a UNIX path name and makes it possible to handle cascading in a similar way to a File System mount operation.

Although our API allows you to implement many cascading schemes, we recommend that applications only implement those schemes that can be compared to a regular File System mount:

Our implementation does not enforce those rules, but applications which are concerned with naming consistency and coherency should make sure to respect them.

Advanced Programming API

In order to perform its mount operation the CascadingService relies on a lower level API. This lower level API offers a greater control on the connectivity (through MBeanServerConnectionFactories ) as well as a deeper control of the underlying implementation.
This API is however more complex and requires a deeper knowledge of the inner structure of the cascading service implementation.

We thus recommend using the {@link com.sun.jdmk.remote.cascading.CascadingService} rather than working with the underlying implementation classes.

The CascadingService provided in this package relies on the following implementation classes:

MBeanServerConnectionFactories

MBeanServerConnectionFactories serve several objectives. First, they make it possible to share connections between CascadingAgents, and with the application code.
Typically, an application will create a JMXConnector, and connect it to the remote MBeanServer. Then the application will wrap this JMXConnector into a {@link com.sun.jdmk.remote.cascading.BasicMBeanServerConnectionFactory}. The application can then create several CascadingAgents, each with its own pattern and filter, but all sharing the same MBeanServerConnectionFactory, hence the same underlying MBeanServerConnection. The JMXConnector that was passed to MBeanServerConnectionFactory (or the MBeanServerConnectionFactory itself) can also be used by the application code for its own purposes.

Another advantage of the MBeanServerConnectionFactory is to make it possible to transparently handle reconnection when a server goes down. Although this feature is not implemented by the provided implementations, the MBeanServerConnectionFactory could embed the necessary logic to detect that the underlying connection can no longer be used (e.g. IOException was thrown by a method of MBeanServerConnection) and attempt to create and connect a new JMXConnector.

Note that creating a new JMXConnector would usually involve looking up a new JMXServiceURL for the server in a naming service, which usually depends on the application logic.

Patterns and Filters

Each CascadingAgent can be instantiated with an {@link javax.management.ObjectName} pattern filter and a {@link javax.management.QueryExp} query filter. Only the source MBeans that satisfy both of them will be cascaded into the target MBeanServer.
Note that in a proxy-based cascading solution, as implemented by the {@link com.sun.jdmk.remote.cascading.proxy} package, the pattern and query filters will only be evaluated at the time where the target proxy MBean is registered in the target MBeanServer. Therefore, the QueryExp filter should only involve attributes/properties that do not change over time.
As a general rule, using non null QueryExp filters is thus highly discouraged.

It is possible, using disjoint patterns and filters, to use several CascadingAgents in order to cascade several disjoint sets of MBeans from the same remote MBeanServer. As explained in the previous section, all these CascadingAgents can share the same MBeanServerConnectionFactory. However if the sets of MBeans they cascade are not disjoint, then only one of the CascadingAgents will be able to cascade the conflicting MBeans. The other agents will usually skip conflicting names - though how conflicting names are managed is usually implementation dependent - see {@link com.sun.jdmk.remote.cascading.proxy.ProxyCascadingAgent}.
Although our Java DMK API permit such cascading schemes - we recommend to refrain from implementing them in an application.
We recommend using the Java DMK cascading API in a way that emulate FileSystem mountpoints, as explained in The File System Analogy.

Note that the pattern and query filters passed to the CascadingAgent are always evaluated in the context of the source MBeanServer - that is, using the ObjectNames of the source MBeans.

Notifications

CascadingAgents are {@link javax.management.NotificationEmitter Notification Emitters}. More specifically, they emit the {@link javax.management.remote.JMXConnectionNotification JMX Connection Notifications} received through their underlying MBeanServerConnectionFactory. Client application which are concerned about potential notifications loss from cascaded MBeans should therefore register for these notifications.

The cascading solution makes it also possible for a client application to transparently register for notifications emitted by source MBeans. This is done by invoking the regular add/remove notification listener methods of the target {@link javax.management.MBeanServer}. In the proxy-based cascading solution, the appropriate glue that makes this happen is implemented by the {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy} object, and is completely transparent to the application code. However, depending on the cascading implementation, some of the addNotificationListener(...) forms may not work - e.g. the proxy-based cascading may not always support the form where the listener is an ObjectName (e.g: when the listener is a cascaded MBean).

Subclassing

As explained in the File System Analogy, The Java DMK CascadingService and CascadingAgents makes it possible to emulate a File System mount operation. However, this analogy only goes so far: the mount operation is not completely transparent, in particular with regards to ObjectNames returned or passed to mounted MBeans.

Interpreting ObjectNames returned by cascaded MBeans

The names returned by MBeans that are mounted through a cascading agent needs to be interpreted in the context of the source MBean. The cascading solution proposed in this package will not translate any ObjectName passed as MBean method parameters, or returned as Attribute values or MBean method invocations.

Applications that would need to perform these substitutions can do so by providing their own CascadingProxy class - see {@link com.sun.jdmk.remote.cascading.proxy.ProxyCascadingAgent#createProxy ProxyCascadingAgent.createProxy(name,factory)}. That class could extend {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy CascadingProxy} in order to override the {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy#getAttribute getAttribute}, {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy#getAttributes getAttributes}, and {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy#invoke invoke} methods. In that case the setAttribute and setAttributes methods will probably need to be also overridden in a consistent manner.

Interpreting ObjectNames in Forwarded Notifications

The {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy} class used by the {@link com.sun.jdmk.remote.cascading.proxy.ProxyCascadingAgent} does not make the assumption that the name of the target cascading proxy in the target MBeanServer is the same than that of the proxied source MBean in the source MBeanServer. The CascadingProxy class thus contains the logic that will substitute the {@link javax.management.Notification} source with the target proxy ObjectName, as if the notification originated directly from the proxy object. Note however that only the Notification source is substituted, and only if it corresponds to the source ObjectName of the source MBean proxied by that CascadingProxy. Other ObjectNames that may be contained in the Notification are ignored.

Applications that would need deeper substitutions can do so by providing their own CascadingProxy class - see {@link com.sun.jdmk.remote.cascading.proxy.ProxyCascadingAgent#createProxy ProxyCascadingAgent.createProxy(name,factory)}. That class could extend {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy CascadingProxy} in order to override {@link com.sun.jdmk.remote.cascading.proxy.CascadingProxy#translate CascadingProxy.translate(Notification)}.

Note: The default CascadingService implementation does not let you provide your own CascadingAgent implementation. If your application needs to perform such substitutions you will thus have to provide your own implementation of CascadingServiceMBean, or work directly with CascadingAgents.

Name Conflict Detection

The CascadingAgent provides a {@link com.sun.jdmk.remote.cascading.CascadingAgentMBean#start(boolean) start(boolean conflictAllowed)} method that will throw an exception if a name conflict is detected at start time when conflictAllowed is false. Further name conflicts detected after start time are simply ignored and resolved by not registering a proxy in the target MBeanServer when a conflict arises.

The CascadingService provided in this package always calls CascadingAgent.start(false) in order to detect initial name conflicts. However it has no means to check that new MBeans locally created in the target MBeanServer will not conflict with new MBeans that may later appear in the cascaded source MBeanServer.

This kind of name conflicts can usually be avoided by using appropriate targetPaths as explained in the File System Analogy.

Example

An example of cascading over JSR 160 connector using this API is provided with Java DMK 5.1 examples.

@since Java DMK 5.1