diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 2ec5a2125a2..133fed69085 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -129,6 +129,9 @@ New Features * SOLR-1871: The 'map' function query accepts a ValueSource as target and default value. (Chris Harris, shalin) +* SOLR-5556: Allow class of CollectionsHandler and InfoHandler to be specified + in solr.xml. (Gregory Chanan, Alan Woodward) + Bug Fixes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSolr.java b/solr/core/src/java/org/apache/solr/core/ConfigSolr.java index 45ffb1638bb..78f70d0a066 100644 --- a/solr/core/src/java/org/apache/solr/core/ConfigSolr.java +++ b/solr/core/src/java/org/apache/solr/core/ConfigSolr.java @@ -187,6 +187,14 @@ public abstract class ConfigSolr { return get(CfgProp.SOLR_ADMINHANDLER, "org.apache.solr.handler.admin.CoreAdminHandler"); } + public String getCollectionsHandlerClass() { + return get(CfgProp.SOLR_COLLECTIONSHANDLER, "org.apache.solr.handler.admin.CollectionsHandler"); + } + + public String getInfoHandlerClass() { + return get(CfgProp.SOLR_INFOHANDLER, "org.apache.solr.handler.admin.InfoHandler"); + } + public boolean hasSchemaCache() { return getBool(ConfigSolr.CfgProp.SOLR_SHARESCHEMA, false); } @@ -211,6 +219,7 @@ public abstract class ConfigSolr { // Ugly for now, but we'll at least be able to centralize all of the differences between 4x and 5x. protected static enum CfgProp { SOLR_ADMINHANDLER, + SOLR_COLLECTIONSHANDLER, SOLR_CORELOADTHREADS, SOLR_COREROOTDIRECTORY, SOLR_DISTRIBUPDATECONNTIMEOUT, @@ -220,6 +229,7 @@ public abstract class ConfigSolr { SOLR_HOST, SOLR_HOSTCONTEXT, SOLR_HOSTPORT, + SOLR_INFOHANDLER, SOLR_LEADERVOTEWAIT, SOLR_LOGGING_CLASS, SOLR_LOGGING_ENABLED, diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java b/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java index f4186a51c14..35b7e5e8b6f 100644 --- a/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java +++ b/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java @@ -103,6 +103,8 @@ public class ConfigSolrXml extends ConfigSolr { private void fillPropMap() { propMap.put(CfgProp.SOLR_ADMINHANDLER, doSub("solr/str[@name='adminHandler']")); + propMap.put(CfgProp.SOLR_COLLECTIONSHANDLER, doSub("solr/str[@name='collectionsHandler']")); + propMap.put(CfgProp.SOLR_INFOHANDLER, doSub("solr/str[@name='infoHandler']")); propMap.put(CfgProp.SOLR_CORELOADTHREADS, doSub("solr/int[@name='coreLoadThreads']")); propMap.put(CfgProp.SOLR_COREROOTDIRECTORY, doSub("solr/str[@name='coreRootDirectory']")); propMap.put(CfgProp.SOLR_DISTRIBUPDATECONNTIMEOUT, doSub("solr/solrcloud/int[@name='distribUpdateConnTimeout']")); diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java b/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java index d18445fcef0..f33bf620327 100644 --- a/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java +++ b/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java @@ -141,6 +141,8 @@ public class ConfigSolrXmlOld extends ConfigSolr { propMap.put(CfgProp.SOLR_ADMINHANDLER, config.getVal("solr/cores/@adminHandler", false)); + propMap.put(CfgProp.SOLR_COLLECTIONSHANDLER, config.getVal("solr/cores/@collectionsHandler", false)); + propMap.put(CfgProp.SOLR_INFOHANDLER, config.getVal("solr/cores/@infoHandler", false)); propMap.put(CfgProp.SOLR_DISTRIBUPDATECONNTIMEOUT, config.getVal("solr/cores/@distribUpdateConnTimeout", false)); propMap.put(CfgProp.SOLR_DISTRIBUPDATESOTIMEOUT, diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java index 20b8e5dd3ee..c088a5214ee 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -214,9 +214,9 @@ public class CoreContainer { zkSys.initZooKeeper(this, solrHome, cfg); - collectionsHandler = new CollectionsHandler(this); - infoHandler = new InfoHandler(this); - coreAdminHandler = createMultiCoreHandler(cfg.getCoreAdminHandlerClass()); + collectionsHandler = createHandler(cfg.getCollectionsHandlerClass(), CollectionsHandler.class); + infoHandler = createHandler(cfg.getInfoHandlerClass(), InfoHandler.class); + coreAdminHandler = createHandler(cfg.getCoreAdminHandlerClass(), CoreAdminHandler.class); containerProperties = cfg.getSolrProperties("solr"); @@ -778,10 +778,10 @@ public class CoreContainer { return null; } - /** + /** * Gets a core by name and increase its refcount. * - * @see SolrCore#close() + * @see SolrCore#close() * @param name the core name * @return the core if found, null if a SolrCore by this name does not exist * @exception SolrException if a SolrCore with this name failed to be initialized @@ -800,7 +800,7 @@ public class CoreContainer { // OK, it's not presently in any list, is it in the list of dynamic cores but not loaded yet? If so, load it. CoreDescriptor desc = solrCores.getDynamicDescriptor(name); if (desc == null) { //Nope, no transient core with this name - + // if there was an error initalizing this core, throw a 500 // error with the details for clients attempting to access it. Exception e = getCoreInitFailures().get(name); @@ -831,7 +831,7 @@ public class CoreContainer { } } catch(Exception ex){ // remains to be seen how transient cores and such - // will work in SolrCloud mode, but just to be future + // will work in SolrCloud mode, but just to be future // proof... /*if (isZooKeeperAware()) { try { @@ -851,34 +851,33 @@ public class CoreContainer { return core; } - // ---------------- Multicore self related methods --------------- - /** - * Creates a CoreAdminHandler for this MultiCore. - * @return a CoreAdminHandler - */ - protected CoreAdminHandler createMultiCoreHandler(final String adminHandlerClass) { - return loader.newAdminHandlerInstance(CoreContainer.this, adminHandlerClass); + // ---------------- CoreContainer request handlers -------------- + + protected T createHandler(String handlerClass, Class clazz) { + return loader.newInstance(handlerClass, clazz, null, new Class[] { CoreContainer.class }, new Object[] { this }); } public CoreAdminHandler getMultiCoreHandler() { return coreAdminHandler; } - + public CollectionsHandler getCollectionsHandler() { return collectionsHandler; } - + public InfoHandler getInfoHandler() { return infoHandler; } + // ---------------- Multicore self related methods --------------- + /** * the default core name, or null if there is no default core name */ public String getDefaultCoreName() { return cfg.getDefaultCoreName(); } - + // all of the following properties aren't synchronized // but this should be OK since they normally won't be changed rapidly @Deprecated diff --git a/solr/core/src/test-files/solr/solr-50-all.xml b/solr/core/src/test-files/solr/solr-50-all.xml index cb6646abdae..32e52fb0028 100644 --- a/solr/core/src/test-files/solr/solr-50-all.xml +++ b/solr/core/src/test-files/solr/solr-50-all.xml @@ -17,8 +17,10 @@ testAdminHandler + testCollectionsHandler 11 ${coreRootDirectory:testCoreRootDirectory} + testInfoHandler testManagementPath testSharedLib ${shareSchema:testShareSchema} diff --git a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java index 5679943c24a..1e62d639b59 100644 --- a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java +++ b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java @@ -21,6 +21,9 @@ import org.apache.commons.io.FileUtils; import org.apache.lucene.util.IOUtils; import org.apache.lucene.util._TestUtil; import org.apache.solr.SolrTestCaseJ4; +import org.apache.solr.handler.admin.CollectionsHandler; +import org.apache.solr.handler.admin.CoreAdminHandler; +import org.apache.solr.handler.admin.InfoHandler; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -37,6 +40,9 @@ import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; +import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.IsInstanceOf.instanceOf; + public class TestCoreContainer extends SolrTestCaseJ4 { private static String oldSolrHome; @@ -287,4 +293,48 @@ public class TestCoreContainer extends SolrTestCaseJ4 { private static final String EMPTY_SOLR_XML2 ="\n" + "\n" + ""; + + private static final String CUSTOM_HANDLERS_SOLR_XML = "\n" + + "" + + " " + CustomCollectionsHandler.class.getName() + "" + + " " + CustomInfoHandler.class.getName() + "" + + " " + CustomCoreAdminHandler.class.getName() + "" + + ""; + + public static class CustomCollectionsHandler extends CollectionsHandler { + public CustomCollectionsHandler(CoreContainer cc) { + super(cc); + } + } + + public static class CustomInfoHandler extends InfoHandler { + public CustomInfoHandler(CoreContainer cc) { + super(cc); + } + } + + public static class CustomCoreAdminHandler extends CoreAdminHandler { + public CustomCoreAdminHandler(CoreContainer cc) { + super(cc); + } + } + + @Test + public void testCustomHandlers() throws Exception { + + ConfigSolr config = ConfigSolr.fromString(CUSTOM_HANDLERS_SOLR_XML); + SolrResourceLoader loader = new SolrResourceLoader("solr/collection1"); + + CoreContainer cc = new CoreContainer(loader, config); + try { + cc.load(); + assertThat(cc.getCollectionsHandler(), is(instanceOf(CustomCollectionsHandler.class))); + assertThat(cc.getInfoHandler(), is(instanceOf(CustomInfoHandler.class))); + assertThat(cc.getMultiCoreHandler(), is(instanceOf(CustomCoreAdminHandler.class))); + } + finally { + cc.shutdown(); + } + + } } diff --git a/solr/core/src/test/org/apache/solr/core/TestSolrXml.java b/solr/core/src/test/org/apache/solr/core/TestSolrXml.java index 566749a3749..b70c52da7b6 100644 --- a/solr/core/src/test/org/apache/solr/core/TestSolrXml.java +++ b/solr/core/src/test/org/apache/solr/core/TestSolrXml.java @@ -47,6 +47,8 @@ public class TestSolrXml extends SolrTestCaseJ4 { ConfigSolr cfg = ConfigSolr.fromSolrHome(loader, solrHome.getAbsolutePath()); assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_ADMINHANDLER, null), "testAdminHandler"); + assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_COLLECTIONSHANDLER, null), "testCollectionsHandler"); + assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_INFOHANDLER, null), "testInfoHandler"); assertEquals("Did not find expected value", cfg.getInt(ConfigSolr.CfgProp.SOLR_CORELOADTHREADS, 0), 11); assertEquals("Did not find expected value", cfg.get(ConfigSolr.CfgProp.SOLR_COREROOTDIRECTORY, null), "testCoreRootDirectory"); assertEquals("Did not find expected value", cfg.getInt(ConfigSolr.CfgProp.SOLR_DISTRIBUPDATECONNTIMEOUT, 0), 22);