The connector server on the agent side listens for management requests issued through a corresponding connector client. It transmits these requests to its MBean server and forwards any response back to the management application. The connector server also forwards notifications, when the management application has registered to receive them through its connector client (see "Notification Forwarding" for more details).
There is a connector server for each of the protocols supported in the Java Dynamic Management Kit: RMI, HTTP and HTTPS. They all inherit from the CommunicatorServer class which is the superclass for all protocol adaptors and connector servers. This class defines the methods needed to control the port and communication settings that are common to all. Each connector server class then provides specific controls, such as the service name for RMI and authentication information for HTTP. This example covers the RMI connector server, and the HTTP authentication mechanism is covered in "Password-Based Authentication".
A connector server listens for incoming requests from its corresponding connector client, decodes that request and encodes the reply. Several connector clients may establish connections with the same connector server, and the connector server can handle multiple requests simultaneously. There only needs to be one connector server MBean per protocol to which the agent needs to respond. However, several connector servers for the same protocol can coexist in an agent for processing requests on different ports.
The RMI connector server is an MBean, so we instantiate its class and register it in the MBean server. This operation could also be performed remotely, for example if a management application wishes to access an agent through an alternate protocol.
// Instantiate an RMI connector server with default port // CommunicatorServer rmiConnector = new RmiConnectorServer(); try { // We let the RMI connector server provides its default name ObjectName rmiConnectorName = null; ObjectInstance rmiConnectorInstance = myMBeanServer.registerMBean( rmiConnector, rmiConnectorName ); } catch(Exception e) { e.printStackTrace(); } |
Other constructors for the RmiConnectorServer class have parameters for specifing the port and the RMI service name that the connector server will use. The default constructor assigns port 1099 and "name=RmiConnectorServer", as given by the static variables RMI_CONNECTOR_PORT and RMI_CONNECTOR_SERVER, respectively, of the ServiceName class. Both attributes can also be accessed through the getter and setter methods of the RmiConnectorServer class.
Each connector uses different parameters that are specific to its protocol. For example, the HTTP connector does not need a service name. The default values for all parameters are given by the static variables of the ServiceName class.
Registering a connector server as an MBean implies that its MBean server will handle the remote requests that it receives. However, you may specify a different object for fulfilling management requests through the setMBeanServer method that the RmiConnectorServer class inherits from the CommunicatorServer class. For security reasons, this method is not exposed in the RMI connector server MBean, so it must be called from the agent application.
Registering the connector server as an MBean is optional: for example, you may not want it exposed for management. In this case, you must use the setMBeanServer method to specify an object which implements the MBeanServer interface so that it can fulfill management requests.
Like all communicator servers, the RMI connector server has a connection state which is identified by the static variables of the CommunicatorServer class:
OFFLINE - Stopped and not responding.
STARTING - In a transitional state and not yet responding.
ONLINE - Able to respond to management requests.
STOPPING - In a transitional state and no longer responding.
All connector servers are OFFLINE after their instantiation, so they must be started explicitly. Then, you must wait for a connector server to come ONLINE before it can respond to connections on its designated port.
// Explicitly start the RMI connector server // rmiConnector.start(); // waiting for it to leave starting state... while (rmiConnector.getState() == CommunicatorServer.STARTING) { try { Thread.sleep( 1000 ); } catch (InterruptedException e) { continue; } } |
Instead of blocking the application thread, you may register a listener for attribute change notifications concerning the State attribute of the connector server MBean. All connector servers implement this notification which contains both old and new values of the attribute (see "Attribute Change Notifications"). Listeners in the agent can then asynchronously detect when the state changes from STARTING to ONLINE.
During the STARTING state, the RMI connector server registers its RMI service name with the RMI registry on the local host for its designated port. If no registry exists, one is instantiated for the given port. Due to a limitation of the JDK software, creating a second registry in the same Java VM will fail. As a workaround, before starting an RMI connector server on a new, distinct port number in an agent, you must run the rmiregistry command from a terminal on the same host. This limitation is specific to the RMI connector: the HTTP protocols do not require a registry.
The stop method is used to take a connector server offline. The stop method is also called by the preDeregister method that all connector servers inherit. Stopping a connector server will interrupt all requests that are pending and close all connections that are active. When a connection is closed, all of its resources are cleaned up, including all notification listeners, and the connector client may be notified by a heartbeat notification (see "The Heartbeat Mechanism"). A connection that is closed can no longer be reopened, the connector client must establish a new connection when the connector server is restarted.
The setPort method that all connector servers inherit from the CommunicatorServer class allows you to change the port on which management requests will be expected. You can only change the port when the connector server is offline, so it must be explicitly stopped and then restarted. The same rule applies to the setServiceName method which is specific to the RMI connector server. These methods are also exposed in the MBean interface, along with start and stop, allowing a remote management application to configure the connector server through a different connection.