Java Dynamic Management Kit 5.0 Tutorial

Active Discovery

In active discovery, the discovery client initiates searches for agents on the network. It involves a discovery client that sends the discovery request and a discovery responder in each agent that responds. Each instance of the responder supplies the return information about the agent in which it is registered. The return information is represented in the discovery client by a vector of discovery response objects.

The application containing the discovery client can initiate a search at any time. For example, it might do a search when it is first started and periodically search again for information about the communicators that might have changed. For each search, the discovery client broadcasts a request and waits for the return information from any responders.

In the following sections, we describe each of these objects in further detail.

Discovery Client

The DiscoveryClient class provides methods to discover agents. The active discovery operation sends a discovery request to a multicast group and waits for responses. These messages are proprietary and are not exposed to the user. Discovery clients can only discover agents listening on the same multicast group and port, so your design must coordinate this information between the discovery client and responders.

You can instantiate and perform searches from multiple discovery clients in a single application. Each discovery client can be configured to use different multicast groups or ports, enabling you to discover different groups of agents.

Since Java DMK 5.0, the discovery services enable users to specify a local interface from which to send out multicast messages. This is useful when working on a system that has multihome interfaces connecting to disconnected multinetworks. In addition, the DiscoveryResponder constructor enables you to specify the host address to be used to build the discovery response. The address can be specified either as an IPV4 or IPv6 address, or as a host name.

In our example, the discovery client is in an agent application: we register it as an MBean and interact with it through the MBean server.


Example 17–1 Instantiating and Initializing a Discovery Client

// build the DiscoveryClient MBean ObjectName
//
ObjectName discoveryClientMBeanObjectName =
    new ObjectName(domain + "name=myDiscoveryClient") ;

// Create, register and start the DiscoveryClient MBean
//
try {
    ObjectInstance discoveryClientObjectInstance =
        myMBeanServer.createMBean(
            "com.sun.jdmk.discovery.DiscoveryClient",
            discoveryClientMBeanObjectName) ;
    myMBeanServer.invoke (discoveryClientMBeanObjectName,
        "start", null, null) ;

} catch(Exception e) {
    e.printStackTrace();
    System.exit(1);
}

The default multicast group is 224.224.224.224 and the default port is 9000. These can be set to other values through the multicastGroup and multicastPort attributes, but only when the state of the discovery client is OFFLINE. Before initiating searches, you must call the discovery client's start method. This will create its multicast socket and join the multicast group used for broadcasting its discovery request.

The scope of the discovery request depends on the time-to-live used by the multicast socket. Time-to-live is defined by the Java class java.net.MulticastSocket to be a number between 1 and 255. By default, the time-to-live is 1, which corresponds to the host's local area network. You can modify this value at any time by setting the discovery client's TimeToLive attribute.

By default, a discovery client waits for responses for one second after it has sent a discovery request. This period can be customized by setting a value in milliseconds for its TimeOut attribute. When setting this attribute, you should take into account estimated time for a round-trip of a network packet using the given time-to-live.

Performing a Discovery Operation

An application triggers a search operation by invoking the findMBeanServers or findCommunicators methods on an active DiscoveryClient object. Using the current settings, it will send the multicast request and block for the timeout period. At the end of the timeout period, these methods return the responses that were received.

Both methods return a vector of DiscoveryResponse objects. This class exposes methods for retrieving information about the MBean server and the registered communicator MBeans in the agent. The MBean server information is the same as that exposed by that agent's MBean server delegate. The communicators are identified by ConnectorAddress objects and indexed by object name in a hash table.

Both search methods return the information about the agent's MBean server. The hash table of communicator MBeans is always empty for discovery responses returned by the findMBeanServers method. Otherwise, you can extract object names and protocol information from the hash table. One way of distinguishing the communicator MBeans is to rely on the default names provided by the ServiceName class.


Note –

All discovery messages sent between components of the discovery service are compatible between applications running different versions of the Java SDK or different versions of the Java Dynamic Management Kit (4.x only). However, these different configurations are not compatible for subsequent management operations through connectors. You can use the getImplementationVersion method of the DiscoveryResponse object to determine both the Java SDK and product version numbers.


In our example, we request all information about the agents and use a simple subroutine to print out all information in the discovery responses.


Example 17–2 Performing a Discovery Operation

// Discover all JDMK agents with a registered discovery responder
//
Vector discoveryResponses = (Vector) myMBeanServer.invoke (
    discoveryClientMBeanObjectName,"findCommunicators", null, null) ;

echo("We have found " + discoveryResponses.size() + " JDMK agent(s): ");
for (Enumeration e = discoveryResponses.elements();
     e.hasMoreElements();) {
    DiscoveryResponse discoveryResponse =
        (DiscoveryResponse)e.nextElement() ;
    printDiscoveryResponse(discoveryResponse) ;
}

[...]

private void printDiscoveryResponse(DiscoveryResponse discoveryResponse) {

    // display information about the agent's MBean server
    //
    echo("\t MBeanServerId = " + discoveryResponse.getMBeanServerId())  ;
    echo("\t\t host name        = " + discoveryResponse.getHost())  ;
    [...]

    // display information about communicator objects, if any
    //
    if (discoveryResponse.getObjectList() != null) {
    	for( Enumeration e= discoveryResponse.getObjectList().keys();
             e.hasMoreElements(); ) {
            ObjectName o = (ObjectName) e.nextElement();
            echo("\t\t Communicator name        = " + o ) ;
    	}
    }
}

On the agent side, the discovery responder automatically replies to discovery requests. Any active, registered responder in the same multicast group that is reached within the given time-to-live of the request will respond. It will automatically gather the requested information about its MBean server and send the response. The settings of the responder do not affect its automatic reply to discovery requests. In Discovery Responder we will cover how its settings control passive discovery.

In active discovery, the discovery client controls all parameters of a search it initiates, including the response mode of the discovery responder. The discovery client determines whether responses are sent back on a different socket (unicast) or sent to the same multicast group. The default is unicast: if you want to use the multicast response mode, set the PointToPointResponse attribute to false before initiating the discovery.

Unicast Response Mode

When the PointToPointResponse boolean attribute is true, the discovery client specifies unicast mode in its discovery requests. The responder will create a datagram socket for sending the response only to the discovery client. As shown in the following diagram, each responder will send its response directly back to the discovery client. The datagram socket used by each responder is bound to its local host address; this cannot be customized.

Figure 17–1 Unicast Response Mode

Unicast response mode

Multicast Response Mode

When the PointToPointResponse boolean attribute is false, the discovery client specifies multicast mode in its requests. The discovery responder will use the existing multicast socket to send response, broadcasting it to the same multicast group as the request. As shown in the following diagram, every member of the multicast group will receive the message, but only the discovery client can make use of its contents. Multicast mode avoids having to open another socket for the response, but all of the responses will create traffic in each application's socket.

Figure 17–2 Multicast Response Mode

Multicast response mode