/* * JBoss, Home of Professional Open Source. * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package javax.management.monitor; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.management.MBeanRegistration; import javax.management.MBeanServer; import javax.management.NotificationBroadcasterSupport; import javax.management.ObjectName; import org.jboss.mx.util.ObservedObject; import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap; /** * The monitor service. * *

Revisions: *

20020319 Adrian Brock: *

* * @author Adrian Brock * @version $Revision: 57200 $ */ public abstract class Monitor extends NotificationBroadcasterSupport implements MonitorMBean, MBeanRegistration { // Constants ----------------------------------------------------- /** * The amount by which arrays are incremented. */ protected static final int capacityIncrement = 16; /** * Used to reset errors in {@link #alreadyNotified}. */ protected static final int RESET_FLAGS_ALREADY_NOTIFIED = 0; /** * An observed attribute type error has been notified. */ protected static final int RUNTIME_ERROR_NOTIFIED = 8; /** * An observed object error has been notified. */ protected static final int OBSERVED_OBJECT_ERROR_NOTIFIED = 1; /** * An observed attribute error has been notified. */ protected static final int OBSERVED_ATTRIBUTE_ERROR_NOTIFIED = 2; /** * An observed attribute type error has been notified. */ protected static final int OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED = 4; // Attributes ---------------------------------------------------- /** * The number of valid elements in the arrays. */ protected int elementCount = 0; /** * The granularity period. */ long granularityPeriod = 10000; /** * The observed attribute. */ String observedAttribute = null; /** * The observed objects. */ ConcurrentHashMap observedObjects = new ConcurrentHashMap(); /** * Whether the service is active. */ boolean active = false; /** * The server this service is registered in. */ protected MBeanServer server; /** * The object name of this monitor. */ ObjectName objectName; /** * The errors that have already been notified. * REVIEW: Check * @deprecated use {@link #alreadyNotifieds}[0] */ protected int alreadyNotified = 0; /** * The errors that have already been notified. */ protected int[] alreadyNotifieds = new int[0]; /** @deprecated No replacement. */ protected String dbgTag = null; /** * The notification sequence number. */ private long sequenceNumber; // Static -------------------------------------------------------- // Constructors -------------------------------------------------- // Public -------------------------------------------------------- // MonitorMBean implementation ----------------------------------- public long getGranularityPeriod() { return granularityPeriod; } public String getObservedAttribute() { return observedAttribute; } public ObjectName getObservedObject() { ObservedObject object = getFirstObservedObject(); if (object != null) return object.getObjectName(); else return null; } public ObjectName[] getObservedObjects() { Set set = new HashSet(observedObjects.values()); elementCount = set.size(); ObjectName[] result = new ObjectName[set.size()]; alreadyNotifieds = new int[set.size()]; int count = 0; for (Iterator i = set.iterator(); i.hasNext();) { ObservedObject object = (ObservedObject) i.next(); result[count] = object.getObjectName(); alreadyNotifieds[count++] = object.getAlreadyNotified(); } return result; } public synchronized boolean isActive() { return active; } public void setGranularityPeriod(long period) throws IllegalArgumentException { if (period <= 0) throw new IllegalArgumentException("Period must be positive."); granularityPeriod = period; } public void setObservedAttribute(String attribute) throws IllegalArgumentException { observedAttribute = attribute; } public void setObservedObject(ObjectName object) throws IllegalArgumentException { observedObjects.clear(); addObservedObject(object); } public void addObservedObject(ObjectName object) throws IllegalArgumentException { if (object == null) throw new IllegalArgumentException("null object name"); ObservedObject o = new ObservedObject(object); initObservedObject(o); observedObjects.put(object, o); } public void removeObservedObject(ObjectName object) { if (object == null) throw new IllegalArgumentException("null object name"); observedObjects.remove(object); } public boolean containsObservedObject(ObjectName object) { if (object == null) throw new IllegalArgumentException("null object name"); return observedObjects.containsKey(object); } public abstract void start(); public abstract void stop(); public String toString() { StringBuffer buffer = new StringBuffer(100); buffer.append(getClass()).append(System.identityHashCode(this)).append(": {"); buffer.append(" objectName=").append(objectName); return buffer.append("}").toString(); } // MBeanRegistrationImplementation overrides --------------------- public ObjectName preRegister(MBeanServer server, ObjectName objectName) throws Exception { // Remember the server. this.server = server; // Remember the object name. this.objectName = objectName; // Use the passed object name. return objectName; } public void postRegister(Boolean registrationDone) { } public void preDeregister() throws Exception { // Stop the monitor before deregistration. stop(); } public void postDeregister() { } // Package protected --------------------------------------------- /** * Get an observed object */ ObservedObject retrieveObservedObject(ObjectName name) { return (ObservedObject) observedObjects.get(name); } /** * retrieve the observed objects */ Map retrieveObservedObjects() { return observedObjects; } /** * retrieve the first observed objects */ ObservedObject getFirstObservedObject() { Iterator i = observedObjects.values().iterator(); if (i.hasNext()) return (ObservedObject) i.next(); else return null; } void initObservedObject(ObservedObject object) { object.resetAlreadyNotified(); object.setDerivedGaugeTimeStamp(System.currentTimeMillis()); } /** * Sends the notification * * @param object the observedObject. * @param type the notification type. * @param timestamp the time of the notification. * @param message the human readable message to send. * @param attribute the attribute name. * @param gauge the derived gauge. * @param trigger the trigger value. */ void sendNotification(ObservedObject object, String type, long timestamp, String message, String attribute, Object gauge, Object trigger) { long seq = nextSeqNo(); if (timestamp == 0) timestamp = System.currentTimeMillis(); sendNotification(new MonitorNotification(type, objectName, seq, timestamp, message, gauge, attribute, object.getObjectName(), trigger)); } /** * Send a runtime error notification. * * @param object the observedObject. * @param message the human readable message to send. */ void sendRuntimeErrorNotification(ObservedObject object, String message) { if (object.notAlreadyNotified(RUNTIME_ERROR_NOTIFIED)) sendNotification(object, MonitorNotification.RUNTIME_ERROR, 0, message, observedAttribute, null, null); } /** * Send an object error notification. * * @param object the observedObject. * @param message the human readable message to send. */ void sendObjectErrorNotification(ObservedObject object, String message) { if (object.notAlreadyNotified(OBSERVED_OBJECT_ERROR_NOTIFIED)) sendNotification(object, MonitorNotification.OBSERVED_OBJECT_ERROR, 0, message, observedAttribute, null, null); } /** * Send an attribute error notification. * * @param object the observedObject. * @param message the human readable message to send. */ void sendAttributeErrorNotification(ObservedObject object, String message) { if (object.notAlreadyNotified(OBSERVED_ATTRIBUTE_ERROR_NOTIFIED)) sendNotification(object, MonitorNotification.OBSERVED_ATTRIBUTE_ERROR, 0, message, observedAttribute, null, null); } /** * Send an attribute type error notification. * * @param object the observedObject. * @param message the human readable message to send. */ void sendAttributeTypeErrorNotification(ObservedObject object, String message) { if (object.notAlreadyNotified(OBSERVED_ATTRIBUTE_TYPE_ERROR_NOTIFIED)) sendNotification(object, MonitorNotification.OBSERVED_ATTRIBUTE_TYPE_ERROR, 0, message, observedAttribute, null, null); } /** * Reset the already notifieds */ void resetAlreadyNotified() { for (Iterator i = observedObjects.values().iterator(); i.hasNext();) ((ObservedObject) i.next()).resetAlreadyNotified(); } synchronized long nextSeqNo() { long nextSeqNo = sequenceNumber ++; return nextSeqNo; } // Protected ----------------------------------------------------- // Private ------------------------------------------------------- // Inner classes ------------------------------------------------- }