org.infinispan.jmx.CacheJmxRegistration Maven / Gradle / Ivy
package org.infinispan.jmx;
import java.util.HashSet;
import java.util.Set;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import org.infinispan.AdvancedCache;
import org.infinispan.Cache;
import org.infinispan.commons.CacheException;
import org.infinispan.commons.api.BasicCacheContainer;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.factories.AbstractComponentRegistry;
import org.infinispan.factories.AbstractComponentRegistry.Component;
import org.infinispan.factories.GlobalComponentRegistry;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.annotations.Start;
import org.infinispan.factories.annotations.Stop;
import org.infinispan.factories.annotations.SurvivesRestarts;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
/**
* If {@link org.infinispan.configuration.cache.Configuration#jmxStatistics()} is enabled, then class will register all
* the MBeans from cache local's ConfigurationRegistry to the MBean server.
*
* @author [email protected]
* @author Galder Zamarreño
* @see java.lang.management.ManagementFactory#getPlatformMBeanServer()
* @since 4.0
*/
@SurvivesRestarts
public class CacheJmxRegistration extends AbstractJmxRegistration {
private static final Log log = LogFactory.getLog(CacheJmxRegistration.class);
public static final String CACHE_JMX_GROUP = "type=Cache";
private AdvancedCache, ?> cache;
private Set nonCacheComponents;
private boolean needToUnregister = false;
private volatile boolean unregisterCacheMBean;
@Inject
public void initialize(Cache, ?> cache, GlobalConfiguration globalConfig) {
this.cache = cache.getAdvancedCache();
this.globalConfig = globalConfig;
}
/**
* Here is where the registration is being performed.
*/
@Start(priority = 14)
public void start() {
if (cache == null)
throw new IllegalStateException("The cache should had been injected before a call to this method");
Set components = cache.getComponentRegistry().getRegisteredComponents();
nonCacheComponents = getNonCacheComponents(components);
if (registerMBeans(components, cache.getCacheManager().getCacheManagerConfiguration())) {
needToUnregister = true;
log.mbeansSuccessfullyRegistered();
} else {
if (cache.getName().equals(BasicCacheContainer.DEFAULT_CACHE_NAME)) {
log.unableToRegisterMBeans();
} else {
log.unableToRegisterMBeans(cache.getName());
}
}
}
/**
* Unregister when the cache is being stopped.
*/
@Stop
public void stop() {
// This method might get called several times.
// After the first call the cache will become null, so we guard this
if (cache == null) return;
if (needToUnregister) {
// Only unregister the non cache MBean so that it can be restarted
try {
unregisterMBeans(nonCacheComponents);
needToUnregister = false;
} catch (Exception e) {
log.problemsUnregisteringMBeans(e);
}
}
// If removing cache, also remove cache MBean
if (unregisterCacheMBean)
unregisterCacheMBean();
// make sure we don't set cache to null, in case it needs to be restarted via JMX.
}
public void unregisterCacheMBean() {
if (mBeanServer != null) {
String groupName = CACHE_JMX_GROUP + "," + getCacheJmxName() + ",manager=" + ObjectName.quote(globalConfig.globalJmxStatistics().cacheManagerName());
String pattern = jmxDomain + ":" + groupName + ",*";
try {
Set names = SecurityActions.queryNames(new ObjectName(pattern), null, mBeanServer);
for (ObjectName name : names) {
JmxUtil.unregisterMBean(name, mBeanServer);
}
} catch (MBeanRegistrationException e) {
log.unableToUnregisterMBeanWithPattern(pattern, e);
} catch (InstanceNotFoundException e) {
// Ignore if Cache MBeans not present
} catch (MalformedObjectNameException e) {
String message = "Malformed pattern " + pattern;
throw new CacheException(message, e);
} catch (Exception e) {
throw new CacheException(e);
}
}
}
public void setUnregisterCacheMBean(boolean unregisterCacheMBean) {
this.unregisterCacheMBean = unregisterCacheMBean;
}
@Override
protected ComponentsJmxRegistration buildRegistrar(Set components) {
// Quote group name, to handle invalid ObjectName characters
String groupName = CACHE_JMX_GROUP + "," + getCacheJmxName() + ",manager=" + ObjectName.quote(globalConfig.globalJmxStatistics().cacheManagerName());
ComponentsJmxRegistration registrar = new ComponentsJmxRegistration(mBeanServer, components, groupName);
updateDomain(registrar, cache.getComponentRegistry().getGlobalComponentRegistry(), mBeanServer, groupName);
return registrar;
}
private String getCacheJmxName() {
return ComponentsJmxRegistration.NAME_KEY + "="
+ ObjectName.quote(cache.getName() + "(" + cache.getCacheConfiguration().clustering().cacheModeString().toLowerCase() + ")");
}
protected void updateDomain(ComponentsJmxRegistration registrar, GlobalComponentRegistry componentRegistry,
MBeanServer mBeanServer, String groupName) {
CacheManagerJmxRegistration managerJmxReg = componentRegistry.getComponent(CacheManagerJmxRegistration.class);
if (!globalConfig.globalJmxStatistics().enabled() && jmxDomain == null) {
String tmpJmxDomain = JmxUtil.buildJmxDomain(globalConfig, mBeanServer, groupName);
synchronized (managerJmxReg) {
if (managerJmxReg.jmxDomain == null) {
if (!tmpJmxDomain.equals(globalConfig.globalJmxStatistics().domain()) && !globalConfig.globalJmxStatistics().allowDuplicateDomains()) {
throw log.jmxMBeanAlreadyRegistered(tmpJmxDomain, globalConfig.globalJmxStatistics().domain());
}
// Set manager component's jmx domain so that other caches under same manager
// can see it, particularly important when jmx is only enabled at the cache level
managerJmxReg.jmxDomain = tmpJmxDomain;
}
// So that all caches share the same domain, regardless of whether dups are
// allowed or not, simply assign the manager's calculated jmxDomain
jmxDomain = managerJmxReg.jmxDomain;
}
} else {
// If global stats were enabled, manager's jmxDomain would have been populated
// when cache manager was started, so no need for synchronization here.
jmxDomain = managerJmxReg.jmxDomain == null ? globalConfig.globalJmxStatistics().domain() : managerJmxReg.jmxDomain;
}
registrar.setJmxDomain(jmxDomain);
}
protected Set getNonCacheComponents(Set components) {
Set componentsExceptCache = new HashSet(64);
for (AbstractComponentRegistry.Component component : components) {
String name = component.getName();
if (!name.equals(Cache.class.getName()) && !name.equals(AdvancedCache.class.getName())) {
componentsExceptCache.add(component);
}
}
return componentsExceptCache;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy