![JAR search and dependency download from the Maven repository](/logo.png)
org.echocat.jemoni.jmx.JmxRegistry Maven / Gradle / Ivy
/*****************************************************************************************
* *** BEGIN LICENSE BLOCK *****
*
* Version: MPL 2.0
*
* echocat JeMoni, Copyright (c) 2012-2013 echocat
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* *** END LICENSE BLOCK *****
****************************************************************************************/
package org.echocat.jemoni.jmx;
import org.echocat.jemoni.jmx.Registration.Handler;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.management.*;
import java.lang.management.ManagementFactory;
import static org.apache.commons.lang3.StringUtils.isEmpty;
public class JmxRegistry {
private static final JmxRegistry LOCAL_INSTANCE = new JmxRegistry();
@Nonnull
public static JmxRegistry getLocalInstance() {
return LOCAL_INSTANCE;
}
private final RegistrationHandler _handler = new RegistrationHandler();
private final MBeanServer _server;
private BeanFacadeFactory _beanFacadeFactory = new BeanFacadeFactory();
public JmxRegistry() {
this(ManagementFactory.getPlatformMBeanServer());
}
public JmxRegistry(MBeanServer server) {
_server = server;
}
@Nonnull
public MBeanServer getServer() {
return _server;
}
@Nonnull
public BeanFacadeFactory getBeanFacadeFactory() {
return _beanFacadeFactory;
}
public void setBeanFacadeFactory(@Nonnull BeanFacadeFactory beanFacadeFactory) {
// noinspection ObjectEquality
if (this == LOCAL_INSTANCE) {
throw new IllegalStateException("Modification of the local instance of " + JmxRegistry.class.getName() + " is not supported.");
}
_beanFacadeFactory = beanFacadeFactory;
}
@Nonnull
public Registration register(@Nonnull DynamicMBean bean, @Nonnull ObjectName withName) throws InstanceAlreadyExistsException {
try {
_server.registerMBean(bean, withName);
} catch (MBeanRegistrationException | NotCompliantMBeanException e) {
throw new RuntimeException("Could not register " + bean + " at " + _server + ".", e);
}
return new Registration(withName, bean, _handler);
}
@Nonnull
public Registration register(@Nonnull DynamicMBean bean, @Nonnull Class> forType) {
return register(bean, forType, null);
}
@Nonnull
public Registration register(@Nonnull DynamicMBean bean, @Nonnull Class> forType, @Nullable String variant) {
Registration result = null;
long instance = 0;
do {
try {
final ObjectName objectName = getObjectNameFor(forType, instance > 0 ? Long.toString(instance) : null, variant);
result = register(bean, objectName);
} catch (InstanceAlreadyExistsException ignored) {
instance++;
}
} while (result == null);
return result;
}
@Nonnull
public RegistrationWithFacade register(@Nonnull B bean, @Nonnull ObjectName withName) throws InstanceAlreadyExistsException {
final BeanFacade facade = _beanFacadeFactory.createFor(bean);
register(facade, withName);
return new RegistrationWithFacade<>(withName, facade, _handler);
}
@Nonnull
public RegistrationWithFacade register(@Nonnull B bean, @Nullable String variant) {
RegistrationWithFacade result = null;
long instance = 0;
do {
try {
final ObjectName objectName = getObjectNameFor(bean.getClass(), instance > 0 ? Long.toString(instance) : null, variant);
result = register(bean, objectName);
} catch (InstanceAlreadyExistsException ignored) {
instance++;
}
} while (result == null);
return result;
}
@Nonnull
public RegistrationWithFacade register(@Nonnull B bean) {
return register(bean, (String) null);
}
@Nonnull
public ObjectName getObjectNameFor(@Nonnull Class> type, @Nullable String instance, @Nullable String variant) {
final StringBuilder sb = new StringBuilder();
final Package aPackage = type.getPackage();
final String packageName = aPackage != null ? aPackage.getName() : null;
final String typeName = type.getName();
if (!isEmpty(packageName)) {
sb.append(packageName);
sb.append(!isEmpty(variant) ? ":type=" : ":name=");
sb.append(typeName.substring(packageName.length() + 1));
} else {
sb.append("_");
sb.append(!isEmpty(variant) ? ":type=" : ":name=");
sb.append(typeName);
}
if (!isEmpty(instance)) {
sb.append('.').append(normalize(instance));
}
if (!isEmpty(variant)) {
sb.append(",name=").append(normalize(variant));
}
try {
return new ObjectName(sb.toString());
} catch (MalformedObjectNameException e) {
throw new IllegalArgumentException("Could not create a valid object name for " + typeName + " and variant '" + variant + "'.", e);
}
}
@Nonnull
public T getMBeanProxy(@Nonnull String mbeanName, @Nonnull Class mbeanInterface) {
try {
return getMBeanProxy(new ObjectName(mbeanName), mbeanInterface);
} catch (MalformedObjectNameException e) {
throw new IllegalArgumentException("Could not create object name for " + mbeanName + ".", e);
}
}
@Nonnull
public T getMBeanProxy(@Nonnull ObjectName objectName, @Nonnull Class mbeanInterface) {
try {
final boolean emitter = getServer().isInstanceOf(objectName, NotificationEmitter.class.getName());
// create an MXBean proxy
return JMX.newMXBeanProxy(getServer(), objectName, mbeanInterface, emitter);
} catch (Exception e) {
throw new RuntimeException("Could not create mbean proxy for " + objectName + ".", e);
}
}
@Nonnull
public T getMBeanProxy(@Nonnull Class mbeanInterface, @Nonnull String instance) {
final ObjectName objectName = getObjectNameFor(mbeanInterface, instance, null);
return getMBeanProxy(objectName, mbeanInterface);
}
@Nonnull
protected String normalize(@Nonnull String what) {
final char[] in = what.toCharArray();
final char[] out = new char[in.length];
int i = 0;
for (char c : in) {
if (Character.isLetterOrDigit(c) || c == '_' || c == '-' || c == '.') {
out[i++] = c;
} else if (Character.isWhitespace(c)) {
out[i++] = '_';
}
}
return new String(out, 0, i);
}
public class RegistrationHandler implements Handler {
@Override
public void unregister(@Nonnull Registration registration) throws Exception {
try {
_server.unregisterMBean(registration.getObjectName());
} catch (InstanceNotFoundException ignored) {}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy