1 7 8 package javax.management.monitor; 9 10 import java.util.Date ; 13 import java.util.Timer ; 14 import java.util.TimerTask ; 15 16 import javax.management.ObjectName ; 19 import javax.management.MBeanNotificationInfo ; 20 import javax.management.AttributeNotFoundException ; 21 import javax.management.InstanceNotFoundException ; 22 import javax.management.MBeanException ; 23 import javax.management.ReflectionException ; 24 25 71 public class CounterMonitor extends Monitor implements CounterMonitorMBean { 72 73 74 79 80 private static final Integer INTEGER_ZERO = new Integer (0); 81 82 87 private Number threshold[] = new Number [capacityIncrement]; 88 89 93 private Number modulus = INTEGER_ZERO; 94 95 99 private Number offset = INTEGER_ZERO; 100 101 106 private boolean notify = false; 107 108 115 private boolean differenceMode = false; 116 117 123 private Number initThreshold = INTEGER_ZERO; 124 125 131 private Number derivedGauge[] = new Number [capacityIncrement]; 132 133 138 private long derivedGaugeTimestamp[] = new long[capacityIncrement]; 139 140 145 private Number previousScanCounter[] = new Number [capacityIncrement]; 146 147 154 private boolean modulusExceeded[] = new boolean[capacityIncrement]; 155 156 163 private Number derivedGaugeExceeded[] = new Number [capacityIncrement]; 164 165 171 private boolean eventAlreadyNotified[] = new boolean[capacityIncrement]; 172 173 178 private int type[] = new int[capacityIncrement]; 179 180 private static final int INTEGER = 0; 184 private static final int BYTE = 1; 185 private static final int SHORT = 2; 186 private static final int LONG = 3; 187 188 private static final int THRESHOLD_ERROR_NOTIFIED = 16; 195 196 199 private Timer timer = null; 200 201 202 205 String makeDebugTag() { 206 return "CounterMonitor"; 207 } 208 209 210 215 216 219 public CounterMonitor() { 220 dbgTag = makeDebugTag(); 221 } 222 223 228 229 237 public void preDeregister() throws java.lang.Exception { 238 239 super.preDeregister(); 242 243 if (isTraceOn()) { 244 trace("preDeregister", "reset the threshold values"); 245 } 246 247 synchronized (this) { 250 for (int i = 0; i < elementCount; i++) { 251 threshold[i] = initThreshold; 252 } 253 } 254 } 255 256 259 public synchronized void start() { 260 if (isTraceOn()) { 261 trace("start", "start the counter monitor"); 262 } 263 264 if (isActive()) { 265 if (isTraceOn()) { 266 trace("start", "the counter monitor is already activated"); 267 } 268 269 return; 270 } 271 272 isActive = true; 273 274 for (int i = 0; i < elementCount; i++) { 277 threshold[i] = initThreshold; 278 modulusExceeded[i] = false; 279 eventAlreadyNotified[i] = false; 280 previousScanCounter[i] = null; 281 } 282 283 timer = new Timer (); 286 timer.schedule(new CounterAlarmClock(this), getGranularityPeriod(), 287 getGranularityPeriod()); 288 } 289 290 298 public synchronized void stop() { 299 if (isTraceOn()) { 300 trace("stop", "stop the counter monitor"); 301 } 302 303 if (isTraceOn()) { 304 trace("stop", "the counter monitor is not started"); 305 306 return; 307 } 308 309 isActive = false; 310 311 if (timer != null) { 314 timer.cancel(); 315 timer = null; 316 } 317 } 318 319 322 332 public synchronized void setGranularityPeriod(long period) 333 throws IllegalArgumentException { 334 super.setGranularityPeriod(period); 335 336 if (isActive()) { 339 timer.cancel(); 340 timer = new Timer (); 341 timer.schedule(new CounterAlarmClock(this), 342 getGranularityPeriod(), getGranularityPeriod()); 343 } 344 } 345 346 357 public synchronized Number getDerivedGauge(ObjectName object) { 358 int index = indexOf(object); 359 if (index != -1) 360 return derivedGauge[index]; 361 else 362 return null; 363 } 364 365 377 public synchronized long getDerivedGaugeTimeStamp(ObjectName object) { 378 int index = indexOf(object); 379 if (index != -1) 380 return derivedGaugeTimestamp[index]; 381 else 382 return 0; 383 } 384 385 399 public synchronized Number getThreshold(ObjectName object) { 400 int index = indexOf(object); 401 if (index != -1) 402 return threshold[index]; 403 else 404 return null; 405 } 406 407 416 public synchronized Number getInitThreshold() { 417 return initThreshold; 418 } 419 420 434 public synchronized void setInitThreshold(Number value) 435 throws IllegalArgumentException { 436 437 if (value == null) { 438 throw new IllegalArgumentException ("Null threshold"); 439 } 440 if (value.longValue() < 0L) { 441 throw new IllegalArgumentException ("Negative threshold"); 442 } 443 444 initThreshold = value; 445 for (int i = 0; i < elementCount; i++) { 446 threshold[i] = value; 447 resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED); 448 449 modulusExceeded[i] = false; 452 eventAlreadyNotified[i] = false; 453 } 454 } 455 456 463 @Deprecated 464 public synchronized Number getDerivedGauge() { 465 return derivedGauge[0]; 466 } 467 468 476 @Deprecated 477 public synchronized long getDerivedGaugeTimeStamp() { 478 return derivedGaugeTimestamp[0]; 479 } 480 481 491 @Deprecated 492 public synchronized Number getThreshold() { 493 return threshold[0]; 494 } 495 496 507 @Deprecated 508 public synchronized void setThreshold(Number value) 509 throws IllegalArgumentException { 510 setInitThreshold(value); 511 } 512 513 520 public synchronized Number getOffset() { 521 return offset; 522 } 523 524 533 public synchronized void setOffset(Number value) 534 throws IllegalArgumentException { 535 536 if (value == null) { 537 throw new IllegalArgumentException ("Null offset"); 538 } 539 if (value.longValue() < 0L) { 540 throw new IllegalArgumentException ("Negative offset"); 541 } 542 543 offset = value; 544 for (int i = 0; i < elementCount; i++) { 545 resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED); 546 } 547 } 548 549 556 public synchronized Number getModulus() { 557 return modulus; 558 } 559 560 569 public synchronized void setModulus(Number value) 570 throws IllegalArgumentException { 571 572 if (value == null) { 573 throw new IllegalArgumentException ("Null modulus"); 574 } 575 if (value.longValue() < 0L) { 576 throw new IllegalArgumentException ("Negative modulus"); 577 } 578 579 modulus = value; 580 for (int i = 0; i < elementCount; i++) { 581 resetAlreadyNotified(i, THRESHOLD_ERROR_NOTIFIED); 582 583 modulusExceeded[i] = false; 586 } 587 } 588 589 598 public synchronized boolean getNotify() { 599 return notify; 600 } 601 602 610 public synchronized void setNotify(boolean value) { 611 notify = value; 612 } 613 614 622 public synchronized boolean getDifferenceMode() { 623 return differenceMode; 624 } 625 626 633 public synchronized void setDifferenceMode(boolean value) { 634 differenceMode = value; 635 636 for (int i = 0; i < elementCount; i++) { 637 threshold[i] = initThreshold; 640 modulusExceeded[i] = false; 641 eventAlreadyNotified[i] = false; 642 previousScanCounter[i] = null; 643 } 644 } 645 646 647 652 public MBeanNotificationInfo [] getNotificationInfo() { 653 String [] types = { MonitorNotification.RUNTIME_ERROR, 654 MonitorNotification.OBSERVED_OBJECT_ERROR, 655 MonitorNotification.OBSERVED_ATTRIBUTE_ERROR, 656 MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR, 657 MonitorNotification.THRESHOLD_ERROR, 658 MonitorNotification.THRESHOLD_VALUE_EXCEEDED}; 659 MBeanNotificationInfo [] notifsInfo = { 660 new MBeanNotificationInfo (types, 661 "javax.management.monitor.MonitorNotification", 662 "Notifications sent by the CounterMonitor MBean") 663 }; 664 return notifsInfo; 665 } 666 667 672 673 685 private synchronized boolean updateDerivedGauge(Object scanCounter, 686 int index) { 687 688 boolean is_derived_gauge_valid; 689 690 derivedGaugeTimestamp[index] = System.currentTimeMillis(); 691 692 if (differenceMode) { 695 696 if (previousScanCounter[index] != null) { 699 setDerivedGaugeWithDifference((Number )scanCounter, null, index); 700 701 if (derivedGauge[index].longValue() < 0L) { 706 if (modulus.longValue() > 0L) { 707 setDerivedGaugeWithDifference((Number )scanCounter, 708 (Number )modulus, index); 709 } 710 threshold[index] = initThreshold; 711 eventAlreadyNotified[index] = false; 712 } 713 is_derived_gauge_valid = true; 714 } 715 else { 719 is_derived_gauge_valid = false; 720 } 721 previousScanCounter[index] = (Number )scanCounter; 722 } 723 else { 726 derivedGauge[index] = (Number )scanCounter; 727 is_derived_gauge_valid = true; 728 } 729 return is_derived_gauge_valid; 730 } 731 732 738 private void updateNotifications(int index) { 739 boolean sendNotif = false; 740 String notifType = null; 741 long timeStamp = 0; 742 String msg = null; 743 Object derGauge = null; 744 Object trigger = null; 745 746 synchronized(this) { 747 if (!eventAlreadyNotified[index]) { 750 if (derivedGauge[index].longValue() >= 751 threshold[index].longValue()) { 752 if (notify) { 753 sendNotif = true; 754 notifType = MonitorNotification.THRESHOLD_VALUE_EXCEEDED; 755 timeStamp = derivedGaugeTimestamp[index]; 756 msg = ""; 757 derGauge = derivedGauge[index]; 758 trigger = threshold[index]; 759 } 760 if (!differenceMode) { 761 eventAlreadyNotified[index] = true; 762 } 763 } 764 } else { 765 if (isTraceOn()) { 766 trace("updateNotifications", "the notification:" + 767 "\n\tNotification observed object = " + 768 getObservedObject(index) + 769 "\n\tNotification observed attribute = " + 770 getObservedAttribute() + 771 "\n\tNotification derived gauge = " + 772 derivedGauge[index] + 773 "\nhas already been sent"); 774 } 775 } 776 } 777 778 if (sendNotif) { 779 sendNotification(notifType, timeStamp, msg, derGauge, trigger, index); 780 } 781 } 782 783 788 private synchronized void updateThreshold(int index) { 789 790 if (derivedGauge[index].longValue() >= threshold[index].longValue()) { 794 795 if (offset.longValue() > 0L) { 796 797 long threshold_value = threshold[index].longValue(); 801 while (derivedGauge[index].longValue() >= threshold_value) { 802 threshold_value += offset.longValue(); 803 } 804 805 switch(type[index]) { 808 case INTEGER: 809 threshold[index] = new Integer ((int)threshold_value); 810 break; 811 case BYTE: 812 threshold[index] = new Byte ((byte)threshold_value); 813 break; 814 case SHORT: 815 threshold[index] = new Short ((short)threshold_value); 816 break; 817 case LONG: 818 threshold[index] = new Long ((long)threshold_value); 819 break; 820 default: 821 if (isDebugOn()) { 823 debug("updateThreshold", "the threshold type is invalid"); 824 } 825 break; 826 } 827 828 if (!differenceMode) { 833 if (modulus.longValue() > 0L) { 834 if (threshold[index].longValue() > modulus.longValue()) { 835 modulusExceeded[index] = true; 836 derivedGaugeExceeded[index] = derivedGauge[index]; 837 } 838 } 839 } 840 841 eventAlreadyNotified[index] = false; 844 } 845 else { 846 modulusExceeded[index] = true; 847 derivedGaugeExceeded[index] = derivedGauge[index]; 848 } 849 } 850 } 851 852 864 private synchronized boolean isThresholdTypeValid(int index) { 865 866 switch(type[index]) { 867 case INTEGER: 868 return ((threshold[index] instanceof Integer ) && 869 ((offset == INTEGER_ZERO) || 870 (offset instanceof Integer )) && 871 ((modulus == INTEGER_ZERO) || 872 (modulus instanceof Integer ))); 873 case BYTE: 874 return ((threshold[index] instanceof Byte ) && 875 ((offset == INTEGER_ZERO) || 876 (offset instanceof Byte )) && 877 ((modulus == INTEGER_ZERO) || 878 (modulus instanceof Byte ))); 879 case SHORT: 880 return ((threshold[index] instanceof Short ) && 881 ((offset == INTEGER_ZERO) || 882 (offset instanceof Short )) && 883 ((modulus == INTEGER_ZERO) || 884 (modulus instanceof Short ))); 885 case LONG: 886 return ((threshold[index] instanceof Long ) && 887 ((offset == INTEGER_ZERO) || 888 (offset instanceof Long )) && 889 ((modulus == INTEGER_ZERO) || 890 (modulus instanceof Long ))); 891 default: 892 if (isDebugOn()) { 894 debug("isThresholdTypeValid", "The threshold type is invalid"); 895 } 896 return false; 897 } 898 } 899 900 909 private synchronized void setDerivedGaugeWithDifference(Number scanCounter, 910 Number mod, 911 int index) { 912 918 919 long derived = 920 scanCounter.longValue() - previousScanCounter[index].longValue(); 921 if (mod != null) 922 derived += modulus.longValue(); 923 924 switch (type[index]) { 925 case INTEGER: derivedGauge[index] = new Integer ((int) derived); break; 926 case BYTE: derivedGauge[index] = new Byte ((byte) derived); break; 927 case SHORT: derivedGauge[index] = new Short ((short) derived); break; 928 case LONG: derivedGauge[index] = new Long (derived); break; 929 default: 930 if (isDebugOn()) { 932 debug("setDerivedGaugeWithDifference", 933 "the threshold type is invalid"); 934 } 935 break; 936 } 937 } 938 939 944 945 950 void notifyAlarmClock(int index) { 951 long timeStamp = 0; 952 String msg = null; 953 Object derGauge = null; 954 955 Object scan_counter = null; 956 String notif_type = null; 957 958 synchronized(this) { 959 if (!isActive()) 960 return; 961 962 965 if ((getObservedObject(index) == null) || 972 (getObservedAttribute() == null)) { 973 return; 974 } 975 976 try { 981 scan_counter = server.getAttribute(getObservedObject(index), 982 getObservedAttribute()); 983 if (scan_counter == null) 984 return; 985 } catch (NullPointerException np_ex) { 986 if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED)) 987 return; 988 else { 989 notif_type = MonitorNotification.RUNTIME_ERROR; 990 setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED); 991 msg = 992 "The counter monitor must be registered in " + 993 "the MBean server."; 994 } 995 } catch (InstanceNotFoundException inf_ex) { 996 if (alreadyNotified(index, OBSERVED_OBJECT_ERROR_NOTIFIED)) 997 return; 998 else { 999 notif_type = MonitorNotification.OBSERVED_OBJECT_ERROR; 1000 setAlreadyNotified(index, OBSERVED_OBJECT_ERROR_NOTIFIED); 1001 msg = 1002 "The observed object must be registered in " + 1003 "the MBean server."; 1004 } 1005 } catch (AttributeNotFoundException anf_ex) { 1006 if (alreadyNotified(index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED)) 1007 return; 1008 else { 1009 notif_type = MonitorNotification.OBSERVED_ATTRIBUTE_ERROR; 1010 setAlreadyNotified(index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED); 1011 msg = 1012 "The observed attribute must be accessible in " + 1013 "the observed object."; 1014 } 1015 } catch (MBeanException mb_ex) { 1016 if (alreadyNotified(index, RUNTIME_ERROR_NOTIFIED)) 1017 return; 1018 else { 1019 notif_type = MonitorNotification.RUNTIME_ERROR; 1020 setAlreadyNotified(index, RUNTIME_ERROR_NOTIFIED); 1021 msg = mb_ex.getMessage(); 1022 } 1023 } catch (ReflectionException ref_ex) { 1024 if (alreadyNotified(index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED)) { 1025 return; 1026 } else { 1027 notif_type = MonitorNotification.OBSERVED_ATTRIBUTE_ERROR; 1028 setAlreadyNotified(index, OBSERVED_ATTRIBUTE_ERROR_NOTIFIED); 1029 msg = ref_ex.getMessage(); 1030 } 1031 } 1032 1033 if (msg == null) { 1034 if (scan_counter instanceof Integer ) { 1037 type[index] = INTEGER; 1038 } else if (scan_counter instanceof Byte ) { 1039 type[index] = BYTE; 1040 } else if (scan_counter instanceof Short ) { 1041 type[index] = SHORT; 1042 } else if (scan_counter instanceof Long ) { 1043 type[index] = LONG; 1044 } else { 1045 if (alreadyNotified(index, 1046 OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED)) 1047 return; 1048 else { 1049 notif_type = 1050 MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR; 1051 setAlreadyNotified(index, 1052 OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED); 1053 msg = 1054 "The observed attribute type must be " + 1055 "an integer type."; 1056 } 1057 } 1058 } 1059 1060 if (msg == null) { 1061 if (!isThresholdTypeValid(index)) { 1065 if (alreadyNotified(index, THRESHOLD_ERROR_NOTIFIED)) 1066 return; 1067 else { 1068 notif_type = MonitorNotification.THRESHOLD_ERROR; 1069 setAlreadyNotified(index, THRESHOLD_ERROR_NOTIFIED); 1070 msg = 1071 "The threshold, offset and modulus must " + 1072 "be of the same type as the counter."; 1073 } 1074 } 1075 } 1076 1077 if (msg == null) { 1078 1079 resetAllAlreadyNotified(index); 1082 1083 if (modulusExceeded[index]) { 1086 if (derivedGauge[index].longValue() < 1087 derivedGaugeExceeded[index].longValue()) { 1088 threshold[index] = initThreshold; 1089 modulusExceeded[index] = false; 1090 eventAlreadyNotified[index] = false; 1091 } 1092 } 1093 1094 boolean is_derived_gauge_valid = 1102 updateDerivedGauge(scan_counter, index); 1103 1104 if (is_derived_gauge_valid) { 1108 updateNotifications(index); 1109 updateThreshold(index); 1110 } 1111 1112 } else { 1113 1114 1116 timeStamp = derivedGaugeTimestamp[index]; 1117 derGauge = derivedGauge[index]; 1118 1119 modulusExceeded[index] = false; 1122 eventAlreadyNotified[index] = false; 1123 previousScanCounter[index] = null; 1124 } 1125 } 1126 1127 if (msg != null) { 1128 sendNotification(notif_type, 1129 timeStamp, 1130 msg, 1131 derGauge, 1132 null, 1133 index); 1134 } 1135 } 1136 1137 1142 synchronized void insertSpecificElementAt(int index) { 1143 1147 if (index != elementCount) 1148 throw new Error ("Internal error: index != elementCount"); 1149 1150 if (elementCount >= threshold.length) { 1151 threshold = expandArray(threshold); 1152 derivedGauge = expandArray(derivedGauge); 1153 previousScanCounter = expandArray(previousScanCounter); 1154 derivedGaugeExceeded = expandArray(derivedGaugeExceeded); 1155 derivedGaugeTimestamp = expandArray(derivedGaugeTimestamp); 1156 modulusExceeded = expandArray(modulusExceeded); 1157 eventAlreadyNotified = expandArray(eventAlreadyNotified); 1158 type = expandArray(type); 1159 } 1160 1161 threshold[index] = INTEGER_ZERO; 1162 derivedGauge[index] = INTEGER_ZERO; 1163 previousScanCounter[index] = null; 1164 derivedGaugeExceeded[index] = null; 1165 derivedGaugeTimestamp[index] = System.currentTimeMillis(); 1166 modulusExceeded[index] = false; 1167 eventAlreadyNotified[index] = false; 1168 type[index] = INTEGER; 1169 } 1170 1171 1176 synchronized void removeSpecificElementAt(int index) { 1177 removeElementAt(threshold, index); 1182 removeElementAt(derivedGauge, index); 1183 removeElementAt(previousScanCounter, index); 1184 removeElementAt(derivedGaugeExceeded, index); 1185 removeElementAt(derivedGaugeTimestamp, index); 1186 removeElementAt(modulusExceeded, index); 1187 removeElementAt(eventAlreadyNotified, index); 1188 removeElementAt(type, index); 1189 } 1190 1191 1192 1198 1199 private static class CounterAlarmClock extends TimerTask { 1200 1201 CounterMonitor listener = null; 1202 1203 1208 1209 public CounterAlarmClock(CounterMonitor listener) { 1210 this.listener = listener; 1211 } 1212 1213 1218 1219 1223 public void run() { 1224 if (listener.isActive()) { 1225 for (int i = 0; i < listener.elementCount; i++) { 1226 listener.notifyAlarmClock(i); 1227 } 1228 } 1229 } 1230 } 1231} 1232 | Popular Tags |