KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > monitor > Monitor


1 /*
2  * @(#)Monitor.java 4.42 04/05/18
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.management.monitor;
9
10 // java imports
11
//
12
import java.util.ArrayList JavaDoc;
13 import java.util.Arrays JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16
17 // jmx imports
18
//
19
import javax.management.MBeanServer JavaDoc;
20 import javax.management.MBeanRegistration JavaDoc;
21 import javax.management.ObjectName JavaDoc;
22
23 import com.sun.jmx.trace.Trace;
24
25 /**
26  * Defines the common part to all monitor MBeans.
27  * A monitor MBean monitors values of an attribute common to a set of observed
28  * MBeans. The observed attribute is monitored at intervals specified by the
29  * granularity period. A gauge value (derived gauge) is derived from the values
30  * of the observed attribute.
31  *
32  * @version 4.42 05/18/04
33  * @author Sun Microsystems, Inc
34  *
35  * @since 1.5
36  */

37 public abstract class Monitor
38   extends javax.management.NotificationBroadcasterSupport JavaDoc
39   implements MonitorMBean JavaDoc, javax.management.MBeanRegistration JavaDoc
40 {
41     /*
42      * ------------------------------------------
43      * PRIVATE VARIABLES
44      * ------------------------------------------
45      */

46
47     /**
48      * List of MBeans to which the attribute to observe belongs.
49      * <BR>The default value is set to null.
50      */

51     private List JavaDoc observedObjects = new ArrayList JavaDoc();
52
53     /**
54      * Attribute to observe.
55      * <BR>The default value is set to null.
56      */

57     private String JavaDoc observedAttribute = null;
58
59     /**
60      * Monitor granularity period (in milliseconds).
61      * <BR>The default value is set to 10 seconds.
62      */

63     private long granularityPeriod = 10000;
64
65
66     /*
67      * ------------------------------------------
68      * PROTECTED VARIABLES
69      * ------------------------------------------
70      */

71
72     /**
73      * The amount by which the capacity of the monitor arrays are
74      * automatically incremented when their size becomes greater than
75      * their capacity.
76      */

77     protected final static int capacityIncrement = 16;
78
79     /**
80      * The number of valid components in the vector of observed objects.
81      *
82      * @since.unbundled JMX 1.2
83      */

84     protected int elementCount = 0;
85
86     /**
87      * Monitor errors that have already been notified.
88      * @deprecated equivalent to {@link #alreadyNotifieds}[0].
89      */

90     @Deprecated JavaDoc
91     protected int alreadyNotified = 0;
92
93     /**
94      * <p>Selected monitor errors that have already been notified.</p>
95      *
96      * <p>Each element in this array corresponds to an observed object
97      * in the vector. It contains a bit mask of the flags {@link
98      * #OBSERVED_OBJECT_ERROR_NOTIFIED} etc, indicating whether the
99      * corresponding notification has already been sent for the MBean
100      * being monitored.</p>
101      *
102      * @since.unbundled JMX 1.2
103      */

104     protected int alreadyNotifieds[] = new int[capacityIncrement];
105
106     /**
107      * Reference on the MBean server. This reference is null when the
108      * monitor MBean is not registered in an MBean server. This
109      * reference is initialized before the monitor MBean is registered
110      * in the MBean server.
111      * @see #preRegister(MBeanServer server, ObjectName name)
112      */

113     protected MBeanServer JavaDoc server = null;
114
115     // Flags defining possible monitor errors.
116
//
117

118     /**
119      * This flag is used to reset the {@link #alreadyNotifieds
120      * alreadyNotifieds} monitor attribute.
121      */

122     protected static final int RESET_FLAGS_ALREADY_NOTIFIED = 0;
123
124     /**
125      * Flag denoting that a notification has occurred after changing
126      * the observed object. This flag is used to check that the new
127      * observed object is registered in the MBean server at the time
128      * of the first notification.
129      */

130     protected static final int OBSERVED_OBJECT_ERROR_NOTIFIED = 1;
131
132     /**
133      * Flag denoting that a notification has occurred after changing
134      * the observed attribute. This flag is used to check that the
135      * new observed attribute belongs to the observed object at the
136      * time of the first notification.
137      */

138     protected static final int OBSERVED_ATTRIBUTE_ERROR_NOTIFIED = 2;
139
140     /**
141      * Flag denoting that a notification has occurred after changing
142      * the observed object or the observed attribute. This flag is
143      * used to check that the observed attribute type is correct
144      * (depending on the monitor in use) at the time of the first
145      * notification.
146      */

147     protected static final int OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 4;
148
149     /**
150      * Flag denoting that a notification has occurred after changing
151      * the observed object or the observed attribute. This flag is
152      * used to notify any exception (except the cases described above)
153      * when trying to get the value of the observed attribute at the
154      * time of the first notification.
155      */

156     protected static final int RUNTIME_ERROR_NOTIFIED = 8;
157
158     /**
159      * This field is retained for compatibility but should not be referenced.
160      *
161      * @deprecated No replacement.
162      */

163     @Deprecated JavaDoc
164     protected String JavaDoc dbgTag = "Monitor";
165
166
167     /*
168      * ------------------------------------------
169      * PACKAGE VARIABLES
170      * ------------------------------------------
171      */

172
173     /**
174      * Monitor state.
175      * The default value is set to <CODE>false</CODE>.
176      */

177     boolean isActive = false;
178
179     /**
180      * Monitor sequence number.
181      * The default value is set to 0.
182      */

183     long sequenceNumber = 0;
184
185     // TRACES & DEBUG
186
//---------------
187

188     static boolean isTraceOn() {
189         return Trace.isSelected(Trace.LEVEL_TRACE, Trace.INFO_MONITOR);
190     }
191
192     static void trace(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
193         Trace.send(Trace.LEVEL_TRACE, Trace.INFO_MONITOR, clz, func, info);
194     }
195
196     void trace(String JavaDoc func, String JavaDoc info) {
197         trace(dbgTag, func, info);
198     }
199
200     static boolean isDebugOn() {
201         return Trace.isSelected(Trace.LEVEL_DEBUG, Trace.INFO_MONITOR);
202     }
203
204     static void debug(String JavaDoc clz, String JavaDoc func, String JavaDoc info) {
205         Trace.send(Trace.LEVEL_DEBUG, Trace.INFO_MONITOR, clz, func, info);
206     }
207
208     void debug(String JavaDoc func, String JavaDoc info) {
209         debug(dbgTag, func, info);
210     }
211
212     /*
213      * ------------------------------------------
214      * PUBLIC METHODS
215      * ------------------------------------------
216      */

217
218     /**
219      * Allows the monitor MBean to perform any operations it needs
220      * before being registered in the MBean server.
221      * <P>
222      * Initializes the reference to the MBean server.
223      *
224      * @param server The MBean server in which the monitor MBean will
225      * be registered.
226      * @param name The object name of the monitor MBean.
227      *
228      * @return The name of the monitor MBean registered.
229      *
230      * @exception java.lang.Exception
231      */

232     public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name)
233         throws java.lang.Exception JavaDoc {
234
235         if (isTraceOn()) {
236             trace("preRegister",
237           "initialize the reference on the MBean server");
238         }
239
240         this.server = server;
241         return name;
242     }
243
244     /**
245      * Allows the monitor MBean to perform any operations needed after
246      * having been registered in the MBean server or after the
247      * registration has failed.
248      * <P>
249      * Not used in this context.
250      */

