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 26 package javax.management.monitor; 27 28 import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER; 29 import java.lang.System.Logger.Level; 30 import javax.management.ObjectName; 31 import javax.management.MBeanNotificationInfo; 32 import static javax.management.monitor.MonitorNotification.*; 33 34 /** 35 * Defines a monitor MBean designed to observe the values of a string 36 * attribute. 37 * <P> 38 * A string monitor sends notifications as follows: 39 * <UL> 40 * <LI> if the attribute value matches the string to compare value, 41 * a {@link MonitorNotification#STRING_TO_COMPARE_VALUE_MATCHED 42 * match notification} is sent. 43 * The notify match flag must be set to <CODE>true</CODE>. 44 * <BR>Subsequent matchings of the string to compare values do not 45 * cause further notifications unless 46 * the attribute value differs from the string to compare value. 47 * <LI> if the attribute value differs from the string to compare value, 48 * a {@link MonitorNotification#STRING_TO_COMPARE_VALUE_DIFFERED 49 * differ notification} is sent. 50 * The notify differ flag must be set to <CODE>true</CODE>. 51 * <BR>Subsequent differences from the string to compare value do 52 * not cause further notifications unless 53 * the attribute value matches the string to compare value. 54 * </UL> 55 * 56 * 57 * @since 1.5 58 */ 59 public class StringMonitor extends Monitor implements StringMonitorMBean { 60 61 /* 62 * ------------------------------------------ 63 * PACKAGE CLASSES 64 * ------------------------------------------ 65 */ 66 67 static class StringMonitorObservedObject extends ObservedObject { 68 StringMonitorObservedObject(ObjectName observedObject)69 public StringMonitorObservedObject(ObjectName observedObject) { 70 super(observedObject); 71 } 72 getStatus()73 public final synchronized int getStatus() { 74 return status; 75 } setStatus(int status)76 public final synchronized void setStatus(int status) { 77 this.status = status; 78 } 79 80 private int status; 81 } 82 83 /* 84 * ------------------------------------------ 85 * PRIVATE VARIABLES 86 * ------------------------------------------ 87 */ 88 89 /** 90 * String to compare with the observed attribute. 91 * <BR>The default value is an empty character sequence. 92 */ 93 private String stringToCompare = ""; 94 95 /** 96 * Flag indicating if the string monitor notifies when matching 97 * the string to compare. 98 * <BR>The default value is set to <CODE>false</CODE>. 99 */ 100 private boolean notifyMatch = false; 101 102 /** 103 * Flag indicating if the string monitor notifies when differing 104 * from the string to compare. 105 * <BR>The default value is set to <CODE>false</CODE>. 106 */ 107 private boolean notifyDiffer = false; 108 109 private static final String[] types = { 110 RUNTIME_ERROR, 111 OBSERVED_OBJECT_ERROR, 112 OBSERVED_ATTRIBUTE_ERROR, 113 OBSERVED_ATTRIBUTE_TYPE_ERROR, 114 STRING_TO_COMPARE_VALUE_MATCHED, 115 STRING_TO_COMPARE_VALUE_DIFFERED 116 }; 117 118 private static final MBeanNotificationInfo[] notifsInfo = { 119 new MBeanNotificationInfo( 120 types, 121 "javax.management.monitor.MonitorNotification", 122 "Notifications sent by the StringMonitor MBean") 123 }; 124 125 // Flags needed to implement the matching/differing mechanism. 126 // 127 private static final int MATCHING = 0; 128 private static final int DIFFERING = 1; 129 private static final int MATCHING_OR_DIFFERING = 2; 130 131 /* 132 * ------------------------------------------ 133 * CONSTRUCTORS 134 * ------------------------------------------ 135 */ 136 137 /** 138 * Default constructor. 139 */ StringMonitor()140 public StringMonitor() { 141 } 142 143 /* 144 * ------------------------------------------ 145 * PUBLIC METHODS 146 * ------------------------------------------ 147 */ 148 149 /** 150 * Starts the string monitor. 151 */ start()152 public synchronized void start() { 153 if (isActive()) { 154 MONITOR_LOGGER.log(Level.TRACE, "the monitor is already active"); 155 return; 156 } 157 // Reset values. 158 // 159 for (ObservedObject o : observedObjects) { 160 final StringMonitorObservedObject smo = 161 (StringMonitorObservedObject) o; 162 smo.setStatus(MATCHING_OR_DIFFERING); 163 } 164 doStart(); 165 } 166 167 /** 168 * Stops the string monitor. 169 */ stop()170 public synchronized void stop() { 171 doStop(); 172 } 173 174 // GETTERS AND SETTERS 175 //-------------------- 176 177 /** 178 * Gets the derived gauge of the specified object, if this object is 179 * contained in the set of observed MBeans, or <code>null</code> otherwise. 180 * 181 * @param object the name of the MBean whose derived gauge is required. 182 * 183 * @return The derived gauge of the specified object. 184 * 185 */ 186 @Override getDerivedGauge(ObjectName object)187 public synchronized String getDerivedGauge(ObjectName object) { 188 return (String) super.getDerivedGauge(object); 189 } 190 191 /** 192 * Gets the derived gauge timestamp of the specified object, if 193 * this object is contained in the set of observed MBeans, or 194 * <code>0</code> otherwise. 195 * 196 * @param object the name of the object whose derived gauge 197 * timestamp is to be returned. 198 * 199 * @return The derived gauge timestamp of the specified object. 200 * 201 */ 202 @Override getDerivedGaugeTimeStamp(ObjectName object)203 public synchronized long getDerivedGaugeTimeStamp(ObjectName object) { 204 return super.getDerivedGaugeTimeStamp(object); 205 } 206 207 /** 208 * Returns the derived gauge of the first object in the set of 209 * observed MBeans. 210 * 211 * @return The derived gauge. 212 * 213 * @deprecated As of JMX 1.2, replaced by 214 * {@link #getDerivedGauge(ObjectName)} 215 */ 216 @Deprecated getDerivedGauge()217 public synchronized String getDerivedGauge() { 218 if (observedObjects.isEmpty()) { 219 return null; 220 } else { 221 return (String) observedObjects.get(0).getDerivedGauge(); 222 } 223 } 224 225 /** 226 * Gets the derived gauge timestamp of the first object in the set 227 * of observed MBeans. 228 * 229 * @return The derived gauge timestamp. 230 * 231 * @deprecated As of JMX 1.2, replaced by 232 * {@link #getDerivedGaugeTimeStamp(ObjectName)} 233 */ 234 @Deprecated getDerivedGaugeTimeStamp()235 public synchronized long getDerivedGaugeTimeStamp() { 236 if (observedObjects.isEmpty()) { 237 return 0; 238 } else { 239 return observedObjects.get(0).getDerivedGaugeTimeStamp(); 240 } 241 } 242 243 /** 244 * Gets the string to compare with the observed attribute common 245 * to all observed MBeans. 246 * 247 * @return The string value. 248 * 249 * @see #setStringToCompare 250 */ getStringToCompare()251 public synchronized String getStringToCompare() { 252 return stringToCompare; 253 } 254 255 /** 256 * Sets the string to compare with the observed attribute common 257 * to all observed MBeans. 258 * 259 * @param value The string value. 260 * 261 * @exception IllegalArgumentException The specified 262 * string to compare is null. 263 * 264 * @see #getStringToCompare 265 */ setStringToCompare(String value)266 public synchronized void setStringToCompare(String value) 267 throws IllegalArgumentException { 268 269 if (value == null) { 270 throw new IllegalArgumentException("Null string to compare"); 271 } 272 273 if (stringToCompare.equals(value)) 274 return; 275 stringToCompare = value; 276 277 // Reset values. 278 // 279 for (ObservedObject o : observedObjects) { 280 final StringMonitorObservedObject smo = 281 (StringMonitorObservedObject) o; 282 smo.setStatus(MATCHING_OR_DIFFERING); 283 } 284 } 285 286 /** 287 * Gets the matching notification's on/off switch value common to 288 * all observed MBeans. 289 * 290 * @return <CODE>true</CODE> if the string monitor notifies when 291 * matching the string to compare, <CODE>false</CODE> otherwise. 292 * 293 * @see #setNotifyMatch 294 */ getNotifyMatch()295 public synchronized boolean getNotifyMatch() { 296 return notifyMatch; 297 } 298 299 /** 300 * Sets the matching notification's on/off switch value common to 301 * all observed MBeans. 302 * 303 * @param value The matching notification's on/off switch value. 304 * 305 * @see #getNotifyMatch 306 */ setNotifyMatch(boolean value)307 public synchronized void setNotifyMatch(boolean value) { 308 if (notifyMatch == value) 309 return; 310 notifyMatch = value; 311 } 312 313 /** 314 * Gets the differing notification's on/off switch value common to 315 * all observed MBeans. 316 * 317 * @return <CODE>true</CODE> if the string monitor notifies when 318 * differing from the string to compare, <CODE>false</CODE> otherwise. 319 * 320 * @see #setNotifyDiffer 321 */ getNotifyDiffer()322 public synchronized boolean getNotifyDiffer() { 323 return notifyDiffer; 324 } 325 326 /** 327 * Sets the differing notification's on/off switch value common to 328 * all observed MBeans. 329 * 330 * @param value The differing notification's on/off switch value. 331 * 332 * @see #getNotifyDiffer 333 */ setNotifyDiffer(boolean value)334 public synchronized void setNotifyDiffer(boolean value) { 335 if (notifyDiffer == value) 336 return; 337 notifyDiffer = value; 338 } 339 340 /** 341 * Returns a <CODE>NotificationInfo</CODE> object containing the name of 342 * the Java class of the notification and the notification types sent by 343 * the string monitor. 344 */ 345 @Override getNotificationInfo()346 public MBeanNotificationInfo[] getNotificationInfo() { 347 return notifsInfo.clone(); 348 } 349 350 /* 351 * ------------------------------------------ 352 * PACKAGE METHODS 353 * ------------------------------------------ 354 */ 355 356 /** 357 * Factory method for ObservedObject creation. 358 * 359 * @since 1.6 360 */ 361 @Override createObservedObject(ObjectName object)362 ObservedObject createObservedObject(ObjectName object) { 363 final StringMonitorObservedObject smo = 364 new StringMonitorObservedObject(object); 365 smo.setStatus(MATCHING_OR_DIFFERING); 366 return smo; 367 } 368 369 /** 370 * Check that the type of the supplied observed attribute 371 * value is one of the value types supported by this monitor. 372 */ 373 @Override isComparableTypeValid(ObjectName object, String attribute, Comparable<?> value)374 synchronized boolean isComparableTypeValid(ObjectName object, 375 String attribute, 376 Comparable<?> value) { 377 // Check that the observed attribute is of type "String". 378 // 379 if (value instanceof String) { 380 return true; 381 } 382 return false; 383 } 384 385 @Override onErrorNotification(MonitorNotification notification)386 synchronized void onErrorNotification(MonitorNotification notification) { 387 final StringMonitorObservedObject o = (StringMonitorObservedObject) 388 getObservedObject(notification.getObservedObject()); 389 if (o == null) 390 return; 391 392 // Reset values. 393 // 394 o.setStatus(MATCHING_OR_DIFFERING); 395 } 396 397 @Override buildAlarmNotification( ObjectName object, String attribute, Comparable<?> value)398 synchronized MonitorNotification buildAlarmNotification( 399 ObjectName object, 400 String attribute, 401 Comparable<?> value) { 402 String type = null; 403 String msg = null; 404 Object trigger = null; 405 406 final StringMonitorObservedObject o = 407 (StringMonitorObservedObject) getObservedObject(object); 408 if (o == null) 409 return null; 410 411 // Send matching notification if notifyMatch is true. 412 // Send differing notification if notifyDiffer is true. 413 // 414 if (o.getStatus() == MATCHING_OR_DIFFERING) { 415 if (o.getDerivedGauge().equals(stringToCompare)) { 416 if (notifyMatch) { 417 type = STRING_TO_COMPARE_VALUE_MATCHED; 418 msg = ""; 419 trigger = stringToCompare; 420 } 421 o.setStatus(DIFFERING); 422 } else { 423 if (notifyDiffer) { 424 type = STRING_TO_COMPARE_VALUE_DIFFERED; 425 msg = ""; 426 trigger = stringToCompare; 427 } 428 o.setStatus(MATCHING); 429 } 430 } else { 431 if (o.getStatus() == MATCHING) { 432 if (o.getDerivedGauge().equals(stringToCompare)) { 433 if (notifyMatch) { 434 type = STRING_TO_COMPARE_VALUE_MATCHED; 435 msg = ""; 436 trigger = stringToCompare; 437 } 438 o.setStatus(DIFFERING); 439 } 440 } else if (o.getStatus() == DIFFERING) { 441 if (!o.getDerivedGauge().equals(stringToCompare)) { 442 if (notifyDiffer) { 443 type = STRING_TO_COMPARE_VALUE_DIFFERED; 444 msg = ""; 445 trigger = stringToCompare; 446 } 447 o.setStatus(MATCHING); 448 } 449 } 450 } 451 452 return new MonitorNotification(type, 453 this, 454 0, 455 0, 456 msg, 457 null, 458 null, 459 null, 460 trigger); 461 } 462 } 463