Skip to content

Commit

Permalink
SOLR-16959: Make CoresContainer class configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
Vincent Primault committed Sep 4, 2023
1 parent 931de51 commit fe87566
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 4 deletions.
11 changes: 7 additions & 4 deletions solr/core/src/java/org/apache/solr/core/CoreContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -377,21 +377,24 @@ public CoreContainer(Path solrHome, Properties properties) {
* @see #load()
*/
public CoreContainer(NodeConfig config) {
this(config, new CorePropertiesLocator(config.getCoreRootDirectory()));
this(config, CoresLocator.instantiate(config));
}

public CoreContainer(NodeConfig config, boolean asyncSolrCoreLoad) {
this(config, new CorePropertiesLocator(config.getCoreRootDirectory()), asyncSolrCoreLoad);
this(config, CoresLocator.instantiate(config), asyncSolrCoreLoad);
}

/**
* Create a new CoreContainer using the given configuration and locator. The container's cores are
* not loaded.
* Create a new CoreContainer using the given configuration and locator.
*
* <p>The container's cores are not loaded. This constructor should be used only in tests, as it
* overrides {@link CoresLocator}'s instantiation process.
*
* @param config a ConfigSolr representation of this container's configuration
* @param locator a CoresLocator
* @see #load()
*/
@VisibleForTesting
public CoreContainer(NodeConfig config, CoresLocator locator) {
this(config, locator, false);
}
Expand Down
23 changes: 23 additions & 0 deletions solr/core/src/java/org/apache/solr/core/CoresLocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package org.apache.solr.core;

import java.lang.reflect.Constructor;
import java.util.List;

/** Manage the discovery and persistence of core definitions across Solr restarts */
Expand Down Expand Up @@ -72,4 +73,26 @@ public interface CoresLocator {
* @return a list of all CoreDescriptors found
*/
public List<CoreDescriptor> discover(CoreContainer cc);

/**
* Returns a new instance of {@link CoresLocator}, depending on provided config.
*
* @param nodeConfig Solr configuration.
*/
static CoresLocator instantiate(NodeConfig nodeConfig) {
final String coresLocatorClass = nodeConfig.getCoresLocatorClass();
if (coresLocatorClass != null) {
try {
Class<? extends CoresLocator> clazz =
nodeConfig.getSolrResourceLoader().findClass(coresLocatorClass, CoresLocator.class);
Constructor<? extends CoresLocator> constructor = clazz.getConstructor(NodeConfig.class);
return constructor.newInstance(nodeConfig);
} catch (Exception e) {
throw new RuntimeException(
"create CoresLocator instance failed, coresLocatorClass=" + coresLocatorClass, e);
}
} else {
return new CorePropertiesLocator(nodeConfig.getCoreRootDirectory());
}
}
}
14 changes: 14 additions & 0 deletions solr/core/src/java/org/apache/solr/core/NodeConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public class NodeConfig {
private final UpdateShardHandlerConfig updateShardHandlerConfig;

private final String configSetServiceClass;
private final String coresLocatorClass;

private final String coreAdminHandlerClass;

Expand Down Expand Up @@ -154,6 +155,7 @@ private NodeConfig(
Set<Path> allowPaths,
List<String> allowUrls,
String configSetServiceClass,
String coresLocatorClass,
String modules,
Set<String> hiddenSysProps) {
// all Path params here are absolute and normalized.
Expand Down Expand Up @@ -190,6 +192,7 @@ private NodeConfig(
this.allowPaths = allowPaths;
this.allowUrls = allowUrls;
this.configSetServiceClass = configSetServiceClass;
this.coresLocatorClass = coresLocatorClass;
this.modules = modules;
this.hiddenSysProps = hiddenSysProps;
this.hiddenSysPropPattern =
Expand Down Expand Up @@ -258,6 +261,10 @@ public String getConfigSetServiceClass() {
return this.configSetServiceClass;
}

public String getCoresLocatorClass() {
return this.coresLocatorClass;
}

public String getNodeName() {
return nodeName;
}
Expand Down Expand Up @@ -593,6 +600,7 @@ public static class NodeConfigBuilder {
private PluginInfo shardHandlerFactoryConfig;
private UpdateShardHandlerConfig updateShardHandlerConfig = UpdateShardHandlerConfig.DEFAULT;
private String configSetServiceClass;
private String coresLocatorClass;
private String coreAdminHandlerClass = DEFAULT_ADMINHANDLERCLASS;
private Map<String, String> coreAdminHandlerActions = Collections.emptyMap();
private String collectionsAdminHandlerClass = DEFAULT_COLLECTIONSHANDLERCLASS;
Expand Down Expand Up @@ -814,6 +822,11 @@ public NodeConfigBuilder setConfigSetServiceClass(String configSetServiceClass)
return this;
}

public NodeConfigBuilder setCoresLocatorClass(String coresLocatorClass) {
this.coresLocatorClass = coresLocatorClass;
return this;
}

/**
* Set list of modules to add to class path
*
Expand Down Expand Up @@ -903,6 +916,7 @@ public NodeConfig build() {
allowPaths,
allowUrls,
configSetServiceClass,
coresLocatorClass,
modules,
resolveHiddenSysPropsFromSysPropOrEnvOrDefault(hiddenSysProps));
}
Expand Down
3 changes: 3 additions & 0 deletions solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ private static NodeConfig fillSolrSection(NodeConfig.NodeConfigBuilder builder,
case "configSetService":
builder.setConfigSetServiceClass(it.txt());
break;
case "coresLocator":
builder.setCoresLocatorClass(it.txt());
break;
case "coreRootDirectory":
builder.setCoreRootDirectory(it.txt());
break;
Expand Down
54 changes: 54 additions & 0 deletions solr/core/src/test/org/apache/solr/core/CoresLocatorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.core;

import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import org.apache.solr.util.NoCoresLocator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

/** Unit tests for {@link CoresLocator}. */
public class CoresLocatorTest {

@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();

@Test
public void testInstantiateDefaultCoresLocator() throws Exception {
String solrXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><solr></solr>";
NodeConfig nodeConfig = SolrXmlConfig.fromString(temporaryFolder.newFolder().toPath(), solrXml);
CoresLocator coresLocator = CoresLocator.instantiate(nodeConfig);

assertTrue(coresLocator instanceof CorePropertiesLocator);
}

@Test
public void testInstantiateCustomCoresLocator() throws Exception {
String solrXml =
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+ "<solr>\n"
+ "<str name=\"coresLocator\">org.apache.solr.util.NoCoresLocator</str>\n"
+ "</solr>";
NodeConfig nodeConfig = SolrXmlConfig.fromString(temporaryFolder.newFolder().toPath(), solrXml);
CoresLocator coresLocator = CoresLocator.instantiate(nodeConfig);

assertTrue(coresLocator instanceof NoCoresLocator);
assertSame(nodeConfig, ((NoCoresLocator) coresLocator).getNodeConfig());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ For example, `<str name="configSetService">com.myorg.CustomConfigSetService</str
+
If this attribute isn't set, Solr uses the default `configSetService`, with zookeeper aware of `org.apache.solr.cloud.ZkConfigSetService`, without zookeeper aware of `org.apache.solr.core.FileSystemConfigSetService`.

`coresLocator`::
+
[%autowidth,frame=none]
|===
|Optional |Default: `org.apache.solr.core.CoresPropertiesLocator`
|===
+
This attribute does not need to be set.
+
If used, this attribute should be set to the FQN (Fully qualified name) of a class that inherits from `CoresLocator`, and you must provide a constructor with one parameter which the type is `org.apache.solr.core.NodeConfig`.
For example, `<str name="coresLocator">com.myorg.CustomCoresLocator</str>`.

`adminHandler`::
+
[%autowidth,frame=none]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.solr.util;

import java.util.List;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.NodeConfig;

/** A {@link org.apache.solr.core.CoresLocator} that locates no cores. */
public class NoCoresLocator extends ReadOnlyCoresLocator {
private final NodeConfig nodeConfig;

public NoCoresLocator(NodeConfig nodeConfig) {
this.nodeConfig = nodeConfig;
}

public NodeConfig getNodeConfig() {
return nodeConfig;
}

@Override
public List<CoreDescriptor> discover(CoreContainer cc) {
return List.of();
}
}

0 comments on commit fe87566

Please sign in to comment.