Previous Next Contents Index


14


Event Handling, Alarm Clock, and Monitoring Services

The Java Dynamic Management Kit provides services for observing and reporting on the behavior of managed resources.


Event Handling Service

The Java Dynamic Management Kit provides event handling services for forwarding events through different communications protocols. For an m-bean that provides event handling services, you have to write code that defines:

Event Objects

Any event object you define must extend the event object defined by java.util.EventObject. The definition of an event object named SimpleEvent object is given in CODE EXAMPLE 14-1.

CODE  EXAMPLE  14-1     Definition of an Event Object

   public class SimpleEvent extends java.util.EventObject
   implements java.io.Serializable {

      public SimpleEvent(Simple source, Integer val) {
         super(source);
         nbChanges= val;
      }

      public Integer getNbChanges() {
         return nbChanges;
      }
      private Integer nbChanges;
   }


Listeners

Any listener you define must be an interface containing one or more methods. Each method must have exactly one input parameter. The input parameter must specify the event object that the listener listens for. The event object must be as described in "Event Objects." An event listener class must always be declared as a public class. The definition of a listener interface named SimpleListener interface is given in CODE EXAMPLE 14-2. The listener in this example listens for SimpleEvent objects as defined in CODE EXAMPLE 14-1.

CODE  EXAMPLE  14-2     Definition of a Listener Interface 

   public interface SimpleListener extends java.util.EventListener {

   public void handleEvent1(SimpleEvent evt);

   public void handleEvent2(SimpleEvent evt);
   }


Listener Methods in an M-Bean

When writing an m-bean that provides event handling services, you have to define methods for adding and removing listeners. These methods must conform to the design patterns for event sources defined in Chapter 3. An example of how to register and remove listeners is shown in CODE EXAMPLE 14-3.

CODE  EXAMPLE  14-3     Listeners in an M-Bean

   public synchronized void addSimpleListener(SimpleListener x) {
   simpleListeners.addElement(x);
   }

   public synchronized void removeSimpleListener(SimpleListener x){
      simpleListeners.removeElement(x);
   }


Developing a Manager to Receive Events

The steps in developing a manager to receive events from an m-bean are:

CODE EXAMPLE 14-4 shows code for receiving framework events in a Java manager through an adaptor client.

CODE  EXAMPLE  14-4     Receiving Framework Events

   ObjectName fmkName = new ObjectName(":" + ServiceName.FRAME) ;
   Vector objVect = adaptor.getObject(fmkName, null) ;
   FrameworkMO fmkObj = (FrameworkMO)objVect.firstElement();
   fmkObj.addFrameworkListenerMO(this) ;


The mogen compiler is described in detail in Chapter 6.

Output From mogen for an M-Bean With Listeners and Events

An m-bean that uses a listener is associated with Java classes that represent the listener and the event that is listened for. For example, an m-bean that defines the Java class example is associated with:

For further information, see Chapter 3 "Design Patterns for Developing M-Beans."

For such an m-bean, the mogen compiler generates:

For example, an m-bean representing the Java class named Simple defines a listener interface called SimpleListener. In this example, SimpleListener listens for an event called SimpleEvent. The Java source code defining this example is shown in CODE EXAMPLE 14-1, CODE EXAMPLE 14-2 and CODE EXAMPLE 14-3.

When compiling the Simple m-bean, mogen generates interfaces and stubs as 
illustrated in FIGURE 14-1. The interfaces and stubs generated are described in 
TABLE 14-1.

FIGURE  14-1 Output of the mogen Compiler for Listeners and Events


TABLE  14-1 Output for an M-Bean That Uses Listeners and Events

M-Bean Class
C-Bean Code Generated
Comment

Simple.class

SimpleMO.java

Defines which of the methods of the m-bean are accessible to a Java manager. CODE EXAMPLE 14-5 shows the generated code corresponding to the methods in the m-bean for adding and removing listeners.

SimpleMOStub.java

Implements the methods defined in the Java interface SimpleMO.

SimpleListener.class

SimpleListenerMO.java

Defines the interface to be implemented to register for events on SimpleMO. In the SimpleListenerMO interface, the event object is called SimpleEventMO.

SimpleListenerStub.java

Implements the SimpleListener interface for catching events emitted by the Simple m-bean and forwarding them to SimpleMO.

SimpleEvent.class

SimpleEventMO.java

Defines the event type emitted by the SimpleMO c-bean whenever its associated Simple m-bean emits an event of type SimpleEvent


CODE EXAMPLE 14-5 shows the code generated in SimpleMO.java corresponding to the methods in the Simple m-bean for adding and removing listeners. The code shown in CODE EXAMPLE 14-5 is a subset of the code mogen generates in the SimpleMO.java when compiling the Simple m-bean.