251     public void postRegister (Boolean JavaDoc registrationDone) {
252     }
253
254     /**
255      * Allows the monitor MBean to perform any operations it needs
256      * before being unregistered by the MBean server.
257      * <P>
258      * Stops the monitor.
259      *
260      * @exception java.lang.Exception
261      */

262     public void preDeregister() throws java.lang.Exception JavaDoc {
263
264         if (isTraceOn()) {
265             trace("preDeregister", "stop the monitor");
266         }
267
268         // Stop the Monitor.
269
//
270
stop();
271     }
272
273     /**
274      * Allows the monitor MBean to perform any operations needed after
275      * having been unregistered by the MBean server.
276      * <P>
277      * Not used in this context.
278      */

279     public void postDeregister() {
280     }
281
282     /**
283      * Starts the monitor.
284      */

285     public abstract void start();
286
287     /**
288      * Stops the monitor.
289      */

290     public abstract void stop();
291
292     // GETTERS AND SETTERS
293
//--------------------
294

295     /**
296      * Returns the object name of the first object in the set of observed
297      * MBeans, or <code>null</code> if there is no such object.
298      *
299      * @return The object being observed.
300      *
301      * @see #setObservedObject(ObjectName)
302      *
303      * @deprecated As of JMX 1.2, replaced by {@link #getObservedObjects}
304      */

305     @Deprecated JavaDoc
306     public ObjectName JavaDoc getObservedObject() {
307     synchronized(this) {
308         if (observedObjects.isEmpty()) {
309         return null;
310         } else {
311         return (ObjectName JavaDoc)observedObjects.get(0);
312     }
313     }
314     }
315
316     /**
317      * Removes all objects from the set of observed objects, and then adds the
318      * specified object.
319      *
320      * @param object The object to observe.
321      * @exception java.lang.IllegalArgumentException The specified
322      * object is null.
323      *
324      * @see #getObservedObject()
325      *
326      * @deprecated As of JMX 1.2, replaced by {@link #addObservedObject}
327      */

