1/* 2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package javax.management.monitor; 27 28import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER; 29import java.lang.System.Logger.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.log(Level.TRACE, "the monitor is already active"); 228 return; 229 } 230 // Reset values. 231 // 232 for (ObservedObject o : observedObjects) { 233 final GaugeMonitorObservedObject gmo = 234 (GaugeMonitorObservedObject) o; 235 gmo.setStatus(RISING_OR_FALLING); 236 gmo.setPreviousScanGauge(null); 237 } 238 doStart(); 239 } 240 241 /** 242 * Stops the gauge monitor. 243 */ 244 public synchronized void stop() { 245 doStop(); 246 } 247 248 // GETTERS AND SETTERS 249 //-------------------- 250 251 /** 252 * Gets the derived gauge of the specified object, if this object is 253 * contained in the set of observed MBeans, or <code>null</code> otherwise. 254 * 255 * @param object the name of the MBean. 256 * 257 * @return The derived gauge of the specified object. 258 * 259 */ 260 @Override 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 @Override 277 public synchronized long getDerivedGaugeTimeStamp(ObjectName object) { 278 return super.getDerivedGaugeTimeStamp(object); 279 } 280 281 /** 282 * Returns the derived gauge of the first object in the set of 283 * observed MBeans. 284 * 285 * @return The derived gauge. 286 * 287 * @deprecated As of JMX 1.2, replaced by 288 * {@link #getDerivedGauge(ObjectName)} 289 */ 290 @Deprecated 291 public synchronized Number getDerivedGauge() { 292 if (observedObjects.isEmpty()) { 293 return null; 294 } else { 295 return (Number) observedObjects.get(0).getDerivedGauge(); 296 } 297 } 298 299 /** 300 * Gets the derived gauge timestamp of the first object in the set 301 * of observed MBeans. 302 * 303 * @return The derived gauge timestamp. 304 * 305 * @deprecated As of JMX 1.2, replaced by 306 * {@link #getDerivedGaugeTimeStamp(ObjectName)} 307 */ 308 @Deprecated 309 public synchronized long getDerivedGaugeTimeStamp() { 310 if (observedObjects.isEmpty()) { 311 return 0; 312 } else { 313 return observedObjects.get(0).getDerivedGaugeTimeStamp(); 314 } 315 } 316 317 /** 318 * Gets the high threshold value common to all observed MBeans. 319 * 320 * @return The high threshold value. 321 * 322 * @see #setThresholds 323 */ 324 public synchronized Number getHighThreshold() { 325 return highThreshold; 326 } 327 328 /** 329 * Gets the low threshold value common to all observed MBeans. 330 * 331 * @return The low threshold value. 332 * 333 * @see #setThresholds 334 */ 335 public synchronized Number getLowThreshold() { 336 return lowThreshold; 337 } 338 339 /** 340 * Sets the high and the low threshold values common to all 341 * observed MBeans. 342 * 343 * @param highValue The high threshold value. 344 * @param lowValue The low threshold value. 345 * 346 * @exception IllegalArgumentException The specified high/low 347 * threshold is null or the low threshold is greater than the high 348 * threshold or the high threshold and the low threshold are not 349 * of the same type. 350 * 351 * @see #getHighThreshold 352 * @see #getLowThreshold 353 */ 354 public synchronized void setThresholds(Number highValue, Number lowValue) 355 throws IllegalArgumentException { 356 357 if ((highValue == null) || (lowValue == null)) { 358 throw new IllegalArgumentException("Null threshold value"); 359 } 360 361 if (highValue.getClass() != lowValue.getClass()) { 362 throw new IllegalArgumentException("Different type " + 363 "threshold values"); 364 } 365 366 if (isFirstStrictlyGreaterThanLast(lowValue, highValue, 367 highValue.getClass().getName())) { 368 throw new IllegalArgumentException("High threshold less than " + 369 "low threshold"); 370 } 371 372 if (highThreshold.equals(highValue) && lowThreshold.equals(lowValue)) 373 return; 374 highThreshold = highValue; 375 lowThreshold = lowValue; 376 377 // Reset values. 378 // 379 int index = 0; 380 for (ObservedObject o : observedObjects) { 381 resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED); 382 final GaugeMonitorObservedObject gmo = 383 (GaugeMonitorObservedObject) o; 384 gmo.setStatus(RISING_OR_FALLING); 385 } 386 } 387 388 /** 389 * Gets the high notification's on/off switch value common to all 390 * observed MBeans. 391 * 392 * @return <CODE>true</CODE> if the gauge monitor notifies when 393 * exceeding the high threshold, <CODE>false</CODE> otherwise. 394 * 395 * @see #setNotifyHigh 396 */ 397 public synchronized boolean getNotifyHigh() { 398 return notifyHigh; 399 } 400 401 /** 402 * Sets the high notification's on/off switch value common to all 403 * observed MBeans. 404 * 405 * @param value The high notification's on/off switch value. 406 * 407 * @see #getNotifyHigh 408 */ 409 public synchronized void setNotifyHigh(boolean value) { 410 if (notifyHigh == value) 411 return; 412 notifyHigh = value; 413 } 414 415 /** 416 * Gets the low notification's on/off switch value common to all 417 * observed MBeans. 418 * 419 * @return <CODE>true</CODE> if the gauge monitor notifies when 420 * exceeding the low threshold, <CODE>false</CODE> otherwise. 421 * 422 * @see #setNotifyLow 423 */ 424 public synchronized boolean getNotifyLow() { 425 return notifyLow; 426 } 427 428 /** 429 * Sets the low notification's on/off switch value common to all 430 * observed MBeans. 431 * 432 * @param value The low notification's on/off switch value. 433 * 434 * @see #getNotifyLow 435 */ 436 public synchronized void setNotifyLow(boolean value) { 437 if (notifyLow == value) 438 return; 439 notifyLow = value; 440 } 441 442 /** 443 * Gets the difference mode flag value common to all observed MBeans. 444 * 445 * @return <CODE>true</CODE> if the difference mode is used, 446 * <CODE>false</CODE> otherwise. 447 * 448 * @see #setDifferenceMode 449 */ 450 public synchronized boolean getDifferenceMode() { 451 return differenceMode; 452 } 453 454 /** 455 * Sets the difference mode flag value common to all observed MBeans. 456 * 457 * @param value The difference mode flag value. 458 * 459 * @see #getDifferenceMode 460 */ 461 public synchronized void setDifferenceMode(boolean value) { 462 if (differenceMode == value) 463 return; 464 differenceMode = value; 465 466 // Reset values. 467 // 468 for (ObservedObject o : observedObjects) { 469 final GaugeMonitorObservedObject gmo = 470 (GaugeMonitorObservedObject) o; 471 gmo.setStatus(RISING_OR_FALLING); 472 gmo.setPreviousScanGauge(null); 473 } 474 } 475 476 /** 477 * Returns a <CODE>NotificationInfo</CODE> object containing the 478 * name of the Java class of the notification and the notification 479 * types sent by the gauge monitor. 480 */ 481 @Override 482 public MBeanNotificationInfo[] getNotificationInfo() { 483 return notifsInfo.clone(); 484 } 485 486 /* 487 * ------------------------------------------ 488 * PRIVATE METHODS 489 * ------------------------------------------ 490 */ 491 492 /** 493 * Updates the derived gauge attribute of the observed object. 494 * 495 * @param scanGauge The value of the observed attribute. 496 * @param o The observed object. 497 * @return <CODE>true</CODE> if the derived gauge value is valid, 498 * <CODE>false</CODE> otherwise. The derived gauge value is 499 * invalid when the differenceMode flag is set to 500 * <CODE>true</CODE> and it is the first notification (so we 501 * haven't 2 consecutive values to update the derived gauge). 502 */ 503 private synchronized boolean updateDerivedGauge( 504 Object scanGauge, GaugeMonitorObservedObject o) { 505 506 boolean is_derived_gauge_valid; 507 508 // The gauge difference mode is used. 509 // 510 if (differenceMode) { 511 512 // The previous scan gauge has been initialized. 513 // 514 if (o.getPreviousScanGauge() != null) { 515 setDerivedGaugeWithDifference((Number)scanGauge, o); 516 is_derived_gauge_valid = true; 517 } 518 // The previous scan gauge has not been initialized. 519 // We cannot update the derived gauge... 520 // 521 else { 522 is_derived_gauge_valid = false; 523 } 524 o.setPreviousScanGauge((Number)scanGauge); 525 } 526 // The gauge difference mode is not used. 527 // 528 else { 529 o.setDerivedGauge((Number)scanGauge); 530 is_derived_gauge_valid = true; 531 } 532 533 return is_derived_gauge_valid; 534 } 535 536 /** 537 * Updates the notification attribute of the observed object 538 * and notifies the listeners only once if the notify flag 539 * is set to <CODE>true</CODE>. 540 * @param o The observed object. 541 */ 542 private synchronized MonitorNotification updateNotifications( 543 GaugeMonitorObservedObject o) { 544 545 MonitorNotification n = null; 546 547 // Send high notification if notifyHigh is true. 548 // Send low notification if notifyLow is true. 549 // 550 if (o.getStatus() == RISING_OR_FALLING) { 551 if (isFirstGreaterThanLast((Number)o.getDerivedGauge(), 552 highThreshold, 553 o.getType())) { 554 if (notifyHigh) { 555 n = new MonitorNotification( 556 THRESHOLD_HIGH_VALUE_EXCEEDED, 557 this, 558 0, 559 0, 560 "", 561 null, 562 null, 563 null, 564 highThreshold); 565 } 566 o.setStatus(FALLING); 567 } else if (isFirstGreaterThanLast(lowThreshold, 568 (Number)o.getDerivedGauge(), 569 o.getType())) { 570 if (notifyLow) { 571 n = new MonitorNotification( 572 THRESHOLD_LOW_VALUE_EXCEEDED, 573 this, 574 0, 575 0, 576 "", 577 null, 578 null, 579 null, 580 lowThreshold); 581 } 582 o.setStatus(RISING); 583 } 584 } else { 585 if (o.getStatus() == RISING) { 586 if (isFirstGreaterThanLast((Number)o.getDerivedGauge(), 587 highThreshold, 588 o.getType())) { 589 if (notifyHigh) { 590 n = new MonitorNotification( 591 THRESHOLD_HIGH_VALUE_EXCEEDED, 592 this, 593 0, 594 0, 595 "", 596 null, 597 null, 598 null, 599 highThreshold); 600 } 601 o.setStatus(FALLING); 602 } 603 } else if (o.getStatus() == FALLING) { 604 if (isFirstGreaterThanLast(lowThreshold, 605 (Number)o.getDerivedGauge(), 606 o.getType())) { 607 if (notifyLow) { 608 n = new MonitorNotification( 609 THRESHOLD_LOW_VALUE_EXCEEDED, 610 this, 611 0, 612 0, 613 "", 614 null, 615 null, 616 null, 617 lowThreshold); 618 } 619 o.setStatus(RISING); 620 } 621 } 622 } 623 624 return n; 625 } 626 627 /** 628 * Sets the derived gauge when the differenceMode flag is set to 629 * <CODE>true</CODE>. Both integer and floating-point types are 630 * allowed. 631 * 632 * @param scanGauge The value of the observed attribute. 633 * @param o The observed object. 634 */ 635 private synchronized void setDerivedGaugeWithDifference( 636 Number scanGauge, GaugeMonitorObservedObject o) { 637 Number prev = o.getPreviousScanGauge(); 638 Number der; 639 switch (o.getType()) { 640 case INTEGER: 641 der = Integer.valueOf(((Integer)scanGauge).intValue() - 642 ((Integer)prev).intValue()); 643 break; 644 case BYTE: 645 der = Byte.valueOf((byte)(((Byte)scanGauge).byteValue() - 646 ((Byte)prev).byteValue())); 647 break; 648 case SHORT: 649 der = Short.valueOf((short)(((Short)scanGauge).shortValue() - 650 ((Short)prev).shortValue())); 651 break; 652 case LONG: 653 der = Long.valueOf(((Long)scanGauge).longValue() - 654 ((Long)prev).longValue()); 655 break; 656 case FLOAT: 657 der = Float.valueOf(((Float)scanGauge).floatValue() - 658 ((Float)prev).floatValue()); 659 break; 660 case DOUBLE: 661 der = Double.valueOf(((Double)scanGauge).doubleValue() - 662 ((Double)prev).doubleValue()); 663 break; 664 default: 665 // Should never occur... 666 MONITOR_LOGGER.log(Level.TRACE, 667 "the threshold type is invalid"); 668 return; 669 } 670 o.setDerivedGauge(der); 671 } 672 673 /** 674 * Tests if the first specified Number is greater than or equal to 675 * the last. Both integer and floating-point types are allowed. 676 * 677 * @param greater The first Number to compare with the second. 678 * @param less The second Number to compare with the first. 679 * @param type The number type. 680 * @return <CODE>true</CODE> if the first specified Number is 681 * greater than or equal to the last, <CODE>false</CODE> 682 * otherwise. 683 */ 684 private boolean isFirstGreaterThanLast(Number greater, 685 Number less, 686 NumericalType type) { 687 688 switch (type) { 689 case INTEGER: 690 case BYTE: 691 case SHORT: 692 case LONG: 693 return (greater.longValue() >= less.longValue()); 694 case FLOAT: 695 case DOUBLE: 696 return (greater.doubleValue() >= less.doubleValue()); 697 default: 698 // Should never occur... 699 MONITOR_LOGGER.log(Level.TRACE, 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.log(Level.TRACE, 734 "the threshold type is invalid"); 735 return false; 736 } 737 } 738 739 /* 740 * ------------------------------------------ 741 * PACKAGE METHODS 742 * ------------------------------------------ 743 */ 744 745 /** 746 * Factory method for ObservedObject creation. 747 * 748 * @since 1.6 749 */ 750 @Override 751 ObservedObject createObservedObject(ObjectName object) { 752 final GaugeMonitorObservedObject gmo = 753 new GaugeMonitorObservedObject(object); 754 gmo.setStatus(RISING_OR_FALLING); 755 gmo.setPreviousScanGauge(null); 756 return gmo; 757 } 758 759 /** 760 * This method globally sets the derived gauge type for the given 761 * "object" and "attribute" after checking that the type of the 762 * supplied observed attribute value is one of the value types 763 * supported by this monitor. 764 */ 765 @Override 766 synchronized boolean isComparableTypeValid(ObjectName object, 767 String attribute, 768 Comparable<?> value) { 769 final GaugeMonitorObservedObject o = 770 (GaugeMonitorObservedObject) getObservedObject(object); 771 if (o == null) 772 return false; 773 774 // Check that the observed attribute is either of type 775 // "Integer" or "Float". 776 // 777 if (value instanceof Integer) { 778 o.setType(INTEGER); 779 } else if (value instanceof Byte) { 780 o.setType(BYTE); 781 } else if (value instanceof Short) { 782 o.setType(SHORT); 783 } else if (value instanceof Long) { 784 o.setType(LONG); 785 } else if (value instanceof Float) { 786 o.setType(FLOAT); 787 } else if (value instanceof Double) { 788 o.setType(DOUBLE); 789 } else { 790 return false; 791 } 792 return true; 793 } 794 795 @Override 796 synchronized Comparable<?> getDerivedGaugeFromComparable( 797 ObjectName object, 798 String attribute, 799 Comparable<?> value) { 800 final GaugeMonitorObservedObject o = 801 (GaugeMonitorObservedObject) getObservedObject(object); 802 if (o == null) 803 return null; 804 805 // Update the derived gauge attributes and check the 806 // validity of the new value. The derived gauge value 807 // is invalid when the differenceMode flag is set to 808 // true and it is the first notification, i.e. we 809 // haven't got 2 consecutive values to update the 810 // derived gauge. 811 // 812 o.setDerivedGaugeValid(updateDerivedGauge(value, o)); 813 814 return (Comparable<?>) o.getDerivedGauge(); 815 } 816 817 @Override 818 synchronized void onErrorNotification(MonitorNotification notification) { 819 final GaugeMonitorObservedObject o = (GaugeMonitorObservedObject) 820 getObservedObject(notification.getObservedObject()); 821 if (o == null) 822 return; 823 824 // Reset values. 825 // 826 o.setStatus(RISING_OR_FALLING); 827 o.setPreviousScanGauge(null); 828 } 829 830 @Override 831 synchronized MonitorNotification buildAlarmNotification( 832 ObjectName object, 833 String attribute, 834 Comparable<?> value) { 835 final GaugeMonitorObservedObject o = 836 (GaugeMonitorObservedObject) getObservedObject(object); 837 if (o == null) 838 return null; 839 840 // Notify the listeners if the updated derived 841 // gauge value is valid. 842 // 843 final MonitorNotification alarm; 844 if (o.getDerivedGaugeValid()) 845 alarm = updateNotifications(o); 846 else 847 alarm = null; 848 return alarm; 849 } 850 851 /** 852 * Tests if the threshold high and threshold low are both of the 853 * same type as the gauge. Both integer and floating-point types 854 * are allowed. 855 * 856 * Note: 857 * If the optional lowThreshold or highThreshold have not been 858 * initialized, their default value is an Integer object with 859 * a value equal to zero. 860 * 861 * @param object The observed object. 862 * @param attribute The observed attribute. 863 * @param value The sample value. 864 * @return <CODE>true</CODE> if type is the same, 865 * <CODE>false</CODE> otherwise. 866 */ 867 @Override 868 synchronized boolean isThresholdTypeValid(ObjectName object, 869 String attribute, 870 Comparable<?> value) { 871 final GaugeMonitorObservedObject o = 872 (GaugeMonitorObservedObject) getObservedObject(object); 873 if (o == null) 874 return false; 875 876 Class<? extends Number> c = classForType(o.getType()); 877 return (isValidForType(highThreshold, c) && 878 isValidForType(lowThreshold, c)); 879 } 880} 881