CODE  EXAMPLE  14-5     Generated Code for the SimpleMO Interface

public interface SimpleMO extends ManagedObject {
...
   public void addSimpleListenerMO(SimpleListenerMO x )
      throws InstanceNotFoundException, IllegalAccessException,
         InstantiationException, ClassNotFoundException;
         InstanceNotFoundException, ClassNotFoundException;

   public void removeSimpleListenerMO(SimpleListenerMO x );
...
}


Suppressing Code Generation for Listeners

Options of the mogen compiler enable you to generate a c-bean without any code for listeners or events. This is useful if you want to reduce the size of a c-bean, or if you want to prevent a user of the Java manager from listening for events. If you modify an m-bean without modifying its listeners, you can use these options to regenerate the c-bean without affecting code already generated for listeners and events.

To generate a c-bean without any code for listeners or events, specify any combination of these options in the command to start mogen:

For a full list of the mogen compiler options, see "Options for mogen" on page 68.

Using Code Generated for Listeners and Events

To use a c-bean generated for a listener, you have to implement the beanListenerMO interface to add or remove the listener on the c-bean. To add a beanListenerMO on a beanMO object, include a call to addbeanListenerMO in the Java manager you develop. The listener waits for events sent by the corresponding bean object. CODE EXAMPLE 14-6 shows code for adding and removing a listener in a manager.

CODE  EXAMPLE  14-6     Creating and Removing an Event Listener in a Manager

   //Create an event listener
   ClientListener listener = new ClientListener();

   // Add this manager as a listener for SimpleEvent events
   //
   mo.addSimpleListenerMO(listener);
...
   // Remove the listener
   //
   mo.removeSimpleListenerMO(listener);
...


In the example shown in CODE EXAMPLE 14-6:

When addbeanListenerMO is called to add the listener beanListenerMO on the c-bean, the adaptor transparently instantiates a listener beanListenerStub on the remote m-bean. The code generated for beanListenerStub includes the code required for registering itself as a listener on the m-bean.

When the m-bean emits an event (beanEvent), the registered beanListenerStub forwards the event to the c-bean. The c-bean (beanMOStub) then calls all the beanListenerMO listeners registered. The mechanism for adding event listeners is illustrated in FIGURE 14-2.

FIGURE  14-2 Mechanism for Adding an Event Listener

Defining Your Own Event Handler

Any event handling service you define must implement the com.sun.jaw.reference.agent.services.EventHandlerIf interface. To enable an event handling service to be identified, the class part of its object name must be ServiceName.EVENT.


Alarm Clock Service

The alarm clock service activates (or "wakes up") alarm clock event listeners when the timeout elapses. The alarm clock service is not manageable as no MO stubs are provided, therefore it must be used locally. To add an alarm clock, create an instance of the com.sun.jaw.impl.agent.services.alarm.AlarmClock class.

All events sent by an alarm clock are instances of the class com.sun.jaw.impl.agent.services.alarm.AlarmClockEvent. To enable an application to receive alarm clock events, ensure that the application implements the com.sun.jaw.impl.agent.services.alarm.AlarmClockListener interface. This interface contains a single method for handling alarm clock events. The prototype of this method is defined in CODE EXAMPLE 14-7.


CODE  EXAMPLE  14-7     Prototype of the handleAlarmClockEvent Method

public abstract void handleAlarmClock(AlarmClockEvent event);


Setting the Alarm Clock Timeout

To set an alarm clock timeout, use the setTimeout method specifying the required elapsed time, in milliseconds, after which the alarm clock event will be sent. CODE EXAMPLE 14-8 shows the instantiation of an an alarm clock and use of the setTimeout method to set the timeout for the alarm clock.    

CODE  EXAMPLE  14-8     Instantiating and Setting the Alarm Clock

// Instantiate an alarm clock
AlarmClock alarm= new AlarmClock();

// Set timeout in milliseconds
alarm.setTimeout(new Integer(30000));


Getting the Alarm Clock Timeout

CODE EXAMPLE 14-9 shows how to get the timeout for the alarm clock service that was instantiated in CODE EXAMPLE 14-8.

CODE  EXAMPLE  14-9     Getting the Alarm Clock Timeout

// Get timeout in milliseconds
Integer value= alarm.getTimeout();


The alarm clock service is used by the scheduler service and the monitoring service.


Scheduler Service