328     @Deprecated JavaDoc
329     public synchronized void setObservedObject(ObjectName JavaDoc object)
330         throws IllegalArgumentException JavaDoc {
331     while (!observedObjects.isEmpty()) {
332         removeObservedObject((ObjectName JavaDoc)observedObjects.get(0));
333     }
334
335     addObservedObject(object);
336     }
337
338     /**
339      * Adds the specified object in the set of observed MBeans, if this object
340      * is not already present.
341      *
342      * @param object The object to observe.
343      * @exception IllegalArgumentException The specified object is null.
344      *
345      * @since.unbundled JMX 1.2
346      */

347     public synchronized void addObservedObject(ObjectName JavaDoc object)
348         throws IllegalArgumentException JavaDoc {
349
350         if (object == null) {
351             throw new IllegalArgumentException JavaDoc("Null observed object");
352         }
353
354     // Check that the specified object is not already contained
355
//
356
if (observedObjects.contains(object)) {
357         return;
358     }
359
360     // Add the specified object in the list.
361
//
362
observedObjects.add(object);
363
364     // Update alreadyNotified array.
365
//
366
int value = RESET_FLAGS_ALREADY_NOTIFIED;
367     value &= ~(OBSERVED_OBJECT_ERROR_NOTIFIED |
368            OBSERVED_ATTRIBUTE_ERROR_NOTIFIED |
369            OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED);
370     if (alreadyNotifieds.length >= elementCount)
371         alreadyNotifieds = expandArray(alreadyNotifieds);
372     alreadyNotifieds[elementCount] = value;
373
374     updateDeprecatedAlreadyNotified();
375
376     // Update other specific arrays.
377
//
378
insertSpecificElementAt(elementCount);
379
380     // Update elementCount.
381
//
382
elementCount++;
383     }
384
385     /**
386      * Removes the specified object from the set of observed MBeans.
387      *
388      * @param object The object to remove.
389      *
390      * @since.unbundled JMX 1.2
391      */

392     public void removeObservedObject(ObjectName JavaDoc object) {
393     synchronized(this) {
394             int index = observedObjects.indexOf(object);
395         if (index >= 0) {
396         observedObjects.remove(index);
397
398             // Update alreadyNotifieds array.
399
//
400
removeElementAt(alreadyNotifieds, index);
401         updateDeprecatedAlreadyNotified();
402
403             // Update other specific arrays.
404
//
405
removeSpecificElementAt(index);
406
407             // Update elementCount.
408
//
409
elementCount--;
410         }
411     }
412     }
413
414     /**
415      * Tests whether the specified object is in the set of observed MBeans.
416      *
417      * @param object The object to check.
418      * @return <CODE>true</CODE> if the specified object is present,
419      * <CODE>false</CODE> otherwise.
420      *
421      * @since.unbundled JMX 1.2
422      */

423     public boolean containsObservedObject(ObjectName JavaDoc object) {
424     synchronized(this) {
425         return observedObjects.contains(object);
426     }
427     }
428
429     /**
430      * Returns an array containing the objects being observed.
431      *
432      * @return The objects being observed.
433      *
434      * @since.unbundled JMX 1.2
435      */

436     public ObjectName JavaDoc[] getObservedObjects() {
437     ObjectName JavaDoc[] objects;
438     synchronized(this) {
439         objects = new ObjectName JavaDoc[elementCount];
440         for (int i=0; i<elementCount; i++) {
441           objects[i] = (ObjectName JavaDoc)observedObjects.get(i);
442         }
443     }
444         return objects;
445     }
446
447     /**
448      * Gets the attribute being observed.
449      * <BR>The observed attribute is not initialized by default (set to null).
450      *
451      * @return The attribute being observed.
452      *
453      * @see #setObservedAttribute
454      */

455     public String JavaDoc getObservedAttribute() {
456         return observedAttribute;
457     }
458
459     /**
460      * Sets the attribute to observe.
461      * <BR>The observed attribute is not initialized by default (set to null).
462      *
463      * @param attribute The attribute to observe.
464      * @exception java.lang.IllegalArgumentException The specified
465      * attribute is null.
466      *
467      * @see #getObservedAttribute
468      */

