001: /**
002: * The XMOJO Project 5
003: * Copyright © 2003 XMOJO.org. All rights reserved.
004:
005: * NO WARRANTY
006:
007: * BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
008: * THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
009: * OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
010: * PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
011: * OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
012: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
013: * TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE
014: * LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
015: * REPAIR OR CORRECTION.
016:
017: * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
018: * ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
019: * THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
020: * GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
021: * USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF
022: * DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
023: * PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE),
024: * EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
025: * SUCH DAMAGES.
026: **/package javax.management.monitor;
027:
028: import java.util.Date;
029:
030: import javax.management.ObjectName;
031: import javax.management.MBeanServer;
032: import javax.management.MBeanNotificationInfo;
033: import javax.management.MBeanException;
034: import javax.management.AttributeNotFoundException;
035: import javax.management.InstanceNotFoundException;
036: import javax.management.ReflectionException;
037:
038: import com.adventnet.agent.logging.Log;
039: import com.adventnet.agent.logging.LogFactory;
040:
041: /**
042: * Defines a monitor MBean designed to observe the values of a string attribute.
043: * <P>
044: * A string monitor sends notifications as follows:
045: * <UL>
046: * <LI> if the attribute value matches the string to compare value,
047: * a {@link MonitorNotification#STRING_TO_COMPARE_VALUE_MATCHED match notification} is sent.
048: * The notify match flag must be set to <CODE>true</CODE>.
049: * <BR>Subsequent matchings of the string to compare values do not cause
050: * further notifications unless the attribute value differs from the
051: * string to compare value.
052: * <LI> if the attribute value differs from the string to compare value,
053: * a {@link MonitorNotification#STRING_TO_COMPARE_VALUE_DIFFERED differ notification} is sent.
054: * The notify differ flag must be set to <CODE>true</CODE>.
055: * <BR>Subsequent differences from the string to compare value do not
056: * cause further notifications unless the attribute value matches the
057: * string to compare value.
058: * </UL>
059: */
060: public class StringMonitor extends Monitor implements
061: StringMonitorMBean {
062: /**
063: * String to compare with the observed attribute.
064: * <BR>The default value is an empty character sequence.
065: */
066: private String string_to_compare = new String();
067:
068: /**
069: * Flag indicating if the string monitor notifies when matching the string
070: * to compare. <BR>The default value is set to <CODE>false</CODE>.
071: */
072: private boolean notify_match = false;
073:
074: /**
075: * Flag indicating if the string monitor notifies when differing from the
076: * string to compare. <BR>The default value is set to <CODE>false</CODE>.
077: */
078: private boolean notify_differ = false;
079:
080: /**
081: * Derived gauge.
082: */
083: private transient String derivedGauge = new String();
084:
085: /**
086: * Derived gauge timestamp.
087: */
088: private transient long derivedGaugeTimestamp = (new Date())
089: .getTime();
090:
091: private Thread stringMonitorThread = null;
092: private long sequenceNumber = 1;
093: private boolean nmatch = true;
094: private boolean ndiffer = true;
095: private MonitorNotification notif = null;
096: private int ERROR_VALUE = 0;
097: private ObjectName objName = null;
098: private Log log;
099:
100: /**
101: * Default Constructor.
102: */
103: public StringMonitor() {
104: createLogger();
105: }
106:
107: /**
108: * This method gets the value of the derived gauge. The derived gauge is
109: * either the exact value of the observed attribute , or the difference
110: * between the two consecutive observed values of the attribute.
111: *
112: * @return An instance of java.lang.String giving the value of the derived gauge.
113: */
114: public String getDerivedGauge() {
115: return derivedGauge;
116: }
117:
118: /**
119: * This method gets the value of the derived gauge time stamp.The derived
120: * gauge time stamp is the value(in the nearest miliseconds) when the
121: * notification was triggered.
122: *
123: * @return long value representing the time the notification was triggered.
124: */
125: public long getDerivedGaugeTimeStamp() {
126: return derivedGaugeTimeStamp;
127: }
128:
129: /**
130: * This method sets the differing notification's on/off switch value.
131: *
132: * @return The differing notification's on/off switch value.
133: */
134: public boolean getNotifyDiffer() {
135: return notify_differ;
136: }
137:
138: /**
139: * This method sets the differing notification's on/off switch value.
140: *
141: * @param value - The differing notification's on/off switch value.
142: */
143: public void setNotifyDiffer(boolean value) {
144: this .notify_differ = value;
145: }
146:
147: /**
148: * This method gets the matching notification's on/off switch value.
149: *
150: * @return The matching notification's on/off switch value.
151: */
152: public boolean getNotifyMatch() {
153: return notify_match;
154: }
155:
156: /**
157: * This method sets the matching notification's on/off switch value.
158: *
159: * @param value - The matching notification's on/off switch value.
160: */
161: public void setNotifyMatch(boolean value) {
162: this .notify_match = value;
163: }
164:
165: /**
166: * This method gets the string to compare with the observed attribute.
167: *
168: * @return the String to be compared.
169: */
170: public String getStringToCompare() {
171: return string_to_compare;
172: }
173:
174: /**
175: * This method sets the string to compare with the observed attribute.
176: *
177: * @param The String Value to be compared.
178: *
179: * @exception java.lang.IllegalArgumentException - The specified string to
180: * compare is null.
181: */
182: public void setStringToCompare(String value)
183: throws IllegalArgumentException {
184: if (value == null)
185: throw new IllegalArgumentException(
186: "The String to Compare cannot be null");
187:
188: this .string_to_compare = value;
189: }
190:
191: /**
192: * This method starts the String Monitor.
193: */
194: public void start() {
195: stringMonitorThread = new Thread(new StringMonitorThread(this ));
196: isActive = true;
197: stringMonitorThread.setName("StringMonitorThread-"
198: + stringMonitorThread.getName());
199: stringMonitorThread.start();
200: log.trace("String Monitor Started");
201: }
202:
203: /**
204: * This method stops the String Monitor.
205: */
206: public void stop() {
207: isActive = false;
208: stringMonitorThread.stop();
209: log.trace("String Monitor Stopped");
210: }
211:
212: /**
213: * Overriding the preRegister() of MBeanRegistration interface to store
214: * the ObjectName locally.
215: */
216: public ObjectName preRegister(MBeanServer server, ObjectName name)
217: throws Exception {
218: this .objName = name;
219: super .preRegister(server, name);
220: return name;
221: }
222:
223: public MBeanNotificationInfo[] getNotificationInfo() {
224: MBeanNotificationInfo[] notifInfo = super .getNotificationInfo();
225:
226: MBeanNotificationInfo[] newNotifInfo = new MBeanNotificationInfo[notifInfo.length + 1];
227:
228: for (int i = 0; i < notifInfo.length; i++) {
229: newNotifInfo[i] = notifInfo[i];
230: }
231:
232: String[] types = { "jmx.monitor.string.matches",
233: "jmx.monitor.string.differs" };
234: newNotifInfo[newNotifInfo.length - 1] = new MBeanNotificationInfo(
235: types, "Monitor String Comparison Notification",
236: "Emimitted for a difference in the comparison ");
237:
238: return newNotifInfo;
239: }
240:
241: //---------------------------- Private methods ---------------------------//
242:
243: private void createLogger() {
244: try {
245: log = LogFactory.getInstance("JMX");
246: } catch (Exception e) {
247: e.printStackTrace();
248: }
249: }
250:
251: //------------------------------ Inner class -----------------------------//
252:
253: // This inner class implements Runnable and when the StringMonitor is started,
254: // the start method of this class is called and it periodically polls the
255: // Observed Attribute according to the granularity period and when there is
256: // a deviation from the configuration details, sends a notification.
257: class StringMonitorThread implements Runnable {
258: StringMonitor monitor = null;
259: private boolean isNotifDifferSent = false;
260: private boolean isNotifMatchSent = false;
261:
262: StringMonitorThread(StringMonitor monitor) {
263: this .monitor = monitor;
264: }
265:
266: public void run() {
267: Object obj = null;
268: boolean temp = true;
269:
270: while (true) {
271: try {
272: obj = server.getAttribute(observedObject,
273: attributeName);
274: derivedGaugeTimeStamp = System.currentTimeMillis();
275: } catch (InstanceNotFoundException ine) {
276: if (Monitor.OBSERVED_OBJECT_ERROR_NOTIFIED == 1) {
277: sendNotification(new MonitorNotification(
278: MonitorNotification.OBSERVED_OBJECT_ERROR,
279: monitor, observedObject, attributeName,
280: null, null, sequenceNumber++));
281: Monitor.OBSERVED_OBJECT_ERROR_NOTIFIED = 0;
282: }
283: sleep();
284: continue;
285: } catch (AttributeNotFoundException ane) {
286: if (Monitor.OBSERVED_ATTRIBUTE_ERROR_NOTIFIED == 1) {
287: sendNotification(new MonitorNotification(
288: MonitorNotification.OBSERVED_ATTRIBUTE_ERROR,
289: monitor, observedObject, attributeName,
290: null, null, sequenceNumber++));
291: Monitor.OBSERVED_ATTRIBUTE_ERROR_NOTIFIED = 0;
292: }
293: sleep();
294: continue;
295: } catch (MBeanException mbe) {
296: if (Monitor.RUNTIME_ERROR_NOTIFIED == 1) {
297: sendNotification(new MonitorNotification(
298: MonitorNotification.RUNTIME_ERROR,
299: monitor, observedObject, attributeName,
300: null, null, sequenceNumber++));
301: Monitor.RUNTIME_ERROR_NOTIFIED = 0;
302: }
303:
304: /*
305: if(Monitor.OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED == 1)
306: {
307: sendNotification(new MonitorNotification(MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,monitor,
308: observedObject,attributeName, null,null,sequenceNumber++));
309: Monitor.OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 0;
310: }*/
311: sleep();
312: continue;
313: } catch (ReflectionException re) {
314: if (Monitor.RUNTIME_ERROR_NOTIFIED == 1) {
315: sendNotification(new MonitorNotification(
316: MonitorNotification.RUNTIME_ERROR,
317: monitor, observedObject, attributeName,
318: null, null, sequenceNumber++));
319: Monitor.RUNTIME_ERROR_NOTIFIED = 0;
320: }
321: sleep();
322: continue;
323: } catch (Exception e) {
324: if (Monitor.RUNTIME_ERROR_NOTIFIED == 1) {
325: sendNotification(new MonitorNotification(
326: MonitorNotification.RUNTIME_ERROR,
327: monitor, observedObject, attributeName,
328: null, null, sequenceNumber++));
329: Monitor.RUNTIME_ERROR_NOTIFIED = 0;
330: }
331: sleep();
332: continue;
333: }
334:
335: if (obj == null) {
336: continue;
337: }
338:
339: if (!(obj.getClass().getName()
340: .equals("java.lang.String"))) {
341: if (Monitor.OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED == 1) {
342: sendNotification(new MonitorNotification(
343: MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,
344: monitor, observedObject, attributeName,
345: null, null, sequenceNumber++));
346: Monitor.OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 0;
347: }
348: }
349:
350: derivedGauge = (String) obj;
351:
352: if (notify_match) {
353: if (isNotifMatchSent) {
354: if (!(derivedGauge.equals(string_to_compare))) {
355: isNotifMatchSent = false;
356: }
357: } else {
358: if (derivedGauge.equals(string_to_compare)) {
359: notif = new MonitorNotification(
360: MonitorNotification.STRING_TO_COMPARE_VALUE_MATCHED,
361: monitor, observedObject,
362: attributeName, derivedGauge,
363: string_to_compare, sequenceNumber++);
364:
365: isNotifMatchSent = true;
366: sendNotification(notif);
367: }
368: }
369: }
370:
371: if (notify_differ) {
372: if (isNotifDifferSent) {
373: if (derivedGauge.equals(string_to_compare)) {
374: isNotifDifferSent = false;
375: }
376: } else {
377: if (!(derivedGauge.equals(string_to_compare))) {
378: notif = new MonitorNotification(
379: MonitorNotification.STRING_TO_COMPARE_VALUE_DIFFERED,
380: monitor, observedObject,
381: attributeName, derivedGauge,
382: string_to_compare, sequenceNumber++);
383:
384: isNotifDifferSent = true;
385: sendNotification(notif);
386: }
387: }
388: }
389:
390: try {
391: Thread.sleep(granularityPeriod);
392: } catch (InterruptedException IE) {
393: }
394: }
395: }
396:
397: private void sleep() {
398: try {
399: Thread.sleep(granularityPeriod);
400: } catch (Exception e) {
401: }
402: }
403: }//End StringMonitorThread class.
404: }//End StringMonitor class.
|