The scheduler service enables you to create alarms for specific dates and times. The alarms or `scheduler events' are sent to all objects registered to receive scheduler events. An object is registered to receive scheduler events by adding a scheduler listener interface. The scheduler service is not manageable as no MO stubs are provided, therefore it must be used locally.

The scheduler class uses a vector to store the scheduler events. A method is provided that allows you to add events. Each scheduler event runs in a separate thread and has a dedicated AlarmClock object. When the scheduler is started, all of the alarm clock objects associated with the scheduler events are updated and started. If any of the alarm clocks have dates that have passed, the scheduler either sends them immediately or discards them. This behavior is defined by setting the notifyPastEvents flag.

To create a scheduler, create an instance of the following class: com.sun.jaw.impl.agent.services.scheduler.Scheduler    


CODE  EXAMPLE  14-10     Creating a Scheduler  

   private Scheduler           sch = new Scheduler();  
      // Create a new scheduler,
      // this object is not registered in the framework


Scheduler Listener

You must implement a SchedulerListener interface in any object that receives scheduler event objects. This registers the object as a scheduler listener. To add a SchedulerListener, invoke the addSchedulerListener method of the scheduler. CODE EXAMPLE 14-11 shows the code for registering as a scheduler listener with the sch scheduler created in CODE EXAMPLE 14-10.     

CODE  EXAMPLE  14-11     Scheduler Listener Interface  

   sch.addSchedulerListener(this);
      // Register as a scheduler listener


Scheduler Events

Scheduler events are defined as instances of the Java class: com.sun.jaw.impl.agent.services.scheduler.SchedulerEvent.

The scheduler that generates the event must be specified when instantiating a new SchedulerEvent object. CODE EXAMPLE 14-12 shows the constructor for an object called EventSpring. The EventSpring object extends SchedulerEvent.    


CODE  EXAMPLE  14-12     Creating a Scheduler Event  

   public class EventSpring extends SchedulerEvent {
      public EventSpring(Scheduler source) {
         super(source);
      }
   }


There are two types of scheduler events:

The event type is defined by the parameters passed to the scheduler when the event is added.

Adding Events to the Scheduler

Events are added to the scheduler vector using the scheduler's performAddEvent method. The performAddEvent method is overloaded and, in addition to the event and date, can take the following optional parameters:

If the scheduler event to be inserted has a date that is before the current date, the method attempts to update the event by adding the defined period to the event date to make it later than the current date. If a null periodicity is defined, the event cannot be updated to a valid date and an InvalidPropertyValueException is thrown.

If the scheduler event has a non-null periodicity, the performAddEvent method updates the event date by adding the periodicity until the event date is later than the current date. When the event date is later than the current date, the method inserts the scheduler event into the vector.

If a number of repetitions is specified with the periodicity, the performAddEvent method updates the event date as before. The number of times that the method adds the period is limited to the specified number of repetitions. If the event date remains earlier than the current date, the method generates an exception.

After an event has been added to the scheduler vector, it cannot be updated.

CODE EXAMPLE 14-13 shows the addition of an evtSpring object to the scheduler sch that was created in CODE EXAMPLE 14-10. The variable ONE_SECOND is defined in the scheduler class.    


CODE  EXAMPLE  14-13     Adding Events to the Scheduler  

   Date currentDate = new Date();
   Date dSpring = new Date();
    
   // Date of the scheduler event
   dSpring.setTime(currentDate.getTime() + 2 *
                               Scheduler.ONE_SECOND);

   // Set the period of the scheduler event
   long periodSpring = 8 * Scheduler.ONE_SECOND;

   // Create the scheduler event
   evtSpring = new EventSpring(sch);

   // Add event
   sch.performAddEvent((SchedulerEvent)evtSpring,
                                       dSpring, periodSpring);


Removing Events From the Scheduler

Events are removed from the scheduler vector using the scheduler's performRemoveEvent method. The performRemoveEvent method is overloaded and can take either the scheduler event or the position of the event in the vector as parameters. If the event specified is not in the vector or the index is invalid, the method throws an InstanceNotFoundException.

CODE EXAMPLE 14-14 shows both ways of removing a scheduler event from the scheduler vector.


CODE  EXAMPLE  14-14     Removing Events From the Scheduler  

   // Remove the event evtSpring from the vector
   //
   sch.performRemoveEvent(evtSpring);
...
   // Remove the event evtSpring from the vector
   // evtSpring is in position number two in the vector
   //
   int index = 2;
   sch.performRemoveEvent(index);


Starting and Stopping the Scheduler

The scheduler is started using the scheduler performStart method and stopped using the performStop method. If the vector is empty when the scheduler is started, the scheduler waits for an event to be added. If events are added later, the associated alarm clock is instantiated and started. The alarm clock timeout is set for the required event date.

You can determine whether the scheduler is running or not by invoking the scheduler method isActive. The isActive method returns true if the scheduler is running.

If any of the alarm clocks have dates that have passed when the scheduler is started, the event is ignored or sent immediately. The action taken is defined by the notifyPastEvents flag.    


notifyPastEvents = true

All events with a date before the current date are handled;
the alarm clocks are updated and notification is sent.

notifyPastEvents = false

Events with a date before the current date are ignored;
the alarm clocks are updated but no notification is sent.


Setting the notifyPastEvents flag to false can be used to suppress a flood of scheduler events being sent out when the scheduler is started. The default value for this flag is false.

CODE EXAMPLE 14-15 shows code for starting and stopping a scheduler.


CODE  EXAMPLE  14-15     Starting and Stopping the Scheduler  

  public void performStartScheduler() throws
  InstanceAlreadyExistException, InvalidPropertyValueException {
        if (sch.isListOfEventsEmpty() == true) {
           performAddSeasonEvent();                  // Add events
        }

        sch.performStart();                          // Starts the scheduler
  }

...

public void performStopScheduler() throws
   SchedulerIllegalAccessException {
        sch.performStop();                // Stops the scheduler service.
        sch.performRemoveAllEvents();     // Deletes the remaining events
                                          // from the scheduler vector.
        state = "initial state";          // Resets the season object.
        temp = new Float(0);
  }


   

Scheduler Event Handling

When the date of an event in the event list is reached, the handleScheduler method is invoked. CODE EXAMPLE 14-16 shows an example of how the events can be handled. This example uses four events:


CODE  EXAMPLE  14-16     Scheduler Event Handling  

 public void handleScheduler(SchedulerEvent event) {
   if (event instanceof EventSpring) {
      temp = new Float(15);
      state = "Spring weather";
   }
   else if (event instanceof EventSummer) {
      temp = new Float(30);
      state = "Summer weather";
   }
   else if (event instanceof EventAutumn) {
      temp = new Float(15);
      state = "Autumn weather";
   }
   else if (event instanceof EventWinter) {
      temp = new Float(0);
      state = "Winter weather";
   }
   else
      return;
 }



Monitoring Service

The monitoring service enables the variation with time of a property in an m-bean to be monitored. The observed property is monitored at intervals specified by the granularity period. An event notification is sent when the value of the property satisfies one of a set conditions. You specify the conditions when you initialize a monitor.

Types of Monitor

Information on the value of a property within an m-bean is provided by two different monitors:

Both monitors are defined as Java classes that extend one of the following generic monitor classes:

Each of these classes defines attributes and methods common to both types of monitor.

Counter Monitor

A counter monitor sends an event notification when the value of the counter reaches or exceeds a threshold known as the comparison level. In addition, an offset mechanism enables particular counting intervals to be detected.

If the counter can wrap around its maximum value, then the modulus of the counter needs to be specified. The modulus is the value at which the counter is reset to zero. The operation of the counter monitor is illustrated in FIGURE 14-3.


Note - The counter monitor can only be used with properties of type integer. The property must be increased in increments of one unit only.

Gauge Monitor

A gauge monitor observes a property that is continuously variable with time. A high threshold value and a low threshold value are specified. Events are sent as follows:

This provides a hysteresis mechanism to avoid repeated triggering of event notifications when the value of the property makes small oscillations around the high or low threshold value.


Note - The gauge monitor can only be used with properties of type integer or float.
The operation of the gauge monitor is illustrated in FIGURE 14-4.

Adding a Monitor

You can add a monitor to an agent or a manager, depending on where you want the events the monitor sends to be processed. To add a monitor, create an instance of the Java class that implements the monitor you want to add.

Monitor
Java Class

Counter:

  • Agent
  • com.sun.jaw.impl.agent.services.monitor.CounterMonitor

  • Manager
  • com.sun.jaw.impl.agent.services.monitor.CounterMonitorMO

    Gauge:

  • Agent
  • com.sun.jaw.impl.agent.services.monitor.GaugeMonitor

  • Manager
  • com.sun.jaw.impl.agent.services.monitor.GaugeMonitorMO


    CODE EXAMPLE 14-17 shows code for creating and initializing a counter monitor in an agent.


    CODE  EXAMPLE  14-17     Creating and Initializing a Counter Monitor 

       // Counter Monitor
       //
       try {
          CounterMonitor cm = (CounterMonitor)
             cmf.newObject
                ("com.sun.jaw.impl.agent.services.monitor.CounterMonitor",
                cmf.getDomain()+":"+"com.sun.jaw.impl.agent.services.monitor.
                                                      CounterMonitorMO.id=1");


    // The object to be added as listener implements the MonitorListener interface
          cm.addMonitorListener((MonitorListener) this); // this - current instance
          cm.setObservedObject(object_name);
          cm.setObservedProperty(property_name);
          cm.setGranularityPeriod(new Integer(30000));   //* 30 secs */
          cm.setComparisonLevel(new Integer(3));
          cm.setNotifyOnOff(new Boolean(true));
          cm.setOffsetValue(new Integer(2));
          cm.setCounterDifferenceOnOff(new Boolean(false)); // True if diff counter
          cm.performStart();
          } catch (Exception e) {
          System.out.println("Exception occurs: " + e.getMessage());
          e.printStackTrace();
          System.exit(0);
          }


    CODE EXAMPLE 14-18 shows code for creating and initializing a gauge monitor in an agent.


    CODE  EXAMPLE  14-18     Creating and Initializing a Gauge Monitor 

       // Gauge Monitor
       //
       try {
          GaugeMonitor gm = (GaugeMonitor)
             cmf.newObject
                ("com.sun.jaw.impl.agent.services.monitor.GaugeMonitor",
             cmf.getDomain()+":"+"com.sun.jaw.impl.agent.services.monitor.
                                                     GaugeMonitorMO.id=1");
    // The object to be added as listener implements the MonitorListener interface
          gm.addMonitorListener((MonitorListener) this); //this - current instance
          gm.setObservedObject(object_name);
          gm.setObservedProperty(property_name);
          gm.setGranularityPeriod(new Integer(20000));     // 20 secs
          gm.setThresholdLowValue(new Integer(20));
          gm.setThresholdHighValue(new Integer(80));
          gm.setNotifyLowOnOff(new Boolean(true));
          gm.setNotifyHighOnOff(new Boolean(true));
          gm.setGaugeDifferenceOnOff(new Boolean(false));  // True if diff gauge
          gm.performStart();
          } catch (Exception e) {
          System.out.println("Exception occurs: " + e.getMessage());
          e.printStackTrace();
          System.exit(0);
          }


    Listening for Monitor Events

    All events sent by a monitor are instances of the class com.sun.jaw.impl.agent.services.monitor.MonitorEvent, regardless of the type of monitor. The constructor for this class requires that the monitor that sent the event, the event type, and information about the cause of the event are specified.

    To enable an application to receive monitor events, you have to make sure that the application implements a monitor listener interface. The interface your application must implement is independent of the type of monitor, although it depends whether the application is an agent or a manager:      


    Application
    Java Interface

    Agent

    com.sun.jaw.impl.agent.services.monitor.MonitorListener

    Manager

    com.sun.jaw.impl.agent.services.monitor.MonitorListenerMO


    Both of these interfaces contain a single method for handling monitor events. The prototype of this method on the agent side is defined in CODE EXAMPLE 14-19.


    CODE  EXAMPLE  14-19     Prototype of the handleMonitorEvent Method

       public abstract void handleMonitor(MonitorEvent event);


    An application that receives monitor events must also include code for registering itself as a monitor listener. To add a monitor listener, invoke the addMonitorListener method of the monitor as shown in CODE EXAMPLE 14-20. In this example, gm is an instance of the GaugeMonitor class instantiated, as shown in CODE EXAMPLE 14-18.


    CODE  EXAMPLE  14-20     Adding a Monitor Listener

       gm.addMonitorListener((MonitorListener) this);
       // this - current instance


    Specifying the Property to be Monitored

    A monitor observes a particular property in a particular m-bean instance. To specify the property to be monitored, invoke both of these methods of the monitor:

    Code for specifying the object name of an m-bean instance and the property in it to be monitored is shown in CODE EXAMPLE 14-21. In this example, gm is an instance of the GaugeMonitor class instantiated as shown in CODE EXAMPLE 14-18. The monitor monitors the property NbChanges in the only instance of the SimpleBean class present in the default domain of the agent.

    CODE  EXAMPLE  14-21     Specifying a Property to be Monitored

       // ObjectName of object to be monitored
       ObjectName object_name = new
       ObjectName("defaultDomain:examples.mo.Simple.SimpleBean");
    ...
       // String representing the name of the property to be monitored
       String property_name = new String("NbChanges");
    ...
       gm.setObservedObject(object_name);
       gm.setObservedProperty(property_name);


    Setting the Granularity Period

    The observed property is monitored at intervals specified by the granularity period. It is specified in milliseconds. To set the granularity period, invoke the setGranularityPeriod method of the monitor, as shown in CODE EXAMPLE 14-22. In this example, cm is an instance of the CounterMonitor class instantiated as shown in CODE EXAMPLE 14-17. The granularity period is set to 30 000 milliseconds (30 seconds).

    CODE  EXAMPLE  14-22     Setting the Granularity Period of a Monitor

       cm.setGranularityPeriod(new Integer(30000)); // 30 seconds


    Specify a granularity period that is consistent with the rate at which the property changes.

    Setting Parameters for Counter Monitors

    FIGURE 14-3 shows the operation of a counter monitor. The monitor monitors a counter C(t) which varies with time t. The granularity period is G and the comparison level is T.

    FIGURE  14-3 Operation of the Counter Monitor
    A counter monitor sends an event notification when the value of the counter reaches or exceeds the comparison (threshold) level. After the event has been sent, the comparison level is incremented by the offset value until the comparison level is greater than the current value of the counter.

    Setting the Comparison Level for a Counter Monitor

    When a monitored counter reaches or exceeds its comparison level, an event is sent if specified. To set the comparison level, invoke the setComparisonLevel method of the counter monitor. To specify whether an event is sent, invoke the setNotifyOnOff method of the counter monitor. This is shown in CODE EXAMPLE 14-23. In this example, cm is an instance of the CounterMonitor class instantiated as shown in CODE EXAMPLE 14-17. The comparison level is three and an event will be sent when the counter reaches or exceeds this value.

    CODE  EXAMPLE  14-23     Setting the Threshold Value of a Counter Monitor

       cm.setComparisonLevel(new Integer(3));
       cm.setNotifyOnOff(new Boolean(true));


    As shown in FIGURE 14-3, an event is sent as soon as the counter is monitored after its value has reached the initial comparison level of three.

    Setting the Offset for a Counter Monitor

    The counter monitor provides an offset mechanism to enable a counting interval to be detected. If you specify an offset value, the comparison level is increased by the offset value each time the current comparison level is reached. This takes place before the counter is increased to avoid duplicate events being sent. To set the offset value, invoke the setOffsetValue method of the counter monitor, as shown in CODE EXAMPLE 14-24. In this example, cm is an instance of the CounterMonitor class instantiated as shown in CODE EXAMPLE 14-17. The offset value is two.

    CODE  EXAMPLE  14-24     Setting the Offset Value

       cm.setOffsetValue(new Integer(2));


    As shown in FIGURE 14-3, an event is sent as soon as the counter is monitored after its value reaches the comparison level (after the first addition of the offset) at five, and (after the second addition of the offset) at seven.

    Setting the Modulus Value for a Counter Monitor

    If the counter you are monitoring is able to wrap around when it reaches its maximum value, you must set its modulus value. The modulus is the value at which a counter is reset to 0. To set the modulus, invoke the setModulusValue method of the counter monitor. This is shown in CODE EXAMPLE 14-25. The modulus value is 500.

    CODE  EXAMPLE  14-25     Setting the Modulus Value

       cm.setModulusValue(new Integer(500));


    Using a Counter Monitor to Track Differences

    Using a counter monitor to track differences enables you to observe the rate at which a counter changes. If you specify the counter difference option, an event is sent when the derived gauge reaches or exceeds the comparison level. The derived gauge is calculated as the difference between the observed counter values for two successive observations. If this difference is negative, that is, the counter has wrapped around, then the value of the derived gauge is increased by the value of the modulus. This can be expressed algebraically as follows:

    where:

    To specify the counter difference option, invoke the setCounterDifferenceOnOff method of the counter monitor. This is shown in CODE EXAMPLE 14-26. In this example, cdm is an instance of the CounterMonitor class.

    CODE  EXAMPLE  14-26     Monitoring Counter Differences

       cdm.setCounterDifferenceOnOff(new Boolean (true));


    Setting Parameters for a Gauge Monitor

    FIGURE 14-4 shows the operation of a gauge monitor. The monitor monitors a property P(t) that varies with time t. The granularity period is G, the lower threshold is TL, and the higher threshold is TH.

    FIGURE  14-4 Operation of the Gauge Monitor

    Setting the Threshold Values for a Gauge Monitor

    To set the threshold values invoke these methods of the gauge monitor:

    You have to set threshold values in pairs. This restriction enables the gauge monitor to provide a hysteresis mechanism. The difference between the high and low threshold values is the hysteresis interval.

    The high threshold value and the low threshold value must be of the same type as the observed property. The high threshold value must be greater than or equal to the low threshold value.

    To specify whether an event is sent, invoke these methods of the gauge monitor:

    This is shown in CODE EXAMPLE 14-27. In this example, gm is an instance of the GaugeMonitor class instantiated as shown in CODE EXAMPLE 14-18. The low threshold value is 20 and the high threshold value is 80. Threshold high and threshold low events will be sent when the event conditions are satisfied.

    CODE  EXAMPLE  14-27     Setting the Threshold Values for a Gauge Monitor

       gm.setThresholdLowValue(new Integer(20));
       gm.setThresholdHighValue(new Integer(80));
       gm.setNotifyLowOnOff(new Boolean(true));
       gm.setNotifyHighOnOff(new Boolean(true));


    Using a Gauge Monitor to Track Differences

    Using a gauge monitor to track differences enables you to observe the rate at which a gauge property changes. If you specify the gauge difference option, an event is sent when the derived gauge exceeds its specified upper or lower threshold according to the hysteresis mechanism. The derived gauge is calculated as the difference between the observed property values for two successive observations. This can be expressed algebraically as follows:

    V(t) = P(t) - P(t-G)

    where:

    To specify the gauge difference option, invoke the setGaugeDifferenceOnOff method of the gauge monitor as shown in CODE EXAMPLE 14-28. In this example, gdm is an instance of the GaugeMonitor class.

    CODE  EXAMPLE  14-28     Monitoring Gauge Differences

       gdm.setGaugeDifferenceOnOff(new Boolean(true));


    Setting Multiple Thresholds for a Property

    For a single monitor you are allowed to specify only one pair of threshold values. To specify more than one pair of threshold values, create one monitor for each pair of threshold values you want to specify. Make sure that each monitor you create monitors the same property in the same m-bean instance.

    Starting and Stopping a Monitor

    To start or stop a monitor, invoke the performStart or performStop method of the monitor. CODE EXAMPLE 14-29 shows how to start and stop a monitor. In this example, gm is an instance of the GaugeMonitor class instantiated as shown in CODE EXAMPLE 14-18.

    CODE  EXAMPLE  14-29     Starting and Stopping a Monitor

       gm.performStart();         // Starts the monitor
    ...
       gm.performStop();          // Stops the monitor


    When a monitor is stopped, it is reset. For a counter monitor, this means that when the monitor is restarted, the comparison level is reset to the value specified in the last invocation of the setComparisonLevel method. For a gauge monitor, this means that when the monitor is restarted, there is no record of the type (TH or TL) of the last event sent. An event is sent as soon as one of the thresholds is reached or exceeded.


    Discovery Service

    The discovery service enables you to discover Java Dynamic Management agents in a network. Only agents that have a discovery responder registered in their framework can be discovered using this service. The discovery service can be functionally divided into two parts:

    Discovery Search Service

    The discovery search service consists of a discovery client that initiates the discovery operation and a discovery responder, each instance of which supplies the return information about the agent in which it is registered. The return information is represented in the discovery client by a discovery response object.

       

    FIGURE  14-5 Discovery Search Service

    Discovery Client

    The DiscoveryClient class provides methods to discover agents. The discovery operation is initiated by the discovery client that 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. The default multicast group is 224.224.224.224 and the default port is 9000. The multicast group and port can be reconfigured to other values by changing the multicastGroup and multicastPort properties on the DiscoveryClient object. The DiscoveryClient does not join the multicast group until the performStart method is invoked.

    You can instantiate multiple discovery clients on a single agent or manager. Each discovery client can be configured to use different multicast groups or ports. This allows you to use a single agent or manager for monitoring different groups of agents.

    To instantiate a discovery client, create an instance of the Java class: com.sun.jaw.impl.agent.services.jawdiscovery.DiscoveryClient. The scope of the discovery depends on the time-to-live used by the multicast socket. Time-to-live is defined by the Java class java.net.MulticastSocket. By default, the time-to-live is 1. It can be changed by setting the property timeToLive on the discovery client.

    After it has sent a discovery request, a discovery client waits for responses for a specific time. By default the time is 1 second. This can be customized by setting the timeOut property, in milliseconds, on the discovery client. The discovery client also requests the DiscoveryResponder response type; this can be unicast or multicast. The response type is specified using the returnPort variable, a negative number specifies a multicast response. For further information, see page 212. CODE EXAMPLE 14-30 shows the instantiation, initialization, and starting of a discovery client using a non-default multicast group and port.   


    CODE  EXAMPLE  14-30     Instantiating and Initializing a Discovery Client  

       disc = new DiscoveryClient ();
          disc.setMulticastGroup("224.224.224.222");
          disc.setMulticastPort(9002);
          // instantiate a discovery client using non default
          // multicast group and port
    ...
       int timeOut = 1000 ;       // wait for response timeout
       int returnPort = -1 ;      // request multicast response
       int ttlint = 2 ;           // scope

       disc.setTimeOut(timeOut) ;
       disc.setPointToPointResponsePort(returnPort) ;
       disc.setTimeToLiveInt(ttlint) ;
       disc.performStart() ;      // start the discovery client


    Discovery Responder

    The agents must have a DiscoveryResponder registered in their framework to be found by the discovery service. When a new DiscoveryResponder object registers in an agent, or when its performStart method is invoked, it sends out a multicast registration message. Similarly, a responder that deregisters or has its performStop method invoked, sends a multicast deregistration message. These messages are proprietary and are not exposed to the user. The registration/deregistration messages enable you to keep an accurate record of agents with discovery responders in the network; for further information, see "Discovery Support Service" on page 214.

    Discovery responders reply to a request from a discovery client by sending a response that contains information on the hostname of the agent and, optionally, a list of adaptors available in the agent. The message is proprietary and is decoded and represented in the DiscoveryClient by the DiscoveryResponse object. The DiscoveryResponse object consists of a string representing the hostnames of discovered agents and a vector of ObjectName representing the adaptors found on each agent. CODE EXAMPLE 14-31 shows the initialization of a discovery responder.    


    CODE  EXAMPLE  14-31     Initializing a Discovery Responder  

      private static final String multicastResponder=       "com.sun.jaw.impl.agent.services.jawdiscovery.DiscoveryResponder" ;

    // register a discovery responder with the framework
    // the responder uses the multicast group 224.224.224.222
    // and port 9002

      String properties = ".group = 224.224.224.222, port = 9002";
      DiscoveryResponder disc ;
         disc = (DiscoveryResponder) agent.framework.newObject(multicastResponder,
                agent.framework.getDomain() + ":" + multicastResponder
                + properties, null);


    The discovery responder registered in the discovered agent can respond using one of two modes:

    The response method used is specified when the discovery client is initialized. The default is unicast.

    Unicast Mode
    The discovery responder creates a datagram socket for the response to the discovery client. The response is not multicast to the group. The datagram socket address is the same as the local host; this cannot be customized. Unicast mode is enabled by invoking the setPointToPointResponse method with the Boolean value TRUE.

    FIGURE  14-6 Unicast Discovery Mode
    Multicast Mode
    The discovery responder uses a multicast socket to send response messages. The response messages are multicast to the group. Multicast mode is enabled by invoking the setPointToPointResponse method with the Boolean value FALSE.

     

    FIGURE  14-7 Multicast Discovery Mode

    Performing a Discovery Operation

    An application triggers a discovery operation by invoking the methods performFindHosts or performFindAdaptors on a DiscoveryClient object. Both methods return a vector of DiscoveryResponse objects. The DiscoveryResponse object returned by the performFindHosts method contains a string which is the hostname of a discovered agent. The DiscoveryResponse object returned by the performFindAdaptors method contains a string which is the hostname of a discovered agent and a vector of object names which represents a list of adaptors instantiated on that agent. CODE EXAMPLE 14-32 shows code for performing a discovery operation.   

    CODE  EXAMPLE  14-32     Performing a Discovery Operation  

       Vector result ;

       result = disc.performFindAdaptors () ;


    Discovery Support Service

    The discovery support service enables you to monitor discovery responders in a multicast group. A DiscoveryMonitor object listens for discovery responder objects registering or deregistering in the multicast group. When the discovery monitor hears a discovery responder registering or deregistering, it sends a discovery responder event to its listener. The listener is an instance of the Java class that implements the DiscoveryResponderListener interface.  

     

    FIGURE  14-8 Discovery Support Service

    Discovery Monitor

    The DiscoveryMonitor is an m-bean that listens for DiscoveryResponder objects registering or deregistering within a specific multicast group. The default multicast group is 224.224.224.224 and the default port is 9000.

    To instantiate a discovery monitor, create an instance of the com.sun.jaw.impl.agent.services.jawdiscovery.DiscoveryMonitor class. A discovery monitor can also be created using a different multicast group or port, by specifying these when calling the constructor. CODE EXAMPLE 14-33 shows code for instantiating a discovery monitor on the remote agent from the client.    


    CODE  EXAMPLE  14-33     Instantiating and Starting a Discovery Monitor  

       String domain = console;   // domain name of the remote agent
       String DiscoveryMonitorClass =
          "com.sun.jaw.impl.agent.services.jawdiscovery.DiscoveryMonitor";

       DiscoveryMonitorName = new ObjectName(domain +
       ":com.sun.jaw.impl.agent.services.jawdiscovery.DiscoveryMonitorMO.port
       = 9002);

       monitor = (DiscoveryMonitorMO) adaptor.cb_newMO(DiscoveryMonitorClass,
                  DiscoveryMonitorName, null);
                  // adds the discovery monitor mbean to the remote agent
       monitor.addDiscoveryResponderListenerMO(this);   // Registers listener with
                                                        // the remote event source.

       monitor.performStart() ;                         // Starts the monitor


    A discovery monitor can be stopped using the performStop method. When it is stopped, the discovery monitor does not listen for registration/deregistration messages from DiscoveryResponder objects. The discovery monitor is restarted using the performStart method. The discovery monitor has a state property that allows you to determine whether it is ONLINE, OFFLINE, or STOPPING. The STOPPING state is seen only when the discovery monitor is still dealing with active requests. When a DiscoveryMonitor is added in a Java Dynamic Management Kit agent, it is automatically started. When a DiscoveryMonitor is removed from a Java Dynamic Management Kit agent, it is automatically stopped.

    Discovery Responder Listener

    A discovery responder listener is an instance of the Java class that implements the DiscoveryResponderListener interface. For example, it may be implemented to update a list of agents in the network.



    Copyright 1998 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California 94303 U.S.A.
    Copyright in French

    Previous Next Contents Index