1 7 8 package javax.management.monitor; 9 10 11 import java.util.Date ; 14 import java.util.Timer ; 15 import java.util.TimerTask ; 16 17 import javax.management.ObjectName ; 20 import javax.management.MBeanNotificationInfo ; 21 import javax.management.AttributeNotFoundException ; 22 import javax.management.InstanceNotFoundException ; 23 import javax.management.MBeanException ; 24 import javax.management.ReflectionException ; 25 26 80 public class GaugeMonitor extends Monitor implements GaugeMonitorMBean { 81 82 83 88 89 private static final Integer INTEGER_ZERO = new Integer (0); 90 91 95 private Number highThreshold = INTEGER_ZERO; 96 97 101 private Number lowThreshold = INTEGER_ZERO; 102 103 109 private boolean notifyHigh = false; 110 111 117 private boolean notifyLow = false; 118 119 128 private boolean differenceMode = false; 129 130 135 private Number derivedGauge[] = new Number [capacityIncrement]; 136 137 142 private long derivedGaugeTimestamp[] = new long[capacityIncrement]; 143 144 149 private Number previousScanGauge[] = new Number [capacityIncrement]; 150 151 156 private int status[] = new int[capacityIncrement]; 157 158 163 private int type[] = new int[capacityIncrement]; 164 165 private static final int RISING = 0; 168 private static final int FALLING = 1; 169 private static final int RISING_OR_FALLING = 2; 170 171 private static final int INTEGER = 0; 175 private static final int BYTE = 1; 176 private static final int SHORT = 2; 177 private static final int LONG = 3; 178 private static final int FLOAT = 4; 179 private static final int DOUBLE = 5; 180 181 183 private static final int THRESHOLD_ERROR_NOTIFIED = 16; 190 191 194 private Timer timer = null; 195 196 197 198 201 String makeDebugTag() { 202 return "GaugeMonitor"; 203 } 204 205 210 211 214 public GaugeMonitor() { 215 dbgTag = makeDebugTag(); 216 } 217 218 223 224 227 public void start() { 228 229 if (isTraceOn()) { 230 trace("start", "start the gauge monitor"); 231 } 232 233 synchronized(this) { 234 if (isActive) { 235 if (isTraceOn()) { 236 trace("start", "the gauge monitor is already activated"); 237 } 238 239 return; 240 } 241 242 isActive = true; 243 244 for (int i = 0; i < elementCount; i++) { 247 status[i] = RISING_OR_FALLING; 248 previousScanGauge[i] = null; 249 } 250 251 timer = new Timer (); 254 timer.schedule(new GaugeAlarmClock(this), getGranularityPeriod(), 255 getGranularityPeriod()); 256 } 257 } 258 259 262 266 public void stop() { 267 trace("stop", "stop the gauge monitor"); 268 269 synchronized(this) { 270 if (!isActive) { 271 if (isTraceOn()) { 272 trace("stop", "the counter monitor is already started"); 273 } 274 275 return; 276 } 277 278 isActive = false; 279 280 if (timer != null) { 283 timer.cancel(); 284 timer = null; 285 } 286 } 287 } 288 289 292 302 public synchronized void setGranularityPeriod(long period) 303 throws IllegalArgumentException { 304 super.setGranularityPeriod(period); 305 306 if (isActive()) { 309 timer.cancel(); 310 timer = new Timer (); 311 timer.schedule(new GaugeAlarmClock(this), getGranularityPeriod(), 312 getGranularityPeriod()); 313 } 314 } 315 316 326 public synchronized Number getDerivedGauge(ObjectName object) { 327 int index = indexOf(object); 328 if (index != -1) 329 return derivedGauge[index]; 330 else 331 return null; 332 } 333 334 345 public synchronized long getDerivedGaugeTimeStamp(ObjectName object) { 346 int index = indexOf(object); 347 if (index != -1) 348 return derivedGaugeTimestamp[index]; 349 else 350 return 0; 351 } 352 353 360 @Deprecated 361 public synchronized Number getDerivedGauge() { 362 return derivedGauge[0]; 363 } 364 365 373 @Deprecated 374 public synchronized long getDerivedGaugeTimeStamp() { 375 return derivedGaugeTimestamp[0]; 376 } 377 378 383 public synchronized Number getHighThreshold() { 384 return highThreshold; 385 } 386 387 392 public synchronized Number getLowThreshold() { 393 return lowThreshold; 394 } 395 396 408 public synchronized void setThresholds(Number highValue, Number lowValue) 409 throws IllegalArgumentException { 410 411 if ((highValue == null) || (lowValue == null)) { 412 throw new IllegalArgumentException ("Null threshold value"); 413 } 414 if (highValue.getClass() != lowValue.getClass()) { 415 throw new IllegalArgumentException ("Different type " + 416 "threshold values"); 417 } 418 419 if (isFirstStrictlyGreaterThanLast(lowValue, highValue, 420 highValue.getClass().getName())) { 421 throw new IllegalArgumentException ("High threshold less than " + 422 "low threshold"); 423 } 424 425 highThreshold = highValue; 426 lowThreshold = lowValue; 427 for (int i = 0; i < elementCount; i++) { 428 resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED); 429 430 status[i] = RISING_OR_FALLING; 433 } 434 } 435 436 445 public synchronized boolean getNotifyHigh() { 446 return notifyHigh; 447 } 448 449 457 public synchronized void setNotifyHigh(boolean value) { 458 notifyHigh = value; 459 } 460 461 470 public synchronized boolean getNotifyLow() { 471 return notifyLow; 472 } 473 474 482 public synchronized void setNotifyLow(boolean value) { 483 notifyLow = value; 484 } 485 486 494 public synchronized boolean getDifferenceMode() { 495 return differenceMode; 496 } 497 498 505 public synchronized void setDifferenceMode(boolean value) { 506 differenceMode = value; 507 508 for (int i = 0; i < elementCount; i++) { 511 status[i] = RISING_OR_FALLING; 512 previousScanGauge[i] = null; 513 } 514 } 515 516 521 public MBeanNotificationInfo [] getNotificationInfo() { 522 String [] types = { MonitorNotification.RUNTIME_ERROR, 523 MonitorNotification.OBSERVED_OBJECT_ERROR, 524 MonitorNotification.OBSERVED_ATTRIBUTE_ERROR, 525 MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR, 526 MonitorNotification.THRESHOLD_ERROR, 527 MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED, 528 MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED}; 529 MBeanNotificationInfo [] notifsInfo = { 530 new MBeanNotificationInfo (types, 531 "javax.management.monitor.MonitorNotification", 532 "Notifications sent by the GaugeMonitor MBean") 533 }; 534 return notifsInfo; 535 } 536 537 542 543 555 private synchronized boolean updateDerivedGauge(Object scanGauge, 556 int index) { 557 558 boolean is_derived_gauge_valid; 559 560 derivedGaugeTimestamp[index] = System.currentTimeMillis(); 561 562 if (differenceMode) { 565 566 if (previousScanGauge[index] != null) { 569 setDerivedGaugeWithDifference((Number )scanGauge, index); 570 is_derived_gauge_valid = true; 571 } 572 else { 576 is_derived_gauge_valid = false; 577 } 578 previousScanGauge[index] = (Number )scanGauge; 579 } 580 else { 583 derivedGauge[index] = (Number )scanGauge; 584 is_derived_gauge_valid = true; 585 } 586 587 return is_derived_gauge_valid; 588 } 589 590 596 private void updateNotifications(int index) { 597 boolean sendNotify = false; 598 String notifType = null; 599 long timeStamp = 0; 600 String msg = null; 601 Object derGauge = null; 602 Object trigger = null; 603 604 synchronized(this) { 608 if (status[index] == RISING_OR_FALLING) { 609 if (isFirstGreaterThanLast(derivedGauge[index], highThreshold, 610 type[index])) { 611 if (notifyHigh) { 612 sendNotify = true; 613 notifType = 614 MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED; 615 timeStamp = derivedGaugeTimestamp[index]; 616 msg = ""; 617 derGauge = derivedGauge[index]; 618 trigger = highThreshold; 619 } 620 status[index] = FALLING; 621 } else if (isFirstGreaterThanLast(lowThreshold, 622 derivedGauge[index], 623 type[index])) { 624 if (notifyLow) { 625 sendNotify = true; 626 notifType = 627 MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED; 628 timeStamp = derivedGaugeTimestamp[index]; 629 msg =""; 630 derGauge = derivedGauge[index]; 631 trigger = lowThreshold; 632 } 633 status[index] = RISING; 634 } 635 } else { 636 if (status[index] == RISING) { 637 if (isFirstGreaterThanLast(derivedGauge[index], 638 highThreshold, 639 type[index])) { 640 if (notifyHigh) { 641 sendNotify = true; 642 notifType = 643 MonitorNotification.THRESHOLD_HIGH_VALUE_EXCEEDED; 644 timeStamp = derivedGaugeTimestamp[index]; 645 msg = ""; 646 derGauge = derivedGauge[index]; 647 trigger = highThreshold; 648 } 649 status[index] = FALLING; 650 } 651 } else if (status[index] == FALLING) { 652 if (isFirstGreaterThanLast(lowThreshold, 653 derivedGauge[index], 654 type[index])) { 655 if (notifyLow) { 656 sendNotify = true; 657 notifType = 658 MonitorNotification.THRESHOLD_LOW_VALUE_EXCEEDED; 659 timeStamp = derivedGaugeTimestamp[index]; 660 msg = ""; 661 derGauge = derivedGauge[index]; 662 trigger = lowThreshold; 663 } 664 status[index] = RISING; 665 } 666 } 667 } 668 } 669 670 if (sendNotify) { 671 sendNotification(notifType, timeStamp, msg, derGauge, trigger, index); 672 } 673 } 674 675 689 private synchronized boolean isThresholdTypeValid(int index) { 690 691 switch(type[index]) { 692 case INTEGER: 693 return (((highThreshold == INTEGER_ZERO) || 694 (highThreshold instanceof Integer )) && 695 ((lowThreshold == INTEGER_ZERO) || 696 (lowThreshold instanceof Integer ))); 697 case BYTE: 698 return (((highThreshold == INTEGER_ZERO) || 699 (highThreshold instanceof Byte )) && 700 ((lowThreshold == INTEGER_ZERO) || 701 (lowThreshold instanceof Byte ))); 702 case SHORT: 703 return (((highThreshold == INTEGER_ZERO) || 704 (highThreshold instanceof Short )) && 705 ((lowThreshold == INTEGER_ZERO) || 706 (lowThreshold instanceof Short ))); 707 case LONG: 708 return (((highThreshold == INTEGER_ZERO) || 709 (highThreshold instanceof Long )) && 710 ((lowThreshold == INTEGER_ZERO) || 711 (lowThreshold instanceof Long ))); 712 case FLOAT: 713 return (((highThreshold == INTEGER_ZERO) || 714 (highThreshold instanceof Float )) && 715 ((lowThreshold == INTEGER_ZERO) || 716 (lowThreshold instanceof Float ))); 717 case DOUBLE: 718 return (((highThreshold == INTEGER_ZERO) || 719 (highThreshold instanceof Double )) && 720 ((lowThreshold == INTEGER_ZERO) || 721 (lowThreshold instanceof Double ))); 722 default: 723 if (isDebugOn()) { 725 debug("isThresholdTypeValid", "The threshold type is invalid"); 726 } 727 return false; 728 } 729 } 730 731 739 private synchronized void setDerivedGaugeWithDifference(Number scanGauge, 740 int index) { 741 Number prev = previousScanGauge[index]; 742 Number der; 743 switch (type[index]) { 744 case INTEGER: 745 der = new Integer (((Integer )scanGauge).intValue() - 746 ((Integer )prev).intValue()); 747 break; 748 case BYTE: 749 der = new Byte ((byte)(((Byte )scanGauge).byteValue() - 750 ((Byte )prev).byteValue())); 751 break; 752 case SHORT: 753 der = new Short ((short)(((Short )scanGauge).shortValue() - 754 ((Short )prev).shortValue())); 755 break; 756 case LONG: 757 der = new Long (((Long )scanGauge).longValue() - 758 ((Long )prev).longValue()); 759 break; 760 case FLOAT: 761 der = new Float (((Float )scanGauge).floatValue() - 762 ((Float )prev).floatValue()); 763 break; 764 case DOUBLE: 765 der = new Double (((Double )scanGauge).doubleValue() - 766 ((Double )prev).doubleValue()); 767 default: 768 if (isDebugOn()) { 770 debug("setDerivedGaugeWithDifference", 771 "the threshold type is invalid"); 772 } 773 return; 774 } 775 derivedGauge[index] = der; 776 } 777 778 789 private boolean isFirstGreaterThanLast(Number greater, 790 Number less, int type) { 791 792 switch(type) { 793 case INTEGER: 794 case BYTE: 795 case SHORT: 796 case LONG: 797 return (greater.longValue() >= less.longValue()); 798 case FLOAT: 799 case DOUBLE: 800 return (greater.doubleValue() >= less.doubleValue()); 801 default: 802 if (isDebugOn()) { 804 debug("isFirstGreaterThanLast", 805 "the threshold type is invalid"); 806 } 807 return false; 808 } 809 } 810 811 821 private boolean isFirstStrictlyGreaterThanLast(Number greater, 822 Number less, 823 String className) { 824 825 if (className.equals("java.lang.Integer") || 826 className.equals("java.lang.Byte") || 827 className.equals("java.lang.Short") || 828 className.equals("java.lang.Long")) { 829 830 return (greater.longValue() > less.longValue()); 831 } 832 else if (className.equals("java.lang.Float") || 833 className.equals("java.lang.Double")) { 834 835 return (greater.doubleValue() > less.doubleValue()); 836 } 837 else { 838 if (isDebugOn()) { 840 debug("isFirstStrictlyGreaterThanLast", 841 "the threshold type is invalid"); 842 } 843 return false; 844 } 845 } 846 847 852 853 858 void notifyAlarmClock(int index) { 859 long timeStamp = 0; 860 String msg = null; 861 Object derGauge = null; 862 863 Object scan_gauge = null; 864 String notif_type = null; 865 866 synchronized(this) { 867 if (!isActive()) 868 return; 869 870 873 if ((getObservedObject(index) == null) || 879 (getObservedAttribute() == null)) 880 return; 881 882 try { 887 scan_gauge = server.getAttribute(getObservedObject(index), 888 getObservedAttribute()); 889 if (scan_gauge == null) 890 return; 891 } catch (NullPointerException np_ex) { 892 if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED)) 893 return; 894 else { 895 notif_type = MonitorNotification.RUNTIME_ERROR; 896 setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED); 897 msg = 898 "The gauge monitor must be registered in " + 899 "the MBean server."; 900 } 901 } catch (InstanceNotFoundException inf_ex) { 902 if (alreadyNotified(index, OBSERVED_OBJECT_ERROR_NOTIFIED)) 903 return; 904 else { 905 notif_type = MonitorNotification.OBSERVED_OBJECT_ERROR; 906 setAlreadyNotified(index, 907 OBSERVED_OBJECT_ERROR_NOTIFIED); 908 msg = 909 "The observed object must be registered in " + 910 "the MBean server."; 911 } 912 } catch (AttributeNotFoundException anf_ex) { 913 if (alreadyNotified(index, 914 OBSERVED_ATTRIBUTE_ERROR_NOTIFIED)) 915 return; 916 else { 917 notif_type = 918 MonitorNotification.OBSERVED_ATTRIBUTE_ERROR; 919 setAlreadyNotified(index, 920 OBSERVED_ATTRIBUTE_ERROR_NOTIFIED); 921 msg = 922 "The observed attribute must be accessible in " + 923 "the observed object."; 924 } 925 } catch (MBeanException mb_ex) { 926 if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED)) 927 return; 928 else { 929 notif_type = MonitorNotification.RUNTIME_ERROR; 930 setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED); 931 msg = mb_ex.getMessage(); 932 } 933 } catch (ReflectionException ref_ex) { 934 if (alreadyNotified(index, 935 OBSERVED_ATTRIBUTE_ERROR_NOTIFIED)) 936 return; 937 else { 938 notif_type = 939 MonitorNotification.OBSERVED_ATTRIBUTE_ERROR; 940 setAlreadyNotified(index, 941 OBSERVED_ATTRIBUTE_ERROR_NOTIFIED); 942 msg = ref_ex.getMessage(); 943 } 944 } 945 946 if (msg == null) { 947 if (scan_gauge instanceof Integer ) { 951 type[index] = INTEGER; 952 } else if (scan_gauge instanceof Byte ) { 953 type[index] = BYTE; 954 } else if (scan_gauge instanceof Short ) { 955 type[index] = SHORT; 956 } else if (scan_gauge instanceof Long ) { 957 type[index] = LONG; 958 } else if (scan_gauge instanceof Float ) { 959 type[index] = FLOAT; 960 } else if (scan_gauge instanceof Double ) { 961 type[index] = DOUBLE; 962 } else { 963 if (alreadyNotified(index, 964 OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED)) 965 return; 966 else { 967 notif_type = 968 MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR; 969 setAlreadyNotified(index, 970 OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED); 971 msg = 972 "The observed attribute type must be an " + 973 "integer type or a floating-point type."; 974 } 975 } 976 } 977 978 if (msg == null) { 979 if (!isThresholdTypeValid(index)) { 983 if (alreadyNotified(index, THRESHOLD_ERROR_NOTIFIED)) 984 return; 985 else { 986 notif_type = MonitorNotification.THRESHOLD_ERROR; 987 setAlreadyNotified(index, THRESHOLD_ERROR_NOTIFIED); 988 msg = 989 "The threshold high and threshold low must be " + 990 "of the same type as the gauge."; 991 } 992 } 993 } 994 995 if (msg == null) { 996 997 resetAllAlreadyNotified(index); 1000 1001 boolean is_derived_gauge_valid = 1009 updateDerivedGauge(scan_gauge, index); 1010 1011 if (is_derived_gauge_valid) 1015 updateNotifications(index); 1016 1017 } else { 1018 1019 1021 timeStamp = derivedGaugeTimestamp[index]; 1022 derGauge = derivedGauge[index]; 1023 1024 status[index] = RISING_OR_FALLING; 1027 previousScanGauge[index] = null; 1028 } 1029 } 1030 1031 if (msg != null) { 1032 sendNotification(notif_type, 1033 timeStamp, 1034 msg, 1035 derGauge, 1036 null, 1037 index); 1038 } 1039 } 1040 1041 1046 synchronized void insertSpecificElementAt(int index) { 1047 1050 if (index != elementCount) 1051 throw new Error ("Internal error: index != elementCount"); 1052 1053 if (elementCount >= derivedGauge.length) { 1054 derivedGauge = expandArray(derivedGauge); 1055 previousScanGauge = expandArray(previousScanGauge); 1056 derivedGaugeTimestamp = expandArray(derivedGaugeTimestamp); 1057 status = expandArray(status); 1058 type = expandArray(type); 1059 } 1060 1061 derivedGauge[index] = INTEGER_ZERO; 1062 previousScanGauge[index] = null; 1063 derivedGaugeTimestamp[index] = System.currentTimeMillis(); 1064 status[index] = RISING_OR_FALLING; 1065 type[index] = INTEGER; 1066 } 1067 1068 1073 synchronized void removeSpecificElementAt(int index) { 1074 if (index < 0 || index >= elementCount) 1075 return; 1076 1077 removeElementAt(derivedGauge, index); 1081 removeElementAt(previousScanGauge, index); 1082 removeElementAt(derivedGaugeTimestamp, index); 1083 removeElementAt(status, index); 1084 removeElementAt(type, index); 1085 } 1086 1087 1088 1094 1095 private static class GaugeAlarmClock extends TimerTask { 1096 1097 GaugeMonitor listener = null; 1098 1099 1104 1105 public GaugeAlarmClock(GaugeMonitor listener) { 1106 this.listener = listener; 1107 } 1108 1109 1114 1115 1119 public void run() { 1120 if (listener.isActive()) { 1121 for (int i = 0; i < listener.elementCount; i++) { 1122 listener.notifyAlarmClock(i); 1123 } 1124 } 1125 } 1126 } 1127} 1128 | Popular Tags |