diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index a836e4e5e7d..66fa150afec 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -267,6 +267,9 @@ Other Changes * SOLR-4839: Upgrade Jetty to 9.2.10.v20150310 and restlet-jee to 2.3.0 (Bill Bell, Timothy Potter, Uwe Schindler, Mark Miller, shalin) +* SOLR-7457: Make DirectoryFactory publishing MBeanInfo extensible. + (Mike Drob via Mark Miller) + ================== 5.1.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release diff --git a/solr/core/src/java/org/apache/solr/core/DirectoryFactory.java b/solr/core/src/java/org/apache/solr/core/DirectoryFactory.java index 9fd3c070d2a..d889d1ae364 100644 --- a/solr/core/src/java/org/apache/solr/core/DirectoryFactory.java +++ b/solr/core/src/java/org/apache/solr/core/DirectoryFactory.java @@ -19,9 +19,9 @@ package org.apache.solr.core; import java.io.Closeable; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.file.NoSuchFileException; +import java.util.Collection; +import java.util.Collections; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FlushInfo; @@ -264,4 +264,11 @@ public abstract class DirectoryFactory implements NamedListInitializedPlugin, String instanceDir = new File(cd.getInstanceDir()).getAbsolutePath(); return normalize(SolrResourceLoader.normalizeDir(instanceDir) + cd.getDataDir()); } + + /** + * Optionally allow the DirectoryFactory to request registration of some MBeans. + */ + public Collection offerMBeans() { + return Collections.emptySet(); + } } diff --git a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java index 1b1365a3249..42f29cc4f2f 100644 --- a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java +++ b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java @@ -20,8 +20,8 @@ package org.apache.solr.core; import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION; import java.io.IOException; -import java.net.URL; import java.net.URLEncoder; +import java.util.Arrays; import java.util.Collection; import java.util.Locale; import java.util.concurrent.Callable; @@ -59,7 +59,7 @@ import com.google.common.cache.CacheBuilder; import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalNotification; -public class HdfsDirectoryFactory extends CachingDirectoryFactory implements SolrInfoMBean { +public class HdfsDirectoryFactory extends CachingDirectoryFactory { public static Logger LOG = LoggerFactory .getLogger(HdfsDirectoryFactory.class); @@ -438,44 +438,8 @@ public class HdfsDirectoryFactory extends CachingDirectoryFactory implements Sol } } - // SolrInfoMBean methods - @Override - public String getName() { - return getClass().getSimpleName() + "BlockCache"; - } - - @Override - public String getVersion() { - return SolrCore.version; - } - - @Override - public String getDescription() { - return "Provides metrics for the HdfsDirectoryFactory BlockCache."; - } - - @Override - public Category getCategory() { - return Category.CACHE; - } - - @Override - public String getSource() { - return null; - } - - @Override - public URL[] getDocs() { - return null; - } - - @Override - public NamedList getStatistics() { - if (metrics == null) { - return new NamedList(); - } - - return metrics.getStatistics(); + public Collection offerMBeans() { + return Arrays.asList(MetricsHolder.metrics); } } 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 7736cb4d18d..09a1a202c7b 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -830,6 +830,17 @@ public final class SolrCore implements SolrInfoMBean, Closeable { // from the core. resourceLoader.inform(infoRegistry); + // Allow the directory factory to register MBeans as well + for (SolrInfoMBean bean : directoryFactory.offerMBeans()) { + log.debug("Registering JMX bean [{}] from directory factory.", bean.getName()); + // Not worried about concurrency, so no reason to use putIfAbsent + if (infoRegistry.containsKey(bean.getName())){ + log.info("Ignoring JMX bean [{}] due to name conflict.", bean.getName()); + } else { + infoRegistry.put(bean.getName(), bean); + } + } + bufferUpdatesIfConstructing(coreDescriptor); // For debugging diff --git a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java index c9ab33c618e..bfe4105b022 100644 --- a/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java +++ b/solr/core/src/java/org/apache/solr/store/blockcache/Metrics.java @@ -17,12 +17,15 @@ package org.apache.solr.store.blockcache; * limitations under the License. */ +import java.net.URL; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrInfoMBean; import org.apache.solr.search.SolrCacheBase; @@ -31,7 +34,7 @@ import org.apache.solr.search.SolrCacheBase; * * @lucene.experimental */ -public class Metrics extends SolrCacheBase { +public class Metrics extends SolrCacheBase implements SolrInfoMBean { public static class MethodCall { public AtomicLong invokes = new AtomicLong(); @@ -75,7 +78,7 @@ public class Metrics extends SolrCacheBase { } public NamedList getStatistics() { - NamedList stats = new NamedList(); + NamedList stats = new SimpleOrderedMap<>(21); // room for one method call before growing long now = System.nanoTime(); float seconds = (now - previous) / 1000000000.0f; @@ -120,4 +123,26 @@ public class Metrics extends SolrCacheBase { private float getPerSecond(long value, float seconds) { return (float) (value / seconds); } + + // SolrInfoMBean methods + + @Override + public String getName() { + return "HdfsBlockCache"; + } + + @Override + public String getDescription() { + return "Provides metrics for the HdfsDirectoryFactory BlockCache."; + } + + @Override + public String getSource() { + return null; + } + + @Override + public URL[] getDocs() { + return null; + } }