diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 61f80061b29..0b61f717b82 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -351,6 +351,8 @@ Bug Fixes initializing plugins (Frank Wesemann, hossman) +* SOLR-2623: Solr JMX MBeans do not survive core reloads (Alexey Serba, shalin) + Other Changes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java b/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java index 823dd9c0f2b..83abbefb5eb 100644 --- a/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java +++ b/solr/core/src/java/org/apache/solr/core/JmxMonitoredMap.java @@ -53,9 +53,12 @@ public class JmxMonitoredMap extends private String jmxRootName; - public JmxMonitoredMap(final String coreName, + private String coreHashCode; + + public JmxMonitoredMap(String coreName, String coreHashCode, final JmxConfiguration jmxConfig) { - jmxRootName = (null != jmxConfig.rootName ? + this.coreHashCode = coreHashCode; + jmxRootName = (null != jmxConfig.rootName ? jmxConfig.rootName : ("solr" + (null != coreName ? "/" + coreName : ""))); @@ -129,7 +132,7 @@ public class JmxMonitoredMap extends ObjectName name = getObjectName(key, infoBean); if (server.isRegistered(name)) server.unregisterMBean(name); - SolrDynamicMBean mbean = new SolrDynamicMBean(infoBean); + SolrDynamicMBean mbean = new SolrDynamicMBean(coreHashCode, infoBean); server.registerMBean(mbean, name); } catch (Exception e) { LOG.warn( "Failed to register info bean: " + key, e); @@ -164,11 +167,8 @@ public class JmxMonitoredMap extends try { ObjectName name = getObjectName(key, infoBean); - if (server.isRegistered(name)) { + if (server.isRegistered(name) && coreHashCode.equals(server.getAttribute(name, "coreHashCode"))) { server.unregisterMBean(name); - } else { - LOG.info("Failed to unregister mbean: " + key - + " because it was not registered"); } } catch (Exception e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, @@ -195,7 +195,9 @@ public class JmxMonitoredMap extends private HashSet staticStats; - public SolrDynamicMBean(SolrInfoMBean managedResource) { + private String coreHashCode; + + public SolrDynamicMBean(String coreHashCode, SolrInfoMBean managedResource) { this.infoBean = managedResource; staticStats = new HashSet(); @@ -206,6 +208,7 @@ public class JmxMonitoredMap extends staticStats.add("category"); staticStats.add("sourceId"); staticStats.add("source"); + this.coreHashCode = coreHashCode; } public MBeanInfo getMBeanInfo() { @@ -216,6 +219,10 @@ public class JmxMonitoredMap extends null, true, false, false)); } + // add core's hashcode + attrInfoList.add(new MBeanAttributeInfo("coreHashCode", String.class.getName(), + null, true, false, false)); + try { NamedList dynamicStats = infoBean.getStatistics(); if (dynamicStats != null) { @@ -240,7 +247,9 @@ public class JmxMonitoredMap extends public Object getAttribute(String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException { Object val; - if (staticStats.contains(attribute) && attribute != null + if ("coreHashCode".equals(attribute)) { + val = coreHashCode; + } else if (staticStats.contains(attribute) && attribute != null && attribute.length() > 0) { try { String getter = "get" + attribute.substring(0, 1).toUpperCase(Locale.ENGLISH) diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java index de6837122c0..6d0edd171a8 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -541,7 +541,7 @@ public final class SolrCore implements SolrInfoMBean { //Initialize JMX if (config.jmxConfig.enabled) { - infoRegistry = new JmxMonitoredMap(name, config.jmxConfig); + infoRegistry = new JmxMonitoredMap(name, String.valueOf(this.hashCode()), config.jmxConfig); } else { log.info("JMX monitoring not detected for core: " + name); infoRegistry = new ConcurrentHashMap(); diff --git a/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java b/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java index 9e27ddc1370..f62fd2bf4b6 100644 --- a/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java +++ b/solr/core/src/test/org/apache/solr/core/TestJmxIntegration.java @@ -24,9 +24,7 @@ import org.junit.Test; import javax.management.*; import java.lang.management.ManagementFactory; -import java.util.List; -import java.util.Set; -import java.util.Hashtable; +import java.util.*; /** * Test for JMX Integration @@ -110,18 +108,34 @@ public class TestJmxIntegration extends AbstractSolrTestCase { numDocs > oldNumDocs); } + @Test + public void testJmxOnCoreReload() throws Exception { + List 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 oldBeans = mbeanServer.queryMBeans(null, null); + int oldNumberOfObjects = oldBeans.size(); + h.getCoreContainer().reload(coreName); + + Set 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) throws MalformedObjectNameException { Hashtable map = new Hashtable(); map.put("type", key); map.put("id", infoBean.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); } } diff --git a/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java b/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java index e69e074fbbc..6e4d781cdd6 100644 --- a/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java +++ b/solr/core/src/test/org/apache/solr/core/TestJmxMonitoredMap.java @@ -72,7 +72,7 @@ public class TestJmxMonitoredMap extends LuceneTestCase { } String url = "service:jmx:rmi:///jndi/rmi://:" + port + "/solrjmx"; JmxConfiguration config = new JmxConfiguration(true, null, url, null); - monitoredMap = new JmxMonitoredMap(null, config); + monitoredMap = new JmxMonitoredMap("", "", config); JMXServiceURL u = new JMXServiceURL(url); connector = JMXConnectorFactory.connect(u); mbeanServer = connector.getMBeanServerConnection(); diff --git a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java index 59f0f40082c..47908b01907 100644 --- a/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java +++ b/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java @@ -188,7 +188,7 @@ public class TestHarness { CoreDescriptor dcore = new CoreDescriptor(container, coreName, solrConfig.getResourceLoader().getInstanceDir()); dcore.setConfigName(solrConfig.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); return container;