/*
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.management.monitor;
import static com.sun.jmx.defaults.
JmxProperties.
MONITOR_LOGGER;
import java.util.logging.
Level;
import javax.management.
ObjectName;
import javax.management.
MBeanNotificationInfo;
import static javax.management.monitor.
Monitor.
NumericalType.*;
import static javax.management.monitor.
MonitorNotification.*;
/**
* Defines a monitor MBean designed to observe the values of a counter
* attribute.
*
* <P> A counter monitor sends a {@link
* MonitorNotification#THRESHOLD_VALUE_EXCEEDED threshold
* notification} when the value of the counter reaches or exceeds a
* threshold known as the comparison level. The notify flag must be
* set to <CODE>true</CODE>.
*
* <P> In addition, an offset mechanism enables particular counting
* intervals to be detected. If the offset value is not zero,
* whenever the threshold is triggered by the counter value reaching a
* comparison level, that comparison level is incremented by the
* offset value. This is regarded as taking place instantaneously,
* that is, before the count is incremented. Thus, for each level,
* the threshold triggers an event notification every time the count
* increases by an interval equal to the offset value.
*
* <P> If the counter can wrap around its maximum value, the modulus
* needs to be specified. The modulus is the value at which the
* counter is reset to zero.
*
* <P> If the counter difference mode is used, the value of the
* derived gauge is calculated as the difference between the observed
* counter values for two successive observations. If this difference
* is negative, the value of the derived gauge is incremented by the
* value of the modulus. The derived gauge value (V[t]) is calculated
* using the following method:
*
* <UL>
* <LI>if (counter[t] - counter[t-GP]) is positive then
* V[t] = counter[t] - counter[t-GP]
* <LI>if (counter[t] - counter[t-GP]) is negative then
* V[t] = counter[t] - counter[t-GP] + MODULUS
* </UL>
*
* This implementation of the counter monitor requires the observed
* attribute to be of the type integer (<CODE>Byte</CODE>,
* <CODE>Integer</CODE>, <CODE>Short</CODE>, <CODE>Long</CODE>).
*
*
* @since 1.5
*/
public class
CounterMonitor extends
Monitor implements
CounterMonitorMBean {
/*
* ------------------------------------------
* PACKAGE CLASSES
* ------------------------------------------
*/
static class
CounterMonitorObservedObject extends
ObservedObject {
public
CounterMonitorObservedObject(
ObjectName observedObject) {
super(
observedObject);
}
public final synchronized
Number getThreshold() {
return
threshold;
}
public final synchronized void
setThreshold(
Number threshold) {
this.
threshold =
threshold;
}
public final synchronized
Number getPreviousScanCounter() {
return
previousScanCounter;
}
public final synchronized void
setPreviousScanCounter(
Number previousScanCounter) {
this.
previousScanCounter =
previousScanCounter;
}
public final synchronized boolean
getModulusExceeded() {
return
modulusExceeded;
}
public final synchronized void
setModulusExceeded(
boolean
modulusExceeded) {
this.
modulusExceeded =
modulusExceeded;
}
public final synchronized
Number getDerivedGaugeExceeded() {
return
derivedGaugeExceeded;
}
public final synchronized void
setDerivedGaugeExceeded(
Number derivedGaugeExceeded) {
this.
derivedGaugeExceeded =
derivedGaugeExceeded;
}
public final synchronized boolean
getDerivedGaugeValid() {
return
derivedGaugeValid;
}
public final synchronized void
setDerivedGaugeValid(
boolean
derivedGaugeValid) {
this.
derivedGaugeValid =
derivedGaugeValid;
}
public final synchronized boolean
getEventAlreadyNotified() {
return
eventAlreadyNotified;
}
public final synchronized void
setEventAlreadyNotified(
boolean
eventAlreadyNotified) {
this.
eventAlreadyNotified =
eventAlreadyNotified;
}
public final synchronized
NumericalType getType() {
return
type;
}
public final synchronized void
setType(
NumericalType type) {
this.
type =
type;
}
private
Number threshold;
private
Number previousScanCounter;
private boolean
modulusExceeded;
private
Number derivedGaugeExceeded;
private boolean
derivedGaugeValid;
private boolean
eventAlreadyNotified;
private
NumericalType type;
}
/*
* ------------------------------------------
* PRIVATE VARIABLES
* ------------------------------------------
*/
/**
* Counter modulus.
* <BR>The default value is a null Integer object.
*/
private
Number modulus =
INTEGER_ZERO;
/**
* Counter offset.
* <BR>The default value is a null Integer object.
*/
private
Number offset =
INTEGER_ZERO;
/**
* Flag indicating if the counter monitor notifies when exceeding
* the threshold. The default value is set to
* <CODE>false</CODE>.
*/
private boolean
notify = false;
/**
* Flag indicating if the counter difference mode is used. If the
* counter difference mode is used, the derived gauge is the
* difference between two consecutive observed values. Otherwise,
* the derived gauge is directly the value of the observed
* attribute. The default value is set to <CODE>false</CODE>.
*/
private boolean
differenceMode = false;
/**
* Initial counter threshold. This value is used to initialize
* the threshold when a new object is added to the list and reset
* the threshold to its initial value each time the counter
* resets.
*/
private
Number initThreshold =
INTEGER_ZERO;
private static final
String[]
types = {
RUNTIME_ERROR,
OBSERVED_OBJECT_ERROR,
OBSERVED_ATTRIBUTE_ERROR,
OBSERVED_ATTRIBUTE_TYPE_ERROR,
THRESHOLD_ERROR,
THRESHOLD_VALUE_EXCEEDED
};
private static final
MBeanNotificationInfo[]
notifsInfo = {
new
MBeanNotificationInfo(
types,
"javax.management.monitor.MonitorNotification",
"Notifications sent by the CounterMonitor MBean")
};
/*
* ------------------------------------------
* CONSTRUCTORS
* ------------------------------------------
*/
/**
* Default constructor.
*/
public
CounterMonitor() {
}
/*
* ------------------------------------------
* PUBLIC METHODS
* ------------------------------------------
*/
/**
* Starts the counter monitor.
*/
public synchronized void
start() {
if (
isActive()) {
MONITOR_LOGGER.
logp(
Level.
FINER,
CounterMonitor.class.
getName(),
"start", "the monitor is already active");
return;
}
// Reset values.
//
for (
ObservedObject o :
observedObjects) {
final
CounterMonitorObservedObject cmo =
(
CounterMonitorObservedObject)
o;
cmo.
setThreshold(
initThreshold);
cmo.
setModulusExceeded(false);
cmo.
setEventAlreadyNotified(false);
cmo.
setPreviousScanCounter(null);
}
doStart();
}
/**
* Stops the counter monitor.
*/
public synchronized void
stop() {
doStop();
}
// GETTERS AND SETTERS
//--------------------
/**
* Gets the derived gauge of the specified object, if this object is
* contained in the set of observed MBeans, or <code>null</code> otherwise.
*
* @param object the name of the object whose derived gauge is to
* be returned.
*
* @return The derived gauge of the specified object.
*
*/
@
Override
public synchronized
Number getDerivedGauge(
ObjectName object) {
return (
Number) super.getDerivedGauge(
object);
}
/**
* Gets the derived gauge timestamp of the specified object, if
* this object is contained in the set of observed MBeans, or
* <code>0</code> otherwise.
*
* @param object the name of the object whose derived gauge
* timestamp is to be returned.
*
* @return The derived gauge timestamp of the specified object.
*
*/
@
Override
public synchronized long
getDerivedGaugeTimeStamp(
ObjectName object) {
return super.getDerivedGaugeTimeStamp(
object);
}
/**
* Gets the current threshold value of the specified object, if
* this object is contained in the set of observed MBeans, or
* <code>null</code> otherwise.
*
* @param object the name of the object whose threshold is to be
* returned.
*
* @return The threshold value of the specified object.
*
*/
public synchronized
Number getThreshold(
ObjectName object) {
final
CounterMonitorObservedObject o =
(
CounterMonitorObservedObject)
getObservedObject(
object);
if (
o == null)
return null;
// If the counter that is monitored rolls over when it reaches a
// maximum value, then the modulus value needs to be set to that
// maximum value. The threshold will then also roll over whenever
// it strictly exceeds the modulus value. When the threshold rolls
// over, it is reset to the value that was specified through the
// latest call to the monitor's setInitThreshold method, before
// any offsets were applied.
//
if (
offset.
longValue() > 0L &&
modulus.
longValue() > 0L &&
o.
getThreshold().
longValue() >
modulus.
longValue()) {
return
initThreshold;
} else {
return
o.
getThreshold();
}
}
/**
* Gets the initial threshold value common to all observed objects.
*
* @return The initial threshold.
*
* @see #setInitThreshold
*
*/
public synchronized
Number getInitThreshold() {
return
initThreshold;
}
/**
* Sets the initial threshold value common to all observed objects.
*
* <BR>The current threshold of every object in the set of
* observed MBeans is updated consequently.
*
* @param value The initial threshold value.
*
* @exception IllegalArgumentException The specified
* threshold is null or the threshold value is less than zero.
*
* @see #getInitThreshold
*
*/
public synchronized void
setInitThreshold(
Number value)
throws
IllegalArgumentException {
if (
value == null) {
throw new
IllegalArgumentException("Null threshold");
}
if (
value.
longValue() < 0L) {
throw new
IllegalArgumentException("Negative threshold");
}
if (
initThreshold.
equals(
value))
return;
initThreshold =
value;
// Reset values.
//
int
index = 0;
for (
ObservedObject o :
observedObjects) {
resetAlreadyNotified(
o,
index++,
THRESHOLD_ERROR_NOTIFIED);
final
CounterMonitorObservedObject cmo =
(
CounterMonitorObservedObject)
o;
cmo.
setThreshold(
value);
cmo.
setModulusExceeded(false);
cmo.
setEventAlreadyNotified(false);
}
}
/**
* Returns the derived gauge of the first object in the set of
* observed MBeans.
*
* @return The derived gauge.
*
* @deprecated As of JMX 1.2, replaced by
* {@link #getDerivedGauge(ObjectName)}
*/
@
Deprecated
public synchronized
Number getDerivedGauge() {
if (
observedObjects.
isEmpty()) {
return null;
} else {
return (
Number)
observedObjects.
get(0).
getDerivedGauge();
}
}
/**
* Gets the derived gauge timestamp of the first object in the set
* of observed MBeans.
*
* @return The derived gauge timestamp.
*
* @deprecated As of JMX 1.2, replaced by
* {@link #getDerivedGaugeTimeStamp(ObjectName)}
*/
@
Deprecated
public synchronized long
getDerivedGaugeTimeStamp() {
if (
observedObjects.
isEmpty()) {
return 0;
} else {
return
observedObjects.
get(0).
getDerivedGaugeTimeStamp();
}
}
/**
* Gets the threshold value of the first object in the set of
* observed MBeans.
*
* @return The threshold value.
*
* @see #setThreshold
*
* @deprecated As of JMX 1.2, replaced by {@link #getThreshold(ObjectName)}
*/
@
Deprecated
public synchronized
Number getThreshold() {
return
getThreshold(
getObservedObject());
}
/**
* Sets the initial threshold value.
*
* @param value The initial threshold value.
*
* @exception IllegalArgumentException The specified threshold is
* null or the threshold value is less than zero.
*
* @see #getThreshold()
*
* @deprecated As of JMX 1.2, replaced by {@link #setInitThreshold}
*/
@
Deprecated
public synchronized void
setThreshold(
Number value)
throws
IllegalArgumentException {
setInitThreshold(
value);
}
/**
* Gets the offset value common to all observed MBeans.
*
* @return The offset value.
*
* @see #setOffset
*/
public synchronized
Number getOffset() {
return
offset;
}
/**
* Sets the offset value common to all observed MBeans.
*
* @param value The offset value.
*
* @exception IllegalArgumentException The specified
* offset is null or the offset value is less than zero.
*
* @see #getOffset
*/
public synchronized void
setOffset(
Number value)
throws
IllegalArgumentException {
if (
value == null) {
throw new
IllegalArgumentException("Null offset");
}
if (
value.
longValue() < 0L) {
throw new
IllegalArgumentException("Negative offset");
}
if (
offset.
equals(
value))
return;
offset =
value;
int
index = 0;
for (
ObservedObject o :
observedObjects) {
resetAlreadyNotified(
o,
index++,
THRESHOLD_ERROR_NOTIFIED);
}
}
/**
* Gets the modulus value common to all observed MBeans.
*
* @see #setModulus
*
* @return The modulus value.
*/
public synchronized
Number getModulus() {
return
modulus;
}
/**
* Sets the modulus value common to all observed MBeans.
*
* @param value The modulus value.
*
* @exception IllegalArgumentException The specified
* modulus is null or the modulus value is less than zero.
*
* @see #getModulus
*/
public synchronized void
setModulus(
Number value)
throws
IllegalArgumentException {
if (
value == null) {
throw new
IllegalArgumentException("Null modulus");
}
if (
value.
longValue() < 0L) {
throw new
IllegalArgumentException("Negative modulus");
}
if (
modulus.
equals(
value))
return;
modulus =
value;
// Reset values.
//
int
index = 0;
for (
ObservedObject o :
observedObjects) {
resetAlreadyNotified(
o,
index++,
THRESHOLD_ERROR_NOTIFIED);
final
CounterMonitorObservedObject cmo =
(
CounterMonitorObservedObject)
o;
cmo.
setModulusExceeded(false);
}
}
/**
* Gets the notification's on/off switch value common to all
* observed MBeans.
*
* @return <CODE>true</CODE> if the counter monitor notifies when
* exceeding the threshold, <CODE>false</CODE> otherwise.
*
* @see #setNotify
*/
public synchronized boolean
getNotify() {
return
notify;
}
/**
* Sets the notification's on/off switch value common to all
* observed MBeans.
*
* @param value The notification's on/off switch value.
*
* @see #getNotify
*/
public synchronized void
setNotify(boolean
value) {
if (
notify ==
value)
return;
notify =
value;
}
/**
* Gets the difference mode flag value common to all observed MBeans.
*
* @return <CODE>true</CODE> if the difference mode is used,
* <CODE>false</CODE> otherwise.
*
* @see #setDifferenceMode
*/
public synchronized boolean
getDifferenceMode() {
return
differenceMode;
}
/**
* Sets the difference mode flag value common to all observed MBeans.
*
* @param value The difference mode flag value.
*
* @see #getDifferenceMode
*/
public synchronized void
setDifferenceMode(boolean
value) {
if (
differenceMode ==
value)
return;
differenceMode =
value;
// Reset values.
//
for (
ObservedObject o :
observedObjects) {
final
CounterMonitorObservedObject cmo =
(
CounterMonitorObservedObject)
o;
cmo.
setThreshold(
initThreshold);
cmo.
setModulusExceeded(false);
cmo.
setEventAlreadyNotified(false);
cmo.
setPreviousScanCounter(null);
}
}
/**
* Returns a <CODE>NotificationInfo</CODE> object containing the
* name of the Java class of the notification and the notification
* types sent by the counter monitor.
*/
@
Override
public
MBeanNotificationInfo[]
getNotificationInfo() {
return
notifsInfo.
clone();
}
/*
* ------------------------------------------
* PRIVATE METHODS
* ------------------------------------------
*/
/**
* Updates the derived gauge attribute of the observed object.
*
* @param scanCounter The value of the observed attribute.
* @param o The observed object.
* @return <CODE>true</CODE> if the derived gauge value is valid,
* <CODE>false</CODE> otherwise. The derived gauge value is
* invalid when the differenceMode flag is set to
* <CODE>true</CODE> and it is the first notification (so we
* haven't 2 consecutive values to update the derived gauge).
*/
private synchronized boolean
updateDerivedGauge(
Object scanCounter,
CounterMonitorObservedObject o) {
boolean
is_derived_gauge_valid;
// The counter difference mode is used.
//
if (
differenceMode) {
// The previous scan counter has been initialized.
//
if (
o.
getPreviousScanCounter() != null) {
setDerivedGaugeWithDifference((
Number)
scanCounter, null,
o);
// If derived gauge is negative it means that the
// counter has wrapped around and the value of the
// threshold needs to be reset to its initial value.
//
if (((
Number)
o.
getDerivedGauge()).
longValue() < 0L) {
if (
modulus.
longValue() > 0L) {
setDerivedGaugeWithDifference((
Number)
scanCounter,
modulus,
o);
}
o.
setThreshold(
initThreshold);
o.
setEventAlreadyNotified(false);
}
is_derived_gauge_valid = true;
}
// The previous scan counter has not been initialized.
// We cannot update the derived gauge...
//
else {
is_derived_gauge_valid = false;
}
o.
setPreviousScanCounter((
Number)
scanCounter);
}
// The counter difference mode is not used.
//
else {
o.
setDerivedGauge((
Number)
scanCounter);
is_derived_gauge_valid = true;
}
return
is_derived_gauge_valid;
}
/**
* Updates the notification attribute of the observed object
* and notifies the listeners only once if the notify flag
* is set to <CODE>true</CODE>.
* @param o The observed object.
*/
private synchronized
MonitorNotification updateNotifications(
CounterMonitorObservedObject o) {
MonitorNotification n = null;
// Send notification if notify is true.
//
if (!
o.
getEventAlreadyNotified()) {
if (((
Number)
o.
getDerivedGauge()).
longValue() >=
o.
getThreshold().
longValue()) {
if (
notify) {
n = new
MonitorNotification(
THRESHOLD_VALUE_EXCEEDED,
this,
0,
0,
"",
null,
null,
null,
o.
getThreshold());
}
if (!
differenceMode) {
o.
setEventAlreadyNotified(true);
}
}
} else {
if (
MONITOR_LOGGER.
isLoggable(
Level.
FINER)) {
final
StringBuilder strb = new
StringBuilder()
.
append("The notification:")
.
append("\n\tNotification observed object = ")
.
append(
o.
getObservedObject())
.
append("\n\tNotification observed attribute = ")
.
append(
getObservedAttribute())
.
append("\n\tNotification threshold level = ")
.
append(
o.
getThreshold())
.
append("\n\tNotification derived gauge = ")
.
append(
o.
getDerivedGauge())
.
append("\nhas already been sent");
MONITOR_LOGGER.
logp(
Level.
FINER,
CounterMonitor.class.
getName(),
"updateNotifications",
strb.
toString());
}
}
return
n;
}
/**
* Updates the threshold attribute of the observed object.
* @param o The observed object.
*/
private synchronized void
updateThreshold(
CounterMonitorObservedObject o) {
// Calculate the new threshold value if the threshold has been
// exceeded and if the offset value is greater than zero.
//
if (((
Number)
o.
getDerivedGauge()).
longValue() >=
o.
getThreshold().
longValue()) {
if (
offset.
longValue() > 0L) {
// Increment the threshold until its value is greater
// than the one for the current derived gauge.
//
long
threshold_value =
o.
getThreshold().
longValue();
while (((
Number)
o.
getDerivedGauge()).
longValue() >=
threshold_value) {
threshold_value +=
offset.
longValue();
}
// Set threshold attribute.
//
switch (
o.
getType()) {
case
INTEGER:
o.
setThreshold(
Integer.
valueOf((int)
threshold_value));
break;
case
BYTE:
o.
setThreshold(
Byte.
valueOf((byte)
threshold_value));
break;
case
SHORT:
o.
setThreshold(
Short.
valueOf((short)
threshold_value));
break;
case
LONG:
o.
setThreshold(
Long.
valueOf(
threshold_value));
break;
default:
// Should never occur...
MONITOR_LOGGER.
logp(
Level.
FINEST,
CounterMonitor.class.
getName(),
"updateThreshold",
"the threshold type is invalid");
break;
}
// If the counter can wrap around when it reaches
// its maximum and we are not dealing with counter
// differences then we need to reset the threshold
// to its initial value too.
//
if (!
differenceMode) {
if (
modulus.
longValue() > 0L) {
if (
o.
getThreshold().
longValue() >
modulus.
longValue()) {
o.
setModulusExceeded(true);
o.
setDerivedGaugeExceeded(
(
Number)
o.
getDerivedGauge());
}
}
}
// Threshold value has been modified so we can notify again.
//
o.
setEventAlreadyNotified(false);
} else {
o.
setModulusExceeded(true);
o.
setDerivedGaugeExceeded((
Number)
o.
getDerivedGauge());
}
}
}
/**
* Sets the derived gauge of the specified observed object when the
* differenceMode flag is set to <CODE>true</CODE>. Integer types
* only are allowed.
*
* @param scanCounter The value of the observed attribute.
* @param mod The counter modulus value.
* @param o The observed object.
*/
private synchronized void
setDerivedGaugeWithDifference(
Number scanCounter,
Number mod,
CounterMonitorObservedObject o) {
/* We do the arithmetic using longs here even though the
result may end up in a smaller type. Since
l == (byte)l (mod 256) for any long l,
(byte) ((byte)l1 + (byte)l2) == (byte) (l1 + l2),
and likewise for subtraction. So it's the same as if
we had done the arithmetic in the smaller type.*/
long
derived =
scanCounter.
longValue() -
o.
getPreviousScanCounter().
longValue();
if (
mod != null)
derived +=
modulus.
longValue();
switch (
o.
getType()) {
case
INTEGER:
o.
setDerivedGauge(
Integer.
valueOf((int)
derived)); break;
case
BYTE:
o.
setDerivedGauge(
Byte.
valueOf((byte)
derived)); break;
case
SHORT:
o.
setDerivedGauge(
Short.
valueOf((short)
derived)); break;
case
LONG:
o.
setDerivedGauge(
Long.
valueOf(
derived)); break;
default:
// Should never occur...
MONITOR_LOGGER.
logp(
Level.
FINEST,
CounterMonitor.class.
getName(),
"setDerivedGaugeWithDifference",
"the threshold type is invalid");
break;
}
}
/*
* ------------------------------------------
* PACKAGE METHODS
* ------------------------------------------
*/
/**
* Factory method for ObservedObject creation.
*
* @since 1.6
*/
@
Override
ObservedObject createObservedObject(
ObjectName object) {
final
CounterMonitorObservedObject cmo =
new
CounterMonitorObservedObject(
object);
cmo.
setThreshold(
initThreshold);
cmo.
setModulusExceeded(false);
cmo.
setEventAlreadyNotified(false);
cmo.
setPreviousScanCounter(null);
return
cmo;
}
/**
* This method globally sets the derived gauge type for the given
* "object" and "attribute" after checking that the type of the
* supplied observed attribute value is one of the value types
* supported by this monitor.
*/
@
Override
synchronized boolean
isComparableTypeValid(
ObjectName object,
String attribute,
Comparable<?>
value) {
final
CounterMonitorObservedObject o =
(
CounterMonitorObservedObject)
getObservedObject(
object);
if (
o == null)
return false;
// Check that the observed attribute is of type "Integer".
//
if (
value instanceof
Integer) {
o.
setType(
INTEGER);
} else if (
value instanceof
Byte) {
o.
setType(
BYTE);
} else if (
value instanceof
Short) {
o.
setType(
SHORT);
} else if (
value instanceof
Long) {
o.
setType(
LONG);
} else {
return false;
}
return true;
}
@
Override
synchronized
Comparable<?>
getDerivedGaugeFromComparable(
ObjectName object,
String attribute,
Comparable<?>
value) {
final
CounterMonitorObservedObject o =
(
CounterMonitorObservedObject)
getObservedObject(
object);
if (
o == null)
return null;
// Check if counter has wrapped around.
//
if (
o.
getModulusExceeded()) {
if (((
Number)
o.
getDerivedGauge()).
longValue() <
o.
getDerivedGaugeExceeded().
longValue()) {
o.
setThreshold(
initThreshold);
o.
setModulusExceeded(false);
o.
setEventAlreadyNotified(false);
}
}
// Update the derived gauge attributes and check the
// validity of the new value. The derived gauge value
// is invalid when the differenceMode flag is set to
// true and it is the first notification, i.e. we
// haven't got 2 consecutive values to update the
// derived gauge.
//
o.
setDerivedGaugeValid(
updateDerivedGauge(
value,
o));
return (
Comparable<?>)
o.
getDerivedGauge();
}
@
Override
synchronized void
onErrorNotification(
MonitorNotification notification) {
final
CounterMonitorObservedObject o = (
CounterMonitorObservedObject)
getObservedObject(
notification.
getObservedObject());
if (
o == null)
return;
// Reset values.
//
o.
setModulusExceeded(false);
o.
setEventAlreadyNotified(false);
o.
setPreviousScanCounter(null);
}
@
Override
synchronized
MonitorNotification buildAlarmNotification(
ObjectName object,
String attribute,
Comparable<?>
value) {
final
CounterMonitorObservedObject o =
(
CounterMonitorObservedObject)
getObservedObject(
object);
if (
o == null)
return null;
// Notify the listeners and update the threshold if
// the updated derived gauge value is valid.
//
final
MonitorNotification alarm;
if (
o.
getDerivedGaugeValid()) {
alarm =
updateNotifications(
o);
updateThreshold(
o);
} else {
alarm = null;
}
return
alarm;
}
/**
* Tests if the threshold, offset and modulus of the specified observed
* object are of the same type as the counter. Only integer types are
* allowed.
*
* Note:
* If the optional offset or modulus have not been initialized, their
* default value is an Integer object with a value equal to zero.
*
* @param object The observed object.
* @param attribute The observed attribute.
* @param value The sample value.
* @return <CODE>true</CODE> if type is the same,
* <CODE>false</CODE> otherwise.
*/
@
Override
synchronized boolean
isThresholdTypeValid(
ObjectName object,
String attribute,
Comparable<?>
value) {
final
CounterMonitorObservedObject o =
(
CounterMonitorObservedObject)
getObservedObject(
object);
if (
o == null)
return false;
Class<? extends
Number>
c =
classForType(
o.
getType());
return (
c.
isInstance(
o.
getThreshold()) &&
isValidForType(
offset,
c) &&
isValidForType(
modulus,
c));
}
}