469     public void setObservedAttribute(String JavaDoc attribute)
470         throws IllegalArgumentException JavaDoc {
471
472         if (attribute == null) {
473             throw new IllegalArgumentException JavaDoc("Null observed attribute");
474         }
475
476         // Update alreadyNotified array.
477
//
478
synchronized(this) {
479         observedAttribute = attribute;
480
481         for (int i = 0; i < elementCount; i++) {
482         resetAlreadyNotified(i,
483                  OBSERVED_ATTRIBUTE_ERROR_NOTIFIED |
484                  OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED);
485         }
486     }
487     }
488
489     /**
490      * Gets the granularity period (in milliseconds).
491      * <BR>The default value of the granularity period is 10 seconds.
492      *
493      * @return The granularity period value.
494      *
495      * @see #setGranularityPeriod
496      */

497     public synchronized long getGranularityPeriod() {
498         return granularityPeriod;
499     }
500
501     /**
502      * Sets the granularity period (in milliseconds).
503      * <BR>The default value of the granularity period is 10 seconds.
504      *
505      * @param period The granularity period value.
506      * @exception java.lang.IllegalArgumentException The granularity
507      * period is less than or equal to zero.
508      *
509      * @see #getGranularityPeriod
510      */

511     public synchronized void setGranularityPeriod(long period)
512         throws IllegalArgumentException JavaDoc {
513
514         if (period <= 0) {
515             throw new IllegalArgumentException JavaDoc("Nonpositive granularity " +
516                            "period");
517         }
518         granularityPeriod = period;
519     }
520
521     /**
522      * Tests whether the monitor MBean is active. A monitor MBean is
523      * marked active when the {@link #start start} method is called.
524      * It becomes inactive when the {@link #stop stop} method is
525      * called.
526      *
527      * @return <CODE>true</CODE> if the monitor MBean is active,
528      * <CODE>false</CODE> otherwise.
529      */

530     /* This method must be synchronized so that the monitoring thread will
531        correctly see modifications to the isActive variable. See the various
532        AlarmClock threads in the subclasses. */

533     public synchronized boolean isActive() {
534         return isActive;
535     }
536
537     /*
538      * ------------------------------------------
539      * PACKAGE METHODS
540      * ------------------------------------------
541      */

542
543     /**
544      * Gets the {@link ObjectName} of the object at the specified
545      * index in the list of observed MBeans.
546      * @return The observed object at the specified index.
547      * @exception ArrayIndexOutOfBoundsException If the index is invalid.
548      */

549     synchronized ObjectName JavaDoc getObservedObject(int index)
550         throws ArrayIndexOutOfBoundsException JavaDoc {
551         return (ObjectName JavaDoc)observedObjects.get(index);
552     }
553
554     /**
555      * Update the deprecated {@link #alreadyNotified} field.
556      */

557     synchronized void updateDeprecatedAlreadyNotified() {
558     if (elementCount > 0)
559         alreadyNotified = alreadyNotifieds[0];
560     else
561         alreadyNotified = 0;
562     }
563
564     /**
565      * Set the given bits in the given element of {@link #alreadyNotifieds}.
566      * Ensure the deprecated {@link #alreadyNotified} field is updated
567      * if appropriate.
568      */

569     synchronized void setAlreadyNotified(int index, int mask) {
570     alreadyNotifieds[index] |= mask;
571     if (index == 0)
572         updateDeprecatedAlreadyNotified();
573     }
574
575     /**
576      * Reset the given bits in the given element of {@link #alreadyNotifieds}.
577      * Ensure the deprecated {@link #alreadyNotified} field is updated
578      * if appropriate.
579      */

580     synchronized void resetAlreadyNotified(int index, int mask) {
581     alreadyNotifieds[index] &= ~mask;
582     if (index == 0)
583         updateDeprecatedAlreadyNotified();
584     }
585
586     synchronized boolean alreadyNotified(int index, int mask) {
587     return ((alreadyNotifieds[index] & mask) != 0);
588     }
589
590     /**
591      * Reset all bits in the given element of {@link #alreadyNotifieds}.
592      * Ensure the deprecated {@link #alreadyNotified} field is updated
593      * if appropriate.
594      */

