package rocks.inspectit.agent.java.sensor.method.special;
import java.util.Collection;
import javax.management.MBeanServer;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import rocks.inspectit.agent.java.config.impl.SpecialSensorConfig;
import rocks.inspectit.agent.java.hooking.ISpecialHook;
import rocks.inspectit.agent.java.sensor.jmx.IMBeanServerListener;
/**
* Hook that intercepts the adding or removing of the {@link MBeanServer}s and delegating this
* information to the {@link IMBeanServerListener}s.
*
* @author Ivan Senic
*
*/
public class MBeanServerInterceptorHook implements ISpecialHook {
/**
* Add mbean server method name in the {@link javax.management.MBeanServerFactory}.
*/
private static final Object ADD_METHOD = "addMBeanServer";
/**
* Remove mbean server method name in the {@link javax.management.MBeanServerFactory}.
*/
private static final Object REMOVE_METHOD = "removeMBeanServer";
/**
* Logger for this class.
*/
private static final Logger LOG = LoggerFactory.getLogger(MBeanServerInterceptorHook.class);
/**
* All the listeners to delegate the information to.
*/
private final Collection<IMBeanServerListener> mBeanServerListeners;
/**
* Default constructor.
*
* @param mBeanServerListeners
* All the listeners to delegate the information to.
*/
public MBeanServerInterceptorHook(Collection<IMBeanServerListener> mBeanServerListeners) {
this.mBeanServerListeners = mBeanServerListeners;
}
/**
* {@inheritDoc}
*/
@Override
public Object beforeBody(long methodId, Object object, Object[] parameters, SpecialSensorConfig ssc) {
String methodName = ssc.getTargetMethodName();
MBeanServer server = getServerFromParameters(parameters);
if (ADD_METHOD.equals(methodName)) {
mbeanServerAdded(server);
} else if (REMOVE_METHOD.equals(methodName)) {
mbeanServerRemoved(server);
} else if (LOG.isWarnEnabled()) {
LOG.warn("MBeanServerInterceptorHook not dispatched on the add or remove mbean server method. Dispatched method is " + methodName + " on class " + object.getClass().getName() + ".");
}
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Object afterBody(long methodId, Object object, Object[] parameters, Object result, SpecialSensorConfig ssc) {
return null;
}
/**
* Check if the parameter array has exactly size 1 and that object in the array is instanceOf
* {@link MBeanServer}. If so returns the server object, otherwise returns <code>null</code>.
*
* @param params
* Method parameters
* @return Returns the server object is found in parameters, otherwise returns
* <code>null</code>.
*/
private MBeanServer getServerFromParameters(Object[] params) {
if ((null != params) && (params.length == 1)) {
Object p = params[0];
if (p instanceof MBeanServer) {
return (MBeanServer) p;
}
}
return null;
}
/**
* Informs {@link #mBeanServerListeners} that server has been added.
*
* @param server
* {@link MBeanServer}
*/
private void mbeanServerAdded(MBeanServer server) {
if (null == server) {
return;
}
if (CollectionUtils.isNotEmpty(mBeanServerListeners)) {
for (IMBeanServerListener listener : mBeanServerListeners) {
listener.mbeanServerAdded(server);
}
}
}
/**
* Informs {@link #mBeanServerListeners} that server has been removed.
*
* @param server
* {@link MBeanServer}
*/
private void mbeanServerRemoved(MBeanServer server) {
if (null == server) {
return;
}
if (CollectionUtils.isNotEmpty(mBeanServerListeners)) {
for (IMBeanServerListener listener : mBeanServerListeners) {
listener.mbeanServerRemoved(server);
}
}
}
}