| AlarmTable.java |
/***************************************
* *
* JBoss: The OpenSource J2EE WebOS *
* *
* Distributable under LGPL license. *
* See terms of license at gnu.org. *
* *
***************************************/
package org.jboss.monitor.alarm;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Collection;
import javax.management.Notification;
import javax.management.ObjectName;
/**
* AlarmTable
*
* @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
*
* @version $Revision: 1.1.4.1 $
**/
public class AlarmTable
{
// Private/Protected Data ----------------------------------------
// mediates the related MBean
protected MBeanImplAccess mbeanImpl;
/** the serverId to use when producing AlarmTableNotification */
private String serverId;
/** the active alarm table, contains AlarmTableNotification */
private Map alarmMap;
// Constructors --------------------------------------------------
/**
* CTOR
**/
public AlarmTable(MBeanImplAccess mbeanImpl)
{
this.mbeanImpl = mbeanImpl;
this.alarmMap = new HashMap();
}
// AlarmTable Implementation -------------------------------------
/**
* Sets the serverId
**/
public void setServerId(String serverId)
{
this.serverId = serverId;
}
/**
* Gets the serverId
**/
public String getServerId()
{
return this.serverId;
}
/**
* Update the AlarmTable based on the incoming Notification
**/
public void update(Notification n)
{
if (n instanceof AlarmTableNotification) {
// ignore - those notification are
// meant to be produced only by me
}
else if (n instanceof AlarmNotification) {
AlarmNotification an = (AlarmNotification)n;
if (an.getAlarmState() == Alarm.STATE_NONE)
updateNotificationStateless(n, an.getSeverity());
else
updateNotificationStatefull(an);
}
else
updateNotificationStateless(n, Alarm.SEVERITY_UNKNOWN);
}
/**
* Acknowledge an Alarm
*
* @return true if ack was succesful, false otherwise
* (not in table or acked already)
**/
public boolean acknowledge(String serverId, String source, String type,
String user, String system)
{
AlarmKey key = AlarmKey.createKey(serverId, source, type);
return this.acknowledge(key, user, system);
}
/**
* Acknowledge an Alarm
*
* @return true if ack was succesful, false otherwise
* (not in table or acked already)
**/
public boolean acknowledge(Object key, String user, String system)
{
AlarmTableNotification atn;
synchronized (this) {
AlarmTableNotification entry =
(AlarmTableNotification)this.alarmMap.get(key);
if (entry == null || entry.getAckState() == true)
return false; // ack failed
// ack the alarm
entry.setAckParams(true, System.currentTimeMillis(), user, system);
// prepare the AlarmTableNotification to send
atn = new AlarmTableNotification(entry);
// this is a new notification
atn.setSequenceNumber(this.mbeanImpl.getSequenceNumber());
atn.setTimeStamp(System.currentTimeMillis());
// if alarm Stateless or Statefull but Cleared, remove from table
int alarmState = entry.getAlarmState();
if (alarmState == Alarm.STATE_NONE || alarmState == Alarm.STATE_CLEARED)
this.alarmMap.remove(key);
}
// send the AlarmTableNotification
this.mbeanImpl.emitNotification(atn);
return true; // ok
}
/**
* Uncknowledge an Alarm
*
* @return true if unack was succesful, false otherwise
* (not in table or unacked already)
**/
public boolean unacknowledge(String serverId, String source, String type,
String user, String system)
{
AlarmKey key = AlarmKey.createKey(serverId, source, type);
return this.unacknowledge(key, user, system);
}
/**
* Unacknowledge an Alarm
*
* @return true if unack was succesful, false otherwise
* (not in table or unacked already)
**/
public boolean unacknowledge(Object key, String user, String system)
{
AlarmTableNotification atn;
synchronized (this) {
AlarmTableNotification entry =
(AlarmTableNotification)this.alarmMap.get(key);
if (entry == null || entry.getAckState() == false)
return false; // unack failed
// unack the alarm
entry.setAckParams(false, System.currentTimeMillis(), user, system);
// prepare the AlarmTableNotification to send
atn = new AlarmTableNotification(entry);
// this is a new notification
atn.setSequenceNumber(this.mbeanImpl.getSequenceNumber());
atn.setTimeStamp(System.currentTimeMillis());
}
// send the AlarmTableNotification
this.mbeanImpl.emitNotification(atn);
return true; // ok
}
/**
* Gets a copy of the AlarmTable
**/
public AlarmTableNotification[] getAlarmTable()
{
// this syncronized deep copy is quite expensive
synchronized (this) {
int size = this.alarmMap.size();
AlarmTableNotification[] copy =
new AlarmTableNotification[size];
Collection values = this.alarmMap.values();
Iterator i = values.iterator();
while (i.hasNext()) {
AlarmTableNotification atn =
(AlarmTableNotification)i.next();
copy[--size] = new AlarmTableNotification(atn);
}
return copy;
}
}
// Private Methods -----------------------------------------------
private void updateNotificationStatefull(AlarmNotification an)
{
int alarmState = an.getAlarmState();
int severity = an.getSeverity();
// create an AlarmTableNotification
AlarmTableNotification atn =
new AlarmTableNotification(
AlarmTableNotification.ALARM_TABLE_UPDATE,
this.mbeanImpl.getMBeanName(),
this.mbeanImpl.getSequenceNumber(),
System.currentTimeMillis(),
null,
alarmState,
severity,
this.serverId
);
// store a reference to the original notification
atn.setUserData(an);
Object key = atn.createKey();
synchronized (this) {
// need to check if acked already, in which case
// we must copy the ack data to the new AlarmTableNotification
// and remove the entry from the table
if (alarmState == Alarm.STATE_CLEARED) {
AlarmTableNotification entry =
(AlarmTableNotification)this.alarmMap.get(key);
if (entry != null && entry.getAckState() == true) {
this.alarmMap.remove(key);
atn.setAckParams(true, entry.getAckTime(),
entry.getAckUser(), entry.getAckSystem());
}
else {
// just add it
this.alarmMap.put(key, atn);
}
}
else {
// just add it
this.alarmMap.put(key, atn);
}
}
// the only case to be acked is when it is not stored in table
// in which case send the new AlarmTableNotification itself
if (atn.getAckState() == true)
this.mbeanImpl.emitNotification(atn);
else // send a copy away
this.mbeanImpl.emitNotification(new AlarmTableNotification(atn));
}
private void updateNotificationStateless(Notification n, int severity)
{
// create an AlarmTableNotification
AlarmTableNotification atn =
new AlarmTableNotification(
AlarmTableNotification.ALARM_TABLE_UPDATE,
this.mbeanImpl.getMBeanName(),
this.mbeanImpl.getSequenceNumber(),
System.currentTimeMillis(),
null,
Alarm.STATE_NONE,
severity,
this.serverId
);
// store a reference to the original notification
atn.setUserData(n);
Object key = atn.createKey();
// store the AlarmTableNotification - it may override an existing entry
synchronized (this) {
this.alarmMap.put(key, atn);
}
// send a copy away
this.mbeanImpl.emitNotification(new AlarmTableNotification(atn));
}
}
| AlarmTable.java |