Java Dynamic Management Kit 5.0 Tutorial

Passive Discovery

In passive discovery, the entity seeking knowledge about agents listens for the activation or deactivation of their discovery responders. When discovery responders are started or stopped, they send out a proprietary message that contains all discovery response information. The DiscoveryMonitor object waits to receive any of these messages from the multicast group.

A discovery monitor is often associated with a discovery client. By relying on the information from both, you can keep an up-to-date list of all agents in a given multicast group.

Figure 17–3 Passive Discovery of Discovery Responders

Diagram showing passive discovery of discovery responders

Therefore, configuring and starting the discovery responder is an important step to the overall discovery strategy of your applications.

Discovery Responder

The agents that are configured to be discovered must have an active DiscoveryResponder registered in their MBean server. The responder plays a role in both active and passive discovery:

Both types of messages are proprietary and their contents are not exposed to the user. These messages contain information about the MBean server, its delegate's information and a list of communicator MBeans, unless not requested by the discovery client.

In our example we create the discovery responder in the MBean server and then activate it.


Example 17–3 Initializing a Discovery Responder

// Set the domain name for the demo
//
String domain = "DiscoveryDemo:" ;

// build the DiscoveryResponder MBean ObjectName
//
ObjectName discoveryResponderMBeanObjectName =
    new ObjectName(domain + "name=myDiscoveryResponder");

// Create and register the DiscoveryResponder MBean
//
try {
    ObjectInstance discoveryResponderObjectInstance =
        myMBeanServer.createMBean(
            "com.sun.jdmk.discovery.DiscoveryResponder",
            discoveryResponderMBeanObjectName) ;
    // we don't start the responder until our monitor is listening

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

[...]

try {
    myMBeanServer.invoke (discoveryResponderMBeanObjectName,
        "start", null, null) ;
} catch(Exception e) {
    echo("\tDiscoveryResponder MBean was already started.") ;
}

The discovery responder has attributes for exposing a multicast group and a multicast port. These attributes define a multicast socket that the responder will use to receive discovery requests. It will also send activation and deactivation messages to this multicast group. When sending automatic responses to discovery requests, the time-to-live is provided by the discovery client. The responder's time-to-live attribute is only used when sending activation and deactivation messages.

We use the default settings of the discovery responder that are the multicast group 224.224.224.224 on port 9000 with time-to-live of 1. In order to modify these values, you need to set the corresponding attributes before starting the discovery responder MBean. You can also specify them in the class constructor. If the responder is active, you will need to stop it before trying to set any of these attributes. In that way, it will send a deactivation message using the old values and then an activation message with the new values.

Discovery Monitor

The discovery monitor is a notification broadcaster: when it receives an activation or deactivation message from a discovery responder, it sends a discovery responder notification to its listeners. Once its parameters are configured and the monitor is activated, the discovery is completely passive. You can add or remove listeners at any time.

The DiscoveryMonitor MBean has multicast group and multicast port attributes that determine the multicast socket where it will receive responder messages. Like the other components of the discovery service, the default multicast group is 224.224.224.224 and the default port is 9000. You can specify other values for the group and port either in the constructor or through attribute setters when the monitor is off-line.

The discovery monitor in our example is registered as an MBean. We then add a listener through the MBean server as we would for any other notification broadcaster.


Example 17–4 Instantiating and Starting a Discovery Monitor

// build the DiscoveryMonitor MBean ObjectName
//
ObjectName discoveryMonitorMBeanObjectName =
    new ObjectName(domain + "name=myDiscoveryMonitor");

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

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

// Add ourselves as a listener to the DiscoveryMonitor MBean
//
try {
    myMBeanServer.addNotificationListener(
        discoveryMonitorMBeanObjectName, this, null, null ) ;

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

The discovery monitor must be activated with the start operation before it will receive responder messages and send notifications. It will be stopped automatically if it is unregistered from its MBean server. If it is not used as an MBean, you should invoke its stop method before your application exits.

Discovery Responder Notifications

When it receives a responder's activation or deactivation message, the discovery monitor sends notification objects of the DiscoveryResponderNotification class. This notification contains the new state of the discovery responder (ONLINE or OFFLINE) and a DiscoveryResponse object with information from the agent where the responder is located.

The listener could use this information to update a list of agents in the network. In our example, the listener is the agent application itself, and the handler method only prints out the information in the notification.


Example 17–5 Discovery Responder Notification Handler

public void handleNotification(
    javax.management.Notification notification, java.lang.Object handback) {

  // We know we will only receive this subclass, so we can do the cast
  DiscoveryResponderNotification discoveryNotif =
        (DiscoveryResponderNotification) notification;
  echo("\n>>> RECEIVED Discovery Notification FROM JDMK agent on host \"" +
        discoveryNotif.getEventInfo().getHost() + "\"");

  if ( discoveryNotif.getState().intValue() == DiscoveryMonitor.ONLINE ) {
        echo("\t DiscoveryResponder state = ONLINE");
  } else {  
        echo("\t DiscoveryResponder state = OFFLINE");
  }
  DiscoveryResponse info =
        (DiscoveryResponse) discoveryNotif.getEventInfo();

  // internal method for displaying the discovery response information
  printDiscoveryResponse(info);
}