595     synchronized void resetAllAlreadyNotified(int index) {
596     alreadyNotifieds[index] = 0;
597     if (index == 0)
598         updateDeprecatedAlreadyNotified();
599     }
600
601     int[] expandArray(int[] array) {
602     int[] newArray = new int[array.length + capacityIncrement];
603     System.arraycopy(array, 0, newArray, 0, array.length);
604     return newArray;
605     }
606
607     long[] expandArray(long[] array) {
608     long[] newArray = new long[array.length + capacityIncrement];
609     System.arraycopy(array, 0, newArray, 0, array.length);
610     return newArray;
611     }
612
613     Number JavaDoc[] expandArray(Number JavaDoc[] array) {
614     Number JavaDoc[] newArray = new Number JavaDoc[array.length + capacityIncrement];
615     System.arraycopy(array, 0, newArray, 0, array.length);
616     return newArray;
617     }
618
619     boolean[] expandArray(boolean[] array) {
620     boolean[] newArray = new boolean[array.length + capacityIncrement];
621     System.arraycopy(array, 0, newArray, 0, array.length);
622     return newArray;
623     }
624
625     String JavaDoc[] expandArray(String JavaDoc[] array) {
626     String JavaDoc[] newArray = new String JavaDoc[array.length + capacityIncrement];
627     System.arraycopy(array, 0, newArray, 0, array.length);
628     return newArray;
629     }
630
631     /**
632      * Removes the component at the specified index from the specified
633      * int array.
634      */

635     synchronized void removeElementAt(int[] array, int index) {
636         if (index < 0 || index >= elementCount)
637             return;
638         int j = elementCount - index - 1;
639         if (j > 0) {
640             System.arraycopy(array, index + 1, array, index, j);
641         }
642     }
643
644     /**
645      * Removes the component at the specified index from the specified
646      * long array.
647      */

648     synchronized void removeElementAt(long[] array, int index) {
649         if (index < 0 || index >= elementCount)
650             return;
651         int j = elementCount - index - 1;
652         if (j > 0) {
653             System.arraycopy(array, index + 1, array, index, j);
654         }
655     }
656
657     /**
658      * Removes the component at the specified index from the specified
659      * boolean array.
660      */

661     synchronized void removeElementAt(boolean[] array, int index) {
662         if (index < 0 || index >= elementCount)
663             return;
664         int j = elementCount - index - 1;
665         if (j > 0) {
666             System.arraycopy(array, index + 1, array, index, j);
667         }
668     }
669
670     /**
671      * Removes the component at the specified index from the specified
672      * Number array.
673      */

674     synchronized void removeElementAt(Object JavaDoc[] array, int index) {
675         if (index < 0 || index >= elementCount)
676             return;
677         int j = elementCount - index - 1;
678         if (j > 0) {
679             System.arraycopy(array, index + 1, array, index, j);
680         }
681     array[elementCount - 1] = null;
682     }
683
684     /**
685      * Searches for the first occurence of the given argument, testing
686      * for equality using the equals method.
687      */

688     synchronized int indexOf(ObjectName JavaDoc object) {
689         return observedObjects.indexOf(object);
690     }
691
692     /**
693      * This method is overridden by the specific monitor classes
694      * (Counter, Gauge and String). It updates all the specific
695      * arrays after adding a new observed object in the list.
696      *
697      * The method is not abstract so that this class can be subclassed
698      * by classes outside this package.
699      */

700     void insertSpecificElementAt(int index) {}
701
702     /**
703      * This method is overridden by the specific monitor classes
704      * (Counter, Gauge and String). It updates all the specific
705      * arrays after removing an observed object from the vector.
706      *
707      * The method is not abstract so that this class can be subclassed
708      * by classes outside this package.
709      */

710     void removeSpecificElementAt(int index) {}
711
712     /**
713      * This method is used by the monitor MBean create and send a
714      * monitor notification to all the listeners registered for this
715      * kind of notification.
716      *
717      * @param type The notification type.
718      * @param timeStamp The notification emission date.
719      * @param msg The notification message.
720      * @param derGauge The derived gauge.
721      * @param trigger The threshold/string (depending on the monitor
722      * type) that triggered off the notification.
723      * @param index The index of the observed object that triggered
724      * off the notification.
725      */

726     void sendNotification(String JavaDoc type, long timeStamp, String JavaDoc msg,
727               Object JavaDoc derGauge, Object JavaDoc trigger, int index) {
728
729     if (isTraceOn()) {
730         trace("sendNotification", "send notification:" +
731           "\n\tNotification observed object = " +
732           getObservedObject(index) +
733           "\n\tNotification observed attribute = " +
734           observedAttribute +
735           "\n\tNotification derived gauge = " +
736           derGauge);
737     }
738
739     long seqno;
740     synchronized (this) {
741         seqno = sequenceNumber++;
742     }
743
744     sendNotification(new MonitorNotification JavaDoc(type,
745                          this,
746                          seqno,
747                          timeStamp,
748                          msg,
749                          getObservedObject(index),
750                          observedAttribute,
751                          derGauge,
752                          trigger));
753     }
754 }
755
Popular Tags