001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.mx.util;
023:
024: import java.util.Iterator;
025: import java.util.Map;
026: import javax.management.InstanceNotFoundException;
027: import javax.management.MBeanAttributeInfo;
028: import javax.management.MBeanInfo;
029: import javax.management.MBeanServer;
030: import javax.management.ObjectName;
031: import javax.management.monitor.Monitor;
032: import javax.management.monitor.MonitorNotification;
033:
034: import org.jboss.logging.Logger;
035:
036: /**
037: * @author Scott.Stark@jboss.org
038: * @version $Revision: 57200 $
039: */
040: public class MonitorRunnable extends SchedulableRunnable {
041: private static final Logger log = Logger
042: .getLogger(MonitorRunnable.class);
043:
044: /**
045: * The scheduler.
046: */
047: static RunnableScheduler scheduler;
048:
049: /**
050: * Start the scheduler
051: */
052: static {
053: scheduler = new RunnableScheduler();
054: scheduler.start();
055: }
056:
057: // Attributes ----------------------------------------------------
058:
059: // The monitoring to perform
060: private Monitor monitor;
061: private ObjectName monitorName;
062: private MonitorCallback callback;
063: private Map observedObjects;
064: private MBeanServer server;
065:
066: // Constructors --------------------------------------------------
067:
068: /**
069: * Create a monitor runnable to periodically perform monitoring.
070: *
071: * @param monitor the monitoring to perform.
072: */
073: public MonitorRunnable(Monitor monitor, ObjectName monitorName,
074: MonitorCallback callback, Map observedObjects,
075: MBeanServer server) {
076: this .monitor = monitor;
077: this .monitorName = monitorName;
078: this .callback = callback;
079: this .observedObjects = observedObjects;
080: this .server = server;
081: setScheduler(scheduler);
082: }
083:
084: // Public --------------------------------------------------------
085:
086: /**
087: * Run the monitor.<p>
088: *
089: * Retrieves the monitored attribute and passes it to each service.<p>
090: *
091: * Peforms the common error processing.
092: *
093: * @param object the mbean to run the monitor on
094: */
095: void runMonitor(ObservedObject object) {
096: // Monitor for uncaught errors
097: try {
098: MBeanInfo mbeanInfo = null;
099: try {
100: mbeanInfo = server.getMBeanInfo(object.getObjectName());
101: } catch (InstanceNotFoundException e) {
102: sendObjectErrorNotification(object,
103: "The observed object is not registered.");
104: return;
105: }
106:
107: // Get the attribute information
108: MBeanAttributeInfo[] mbeanAttributeInfo = mbeanInfo
109: .getAttributes();
110: MBeanAttributeInfo attributeInfo = null;
111: for (int i = 0; i < mbeanAttributeInfo.length; i++) {
112: if (mbeanAttributeInfo[i].getName().equals(
113: monitor.getObservedAttribute())) {
114: attributeInfo = mbeanAttributeInfo[i];
115: break;
116: }
117: }
118:
119: // The attribute must exist
120: if (attributeInfo == null) {
121: sendAttributeErrorNotification(object,
122: "The observed attribute does not exist");
123: return;
124: }
125:
126: // The attribute must exist
127: if (!attributeInfo.isReadable()) {
128: sendAttributeErrorNotification(object,
129: "Attribute not readable.");
130: return;
131: }
132:
133: // Get the value
134: Object value = null;
135: try {
136: value = server.getAttribute(object.getObjectName(),
137: monitor.getObservedAttribute());
138: } catch (InstanceNotFoundException e) {
139: sendObjectErrorNotification(object,
140: "The observed object is not registered.");
141: return;
142: }
143:
144: // Check for null value
145: if (value == null) {
146: sendAttributeTypeErrorNotification(object,
147: "Attribute is null");
148: return;
149: }
150:
151: // Now pass the value to the respective monitor.
152: callback.monitorCallback(object, attributeInfo, value);
153: }
154: // Notify an unexcepted error
155: catch (Throwable e) {
156: log.debug("Error in monitor ", e);
157: sendRuntimeErrorNotification(object, "General error: "
158: + e.toString());
159: }
160: }
161:
162: /**
163: * Run the montior
164: */
165: public void doRun() {
166: // Perform the monitoring
167: runMonitor();
168:
169: // Reschedule
170: setNextRun(System.currentTimeMillis()
171: + monitor.getGranularityPeriod());
172: }
173:
174: /**
175: * Run the monitor on each observed object
176: */
177: void runMonitor() {
178: // Loop through each mbean
179: boolean isActive = monitor.isActive();
180: for (Iterator i = observedObjects.values().iterator(); i
181: .hasNext()
182: && isActive;)
183: runMonitor((ObservedObject) i.next());
184: }
185:
186: /**
187: * Sends the notification
188: *
189: * @param object the observedObject.
190: * @param type the notification type.
191: * @param timestamp the time of the notification.
192: * @param message the human readable message to send.
193: * @param attribute the attribute name.
194: * @param gauge the derived gauge.
195: * @param trigger the trigger value.
196: */
197: void sendNotification(ObservedObject object, String type,
198: long timestamp, String message, String attribute,
199: Object gauge, Object trigger) {
200: MonitorNotification n = callback.createNotification(type,
201: monitorName, timestamp, message, gauge, attribute,
202: object.getObjectName(), trigger);
203: monitor.sendNotification(n);
204: }
205:
206: /**
207: * Send a runtime error notification.
208: *
209: * @param object the observedObject.
210: * @param message the human readable message to send.
211: */
212: void sendRuntimeErrorNotification(ObservedObject object,
213: String message) {
214: if (object
215: .notAlreadyNotified(ObservedObject.RUNTIME_ERROR_NOTIFIED))
216: sendNotification(object, MonitorNotification.RUNTIME_ERROR,
217: 0, message, monitor.getObservedAttribute(), null,
218: null);
219: }
220:
221: /**
222: * Send an object error notification.
223: *
224: * @param object the observedObject.
225: * @param message the human readable message to send.
226: */
227: void sendObjectErrorNotification(ObservedObject object,
228: String message) {
229: if (object
230: .notAlreadyNotified(ObservedObject.OBSERVED_OBJECT_ERROR_NOTIFIED))
231: sendNotification(object,
232: MonitorNotification.OBSERVED_OBJECT_ERROR, 0,
233: message, monitor.getObservedAttribute(), null, null);
234: }
235:
236: /**
237: * Send an attribute error notification.
238: *
239: * @param object the observedObject.
240: * @param message the human readable message to send.
241: */
242: void sendAttributeErrorNotification(ObservedObject object,
243: String message) {
244: if (object
245: .notAlreadyNotified(ObservedObject.OBSERVED_ATTRIBUTE_ERROR_NOTIFIED))
246: sendNotification(object,
247: MonitorNotification.OBSERVED_ATTRIBUTE_ERROR, 0,
248: message, monitor.getObservedAttribute(), null, null);
249: }
250:
251: /**
252: * Send an attribute type error notification.
253: *
254: * @param object the observedObject.
255: * @param message the human readable message to send.
256: */
257: void sendAttributeTypeErrorNotification(ObservedObject object,
258: String message) {
259: if (object
260: .notAlreadyNotified(ObservedObject.OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED))
261: sendNotification(object,
262: MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR,
263: 0, message, monitor.getObservedAttribute(), null,
264: null);
265: }
266:
267: }
|