package org.mobicents.slee.container.management.jmx;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.management.ListenerNotFoundException;
import javax.management.MBeanNotificationInfo;
import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster;
import javax.management.NotificationFilter;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.StandardMBean;
import javax.slee.InvalidStateException;
import javax.slee.management.ManagementException;
import javax.slee.management.NotificationSource;
import javax.slee.management.ProfileTableNotification;
import javax.slee.management.ResourceAdaptorEntityNotification;
import javax.slee.management.SbbNotification;
import javax.slee.management.SubsystemNotification;
import javax.slee.usage.UsageMBean;
import javax.slee.usage.UsageNotification;
public class UsageMBeanImpl extends StandardMBean implements UsageMBean,
NotificationBroadcaster {
private static final MBeanNotificationInfo[] notificationInfo = initNotificationInfo();
/**
* Initiates the notification info for usage mbeans
* @return
*/
private static MBeanNotificationInfo[] initNotificationInfo() {
String[] notificationTypes = new String[] {
ProfileTableNotification.USAGE_NOTIFICATION_TYPE,
ResourceAdaptorEntityNotification.USAGE_NOTIFICATION_TYPE,
SbbNotification.USAGE_NOTIFICATION_TYPE,
SubsystemNotification.USAGE_NOTIFICATION_TYPE
};
MBeanNotificationInfo[] mbeanNotificationInfo = new MBeanNotificationInfo[] { new MBeanNotificationInfo(
notificationTypes, UsageNotification.class.getName(),
"JAIN SLEE 1.1 Usage MBean Notification") };
return mbeanNotificationInfo;
}
private InstalledUsageParameterSet usageParameterSet;
private UsageMBeanImplParent parent;
private final NotificationSource notificationSource;
private ObjectName objectName;
public UsageMBeanImpl(Class<?> mbeanInterface, NotificationSource notificationSource) throws NotCompliantMBeanException,
ClassNotFoundException {
super(mbeanInterface);
this.notificationSource = notificationSource;
}
public void setParent(UsageMBeanImplParent parent) {
this.parent = parent;
}
public ObjectName getObjectName() {
return objectName;
}
public void setObjectName(ObjectName objectName) {
this.objectName = objectName;
}
public void setUsageParameter(
InstalledUsageParameterSet usageParameterSet) {
this.usageParameterSet = usageParameterSet;
}
public InstalledUsageParameterSet getUsageParameter() {
return usageParameterSet;
}
public void close() throws InvalidStateException, ManagementException {
if (listeners.size() != 0) {
throw new InvalidStateException(
"Could not close Usage MBean listeners still attached!");
}
}
public NotificationSource getNotificationSource()
throws ManagementException {
return notificationSource;
}
public ObjectName getUsageNotificationManagerMBean()
throws ManagementException {
UsageNotificationManagerMBeanImpl notificationManager = parent.getUsageNotificationManagerMBean(notificationSource);
return notificationManager != null ? notificationManager.getObjectName() : null;
}
public String getUsageParameterSet() throws ManagementException {
return usageParameterSet.getName();
}
public void resetAllUsageParameters() throws ManagementException {
usageParameterSet.reset();
}
// --- NOTIFICATION BROADCASTER IMPL
private final Map<NotificationListener, ListenerFilterHandbackTriplet> listeners = new ConcurrentHashMap<NotificationListener, ListenerFilterHandbackTriplet>();
public void addNotificationListener(NotificationListener listener,
NotificationFilter filter, Object handback)
throws IllegalArgumentException {
if (listener == null) {
throw new IllegalArgumentException("null listener");
} else {
this.listeners.put(listener, new ListenerFilterHandbackTriplet(
listener, filter, handback));
}
}
/*
* (non-Javadoc)
* @see javax.management.NotificationBroadcaster#getNotificationInfo()
*/
public MBeanNotificationInfo[] getNotificationInfo() {
return notificationInfo;
}
public void removeNotificationListener(NotificationListener listener)
throws ListenerNotFoundException {
ListenerFilterHandbackTriplet triplet = listeners.remove(listener);
if (triplet == null) {
throw new ListenerNotFoundException();
}
}
/**
* Send the notification.
*
* @param value
* @param seqno
* @param usageParameterSetName
* @param usageParameterName
* @param isCounter
*/
public void sendUsageNotification(long value, long seqno,
String usageParameterSetName, String usageParameterName,
boolean isCounter) {
UsageNotificationManagerMBeanImpl notificationManager = parent
.getUsageNotificationManagerMBean(notificationSource);
if (notificationManager == null
|| notificationManager
.getNotificationsEnabled(usageParameterName)) {
// if the notification manager is null we consider the notification
// can be sent
UsageNotification notification = createUsageNotification(value,
seqno, usageParameterSetName, usageParameterName, isCounter);
for (ListenerFilterHandbackTriplet triplet : listeners.values()) {
if (triplet.notificationFilter == null
|| triplet.notificationFilter
.isNotificationEnabled(notification)) {
triplet.notificationListener.handleNotification(
notification, triplet.handbackObject);
}
}
}
}
/**
* Creates an instance of an {@link UsageNotification} for the specified
* args. This operation is exposed to allow it be overriden by
* {@link SbbUsageMBean} impl.
*
* @param value
* @param seqno
* @param usageParameterSetName
* @param usageParameterName
* @param isCounter
* @return
*/
protected UsageNotification createUsageNotification(long value, long seqno,
String usageParameterSetName, String usageParameterName,
boolean isCounter) {
return new UsageNotification(notificationSource
.getUsageNotificationType(), this, notificationSource,
usageParameterSetName, usageParameterName, isCounter, value,
seqno, System.currentTimeMillis());
}
class ListenerFilterHandbackTriplet {
NotificationListener notificationListener;
NotificationFilter notificationFilter;
Object handbackObject;
public ListenerFilterHandbackTriplet(NotificationListener listener,
NotificationFilter notificationFilter, Object handbackObject) {
this.notificationListener = listener;
this.notificationFilter = notificationFilter;
this.handbackObject = handbackObject;
}
@Override
public int hashCode() {
return notificationListener.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj != null && obj.getClass() == this.getClass()) {
return ((ListenerFilterHandbackTriplet) obj).notificationListener == this.notificationListener;
} else {
return false;
}
}
}
}