blob: 6e7de298270585df657cf7b72c82082278769e96 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package javax.management.monitor;
27
28import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER;
29import java.util.logging.Level;
30import javax.management.MBeanNotificationInfo;
31import javax.management.ObjectName;
32import static javax.management.monitor.Monitor.NumericalType.*;
33import static javax.management.monitor.MonitorNotification.*;
34
35/**
36 * Defines a monitor MBean designed to observe the values of a gauge attribute.
37 *
38 * <P> A gauge monitor observes an attribute that is continuously
39 * variable with time. A gauge monitor sends notifications as
40 * follows:
41 *
42 * <UL>
43 *
44 * <LI> if the attribute value is increasing and becomes equal to or
45 * greater than the high threshold value, a {@link
46 * MonitorNotification#THRESHOLD_HIGH_VALUE_EXCEEDED threshold high
47 * notification} is sent. The notify high flag must be set to
48 * <CODE>true</CODE>.
49 *
50 * <BR>Subsequent crossings of the high threshold value do not cause
51 * further notifications unless the attribute value becomes equal to
52 * or less than the low threshold value.</LI>
53 *
54 * <LI> if the attribute value is decreasing and becomes equal to or
55 * less than the low threshold value, a {@link
56 * MonitorNotification#THRESHOLD_LOW_VALUE_EXCEEDED threshold low
57 * notification} is sent. The notify low flag must be set to
58 * <CODE>true</CODE>.
59 *
60 * <BR>Subsequent crossings of the low threshold value do not cause
61 * further notifications unless the attribute value becomes equal to
62 * or greater than the high threshold value.</LI>
63 *
64 * </UL>
65 *
66 * This provides a hysteresis mechanism to avoid repeated triggering
67 * of notifications when the attribute value makes small oscillations
68 * around the high or low threshold value.
69 *
70 * <P> If the gauge difference mode is used, the value of the derived
71 * gauge is calculated as the difference between the observed gauge
72 * values for two successive observations.
73 *
74 * <BR>The derived gauge value (V[t]) is calculated using the following method:
75 * <UL>
76 * <LI>V[t] = gauge[t] - gauge[t-GP]</LI>
77 * </UL>
78 *
79 * This implementation of the gauge monitor requires the observed
80 * attribute to be of the type integer or floating-point
81 * (<CODE>Byte</CODE>, <CODE>Integer</CODE>, <CODE>Short</CODE>,
82 * <CODE>Long</CODE>, <CODE>Float</CODE>, <CODE>Double</CODE>).
83 *
84 *
85 * @since 1.5
86 */
87public class GaugeMonitor extends Monitor implements GaugeMonitorMBean {
88
89 /*
90 * ------------------------------------------
91 * PACKAGE CLASSES
92 * ------------------------------------------
93 */
94
95 static class GaugeMonitorObservedObject extends ObservedObject {
96
97 public GaugeMonitorObservedObject(ObjectName observedObject) {
98 super(observedObject);
99 }
100
101 public final synchronized boolean getDerivedGaugeValid() {
102 return derivedGaugeValid;
103 }
104 public final synchronized void setDerivedGaugeValid(
105 boolean derivedGaugeValid) {
106 this.derivedGaugeValid = derivedGaugeValid;
107 }
108 public final synchronized NumericalType getType() {
109 return type;
110 }
111 public final synchronized void setType(NumericalType type) {
112 this.type = type;
113 }
114 public final synchronized Number getPreviousScanGauge() {
115 return previousScanGauge;
116 }
117 public final synchronized void setPreviousScanGauge(
118 Number previousScanGauge) {
119 this.previousScanGauge = previousScanGauge;
120 }
121 public final synchronized int getStatus() {
122 return status;
123 }
124 public final synchronized void setStatus(int status) {
125 this.status = status;
126 }
127
128 private boolean derivedGaugeValid;
129 private NumericalType type;
130 private Number previousScanGauge;
131 private int status;
132 }
133
134 /*
135 * ------------------------------------------
136 * PRIVATE VARIABLES
137 * ------------------------------------------
138 */
139
140 /**
141 * Gauge high threshold.
142 *
143 * <BR>The default value is a null Integer object.
144 */
145 private Number highThreshold = INTEGER_ZERO;
146
147 /**
148 * Gauge low threshold.
149 *
150 * <BR>The default value is a null Integer object.
151 */
152 private Number lowThreshold = INTEGER_ZERO;
153
154 /**
155 * Flag indicating if the gauge monitor notifies when exceeding
156 * the high threshold.
157 *
158 * <BR>The default value is <CODE>false</CODE>.
159 */
160 private boolean notifyHigh = false;
161
162 /**
163 * Flag indicating if the gauge monitor notifies when exceeding
164 * the low threshold.
165 *
166 * <BR>The default value is <CODE>false</CODE>.
167 */
168 private boolean notifyLow = false;
169
170 /**
171 * Flag indicating if the gauge difference mode is used. If the
172 * gauge difference mode is used, the derived gauge is the
173 * difference between two consecutive observed values. Otherwise,
174 * the derived gauge is directly the value of the observed
175 * attribute.
176 *
177 * <BR>The default value is set to <CODE>false</CODE>.
178 */
179 private boolean differenceMode = false;
180
181 private static final String[] types = {
182 RUNTIME_ERROR,
183 OBSERVED_OBJECT_ERROR,
184 OBSERVED_ATTRIBUTE_ERROR,
185 OBSERVED_ATTRIBUTE_TYPE_ERROR,
186 THRESHOLD_ERROR,
187 THRESHOLD_HIGH_VALUE_EXCEEDED,
188 THRESHOLD_LOW_VALUE_EXCEEDED
189 };
190
191 private static final MBeanNotificationInfo[] notifsInfo = {
192 new MBeanNotificationInfo(
193 types,
194 "javax.management.monitor.MonitorNotification",
195 "Notifications sent by the GaugeMonitor MBean")
196 };
197
198 // Flags needed to implement the hysteresis mechanism.
199 //
200 private static final int RISING = 0;
201 private static final int FALLING = 1;
202 private static final int RISING_OR_FALLING = 2;
203
204 /*
205 * ------------------------------------------
206 * CONSTRUCTORS
207 * ------------------------------------------
208 */
209
210 /**
211 * Default constructor.
212 */
213 public GaugeMonitor() {
214 }
215
216 /*
217 * ------------------------------------------
218 * PUBLIC METHODS
219 * ------------------------------------------
220 */
221
222 /**
223 * Starts the gauge monitor.
224 */
225 public synchronized void start() {
226 if (isActive()) {
227 MONITOR_LOGGER.logp(Level.FINER, GaugeMonitor.class.getName(),
228 "start", "the monitor is already active");
229 return;
230 }
231 // Reset values.
232 //
233 for (ObservedObject o : observedObjects) {
234 final GaugeMonitorObservedObject gmo =
235 (GaugeMonitorObservedObject) o;
236 gmo.setStatus(RISING_OR_FALLING);
237 gmo.setPreviousScanGauge(null);
238 }
239 doStart();
240 }
241
242 /**
243 * Stops the gauge monitor.
244 */
245 public synchronized void stop() {
246 doStop();
247 }
248
249 // GETTERS AND SETTERS
250 //--------------------
251
252 /**
253 * Gets the derived gauge of the specified object, if this object is
254 * contained in the set of observed MBeans, or <code>null</code> otherwise.
255 *
256 * @param object the name of the MBean.
257 *
258 * @return The derived gauge of the specified object.
259 *
260 */
261 public synchronized Number getDerivedGauge(ObjectName object) {
262 return (Number) super.getDerivedGauge(object);
263 }
264
265 /**
266 * Gets the derived gauge timestamp of the specified object, if
267 * this object is contained in the set of observed MBeans, or
268 * <code>0</code> otherwise.
269 *
270 * @param object the name of the object whose derived gauge
271 * timestamp is to be returned.
272 *
273 * @return The derived gauge timestamp of the specified object.
274 *
275 */
276 public synchronized long getDerivedGaugeTimeStamp(ObjectName object) {
277 return super.getDerivedGaugeTimeStamp(object);
278 }
279
280 /**
281 * Returns the derived gauge of the first object in the set of
282 * observed MBeans.
283 *
284 * @return The derived gauge.
285 *
286 * @deprecated As of JMX 1.2, replaced by
287 * {@link #getDerivedGauge(ObjectName)}
288 */
289 @Deprecated
290 public synchronized Number getDerivedGauge() {
291 if (observedObjects.isEmpty()) {
292 return null;
293 } else {
294 return (Number) observedObjects.get(0).getDerivedGauge();
295 }
296 }
297
298 /**
299 * Gets the derived gauge timestamp of the first object in the set
300 * of observed MBeans.
301 *
302 * @return The derived gauge timestamp.
303 *
304 * @deprecated As of JMX 1.2, replaced by
305 * {@link #getDerivedGaugeTimeStamp(ObjectName)}
306 */
307 @Deprecated
308 public synchronized long getDerivedGaugeTimeStamp() {
309 if (observedObjects.isEmpty()) {
310 return 0;
311 } else {
312 return observedObjects.get(0).getDerivedGaugeTimeStamp();
313 }
314 }
315
316 /**
317 * Gets the high threshold value common to all observed MBeans.
318 *
319 * @return The high threshold value.
320 *
321 * @see #setThresholds
322 */
323 public synchronized Number getHighThreshold() {
324 return highThreshold;
325 }
326
327 /**
328 * Gets the low threshold value common to all observed MBeans.
329 *
330 * @return The low threshold value.
331 *
332 * @see #setThresholds
333 */
334 public synchronized Number getLowThreshold() {
335 return lowThreshold;
336 }
337
338 /**
339 * Sets the high and the low threshold values common to all
340 * observed MBeans.
341 *
342 * @param highValue The high threshold value.
343 * @param lowValue The low threshold value.
344 *
345 * @exception IllegalArgumentException The specified high/low
346 * threshold is null or the low threshold is greater than the high
347 * threshold or the high threshold and the low threshold are not
348 * of the same type.
349 *
350 * @see #getHighThreshold
351 * @see #getLowThreshold
352 */
353 public synchronized void setThresholds(Number highValue, Number lowValue)
354 throws IllegalArgumentException {
355
356 if ((highValue == null) || (lowValue == null)) {
357 throw new IllegalArgumentException("Null threshold value");
358 }
359
360 if (highValue.getClass() != lowValue.getClass()) {
361 throw new IllegalArgumentException("Different type " +
362 "threshold values");
363 }
364
365 if (isFirstStrictlyGreaterThanLast(lowValue, highValue,
366 highValue.getClass().getName())) {
367 throw new IllegalArgumentException("High threshold less than " +
368 "low threshold");
369 }
370
371 if (highThreshold.equals(highValue) && lowThreshold.equals(lowValue))
372 return;
373 highThreshold = highValue;
374 lowThreshold = lowValue;
375
376 // Reset values.
377 //
378 int index = 0;
379 for (ObservedObject o : observedObjects) {
380 resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
381 final GaugeMonitorObservedObject gmo =
382 (GaugeMonitorObservedObject) o;
383 gmo.setStatus(RISING_OR_FALLING);
384 }
385 }
386
387 /**
388 * Gets the high notification's on/off switch value common to all
389 * observed MBeans.
390 *
391 * @return <CODE>true</CODE> if the gauge monitor notifies when
392 * exceeding the high threshold, <CODE>false</CODE> otherwise.
393 *
394 * @see #setNotifyHigh
395 */
396 public synchronized boolean getNotifyHigh() {
397 return notifyHigh;
398 }
399
400 /**
401 * Sets the high notification's on/off switch value common to all
402 * observed MBeans.
403 *
404 * @param value The high notification's on/off switch value.
405 *
406 * @see #getNotifyHigh
407 */
408 public synchronized void setNotifyHigh(boolean value) {
409 if (notifyHigh == value)
410 return;
411 notifyHigh = value;
412 }
413
414 /**
415 * Gets the low notification's on/off switch value common to all
416 * observed MBeans.
417 *
418 * @return <CODE>true</CODE> if the gauge monitor notifies when
419 * exceeding the low threshold, <CODE>false</CODE> otherwise.
420 *
421 * @see #setNotifyLow
422 */
423 public synchronized boolean getNotifyLow() {
424 return notifyLow;
425 }
426
427 /**
428 * Sets the low notification's on/off switch value common to all
429 * observed MBeans.
430 *
431 * @param value The low notification's on/off switch value.
432 *
433 * @see #getNotifyLow
434 */
435 public synchronized void setNotifyLow(boolean value) {
436 if (notifyLow == value)
437 return;
438 notifyLow = value;
439 }
440
441 /**
442 * Gets the difference mode flag value common to all observed MBeans.
443 *
444 * @return <CODE>true</CODE> if the difference mode is used,
445 * <CODE>false</CODE> otherwise.
446 *
447 * @see #setDifferenceMode
448 */
449 public synchronized boolean getDifferenceMode() {
450 return differenceMode;
451 }
452
453 /**
454 * Sets the difference mode flag value common to all observed MBeans.
455 *
456 * @param value The difference mode flag value.
457 *
458 * @see #getDifferenceMode
459 */
460 public synchronized void setDifferenceMode(boolean value) {
461 if (differenceMode == value)
462 return;
463 differenceMode = value;
464
465 // Reset values.
466 //
467 for (ObservedObject o : observedObjects) {
468 final GaugeMonitorObservedObject gmo =
469 (GaugeMonitorObservedObject) o;
470 gmo.setStatus(RISING_OR_FALLING);
471 gmo.setPreviousScanGauge(null);
472 }
473 }
474
475 /**
476 * Returns a <CODE>NotificationInfo</CODE> object containing the
477 * name of the Java class of the notification and the notification
478 * types sent by the gauge monitor.
479 */
480 public MBeanNotificationInfo[] getNotificationInfo() {
481 return notifsInfo;
482 }
483
484 /*
485 * ------------------------------------------
486 * PRIVATE METHODS
487 * ------------------------------------------
488 */
489
490 /**
491 * Updates the derived gauge attribute of the observed object.
492 *
493 * @param scanGauge The value of the observed attribute.
494 * @param o The observed object.
495 * @return <CODE>true</CODE> if the derived gauge value is valid,
496 * <CODE>false</CODE> otherwise. The derived gauge value is
497 * invalid when the differenceMode flag is set to
498 * <CODE>true</CODE> and it is the first notification (so we
499 * haven't 2 consecutive values to update the derived gauge).
500 */
501 private synchronized boolean updateDerivedGauge(
502 Object scanGauge, GaugeMonitorObservedObject o) {
503
504 boolean is_derived_gauge_valid;
505
506 // The gauge difference mode is used.
507 //
508 if (differenceMode) {
509
510 // The previous scan gauge has been initialized.
511 //
512 if (o.getPreviousScanGauge() != null) {
513 setDerivedGaugeWithDifference((Number)scanGauge, o);
514 is_derived_gauge_valid = true;
515 }
516 // The previous scan gauge has not been initialized.
517 // We cannot update the derived gauge...
518 //
519 else {
520 is_derived_gauge_valid = false;
521 }
522 o.setPreviousScanGauge((Number)scanGauge);
523 }
524 // The gauge difference mode is not used.
525 //
526 else {
527 o.setDerivedGauge((Number)scanGauge);
528 is_derived_gauge_valid = true;
529 }
530
531 return is_derived_gauge_valid;
532 }
533
534 /**
535 * Updates the notification attribute of the observed object
536 * and notifies the listeners only once if the notify flag
537 * is set to <CODE>true</CODE>.
538 * @param o The observed object.
539 */
540 private synchronized MonitorNotification updateNotifications(
541 GaugeMonitorObservedObject o) {
542
543 MonitorNotification n = null;
544
545 // Send high notification if notifyHigh is true.
546 // Send low notification if notifyLow is true.
547 //
548 if (o.getStatus() == RISING_OR_FALLING) {
549 if (isFirstGreaterThanLast((Number)o.getDerivedGauge(),
550 highThreshold,
551 o.getType())) {
552 if (notifyHigh) {
553 n = new MonitorNotification(
554 THRESHOLD_HIGH_VALUE_EXCEEDED,
555 this,
556 0,
557 0,
558 "",
559 null,
560 null,
561 null,
562 highThreshold);
563 }
564 o.setStatus(FALLING);
565 } else if (isFirstGreaterThanLast(lowThreshold,
566 (Number)o.getDerivedGauge(),
567 o.getType())) {
568 if (notifyLow) {
569 n = new MonitorNotification(
570 THRESHOLD_LOW_VALUE_EXCEEDED,
571 this,
572 0,
573 0,
574 "",
575 null,
576 null,
577 null,
578 lowThreshold);
579 }
580 o.setStatus(RISING);
581 }
582 } else {
583 if (o.getStatus() == RISING) {
584 if (isFirstGreaterThanLast((Number)o.getDerivedGauge(),
585 highThreshold,
586 o.getType())) {
587 if (notifyHigh) {
588 n = new MonitorNotification(
589 THRESHOLD_HIGH_VALUE_EXCEEDED,
590 this,
591 0,
592 0,
593 "",
594 null,
595 null,
596 null,
597 highThreshold);
598 }
599 o.setStatus(FALLING);
600 }
601 } else if (o.getStatus() == FALLING) {
602 if (isFirstGreaterThanLast(lowThreshold,
603 (Number)o.getDerivedGauge(),
604 o.getType())) {
605 if (notifyLow) {
606 n = new MonitorNotification(
607 THRESHOLD_LOW_VALUE_EXCEEDED,
608 this,
609 0,
610 0,
611 "",
612 null,
613 null,
614 null,
615 lowThreshold);
616 }
617 o.setStatus(RISING);
618 }
619 }
620 }
621
622 return n;
623 }
624
625 /**
626 * Sets the derived gauge when the differenceMode flag is set to
627 * <CODE>true</CODE>. Both integer and floating-point types are
628 * allowed.
629 *
630 * @param scanGauge The value of the observed attribute.
631 * @param o The observed object.
632 */
633 private synchronized void setDerivedGaugeWithDifference(
634 Number scanGauge, GaugeMonitorObservedObject o) {
635 Number prev = o.getPreviousScanGauge();
636 Number der;
637 switch (o.getType()) {
638 case INTEGER:
639 der = new Integer(((Integer)scanGauge).intValue() -
640 ((Integer)prev).intValue());
641 break;
642 case BYTE:
643 der = new Byte((byte)(((Byte)scanGauge).byteValue() -
644 ((Byte)prev).byteValue()));
645 break;
646 case SHORT:
647 der = new Short((short)(((Short)scanGauge).shortValue() -
648 ((Short)prev).shortValue()));
649 break;
650 case LONG:
651 der = new Long(((Long)scanGauge).longValue() -
652 ((Long)prev).longValue());
653 break;
654 case FLOAT:
655 der = new Float(((Float)scanGauge).floatValue() -
656 ((Float)prev).floatValue());
657 break;
658 case DOUBLE:
659 der = new Double(((Double)scanGauge).doubleValue() -
660 ((Double)prev).doubleValue());
661 break;
662 default:
663 // Should never occur...
664 MONITOR_LOGGER.logp(Level.FINEST, GaugeMonitor.class.getName(),
665 "setDerivedGaugeWithDifference",
666 "the threshold type is invalid");
667 return;
668 }
669 o.setDerivedGauge(der);
670 }
671
672 /**
673 * Tests if the first specified Number is greater than or equal to
674 * the last. Both integer and floating-point types are allowed.
675 *
676 * @param greater The first Number to compare with the second.
677 * @param less The second Number to compare with the first.
678 * @param type The number type.
679 * @return <CODE>true</CODE> if the first specified Number is
680 * greater than or equal to the last, <CODE>false</CODE>
681 * otherwise.
682 */
683 private boolean isFirstGreaterThanLast(Number greater,
684 Number less,
685 NumericalType type) {
686
687 switch (type) {
688 case INTEGER:
689 case BYTE:
690 case SHORT:
691 case LONG:
692 return (greater.longValue() >= less.longValue());
693 case FLOAT:
694 case DOUBLE:
695 return (greater.doubleValue() >= less.doubleValue());
696 default:
697 // Should never occur...
698 MONITOR_LOGGER.logp(Level.FINEST, GaugeMonitor.class.getName(),
699 "isFirstGreaterThanLast",
700 "the threshold type is invalid");
701 return false;
702 }
703 }
704
705 /**
706 * Tests if the first specified Number is strictly greater than the last.
707 * Both integer and floating-point types are allowed.
708 *
709 * @param greater The first Number to compare with the second.
710 * @param less The second Number to compare with the first.
711 * @param className The number class name.
712 * @return <CODE>true</CODE> if the first specified Number is
713 * strictly greater than the last, <CODE>false</CODE> otherwise.
714 */
715 private boolean isFirstStrictlyGreaterThanLast(Number greater,
716 Number less,
717 String className) {
718
719 if (className.equals("java.lang.Integer") ||
720 className.equals("java.lang.Byte") ||
721 className.equals("java.lang.Short") ||
722 className.equals("java.lang.Long")) {
723
724 return (greater.longValue() > less.longValue());
725 }
726 else if (className.equals("java.lang.Float") ||
727 className.equals("java.lang.Double")) {
728
729 return (greater.doubleValue() > less.doubleValue());
730 }
731 else {
732 // Should never occur...
733 MONITOR_LOGGER.logp(Level.FINEST, GaugeMonitor.class.getName(),
734 "isFirstStrictlyGreaterThanLast",
735 "the threshold type is invalid");
736 return false;
737 }
738 }
739
740 /*
741 * ------------------------------------------
742 * PACKAGE METHODS
743 * ------------------------------------------
744 */
745
746 /**
747 * Factory method for ObservedObject creation.
748 *
749 * @since 1.6
750 */
751 @Override
752 ObservedObject createObservedObject(ObjectName object) {
753 final GaugeMonitorObservedObject gmo =
754 new GaugeMonitorObservedObject(object);
755 gmo.setStatus(RISING_OR_FALLING);
756 gmo.setPreviousScanGauge(null);
757 return gmo;
758 }
759
760 /**
761 * This method globally sets the derived gauge type for the given
762 * "object" and "attribute" after checking that the type of the
763 * supplied observed attribute value is one of the value types
764 * supported by this monitor.
765 */
766 @Override
767 synchronized boolean isComparableTypeValid(ObjectName object,
768 String attribute,
769 Comparable<?> value) {
770 final GaugeMonitorObservedObject o =
771 (GaugeMonitorObservedObject) getObservedObject(object);
772 if (o == null)
773 return false;
774
775 // Check that the observed attribute is either of type
776 // "Integer" or "Float".
777 //
778 if (value instanceof Integer) {
779 o.setType(INTEGER);
780 } else if (value instanceof Byte) {
781 o.setType(BYTE);
782 } else if (value instanceof Short) {
783 o.setType(SHORT);
784 } else if (value instanceof Long) {
785 o.setType(LONG);
786 } else if (value instanceof Float) {
787 o.setType(FLOAT);
788 } else if (value instanceof Double) {
789 o.setType(DOUBLE);
790 } else {
791 return false;
792 }
793 return true;
794 }
795
796 @Override
797 synchronized Comparable<?> getDerivedGaugeFromComparable(
798 ObjectName object,
799 String attribute,
800 Comparable<?> value) {
801 final GaugeMonitorObservedObject o =
802 (GaugeMonitorObservedObject) getObservedObject(object);
803 if (o == null)
804 return null;
805
806 // Update the derived gauge attributes and check the
807 // validity of the new value. The derived gauge value
808 // is invalid when the differenceMode flag is set to
809 // true and it is the first notification, i.e. we
810 // haven't got 2 consecutive values to update the
811 // derived gauge.
812 //
813 o.setDerivedGaugeValid(updateDerivedGauge(value, o));
814
815 return (Comparable<?>) o.getDerivedGauge();
816 }
817
818 @Override
819 synchronized void onErrorNotification(MonitorNotification notification) {
820 final GaugeMonitorObservedObject o = (GaugeMonitorObservedObject)
821 getObservedObject(notification.getObservedObject());
822 if (o == null)
823 return;
824
825 // Reset values.
826 //
827 o.setStatus(RISING_OR_FALLING);
828 o.setPreviousScanGauge(null);
829 }
830
831 @Override
832 synchronized MonitorNotification buildAlarmNotification(
833 ObjectName object,
834 String attribute,
835 Comparable<?> value) {
836 final GaugeMonitorObservedObject o =
837 (GaugeMonitorObservedObject) getObservedObject(object);
838 if (o == null)
839 return null;
840
841 // Notify the listeners if the updated derived
842 // gauge value is valid.
843 //
844 final MonitorNotification alarm;
845 if (o.getDerivedGaugeValid())
846 alarm = updateNotifications(o);
847 else
848 alarm = null;
849 return alarm;
850 }
851
852 /**
853 * Tests if the threshold high and threshold low are both of the
854 * same type as the gauge. Both integer and floating-point types
855 * are allowed.
856 *
857 * Note:
858 * If the optional lowThreshold or highThreshold have not been
859 * initialized, their default value is an Integer object with
860 * a value equal to zero.
861 *
862 * @param object The observed object.
863 * @param attribute The observed attribute.
864 * @param value The sample value.
865 * @return <CODE>true</CODE> if type is the same,
866 * <CODE>false</CODE> otherwise.
867 */
868 @Override
869 synchronized boolean isThresholdTypeValid(ObjectName object,
870 String attribute,
871 Comparable<?> value) {
872 final GaugeMonitorObservedObject o =
873 (GaugeMonitorObservedObject) getObservedObject(object);
874 if (o == null)
875 return false;
876
877 Class<? extends Number> c = classForType(o.getType());
878 return (isValidForType(highThreshold, c) &&
879 isValidForType(lowThreshold, c));
880 }
881}