SOLR-2623 -- Solr JMX MBeans do not survive core reloads

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1145518 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shalin Shekhar Mangar 2011-07-12 10:04:35 +00:00
parent 52649534ac
commit e6dcad7e98
6 changed files with 46 additions and 21 deletions

View File

@ -351,6 +351,8 @@ Bug Fixes
initializing plugins initializing plugins
(Frank Wesemann, hossman) (Frank Wesemann, hossman)
* SOLR-2623: Solr JMX MBeans do not survive core reloads (Alexey Serba, shalin)
Other Changes Other Changes
---------------------- ----------------------

View File

@ -53,8 +53,11 @@ public class JmxMonitoredMap<K, V> extends
private String jmxRootName; private String jmxRootName;
public JmxMonitoredMap(final String coreName, private String coreHashCode;
public JmxMonitoredMap(String coreName, String coreHashCode,
final JmxConfiguration jmxConfig) { final JmxConfiguration jmxConfig) {
this.coreHashCode = coreHashCode;
jmxRootName = (null != jmxConfig.rootName ? jmxRootName = (null != jmxConfig.rootName ?
jmxConfig.rootName jmxConfig.rootName
: ("solr" + (null != coreName ? "/" + coreName : ""))); : ("solr" + (null != coreName ? "/" + coreName : "")));
@ -129,7 +132,7 @@ public class JmxMonitoredMap<K, V> extends
ObjectName name = getObjectName(key, infoBean); ObjectName name = getObjectName(key, infoBean);
if (server.isRegistered(name)) if (server.isRegistered(name))
server.unregisterMBean(name); server.unregisterMBean(name);
SolrDynamicMBean mbean = new SolrDynamicMBean(infoBean); SolrDynamicMBean mbean = new SolrDynamicMBean(coreHashCode, infoBean);
server.registerMBean(mbean, name); server.registerMBean(mbean, name);
} catch (Exception e) { } catch (Exception e) {
LOG.warn( "Failed to register info bean: " + key, e); LOG.warn( "Failed to register info bean: " + key, e);
@ -164,11 +167,8 @@ public class JmxMonitoredMap<K, V> extends
try { try {
ObjectName name = getObjectName(key, infoBean); ObjectName name = getObjectName(key, infoBean);
if (server.isRegistered(name)) { if (server.isRegistered(name) && coreHashCode.equals(server.getAttribute(name, "coreHashCode"))) {
server.unregisterMBean(name); server.unregisterMBean(name);
} else {
LOG.info("Failed to unregister mbean: " + key
+ " because it was not registered");
} }
} catch (Exception e) { } catch (Exception e) {
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
@ -195,7 +195,9 @@ public class JmxMonitoredMap<K, V> extends
private HashSet<String> staticStats; private HashSet<String> staticStats;
public SolrDynamicMBean(SolrInfoMBean managedResource) { private String coreHashCode;
public SolrDynamicMBean(String coreHashCode, SolrInfoMBean managedResource) {
this.infoBean = managedResource; this.infoBean = managedResource;
staticStats = new HashSet<String>(); staticStats = new HashSet<String>();
@ -206,6 +208,7 @@ public class JmxMonitoredMap<K, V> extends
staticStats.add("category"); staticStats.add("category");
staticStats.add("sourceId"); staticStats.add("sourceId");
staticStats.add("source"); staticStats.add("source");
this.coreHashCode = coreHashCode;
} }
public MBeanInfo getMBeanInfo() { public MBeanInfo getMBeanInfo() {
@ -216,6 +219,10 @@ public class JmxMonitoredMap<K, V> extends
null, true, false, false)); null, true, false, false));
} }
// add core's hashcode
attrInfoList.add(new MBeanAttributeInfo("coreHashCode", String.class.getName(),
null, true, false, false));
try { try {
NamedList dynamicStats = infoBean.getStatistics(); NamedList dynamicStats = infoBean.getStatistics();
if (dynamicStats != null) { if (dynamicStats != null) {
@ -240,7 +247,9 @@ public class JmxMonitoredMap<K, V> extends
public Object getAttribute(String attribute) public Object getAttribute(String attribute)
throws AttributeNotFoundException, MBeanException, ReflectionException { throws AttributeNotFoundException, MBeanException, ReflectionException {
Object val; Object val;
if (staticStats.contains(attribute) && attribute != null if ("coreHashCode".equals(attribute)) {
val = coreHashCode;
} else if (staticStats.contains(attribute) && attribute != null
&& attribute.length() > 0) { && attribute.length() > 0) {
try { try {
String getter = "get" + attribute.substring(0, 1).toUpperCase(Locale.ENGLISH) String getter = "get" + attribute.substring(0, 1).toUpperCase(Locale.ENGLISH)

View File

@ -541,7 +541,7 @@ public final class SolrCore implements SolrInfoMBean {
//Initialize JMX //Initialize JMX
if (config.jmxConfig.enabled) { if (config.jmxConfig.enabled) {
infoRegistry = new JmxMonitoredMap<String, SolrInfoMBean>(name, config.jmxConfig); infoRegistry = new JmxMonitoredMap<String, SolrInfoMBean>(name, String.valueOf(this.hashCode()), config.jmxConfig);
} else { } else {
log.info("JMX monitoring not detected for core: " + name); log.info("JMX monitoring not detected for core: " + name);
infoRegistry = new ConcurrentHashMap<String, SolrInfoMBean>(); infoRegistry = new ConcurrentHashMap<String, SolrInfoMBean>();

View File

@ -24,9 +24,7 @@ import org.junit.Test;
import javax.management.*; import javax.management.*;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.util.List; import java.util.*;
import java.util.Set;
import java.util.Hashtable;
/** /**
* Test for JMX Integration * Test for JMX Integration
@ -110,18 +108,34 @@ public class TestJmxIntegration extends AbstractSolrTestCase {
numDocs > oldNumDocs); numDocs > oldNumDocs);
} }
@Test
public void testJmxOnCoreReload() throws Exception {
List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null);
MBeanServer mbeanServer = servers.get(0);
log.info("Servers in testJmxUpdate: " + servers);
log.info(h.getCore().getInfoRegistry().toString());
String coreName = h.getCore().getName();
if (coreName.length() == 0) {
coreName = h.getCoreContainer().getDefaultCoreName().length() > 0 ? h.getCoreContainer().getDefaultCoreName() : "";
}
Set<ObjectInstance> oldBeans = mbeanServer.queryMBeans(null, null);
int oldNumberOfObjects = oldBeans.size();
h.getCoreContainer().reload(coreName);
Set<ObjectInstance> newBeans = mbeanServer.queryMBeans(null, null);
int newNumberOfObjects = newBeans.size();
assertEquals("Number of registered MBeans is not the same after Solr core reload", oldNumberOfObjects, newNumberOfObjects);
}
private ObjectName getObjectName(String key, SolrInfoMBean infoBean) private ObjectName getObjectName(String key, SolrInfoMBean infoBean)
throws MalformedObjectNameException { throws MalformedObjectNameException {
Hashtable<String, String> map = new Hashtable<String, String>(); Hashtable<String, String> map = new Hashtable<String, String>();
map.put("type", key); map.put("type", key);
map.put("id", infoBean.getName()); map.put("id", infoBean.getName());
String coreName = h.getCore().getName(); String coreName = h.getCore().getName();
if (coreName.equals("")) {
String defaultCoreName = h.getCore().getCoreDescriptor().getCoreContainer().getDefaultCoreName();
if (!defaultCoreName.equals("")) {
coreName = defaultCoreName;
}
}
return ObjectName.getInstance(("solr" + (null != coreName ? "/" + coreName : "")), map); return ObjectName.getInstance(("solr" + (null != coreName ? "/" + coreName : "")), map);
} }
} }

View File

@ -72,7 +72,7 @@ public class TestJmxMonitoredMap extends LuceneTestCase {
} }
String url = "service:jmx:rmi:///jndi/rmi://:" + port + "/solrjmx"; String url = "service:jmx:rmi:///jndi/rmi://:" + port + "/solrjmx";
JmxConfiguration config = new JmxConfiguration(true, null, url, null); JmxConfiguration config = new JmxConfiguration(true, null, url, null);
monitoredMap = new JmxMonitoredMap<String, SolrInfoMBean>(null, config); monitoredMap = new JmxMonitoredMap<String, SolrInfoMBean>("", "", config);
JMXServiceURL u = new JMXServiceURL(url); JMXServiceURL u = new JMXServiceURL(url);
connector = JMXConnectorFactory.connect(u); connector = JMXConnectorFactory.connect(u);
mbeanServer = connector.getMBeanServerConnection(); mbeanServer = connector.getMBeanServerConnection();

View File

@ -188,7 +188,7 @@ public class TestHarness {
CoreDescriptor dcore = new CoreDescriptor(container, coreName, solrConfig.getResourceLoader().getInstanceDir()); CoreDescriptor dcore = new CoreDescriptor(container, coreName, solrConfig.getResourceLoader().getInstanceDir());
dcore.setConfigName(solrConfig.getResourceName()); dcore.setConfigName(solrConfig.getResourceName());
dcore.setSchemaName(indexSchema.getResourceName()); dcore.setSchemaName(indexSchema.getResourceName());
SolrCore core = new SolrCore("collection1", dataDirectory, solrConfig, indexSchema, dcore); SolrCore core = new SolrCore(coreName, dataDirectory, solrConfig, indexSchema, dcore);
container.register(coreName, core, false); container.register(coreName, core, false);
return container; return container;