diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0c3a28543da..3ee8e5d68b3 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -40,6 +40,8 @@ Other Changes * SOLR-14256: Remove HashDocSet; add DocSet.getBits() instead. DocSet is now strictly immutable and ascending order. It's now locked-down to external extension; only 2 impls exist. (David Smiley) +* SOLR-14197: SolrResourceLoader: remove deprecated methods and do other improvements. (David Smiley) + ================== 8.6.0 ================== Consult the LUCENE_CHANGES.txt file for additional, low level, changes in this release. @@ -62,7 +64,8 @@ Bug Fixes Other Changes --------------------- -(No changes) +* SOLR-14197: SolrResourceLoader: marked many methods as deprecated, and in some cases rerouted exiting logic to avoid + them. (David Smiley) ================== 8.5.0 ================== diff --git a/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/TikaEntityProcessor.java b/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/TikaEntityProcessor.java index 875032b5a1f..c789fc0c631 100644 --- a/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/TikaEntityProcessor.java +++ b/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/TikaEntityProcessor.java @@ -82,22 +82,26 @@ public class TikaEntityProcessor extends EntityProcessorBase { @Override protected void firstInit(Context context) { super.firstInit(context); + // See similar code in ExtractingRequestHandler.inform try { - String tikaConfigFile = context.getResolvedEntityAttribute("tikaConfig"); - if (tikaConfigFile == null) { + String tikaConfigLoc = context.getResolvedEntityAttribute("tikaConfig"); + if (tikaConfigLoc == null) { ClassLoader classLoader = context.getSolrCore().getResourceLoader().getClassLoader(); try (InputStream is = classLoader.getResourceAsStream("solr-default-tika-config.xml")) { tikaConfig = new TikaConfig(is); } } else { - File configFile = new File(tikaConfigFile); - if (!configFile.isAbsolute()) { - configFile = new File(context.getSolrCore().getResourceLoader().getConfigDir(), tikaConfigFile); + File configFile = new File(tikaConfigLoc); + if (configFile.isAbsolute()) { + tikaConfig = new TikaConfig(configFile); + } else { // in conf/ + try (InputStream is = context.getSolrCore().getResourceLoader().openResource(tikaConfigLoc)) { + tikaConfig = new TikaConfig(is); + } } - tikaConfig = new TikaConfig(configFile); } } catch (Exception e) { - wrapAndThrow (SEVERE, e,"Unable to load Tika Config"); + wrapAndThrow(SEVERE, e,"Unable to load Tika Config"); } String extractEmbeddedString = context.getResolvedEntityAttribute("extractEmbedded"); diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java index 285b135c9a0..43e3af70795 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java @@ -113,8 +113,8 @@ public class DocBuilder { VariableResolver resolver = null; String epoch = propWriter.convertDateToString(EPOCH); if(dataImporter != null && dataImporter.getCore() != null - && dataImporter.getCore().getResourceLoader().getCoreProperties() != null){ - resolver = new VariableResolver(dataImporter.getCore().getResourceLoader().getCoreProperties()); + && dataImporter.getCore().getCoreDescriptor().getSubstitutableProperties() != null){ + resolver = new VariableResolver(dataImporter.getCore().getCoreDescriptor().getSubstitutableProperties()); } else { resolver = new VariableResolver(); } diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SimplePropertiesWriter.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SimplePropertiesWriter.java index 1ee18eff696..2d5b078b87a 100644 --- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SimplePropertiesWriter.java +++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SimplePropertiesWriter.java @@ -38,7 +38,7 @@ import java.util.Properties; import org.apache.lucene.util.IOUtils; import org.apache.solr.common.util.SuppressForbidden; import org.apache.solr.core.SolrCore; -import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.core.SolrPaths; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -126,7 +126,7 @@ public class SimplePropertiesWriter extends DIHProperties { } else { SolrCore core = dataImporter.getCore(); if (core == null) { - configDir = SolrResourceLoader.locateSolrHome().toString(); + configDir = SolrPaths.locateSolrHome().toString(); } else { configDir = core.getResourceLoader().getConfigDir(); } diff --git a/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/ExtractingRequestHandler.java b/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/ExtractingRequestHandler.java index 3af9b5b5aa8..2605f9848df 100644 --- a/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/ExtractingRequestHandler.java +++ b/solr/contrib/extraction/src/java/org/apache/solr/handler/extraction/ExtractingRequestHandler.java @@ -17,7 +17,6 @@ package org.apache.solr.handler.extraction; import java.io.File; -import java.io.IOException; import java.io.InputStream; import org.apache.solr.common.SolrException; @@ -32,8 +31,6 @@ import org.apache.solr.security.PermissionNameProvider; import org.apache.solr.update.processor.UpdateRequestProcessor; import org.apache.solr.util.plugin.SolrCoreAware; import org.apache.tika.config.TikaConfig; -import org.apache.tika.exception.TikaException; -import org.xml.sax.SAXException; /** * Handler for rich documents like PDF or Word or any other file format that Tika handles that need the text to be extracted @@ -61,40 +58,34 @@ public class ExtractingRequestHandler extends ContentStreamHandlerBase implement @Override public void inform(SolrCore core) { - if (initArgs != null) { - //if relative,then relative to config dir, otherwise, absolute path + try { String tikaConfigLoc = (String) initArgs.get(CONFIG_LOCATION); - if (tikaConfigLoc != null) { - File configFile = new File(tikaConfigLoc); - if (configFile.isAbsolute() == false) { - configFile = new File(core.getResourceLoader().getConfigDir(), configFile.getPath()); + if (tikaConfigLoc == null) { // default + ClassLoader classLoader = core.getResourceLoader().getClassLoader(); + try (InputStream is = classLoader.getResourceAsStream("solr-default-tika-config.xml")) { + config = new TikaConfig(is); } - try { + } else { + File configFile = new File(tikaConfigLoc); + if (configFile.isAbsolute()) { config = new TikaConfig(configFile); - } catch (Exception e) { - throw new SolrException(ErrorCode.SERVER_ERROR, e); + } else { // in conf/ + try (InputStream is = core.getResourceLoader().openResource(tikaConfigLoc)) { + config = new TikaConfig(is); + } } } String parseContextConfigLoc = (String) initArgs.get(PARSE_CONTEXT_CONFIG); - if (parseContextConfigLoc != null) { - try { - parseContextConfig = new ParseContextConfig(core.getResourceLoader(), parseContextConfigLoc); - } catch (Exception e) { - throw new SolrException(ErrorCode.SERVER_ERROR, e); - } + if (parseContextConfigLoc == null) { // default: + parseContextConfig = new ParseContextConfig(); + } else { + parseContextConfig = new ParseContextConfig(core.getResourceLoader(), parseContextConfigLoc); } + } catch (Exception e) { + throw new SolrException(ErrorCode.SERVER_ERROR, "Unable to load Tika Config", e); } - if (config == null) { - try (InputStream is = core.getResourceLoader().getClassLoader().getResourceAsStream("solr-default-tika-config.xml")){ - config = new TikaConfig(is); - } catch (IOException | SAXException | TikaException e) { - throw new SolrException(ErrorCode.SERVER_ERROR, e); - } - } - if (parseContextConfig == null) { - parseContextConfig = new ParseContextConfig(); - } + factory = createFactory(); } diff --git a/solr/contrib/prometheus-exporter/src/java/org/apache/solr/prometheus/exporter/SolrExporter.java b/solr/contrib/prometheus-exporter/src/java/org/apache/solr/prometheus/exporter/SolrExporter.java index 9df974613dc..c0d0d4dd3a7 100644 --- a/solr/contrib/prometheus-exporter/src/java/org/apache/solr/prometheus/exporter/SolrExporter.java +++ b/solr/contrib/prometheus-exporter/src/java/org/apache/solr/prometheus/exporter/SolrExporter.java @@ -216,7 +216,7 @@ public class SolrExporter { private static MetricsConfiguration loadMetricsConfiguration(Path configPath) { try (SolrResourceLoader loader = new SolrResourceLoader(configPath.getParent())) { - XmlConfigFile config = new XmlConfigFile(loader, configPath.getFileName().toString()); + XmlConfigFile config = new XmlConfigFile(loader, configPath.getFileName().toString(), null, null); return MetricsConfiguration.from(config); } catch (Exception e) { log.error("Could not load scrape configuration from {}", configPath.toAbsolutePath()); diff --git a/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java b/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java index 4a5b45d2cb5..1b4d9629368 100644 --- a/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java +++ b/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java @@ -25,6 +25,7 @@ import java.nio.file.Path; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Properties; import java.util.Set; import java.util.function.Supplier; @@ -50,7 +51,6 @@ import org.apache.solr.common.util.NamedList; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.NodeConfig; import org.apache.solr.core.SolrCore; -import org.apache.solr.core.SolrXmlConfig; import org.apache.solr.request.SolrQueryRequest; import org.apache.solr.request.SolrRequestHandler; import org.apache.solr.request.SolrRequestInfo; @@ -92,7 +92,7 @@ public class EmbeddedSolrServer extends SolrClient { * @param defaultCoreName the core to route requests to by default (optional) */ public EmbeddedSolrServer(Path solrHome, String defaultCoreName) { - this(load(new CoreContainer(SolrXmlConfig.fromSolrHome(solrHome))), defaultCoreName); + this(load(new CoreContainer(solrHome, new Properties())), defaultCoreName); } /** diff --git a/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java b/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java index 41beed737ac..6583db77cde 100644 --- a/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java +++ b/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java @@ -75,8 +75,7 @@ public class CloudConfigSetService extends ConfigSetService { throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "Trouble resolving configSet for collection " + colName + ": " + ex.getMessage()); } - return new ZkSolrResourceLoader(cd.getInstanceDir(), configSetName, parentLoader.getClassLoader(), - cd.getSubstitutableProperties(), zkController); + return new ZkSolrResourceLoader(cd.getInstanceDir(), configSetName, parentLoader.getClassLoader(), zkController); } @Override diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java b/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java index 59e2d6f5c07..5acd63bde6c 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java @@ -25,6 +25,7 @@ import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Paths; import java.util.List; +import java.util.Properties; import java.util.concurrent.TimeoutException; import java.util.regex.Pattern; @@ -206,14 +207,14 @@ public class ZkCLI implements CLIO { System.exit(1); } - CoreContainer cc = new CoreContainer(solrHome); + CoreContainer cc = new CoreContainer(Paths.get(solrHome), new Properties()); if(!ZkController.checkChrootPath(zkServerAddress, true)) { stdout.println("A chroot was specified in zkHost but the znode doesn't exist. "); System.exit(1); } - ZkController.bootstrapConf(zkClient, cc, solrHome); + ZkController.bootstrapConf(zkClient, cc); // No need to close the CoreContainer, as it wasn't started // up in the first place... diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkController.java b/solr/core/src/java/org/apache/solr/cloud/ZkController.java index a9741f55318..d2ec34bc203 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkController.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkController.java @@ -2017,14 +2017,14 @@ public class ZkController implements Closeable { /** * If in SolrCloud mode, upload config sets for each SolrCore in solr.xml. */ - public static void bootstrapConf(SolrZkClient zkClient, CoreContainer cc, String solrHome) throws IOException { + public static void bootstrapConf(SolrZkClient zkClient, CoreContainer cc) throws IOException { ZkConfigManager configManager = new ZkConfigManager(zkClient); //List allCoreNames = cfg.getAllCoreNames(); List cds = cc.getCoresLocator().discover(cc); - log.info("bootstrapping config for " + cds.size() + " cores into ZooKeeper using solr.xml from " + solrHome); + log.info("bootstrapping config for " + cds.size() + " cores into ZooKeeper using solr.xml from " + cc.getSolrHome()); for (CoreDescriptor cd : cds) { String coreName = cd.getName(); diff --git a/solr/core/src/java/org/apache/solr/cloud/ZkSolrResourceLoader.java b/solr/core/src/java/org/apache/solr/cloud/ZkSolrResourceLoader.java index 5f32ef2127c..c0ddfc31687 100644 --- a/solr/core/src/java/org/apache/solr/cloud/ZkSolrResourceLoader.java +++ b/solr/core/src/java/org/apache/solr/cloud/ZkSolrResourceLoader.java @@ -22,10 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.lang.invoke.MethodHandles; import java.nio.file.Path; -import java.util.List; -import java.util.Properties; -import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrException.ErrorCode; import org.apache.solr.common.cloud.ZkConfigManager; import org.apache.solr.common.cloud.ZooKeeperException; @@ -49,12 +46,6 @@ public class ZkSolrResourceLoader extends SolrResourceLoader { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - public ZkSolrResourceLoader(Path instanceDir, String configSet, ZkController zooKeeperController) { - super(instanceDir); - this.zkController = zooKeeperController; - configSetZkPath = ZkConfigManager.CONFIGS_ZKNODE + "/" + configSet; - } - /** *

* This loader will first attempt to load resources from ZooKeeper, but if not found @@ -63,8 +54,8 @@ public class ZkSolrResourceLoader extends SolrResourceLoader { * the "lib/" directory in the specified instance directory. */ public ZkSolrResourceLoader(Path instanceDir, String configSet, ClassLoader parent, - Properties coreProperties, ZkController zooKeeperController) { - super(instanceDir, parent, coreProperties); + ZkController zooKeeperController) { + super(instanceDir, parent); this.zkController = zooKeeperController; configSetZkPath = ZkConfigManager.CONFIGS_ZKNODE + "/" + configSet; } @@ -152,25 +143,6 @@ public class ZkSolrResourceLoader extends SolrResourceLoader { ErrorCode.SERVER_ERROR, "ZkSolrResourceLoader does not support getConfigDir() - likely, what you are trying to do is not supported in ZooKeeper mode"); } - - @Override - public String[] listConfigDir() { - List list; - try { - list = zkController.getZkClient().getChildren(configSetZkPath, null, true); - } catch (InterruptedException e) { - // Restore the interrupted status - Thread.currentThread().interrupt(); - log.error("", e); - throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, - "", e); - } catch (KeeperException e) { - log.error("", e); - throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, - "", e); - } - return list.toArray(new String[0]); - } public String getConfigSetZkPath() { return configSetZkPath; diff --git a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java index f165376328b..3f54fe29c76 100644 --- a/solr/core/src/java/org/apache/solr/core/ConfigSetService.java +++ b/solr/core/src/java/org/apache/solr/core/ConfigSetService.java @@ -108,7 +108,7 @@ public abstract class ConfigSetService { * @return a SolrConfig object */ protected SolrConfig createSolrConfig(CoreDescriptor cd, SolrResourceLoader loader, boolean isTrusted) { - return SolrConfig.readFromResourceLoader(loader, cd.getConfigName(), isTrusted); + return SolrConfig.readFromResourceLoader(loader, cd.getConfigName(), isTrusted, cd.getSubstitutableProperties()); } /** @@ -126,10 +126,10 @@ public abstract class ConfigSetService { // want to pay the overhead of that at this juncture. If we guess wrong, no schema sharing. // The fix is usually to name your schema managed-schema instead of schema.xml. IndexSchemaFactory indexSchemaFactory = IndexSchemaFactory.newIndexSchemaFactory(solrConfig); - String guessSchemaName = indexSchemaFactory.getSchemaResourceName(cdSchemaName); String configSet = cd.getConfigSet(); if (configSet != null && schemaCache != null) { + String guessSchemaName = indexSchemaFactory.getSchemaResourceName(cdSchemaName); Long modVersion = getCurrentSchemaModificationVersion(configSet, solrConfig, guessSchemaName); if (modVersion != null) { // note: luceneMatchVersion influences the schema @@ -204,7 +204,7 @@ public abstract class ConfigSetService { @Override public SolrResourceLoader createCoreResourceLoader(CoreDescriptor cd) { Path instanceDir = locateInstanceDir(cd); - return new SolrResourceLoader(instanceDir, parentLoader.getClassLoader(), cd.getSubstitutableProperties()); + return new SolrResourceLoader(instanceDir, parentLoader.getClassLoader()); } @Override 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 901ff782c5b..24dbbcc05d4 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java +++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java @@ -19,6 +19,7 @@ package org.apache.solr.core; import java.io.Closeable; import java.io.IOException; import java.lang.invoke.MethodHandles; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.spec.InvalidKeySpecException; @@ -192,7 +193,7 @@ public class CoreContainer { protected final NodeConfig cfg; protected final SolrResourceLoader loader; - protected final String solrHome; + protected final Path solrHome; protected final CoresLocator coresLocator; @@ -277,36 +278,16 @@ public class CoreContainer { log.debug("New CoreContainer " + System.identityHashCode(this)); } - /** - * Create a new CoreContainer using system properties to detect the solr home - * directory. The container's cores are not loaded. - * - * @see #load() - */ - public CoreContainer() { - this(new SolrResourceLoader(SolrResourceLoader.locateSolrHome())); - } - - /** - * Create a new CoreContainer using the given SolrResourceLoader. The container's - * cores are not loaded. - * - * @param loader the SolrResourceLoader - * @see #load() - */ - public CoreContainer(SolrResourceLoader loader) { - this(SolrXmlConfig.fromSolrHome(loader, loader.getInstancePath())); - } - /** * Create a new CoreContainer using the given solr home directory. The container's * cores are not loaded. * * @param solrHome a String containing the path to the solr home directory + * @param properties substitutable properties (alternative to Sys props) * @see #load() */ - public CoreContainer(String solrHome) { - this(new SolrResourceLoader(Paths.get(solrHome))); + public CoreContainer(Path solrHome, Properties properties) { + this(SolrXmlConfig.fromSolrHome(solrHome, properties)); } /** @@ -318,25 +299,21 @@ public class CoreContainer { * @see #load() */ public CoreContainer(NodeConfig config) { - this(config, new Properties()); + this(config, new CorePropertiesLocator(config.getCoreRootDirectory())); } - public CoreContainer(NodeConfig config, Properties properties) { - this(config, properties, new CorePropertiesLocator(config.getCoreRootDirectory())); + public CoreContainer(NodeConfig config, boolean asyncSolrCoreLoad) { + this(config, new CorePropertiesLocator(config.getCoreRootDirectory()), asyncSolrCoreLoad); } - public CoreContainer(NodeConfig config, Properties properties, boolean asyncSolrCoreLoad) { - this(config, properties, new CorePropertiesLocator(config.getCoreRootDirectory()), asyncSolrCoreLoad); + public CoreContainer(NodeConfig config, CoresLocator locator) { + this(config, locator, false); } - public CoreContainer(NodeConfig config, Properties properties, CoresLocator locator) { - this(config, properties, locator, false); - } - - public CoreContainer(NodeConfig config, Properties properties, CoresLocator locator, boolean asyncSolrCoreLoad) { - this.cfg = requireNonNull(config); + public CoreContainer(NodeConfig config, CoresLocator locator, boolean asyncSolrCoreLoad) { this.loader = config.getSolrResourceLoader(); - this.solrHome = loader.getInstancePath().toString(); + this.solrHome = config.getSolrHome(); + this.cfg = requireNonNull(config); try { containerHandlers.put(PublicKeyHandler.PATH, new PublicKeyHandler(cfg.getCloudConfig())); } catch (IOException | InvalidKeySpecException e) { @@ -346,7 +323,7 @@ public class CoreContainer { IndexSearcher.setMaxClauseCount(this.cfg.getBooleanQueryMaxClauseCount()); } this.coresLocator = locator; - this.containerProperties = new Properties(properties); + this.containerProperties = new Properties(config.getSolrProperties()); this.asyncSolrCoreLoad = asyncSolrCoreLoad; this.replayUpdatesExecutor = new OrderedExecutor( cfg.getReplayUpdatesThreads(), @@ -557,8 +534,7 @@ public class CoreContainer { * @return a loaded CoreContainer */ public static CoreContainer createAndLoad(Path solrHome, Path configFile) { - SolrResourceLoader loader = new SolrResourceLoader(solrHome); - CoreContainer cc = new CoreContainer(SolrXmlConfig.fromFile(loader, configFile)); + CoreContainer cc = new CoreContainer(SolrXmlConfig.fromFile(solrHome, configFile, new Properties())); try { cc.load(); } catch (Exception e) { @@ -607,7 +583,7 @@ public class CoreContainer { * Load the cores defined for this CoreContainer */ public void load() { - log.debug("Loading cores into CoreContainer [instanceDir={}]", loader.getInstancePath()); + log.debug("Loading cores into CoreContainer [instanceDir={}]", getSolrHome()); // Always add $SOLR_HOME/lib to the shared resource loader Set libDirs = new LinkedHashSet<>(); @@ -621,13 +597,13 @@ public class CoreContainer { boolean modified = false; // add the sharedLib to the shared resource loader before initializing cfg based plugins for (String libDir : libDirs) { - Path libPath = loader.getInstancePath().resolve(libDir); - try { - loader.addToClassLoader(SolrResourceLoader.getURLs(libPath)); - modified = true; - } catch (IOException e) { - if (!libDir.equals("lib")) { // Don't complain if default "lib" dir does not exist - log.warn("Couldn't add files from {} to classpath: {}", libPath, e.getMessage()); + Path libPath = Paths.get(getSolrHome()).resolve(libDir); + if (Files.exists(libPath)) { + try { + loader.addToClassLoader(SolrResourceLoader.getURLs(libPath)); + modified = true; + } catch (IOException e) { + throw new SolrException(ErrorCode.SERVER_ERROR, "Couldn't load libs: " + e, e); } } } @@ -664,7 +640,7 @@ public class CoreContainer { hostName = cfg.getNodeName(); - zkSys.initZooKeeper(this, solrHome, cfg.getCloudConfig()); + zkSys.initZooKeeper(this, cfg.getCloudConfig()); if (isZooKeeperAware()) { pkiAuthenticationPlugin = new PKIAuthenticationPlugin(this, zkSys.getZkController().getNodeName(), (PublicKeyHandler) containerHandlers.get(PublicKeyHandler.PATH)); @@ -1907,8 +1883,9 @@ public class CoreContainer { return solrCores.getUnloadedCoreDescriptor(cname); } + //TODO return Path public String getSolrHome() { - return solrHome; + return solrHome.toString(); } public boolean isZooKeeperAware() { 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 1ce0872126b..114f74f14bd 100644 --- a/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java +++ b/solr/core/src/java/org/apache/solr/core/HdfsDirectoryFactory.java @@ -412,7 +412,7 @@ public class HdfsDirectoryFactory extends CachingDirectoryFactory implements Sol path = cd.getName(); } - return normalize(SolrResourceLoader.normalizeDir(ZkController + return normalize(SolrPaths.normalizeDir(ZkController .trimLeadingAndTrailingSlashes(hdfsDataDir) + "/" + path diff --git a/solr/core/src/java/org/apache/solr/core/NodeConfig.java b/solr/core/src/java/org/apache/solr/core/NodeConfig.java index e03cdb12075..4afca972548 100644 --- a/solr/core/src/java/org/apache/solr/core/NodeConfig.java +++ b/solr/core/src/java/org/apache/solr/core/NodeConfig.java @@ -86,7 +86,8 @@ public class NodeConfig { String coreAdminHandlerClass, String collectionsAdminHandlerClass, String healthCheckHandlerClass, String infoHandlerClass, String configSetsHandlerClass, LogWatcherConfig logWatcherConfig, CloudConfig cloudConfig, Integer coreLoadThreads, int replayUpdatesThreads, - int transientCacheSize, boolean useSchemaCache, String managementPath, SolrResourceLoader loader, + int transientCacheSize, boolean useSchemaCache, String managementPath, + Path solrHome, SolrResourceLoader loader, Properties solrProperties, PluginInfo[] backupRepositoryPlugins, MetricsConfig metricsConfig, PluginInfo transientCacheConfig, PluginInfo tracerConfig) { this.nodeName = nodeName; @@ -109,6 +110,7 @@ public class NodeConfig { this.transientCacheSize = transientCacheSize; this.useSchemaCache = useSchemaCache; this.managementPath = managementPath; + this.solrHome = solrHome; this.loader = loader; this.solrProperties = solrProperties; this.backupRepositoryPlugins = backupRepositoryPlugins; @@ -216,6 +218,7 @@ public class NodeConfig { return transientCacheSize; } + protected final Path solrHome; protected final SolrResourceLoader loader; protected final Properties solrProperties; @@ -223,6 +226,10 @@ public class NodeConfig { return solrProperties; } + public Path getSolrHome() { + return solrHome; + } + public SolrResourceLoader getSolrResourceLoader() { return loader; } @@ -243,6 +250,7 @@ public class NodeConfig { public static class NodeConfigBuilder { + private SolrResourceLoader loader; private Path coreRootDirectory; private Path solrDataHome; private Integer booleanQueryMaxClauseCount; @@ -270,7 +278,7 @@ public class NodeConfig { private PluginInfo transientCacheConfig; private PluginInfo tracerConfig; - private final SolrResourceLoader loader; + private final Path solrHome; private final String nodeName; public static final int DEFAULT_CORE_LOAD_THREADS = 3; @@ -293,28 +301,28 @@ public class NodeConfig { "zkDigestReadonlyPassword" )); - public NodeConfigBuilder(String nodeName, SolrResourceLoader loader) { + public NodeConfigBuilder(String nodeName, Path solrHome) { this.nodeName = nodeName; - this.loader = loader; - this.coreRootDirectory = loader.getInstancePath(); + this.solrHome = solrHome; + this.coreRootDirectory = solrHome; // always init from sysprop because config element may be missing String dataHomeProperty = System.getProperty(SolrXmlConfig.SOLR_DATA_HOME); if (dataHomeProperty != null && !dataHomeProperty.isEmpty()) { - solrDataHome = loader.getInstancePath().resolve(dataHomeProperty); + solrDataHome = solrHome.resolve(dataHomeProperty); } - this.configSetBaseDirectory = loader.getInstancePath().resolve("configsets"); + this.configSetBaseDirectory = solrHome.resolve("configsets"); this.metricsConfig = new MetricsConfig.MetricsConfigBuilder().build(); } public NodeConfigBuilder setCoreRootDirectory(String coreRootDirectory) { - this.coreRootDirectory = loader.getInstancePath().resolve(coreRootDirectory); + this.coreRootDirectory = solrHome.resolve(coreRootDirectory); return this; } public NodeConfigBuilder setSolrDataHome(String solrDataHomeString) { // keep it null unless explicitly set to non-empty value if (solrDataHomeString != null && !solrDataHomeString.isEmpty()) { - this.solrDataHome = loader.getInstancePath().resolve(solrDataHomeString); + this.solrDataHome = solrHome.resolve(solrDataHomeString); } return this; } @@ -325,7 +333,7 @@ public class NodeConfig { } public NodeConfigBuilder setConfigSetBaseDirectory(String configSetBaseDirectory) { - this.configSetBaseDirectory = loader.getInstancePath().resolve(configSetBaseDirectory); + this.configSetBaseDirectory = solrHome.resolve(configSetBaseDirectory); return this; } @@ -432,12 +440,22 @@ public class NodeConfig { } public NodeConfig build() { + // if some things weren't set then set them now. Simple primitives are set on the field declaration + if (loader == null) { + loader = new SolrResourceLoader(solrHome); + } return new NodeConfig(nodeName, coreRootDirectory, solrDataHome, booleanQueryMaxClauseCount, configSetBaseDirectory, sharedLibDirectory, shardHandlerFactoryConfig, updateShardHandlerConfig, coreAdminHandlerClass, collectionsAdminHandlerClass, healthCheckHandlerClass, infoHandlerClass, configSetsHandlerClass, - logWatcherConfig, cloudConfig, coreLoadThreads, replayUpdatesThreads, transientCacheSize, useSchemaCache, managementPath, loader, solrProperties, + logWatcherConfig, cloudConfig, coreLoadThreads, replayUpdatesThreads, transientCacheSize, useSchemaCache, managementPath, + solrHome, loader, solrProperties, backupRepositoryPlugins, metricsConfig, transientCacheConfig, tracerConfig); } + + public NodeConfigBuilder setSolrResourceLoader(SolrResourceLoader resourceLoader) { + this.loader = resourceLoader; + return this; + } } } diff --git a/solr/core/src/java/org/apache/solr/core/SolrConfig.java b/solr/core/src/java/org/apache/solr/core/SolrConfig.java index 653be098b82..aa78164e619 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrConfig.java +++ b/solr/core/src/java/org/apache/solr/core/SolrConfig.java @@ -25,6 +25,7 @@ import java.io.InputStreamReader; import java.lang.invoke.MethodHandles; import java.net.MalformedURLException; import java.net.URL; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.text.ParseException; @@ -79,7 +80,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.w3c.dom.NodeList; -import org.xml.sax.InputSource; import org.xml.sax.SAXException; import static org.apache.solr.common.params.CommonParams.NAME; @@ -133,20 +133,18 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { private final SolrRequestParsers solrRequestParsers; /** - * Creates a configuration instance from an instance directory, configuration name and stream. - * + * TEST-ONLY: Creates a configuration instance from an instance directory and file name * @param instanceDir the directory used to create the resource loader * @param name the configuration name used by the loader if the stream is null - * @param is the configuration stream */ - public SolrConfig(Path instanceDir, String name, InputSource is, boolean isConfigsetTrusted) + public SolrConfig(Path instanceDir, String name) throws ParserConfigurationException, IOException, SAXException { - this(new SolrResourceLoader(instanceDir), name, is, isConfigsetTrusted); + this(new SolrResourceLoader(instanceDir), name, true, null); } - public static SolrConfig readFromResourceLoader(SolrResourceLoader loader, String name, boolean isConfigsetTrusted) { + public static SolrConfig readFromResourceLoader(SolrResourceLoader loader, String name, boolean isConfigsetTrusted, Properties substitutableProperties) { try { - return new SolrConfig(loader, name, null, isConfigsetTrusted); + return new SolrConfig(loader, name, isConfigsetTrusted, substitutableProperties); } catch (Exception e) { String resource; if (loader instanceof ZkSolrResourceLoader) { @@ -162,18 +160,18 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { * Creates a configuration instance from a resource loader, a configuration name and a stream. * If the stream is null, the resource loader will open the configuration stream. * If the stream is not null, no attempt to load the resource will occur (the name is not used). - * - * @param loader the resource loader + * @param loader the resource loader * @param name the configuration name - * @param is the configuration stream * @param isConfigsetTrusted false if configset was uploaded using unsecured configset upload API, true otherwise + * @param substitutableProperties optional properties to substitute into the XML */ - private SolrConfig(SolrResourceLoader loader, String name, InputSource is, boolean isConfigsetTrusted) + private SolrConfig(SolrResourceLoader loader, String name, boolean isConfigsetTrusted, Properties substitutableProperties) throws ParserConfigurationException, IOException, SAXException { - super(loader, name, is, "/config/"); + // insist we have non-null substituteProperties; it might get overlayed + super(loader, name, null, "/config/", substitutableProperties == null ? new Properties() : substitutableProperties); getOverlay();//just in case it is not initialized getRequestParams(); - initLibs(isConfigsetTrusted); + initLibs(loader, isConfigsetTrusted); luceneMatchVersion = SolrConfig.parseLuceneVersionString(getVal(IndexSchema.LUCENE_MATCH_VERSION_PARAM, true)); log.info("Using Lucene MatchVersion: {}", luceneMatchVersion); @@ -748,7 +746,22 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { "Multiple plugins configured for type: " + type); } - private void initLibs(boolean isConfigsetTrusted) { + private void initLibs(SolrResourceLoader loader, boolean isConfigsetTrusted) { + // TODO Want to remove SolrResourceLoader.getInstancePath; it can be on a Standalone subclass. + // For Zk subclass, it's needed for the time being as well. We could remove that one if we remove two things + // in SolrCloud: (1) instancePath/lib and (2) solrconfig lib directives with relative paths. Can wait till 9.0. + Path instancePath = loader.getInstancePath(); + List urls = new ArrayList<>(); + + Path libPath = instancePath.resolve("lib"); + if (Files.exists(libPath)) { + try { + urls.addAll(SolrResourceLoader.getURLs(libPath)); + } catch (IOException e) { + log.warn("Couldn't add files from {} to classpath: {}", libPath, e.getMessage()); + } + } + NodeList nodes = (NodeList) evaluate("lib", XPathConstants.NODESET); if (nodes == null || nodes.getLength() == 0) return; if (!isConfigsetTrusted) { @@ -757,17 +770,13 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { + " after enabling authentication and authorization."); } - log.debug("Adding specified lib dirs to ClassLoader"); - SolrResourceLoader loader = getResourceLoader(); - List urls = new ArrayList<>(); - for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); String baseDir = DOMUtil.getAttr(node, "dir"); String path = DOMUtil.getAttr(node, PATH); if (null != baseDir) { // :TODO: add support for a simpler 'glob' mutually exclusive of regex - Path dir = loader.getInstancePath().resolve(baseDir); + Path dir = instancePath.resolve(baseDir); String regex = DOMUtil.getAttr(node, "regex"); try { if (regex == null) @@ -778,7 +787,7 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { log.warn("Couldn't add files from {} filtered by {} to classpath: {}", dir, regex, e.getMessage()); } } else if (null != path) { - final Path dir = loader.getInstancePath().resolve(path); + final Path dir = instancePath.resolve(path); try { urls.add(dir.toUri().toURL()); } catch (MalformedURLException e) { @@ -789,10 +798,8 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { } } - if (urls.size() > 0) { - loader.addToClassLoader(urls); - loader.reloadLuceneSPI(); - } + loader.addToClassLoader(urls); + loader.reloadLuceneSPI(); } public int getMultipartUploadLimitKB() { @@ -917,7 +924,7 @@ public class SolrConfig extends XmlConfigFile implements MapSerializable { } @Override - protected Properties getSubstituteProperties() { + public Properties getSubstituteProperties() { Map p = getOverlay().getUserProps(); if (p == null || p.isEmpty()) return super.getSubstituteProperties(); Properties result = new Properties(super.getSubstituteProperties()); 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 dd1fd1b3980..3578013f23b 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrCore.java +++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java @@ -134,7 +134,6 @@ import org.apache.solr.rest.ManagedResourceStorage.StorageIO; import org.apache.solr.rest.RestManager; import org.apache.solr.schema.FieldType; import org.apache.solr.schema.IndexSchema; -import org.apache.solr.schema.IndexSchemaFactory; import org.apache.solr.schema.ManagedIndexSchema; import org.apache.solr.schema.SimilarityFactory; import org.apache.solr.search.QParserPlugin; @@ -327,6 +326,11 @@ public final class SolrCore implements SolrInfoBean, Closeable { return schema; } + /** The core's instance directory. */ + public Path getInstancePath() { + return getCoreDescriptor().getInstanceDir(); + } + /** * Sets the latest schema snapshot to be used by this core instance. * If the specified replacementSchema uses a {@link SimilarityFactory} which is @@ -687,9 +691,8 @@ public final class SolrCore implements SolrInfoBean, Closeable { try { CoreDescriptor cd = new CoreDescriptor(name, getCoreDescriptor()); cd.loadExtraProperties(); //Reload the extra properties - core = new SolrCore(coreContainer, getName(), getDataDir(), coreConfig.getSolrConfig(), - coreConfig.getIndexSchema(), coreConfig.getProperties(), - cd, updateHandler, solrDelPolicy, currentCore, true); + core = new SolrCore(coreContainer, getName(), coreConfig, cd, getDataDir(), + updateHandler, solrDelPolicy, currentCore, true); // we open a new IndexWriter to pick up the latest config core.getUpdateHandler().getSolrCoreState().newIndexWriter(core, false); @@ -897,8 +900,8 @@ public final class SolrCore implements SolrInfoBean, Closeable { } public SolrCore(CoreContainer coreContainer, CoreDescriptor cd, ConfigSet coreConfig) { - this(coreContainer, cd.getName(), null, coreConfig.getSolrConfig(), coreConfig.getIndexSchema(), coreConfig.getProperties(), - cd, null, null, null, false); + this(coreContainer, cd.getName(), coreConfig, cd, null, + null, null, null, false); } public CoreContainer getCoreContainer() { @@ -909,15 +912,9 @@ public final class SolrCore implements SolrInfoBean, Closeable { /** * Creates a new core and register it in the list of cores. If a core with the * same name already exists, it will be stopped and replaced by this one. - * - * @param dataDir the index directory - * @param config a solr config instance - * @param schema a solr schema instance - * @since solr 1.3 */ - public SolrCore(CoreContainer coreContainer, String name, String dataDir, SolrConfig config, - IndexSchema schema, NamedList configSetProperties, - CoreDescriptor coreDescriptor, UpdateHandler updateHandler, + private SolrCore(CoreContainer coreContainer, String name, ConfigSet configSet, CoreDescriptor coreDescriptor, + String dataDir, UpdateHandler updateHandler, IndexDeletionPolicyWrapper delPolicy, SolrCore prev, boolean reload) { assert ObjectReleaseTracker.track(searcherExecutor); // ensure that in unclean shutdown tests we still close this @@ -927,6 +924,7 @@ public final class SolrCore implements SolrInfoBean, Closeable { final CountDownLatch latch = new CountDownLatch(1); try { + IndexSchema schema = configSet.getIndexSchema(); CoreDescriptor cd = Objects.requireNonNull(coreDescriptor, "coreDescriptor cannot be null"); coreContainer.solrCores.addCoreDescriptor(cd); @@ -934,11 +932,11 @@ public final class SolrCore implements SolrInfoBean, Closeable { setName(name); MDCLoggingContext.setCore(this); - resourceLoader = config.getResourceLoader(); - this.solrConfig = config; - this.configSetProperties = configSetProperties; + this.solrConfig = configSet.getSolrConfig(); + this.resourceLoader = configSet.getSolrConfig().getResourceLoader(); + this.configSetProperties = configSet.getProperties(); // Initialize the metrics manager - this.coreMetricManager = initCoreMetricManager(config); + this.coreMetricManager = initCoreMetricManager(solrConfig); solrMetricsContext = coreMetricManager.getSolrMetricsContext(); this.coreMetricManager.loadReporters(); @@ -953,13 +951,13 @@ public final class SolrCore implements SolrInfoBean, Closeable { isReloaded = true; } - this.dataDir = initDataDir(dataDir, config, coreDescriptor); + this.dataDir = initDataDir(dataDir, solrConfig, coreDescriptor); this.ulogDir = initUpdateLogDir(coreDescriptor); - log.info("[{}] Opening new SolrCore at [{}], dataDir=[{}]", logid, resourceLoader.getInstancePath(), - this.dataDir); + log.info("[{}] Opening new SolrCore at [{}], dataDir=[{}]", logid, getInstancePath(), this.dataDir); checkVersionFieldExistsInSchema(schema, coreDescriptor); + setLatestSchema(schema); // initialize core metrics initializeMetrics(solrMetricsContext, null); @@ -970,10 +968,8 @@ public final class SolrCore implements SolrInfoBean, Closeable { solrFieldCacheBean.initializeMetrics(solrMetricsContext, "core"); infoRegistry.put("fieldCache", solrFieldCacheBean); - initSchema(config, schema); - - this.maxWarmingSearchers = config.maxWarmingSearchers; - this.slowQueryThresholdMillis = config.slowQueryThresholdMillis; + this.maxWarmingSearchers = solrConfig.maxWarmingSearchers; + this.slowQueryThresholdMillis = solrConfig.slowQueryThresholdMillis; initListeners(); @@ -1154,20 +1150,6 @@ public final class SolrCore implements SolrInfoBean, Closeable { return newUpdateHandler; } - /** - * Initializes the "Latest Schema" for this SolrCore using either the provided schema - * if non-null, or a new instance build via the factory identified in the specified config - * - * @see IndexSchemaFactory - * @see #setLatestSchema - */ - private void initSchema(SolrConfig config, IndexSchema schema) { - if (schema == null) { - schema = IndexSchemaFactory.buildIndexSchema(IndexSchema.DEFAULT_SCHEMA_FILE, config); - } - setLatestSchema(schema); - } - /** * Initializes the core's {@link SolrCoreMetricManager} with a given configuration. * If metric reporters are configured, they are also initialized for this core. @@ -1191,7 +1173,7 @@ public final class SolrCore implements SolrInfoBean, Closeable { parentContext.gauge(() -> name == null ? "(null)" : name, true, "coreName", Category.CORE.toString()); parentContext.gauge(() -> startTime, true, "startTime", Category.CORE.toString()); parentContext.gauge(() -> getOpenCount(), true, "refCount", Category.CORE.toString()); - parentContext.gauge(() -> resourceLoader.getInstancePath().toString(), true, "instanceDir", Category.CORE.toString()); + parentContext.gauge(() -> getInstancePath().toString(), true, "instanceDir", Category.CORE.toString()); parentContext.gauge(() -> isClosed() ? "(closed)" : getIndexDir(), true, "indexDir", Category.CORE.toString()); parentContext.gauge(() -> isClosed() ? 0 : getIndexSize(), true, "sizeInBytes", Category.INDEX.toString()); parentContext.gauge(() -> isClosed() ? "(closed)" : NumberUtils.readableSize(getIndexSize()), true, "size", Category.INDEX.toString()); @@ -1293,7 +1275,7 @@ public final class SolrCore implements SolrInfoBean, Closeable { } } } - return SolrResourceLoader.normalizeDir(dataDir); + return SolrPaths.normalizeDir(dataDir); } diff --git a/solr/core/src/java/org/apache/solr/core/SolrPaths.java b/solr/core/src/java/org/apache/solr/core/SolrPaths.java new file mode 100644 index 00000000000..38c6144e0aa --- /dev/null +++ b/solr/core/src/java/org/apache/solr/core/SolrPaths.java @@ -0,0 +1,130 @@ +/* + * 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 javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.naming.NoInitialContextException; +import java.io.File; +import java.lang.invoke.MethodHandles; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Set; +import java.util.concurrent.ConcurrentSkipListSet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility methods about paths in Solr. + */ +public final class SolrPaths { + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + /** + * Solr allows users to store arbitrary files in a special directory located directly under SOLR_HOME. + *

+ * This directory is generally created by each node on startup. Files located in this directory can then be + * manipulated using select Solr features (e.g. streaming expressions). + */ + public static final String USER_FILES_DIRECTORY = "userfiles"; + private static final Set loggedOnce = new ConcurrentSkipListSet<>(); + + private SolrPaths() {} // don't create this + + /** + * Finds the solrhome based on looking up the value in one of three places: + *

    + *
  1. JNDI: via java:comp/env/solr/home
  2. + *
  3. The system property solr.solr.home
  4. + *
  5. Look in the current working directory for a solr/ directory
  6. + *
+ *

+ * The return value is normalized. Normalization essentially means it ends in a trailing slash. + * + * @return A normalized solrhome + * @see #normalizeDir(String) + */ + public static Path locateSolrHome() { + + String home = null; + // Try JNDI + try { + Context c = new InitialContext(); + home = (String) c.lookup("java:comp/env/solr/home"); + logOnceInfo("home_using_jndi", "Using JNDI solr.home: " + home); + } catch (NoInitialContextException e) { + log.debug("JNDI not configured for solr (NoInitialContextEx)"); + } catch (NamingException e) { + log.debug("No /solr/home in JNDI"); + } catch (RuntimeException ex) { + log.warn("Odd RuntimeException while testing for JNDI: " + ex.getMessage()); + } + + // Now try system property + if (home == null) { + String prop = "solr.solr.home"; + home = System.getProperty(prop); + if (home != null) { + logOnceInfo("home_using_sysprop", "Using system property " + prop + ": " + home); + } + } + + // if all else fails, try + if (home == null) { + home = "solr/"; + logOnceInfo("home_default", "solr home defaulted to '" + home + "' (could not find system property or JNDI)"); + } + return Paths.get(home); + } + + public static void ensureUserFilesDataDir(Path solrHome) { + final Path userFilesPath = getUserFilesPath(solrHome); + final File userFilesDirectory = new File(userFilesPath.toString()); + if (!userFilesDirectory.exists()) { + try { + final boolean created = userFilesDirectory.mkdir(); + if (!created) { + log.warn("Unable to create [{}] directory in SOLR_HOME [{}]. Features requiring this directory may fail.", USER_FILES_DIRECTORY, solrHome); + } + } catch (Exception e) { + log.warn("Unable to create [" + USER_FILES_DIRECTORY + "] directory in SOLR_HOME [" + solrHome + "]. Features requiring this directory may fail.", e); + } + } + } + + public static Path getUserFilesPath(Path solrHome) { + return Paths.get(solrHome.toAbsolutePath().toString(), USER_FILES_DIRECTORY).toAbsolutePath(); + } + + /** + * Ensures a directory name always ends with a '/'. + */ + public static String normalizeDir(String path) { + return (path != null && (!(path.endsWith("/") || path.endsWith("\\")))) ? path + File.separator : path; + } + + // Logs a message only once per startup + private static void logOnceInfo(String key, String msg) { + if (!loggedOnce.contains(key)) { + loggedOnce.add(key); + log.info(msg); + } + } +} diff --git a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java index a57660eb980..89243202a21 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java +++ b/solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java @@ -16,10 +16,6 @@ */ package org.apache.solr.core; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; -import javax.naming.NoInitialContextException; import java.io.Closeable; import java.io.File; import java.io.FileOutputStream; @@ -38,17 +34,13 @@ import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.PathMatcher; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -65,7 +57,6 @@ import org.apache.lucene.codecs.DocValuesFormat; import org.apache.lucene.codecs.PostingsFormat; import org.apache.lucene.util.IOUtils; import org.apache.solr.common.SolrException; -import org.apache.solr.handler.admin.CoreAdminHandler; import org.apache.solr.handler.component.SearchComponent; import org.apache.solr.handler.component.ShardHandlerFactory; import org.apache.solr.request.SolrRequestHandler; @@ -86,30 +77,24 @@ import org.slf4j.LoggerFactory; public class SolrResourceLoader implements ResourceLoader, Closeable { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - static final String project = "solr"; - static final String base = "org.apache" + "." + project; - static final String[] packages = { + private static final String base = "org.apache.solr"; + private static final String[] packages = { "", "analysis.", "schema.", "handler.", "handler.tagger.", "search.", "update.", "core.", "response.", "request.", "update.processor.", "util.", "spelling.", "handler.component.", "handler.dataimport.", "spelling.suggest.", "spelling.suggest.fst.", "rest.schema.analysis.", "security.", "handler.admin.", "cloud.autoscaling." }; - private static final java.lang.String SOLR_CORE_NAME = "solr.core.name"; - private static Set loggedOnce = new ConcurrentSkipListSet<>(); private static final Charset UTF_8 = StandardCharsets.UTF_8; private String name = ""; protected URLClassLoader classLoader; private final Path instanceDir; - private String dataDir; private final List waitingForCore = Collections.synchronizedList(new ArrayList()); private final List infoMBeans = Collections.synchronizedList(new ArrayList()); private final List waitingForResources = Collections.synchronizedList(new ArrayList()); - private final Properties coreProperties; - private volatile boolean live; // Provide a registry so that managed resources can register themselves while the XML configuration @@ -118,6 +103,9 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { // (such as the SolrZkClient) when XML docs are being parsed. private RestManager.Registry managedResourceRegistry; + /** @see #reloadLuceneSPI() */ + private boolean needToReloadLuceneSPI = false; // requires synchronization + public synchronized RestManager.Registry getManagedResourceRegistry() { if (managedResourceRegistry == null) { managedResourceRegistry = new RestManager.Registry(); @@ -126,47 +114,43 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { } public SolrResourceLoader() { - this(SolrResourceLoader.locateSolrHome(), null, null); + this(SolrPaths.locateSolrHome(), null); } /** - *

- * This loader will delegate to the context classloader when possible, - * otherwise it will attempt to resolve resources using any jar files - * found in the "lib/" directory in the specified instance directory. - * If the instance directory is not specified (=null), SolrResourceLoader#locateInstanceDir will provide one. + * Creates a loader. + * Note: we do NOT call {@link #reloadLuceneSPI()}. */ - public SolrResourceLoader(Path instanceDir, ClassLoader parent) { - this(instanceDir, parent, null); - } - - public SolrResourceLoader(String name, List classpath, Path instanceDir, ClassLoader parent) throws MalformedURLException { + public SolrResourceLoader(String name, List classpath, Path instanceDir, ClassLoader parent) { this(instanceDir, parent); this.name = name; - for (Path path : classpath) { - addToClassLoader(path.toUri().normalize().toURL()); + final List libUrls = new ArrayList<>(classpath.size()); + try { + for (Path path : classpath) { + libUrls.add(path.toUri().normalize().toURL()); + } + } catch (MalformedURLException e) { // impossible? + throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); } - + addToClassLoader(libUrls); } public SolrResourceLoader(Path instanceDir) { - this(instanceDir, null, null); + this(instanceDir, null); } /** - *

* This loader will delegate to Solr's classloader when possible, * otherwise it will attempt to resolve resources using any jar files * found in the "lib/" directory in the specified instance directory. - *

* * @param instanceDir - base directory for this resource loader, if null locateSolrHome() will be used. - * @see #locateSolrHome + * @see SolrPaths#locateSolrHome() */ - public SolrResourceLoader(Path instanceDir, ClassLoader parent, Properties coreProperties) { + public SolrResourceLoader(Path instanceDir, ClassLoader parent) { if (instanceDir == null) { - this.instanceDir = SolrResourceLoader.locateSolrHome().toAbsolutePath().normalize(); + this.instanceDir = SolrPaths.locateSolrHome().toAbsolutePath().normalize(); log.debug("new SolrResourceLoader for deduced Solr Home: '{}'", this.instanceDir); } else { this.instanceDir = instanceDir.toAbsolutePath().normalize(); @@ -177,25 +161,6 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { parent = getClass().getClassLoader(); } this.classLoader = URLClassLoader.newInstance(new URL[0], parent); - - /* - * Skip the lib subdirectory when we are loading from the solr home. - * Otherwise load it, so core lib directories still get loaded. - * The default sharedLib will pick this up later, and if the user has - * changed sharedLib, then we don't want to load that location anyway. - */ - if (!this.instanceDir.equals(SolrResourceLoader.locateSolrHome())) { - Path libDir = this.instanceDir.resolve("lib"); - if (Files.exists(libDir)) { - try { - addToClassLoader(getURLs(libDir)); - } catch (IOException e) { - log.warn("Couldn't add files from {} to classpath: {}", libDir, e.getMessage()); - } - reloadLuceneSPI(); - } - } - this.coreProperties = coreProperties; } /** @@ -206,46 +171,36 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { * * @param urls the URLs of files to add */ - void addToClassLoader(List urls) { + synchronized void addToClassLoader(List urls) { URLClassLoader newLoader = addURLsToClassLoader(classLoader, urls); - if (newLoader != classLoader) { - this.classLoader = newLoader; + if (newLoader == classLoader) { + return; // short-circuit } - log.info("[{}] Added {} libs to classloader, from paths: {}", - getCoreName("null"), urls.size(), urls.stream() + this.classLoader = newLoader; + this.needToReloadLuceneSPI = true; + + log.info("Added {} libs to classloader, from paths: {}", + urls.size(), urls.stream() .map(u -> u.getPath().substring(0,u.getPath().lastIndexOf("/"))) .sorted() .distinct() .collect(Collectors.toList())); } - private String getCoreName(String defaultVal) { - if (getCoreProperties() != null) { - return getCoreProperties().getProperty(SOLR_CORE_NAME, defaultVal); - } else { - return defaultVal; - } - } - - /** - * Adds URLs to the ResourceLoader's internal classloader. This method MUST - * only be called prior to using this ResourceLoader to get any resources, otherwise - * its behavior will be non-deterministic. You also have to {link @reloadLuceneSPI} - * before using this ResourceLoader. - * - * @param urls the URLs of files to add - */ - void addToClassLoader(URL... urls) { - addToClassLoader(Arrays.asList(urls)); - } - /** * Reloads all Lucene SPI implementations using the new classloader. * This method must be called after {@link #addToClassLoader(List)} * and before using this ResourceLoader. */ - void reloadLuceneSPI() { + synchronized void reloadLuceneSPI() { + // TODO improve to use a static Set to check when we need to + if (!needToReloadLuceneSPI) { + return; + } + needToReloadLuceneSPI = false; // reset + log.debug("Reloading Lucene SPI"); + // Codecs: PostingsFormat.reloadPostingsFormats(this.classLoader); DocValuesFormat.reloadDocValuesFormats(this.classLoader); @@ -324,34 +279,10 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { }); } - /** - * Ensures a directory name always ends with a '/'. - */ - public static String normalizeDir(String path) { - return (path != null && (!(path.endsWith("/") || path.endsWith("\\")))) ? path + File.separator : path; - } - - public String[] listConfigDir() { - File configdir = new File(getConfigDir()); - if (configdir.exists() && configdir.isDirectory()) { - return configdir.list(); - } else { - return new String[0]; - } - } - public String getConfigDir() { return instanceDir.resolve("conf").toString(); } - public String getDataDir() { - return dataDir; - } - - public Properties getCoreProperties() { - return coreProperties; - } - /** * EXPERT *

@@ -363,26 +294,6 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { return classLoader; } - /** - * Opens a schema resource by its name. - * Override this method to customize loading schema resources. - * - * @return the stream for the named schema - */ - public InputStream openSchema(String name) throws IOException { - return openResource(name); - } - - /** - * Opens a config resource by its name. - * Override this method to customize loading config resources. - * - * @return the stream for the named configuration - */ - public InputStream openConfig(String name) throws IOException { - return openResource(name); - } - private Path checkPathIsSafe(Path pathToCheck) throws IOException { if (Boolean.getBoolean("solr.allow.unsafe.resourceloading")) return pathToCheck; @@ -509,7 +420,7 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { // Using this pattern, legacy analysis components from previous Solr versions are identified and delegated to SPI loader: private static final Pattern legacyAnalysisPattern = - Pattern.compile("((\\Q" + base + ".analysis.\\E)|(\\Q" + project + ".\\E))([\\p{L}_$][\\p{L}\\p{N}_$]+?)(TokenFilter|Filter|Tokenizer|CharFilter)Factory"); + Pattern.compile("((\\Q" + base + ".analysis.\\E)|(\\Qsolr.\\E))([\\p{L}_$][\\p{L}\\p{N}_$]+?)(TokenFilter|Filter|Tokenizer|CharFilter)Factory"); @Override public Class findClass(String cname, Class expectedType) { @@ -569,8 +480,8 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { return clazz = Class.forName(cname, true, classLoader).asSubclass(expectedType); } catch (ClassNotFoundException e) { String newName = cname; - if (newName.startsWith(project)) { - newName = cname.substring(project.length() + 1); + if (newName.startsWith("solr")) { + newName = cname.substring("solr".length() + 1); } for (String subpackage : subpackages) { try { @@ -619,35 +530,6 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { return newInstance(cname, expectedType, subpackages, NO_CLASSES, NO_OBJECTS); } - public CoreAdminHandler newAdminHandlerInstance(final CoreContainer coreContainer, String cname, String... subpackages) { - Class clazz = findClass(cname, CoreAdminHandler.class, subpackages); - if (clazz == null) { - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, - "Can not find class: " + cname + " in " + classLoader); - } - - CoreAdminHandler obj = null; - try { - Constructor ctor = clazz.getConstructor(CoreContainer.class); - obj = ctor.newInstance(coreContainer); - } catch (Exception e) { - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, - "Error instantiating class: '" + clazz.getName() + "'", e); - } - - if (!live) { - //TODO: Does SolrCoreAware make sense here since in a multi-core context - // which core are we talking about ? - if (obj instanceof ResourceLoaderAware) { - assertAwareCompatibility(ResourceLoaderAware.class, obj); - waitingForResources.add((ResourceLoaderAware) obj); - } - } - - return obj; - } - - public T newInstance(String cName, Class expectedType, String[] subPackages, Class[] params, Object[] args) { Class clazz = findClass(cName, expectedType, subPackages); if (clazz == null) { @@ -705,8 +587,6 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { * Tell all {@link SolrCoreAware} instances about the SolrCore */ public void inform(SolrCore core) { - this.dataDir = core.getDataDir(); - // make a copy to avoid potential deadlock of a callback calling newInstance and trying to // add something to waitingForCore. SolrCoreAware[] arr; @@ -781,86 +661,6 @@ public class SolrResourceLoader implements ResourceLoader, Closeable { * if both fail, defaults to solr/ * @return the instance directory name */ - /** - * Finds the solrhome based on looking up the value in one of three places: - *

    - *
  1. JNDI: via java:comp/env/solr/home
  2. - *
  3. The system property solr.solr.home
  4. - *
  5. Look in the current working directory for a solr/ directory
  6. - *
- *

- * The return value is normalized. Normalization essentially means it ends in a trailing slash. - * - * @return A normalized solrhome - * @see #normalizeDir(String) - */ - public static Path locateSolrHome() { - - String home = null; - // Try JNDI - try { - Context c = new InitialContext(); - home = (String) c.lookup("java:comp/env/" + project + "/home"); - logOnceInfo("home_using_jndi", "Using JNDI solr.home: " + home); - } catch (NoInitialContextException e) { - log.debug("JNDI not configured for " + project + " (NoInitialContextEx)"); - } catch (NamingException e) { - log.debug("No /" + project + "/home in JNDI"); - } catch (RuntimeException ex) { - log.warn("Odd RuntimeException while testing for JNDI: " + ex.getMessage()); - } - - // Now try system property - if (home == null) { - String prop = project + ".solr.home"; - home = System.getProperty(prop); - if (home != null) { - logOnceInfo("home_using_sysprop", "Using system property " + prop + ": " + home); - } - } - - // if all else fails, try - if (home == null) { - home = project + '/'; - logOnceInfo("home_default", project + " home defaulted to '" + home + "' (could not find system property or JNDI)"); - } - return Paths.get(home); - } - - /** - * Solr allows users to store arbitrary files in a special directory located directly under SOLR_HOME. - *

- * This directory is generally created by each node on startup. Files located in this directory can then be - * manipulated using select Solr features (e.g. streaming expressions). - */ - public static final String USER_FILES_DIRECTORY = "userfiles"; - - public static void ensureUserFilesDataDir(Path solrHome) { - final Path userFilesPath = getUserFilesPath(solrHome); - final File userFilesDirectory = new File(userFilesPath.toString()); - if (!userFilesDirectory.exists()) { - try { - final boolean created = userFilesDirectory.mkdir(); - if (!created) { - log.warn("Unable to create [{}] directory in SOLR_HOME [{}]. Features requiring this directory may fail.", USER_FILES_DIRECTORY, solrHome); - } - } catch (Exception e) { - log.warn("Unable to create [" + USER_FILES_DIRECTORY + "] directory in SOLR_HOME [" + solrHome + "]. Features requiring this directory may fail.", e); - } - } - } - - public static Path getUserFilesPath(Path solrHome) { - return Paths.get(solrHome.toAbsolutePath().toString(), USER_FILES_DIRECTORY).toAbsolutePath(); - } - - // Logs a message only once per startup - private static void logOnceInfo(String key, String msg) { - if (!loggedOnce.contains(key)) { - loggedOnce.add(key); - log.info(msg); - } - } /** * @return the instance path for this resource loader diff --git a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java index 456cd034314..df4b488c997 100644 --- a/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java +++ b/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java @@ -55,21 +55,22 @@ import static org.apache.solr.common.params.CommonParams.NAME; /** - * + * Loads {@code solr.xml}. */ public class SolrXmlConfig { + // TODO should these from* methods return a NodeConfigBuilder so that the caller (a test) can make further + // manipulations like add properties and set the CorePropertiesLocator and "async" mode? + public final static String SOLR_XML_FILE = "solr.xml"; public final static String SOLR_DATA_HOME = "solr.data.home"; private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - public static NodeConfig fromConfig(XmlConfigFile config) { + public static NodeConfig fromConfig(Path solrHome, XmlConfigFile config) { checkForIllegalConfig(config); - config.substituteProperties(); - CloudConfig cloudConfig = null; UpdateShardHandlerConfig deprecatedUpdateConfig = null; @@ -96,7 +97,8 @@ public class SolrXmlConfig { updateConfig = deprecatedUpdateConfig; } - NodeConfig.NodeConfigBuilder configBuilder = new NodeConfig.NodeConfigBuilder(nodeName, config.getResourceLoader()); + NodeConfig.NodeConfigBuilder configBuilder = new NodeConfig.NodeConfigBuilder(nodeName, solrHome); + configBuilder.setSolrResourceLoader(config.getResourceLoader()); configBuilder.setUpdateShardHandlerConfig(updateConfig); configBuilder.setShardHandlerFactoryConfig(getShardHandlerFactoryPluginInfo(config)); configBuilder.setSolrCoreCacheFactoryConfig(getTransientCoreCacheFactoryPluginInfo(config)); @@ -110,7 +112,7 @@ public class SolrXmlConfig { return fillSolrSection(configBuilder, entries); } - public static NodeConfig fromFile(SolrResourceLoader loader, Path configFile) { + public static NodeConfig fromFile(Path solrHome, Path configFile, Properties substituteProps) { log.info("Loading container configuration from {}", configFile); @@ -120,7 +122,7 @@ public class SolrXmlConfig { } try (InputStream inputStream = Files.newInputStream(configFile)) { - return fromInputStream(loader, inputStream); + return fromInputStream(solrHome, inputStream, substituteProps); } catch (SolrException exc) { throw exc; } catch (Exception exc) { @@ -129,16 +131,24 @@ public class SolrXmlConfig { } } - public static NodeConfig fromString(SolrResourceLoader loader, String xml) { - return fromInputStream(loader, new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8))); + /** TEST-ONLY */ + public static NodeConfig fromString(Path solrHome, String xml) { + return fromInputStream( + solrHome, + new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)), + new Properties()); } - public static NodeConfig fromInputStream(SolrResourceLoader loader, InputStream is) { + public static NodeConfig fromInputStream(Path solrHome, InputStream is, Properties substituteProps) { + SolrResourceLoader loader = new SolrResourceLoader(solrHome); + if (substituteProps == null) { + substituteProps = new Properties(); + } try { byte[] buf = IOUtils.toByteArray(is); try (ByteArrayInputStream dup = new ByteArrayInputStream(buf)) { - XmlConfigFile config = new XmlConfigFile(loader, null, new InputSource(dup), null, false); - return fromConfig(config); + XmlConfigFile config = new XmlConfigFile(loader, null, new InputSource(dup), null, substituteProps); + return fromConfig(solrHome, config); } } catch (SolrException exc) { throw exc; @@ -147,13 +157,8 @@ public class SolrXmlConfig { } } - public static NodeConfig fromSolrHome(SolrResourceLoader loader, Path solrHome) { - return fromFile(loader, solrHome.resolve(SOLR_XML_FILE)); - } - - public static NodeConfig fromSolrHome(Path solrHome) { - SolrResourceLoader loader = new SolrResourceLoader(solrHome); - return fromSolrHome(loader, solrHome); + public static NodeConfig fromSolrHome(Path solrHome, Properties substituteProps) { + return fromFile(solrHome, solrHome.resolve(SOLR_XML_FILE), substituteProps); } private static void checkForIllegalConfig(XmlConfigFile config) { @@ -187,7 +192,7 @@ public class SolrXmlConfig { Node node = ((NodeList) config.evaluate("solr", XPathConstants.NODESET)).item(0); XPath xpath = config.getXPath(); NodeList props = (NodeList) xpath.evaluate("property", node, XPathConstants.NODESET); - Properties properties = new Properties(); + Properties properties = new Properties(config.getSubstituteProperties()); for (int i = 0; i < props.getLength(); i++) { Node prop = props.item(i); properties.setProperty(DOMUtil.getAttr(prop, NAME), diff --git a/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java b/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java index 0490aa494b6..ab9f5aa0c00 100644 --- a/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java +++ b/solr/core/src/java/org/apache/solr/core/XmlConfigFile.java @@ -72,20 +72,25 @@ public class XmlConfigFile { // formerly simply "Config" private final String prefix; private final String name; private final SolrResourceLoader loader; + private final Properties substituteProperties; private int zkVersion = -1; /** - * Builds a config from a resource name with no xpath prefix. + * Builds a config from a resource name with no xpath prefix. Does no property substitution. */ public XmlConfigFile(SolrResourceLoader loader, String name) throws ParserConfigurationException, IOException, SAXException { this( loader, name, null, null ); } + /** + * Builds a config. Does no property substitution. + */ public XmlConfigFile(SolrResourceLoader loader, String name, InputSource is, String prefix) throws ParserConfigurationException, IOException, SAXException { - this(loader, name, is, prefix, true); + this(loader, name, is, prefix, null); } + /** * Builds a config: *

@@ -101,20 +106,22 @@ public class XmlConfigFile { // formerly simply "Config" * @param name the resource name used if the input stream 'is' is null * @param is the resource as a SAX InputSource * @param prefix an optional prefix that will be prepended to all non-absolute xpath expressions + * @param substituteProps optional property substitution */ - public XmlConfigFile(SolrResourceLoader loader, String name, InputSource is, String prefix, boolean substituteProps) throws ParserConfigurationException, IOException, SAXException + public XmlConfigFile(SolrResourceLoader loader, String name, InputSource is, String prefix, Properties substituteProps) throws ParserConfigurationException, IOException, SAXException { if( loader == null ) { - loader = new SolrResourceLoader(SolrResourceLoader.locateSolrHome()); + loader = new SolrResourceLoader(SolrPaths.locateSolrHome()); } this.loader = loader; + this.substituteProperties = substituteProps; this.name = name; this.prefix = (prefix != null && !prefix.endsWith("/"))? prefix + '/' : prefix; try { javax.xml.parsers.DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); if (is == null) { - InputStream in = loader.openConfig(name); + InputStream in = loader.openResource(name); if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) { zkVersion = ((ZkSolrResourceLoader.ZkByteArrayInputStream) in).getStat().getVersion(); log.debug("loaded config {} with version {} ",name,zkVersion); @@ -143,7 +150,7 @@ public class XmlConfigFile { // formerly simply "Config" // some XML parsers are broken and don't close the byte stream (but they should according to spec) IOUtils.closeQuietly(is.getByteStream()); } - if (substituteProps) { + if (substituteProps != null) { DOMUtil.substituteProperties(doc, getSubstituteProperties()); } } catch (ParserConfigurationException | SAXException | TransformerException e) { @@ -167,23 +174,11 @@ public class XmlConfigFile { // formerly simply "Config" } } + /** Returns non-null props to substitute. Param is the base/default set, also non-null. */ protected Properties getSubstituteProperties() { - return loader.getCoreProperties(); + return this.substituteProperties; } - public XmlConfigFile(SolrResourceLoader loader, String name, Document doc) { - this.prefix = null; - this.doc = doc; - try { - this.origDoc = copyDoc(doc); - } catch (TransformerException e) { - throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); - } - this.name = name; - this.loader = loader; - } - - private static Document copyDoc(Document doc) throws TransformerException { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer tx = tfactory.newTransformer(); @@ -224,11 +219,6 @@ public class XmlConfigFile { // formerly simply "Config" return (prefix==null || path.startsWith("/")) ? path : prefix+path; } - public void substituteProperties() { - DOMUtil.substituteProperties(doc, getSubstituteProperties()); - } - - public Object evaluate(String path, QName type) { XPath xpath = xpathFactory.newXPath(); try { @@ -442,8 +432,4 @@ public class XmlConfigFile { // formerly simply "Config" return zkVersion; } - public XmlConfigFile getOriginalConfig() { - return new XmlConfigFile(loader, null, origDoc); - } - } diff --git a/solr/core/src/java/org/apache/solr/core/ZkContainer.java b/solr/core/src/java/org/apache/solr/core/ZkContainer.java index 0d7e6227d4c..417a84f47e0 100644 --- a/solr/core/src/java/org/apache/solr/core/ZkContainer.java +++ b/solr/core/src/java/org/apache/solr/core/ZkContainer.java @@ -60,7 +60,7 @@ public class ZkContainer { } - public void initZooKeeper(final CoreContainer cc, String solrHome, CloudConfig config) { + public void initZooKeeper(final CoreContainer cc, CloudConfig config) { ZkController zkController = null; @@ -79,6 +79,7 @@ public class ZkContainer { // TODO: remove after updating to an slf4j based zookeeper System.setProperty("zookeeper.jmx.log4j.disable", "true"); + String solrHome = cc.getSolrHome(); if (zkRun != null) { String zkDataHome = System.getProperty("zkServerDataDir", Paths.get(solrHome).resolve("zoo_data").toString()); String zkConfHome = System.getProperty("zkServerConfDir", solrHome); @@ -147,7 +148,7 @@ public class ZkContainer { if(boostrapConf) { - ZkController.bootstrapConf(zkController.getZkClient(), cc, solrHome); + ZkController.bootstrapConf(zkController.getZkClient(), cc); } } catch (InterruptedException e) { diff --git a/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java b/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java index 3389bf46ede..951564ae4cd 100644 --- a/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java +++ b/solr/core/src/java/org/apache/solr/filestore/DistribPackageStore.java @@ -73,9 +73,8 @@ public class DistribPackageStore implements PackageStore { public DistribPackageStore(CoreContainer coreContainer) { this.coreContainer = coreContainer; - solrhome = this.coreContainer.getResourceLoader().getInstancePath(); - ensurePackageStoreDir(coreContainer.getResourceLoader().getInstancePath()); - + this.solrhome = Paths.get(this.coreContainer.getSolrHome()); + ensurePackageStoreDir(Paths.get(coreContainer.getSolrHome())); } @Override diff --git a/solr/core/src/java/org/apache/solr/handler/CatStream.java b/solr/core/src/java/org/apache/solr/handler/CatStream.java index 7dc10a115c9..d1ebf5a8dfa 100644 --- a/solr/core/src/java/org/apache/solr/handler/CatStream.java +++ b/solr/core/src/java/org/apache/solr/handler/CatStream.java @@ -42,7 +42,7 @@ import org.apache.solr.client.solrj.io.stream.expr.StreamFactory; import org.apache.solr.common.SolrException; import org.apache.solr.common.StringUtils; import org.apache.solr.core.SolrCore; -import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.core.SolrPaths; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -95,9 +95,9 @@ public class CatStream extends TupleStream implements Expressible { } final SolrCore core = (SolrCore) context.get("solr-core"); - this.chroot = Paths.get(core.getCoreContainer().getSolrHome(), SolrResourceLoader.USER_FILES_DIRECTORY).toString(); + this.chroot = Paths.get(core.getCoreContainer().getSolrHome(), SolrPaths.USER_FILES_DIRECTORY).toString(); if (! new File(this.chroot).exists()) { - throw new IllegalStateException(SolrResourceLoader.USER_FILES_DIRECTORY + " directory used to load files must exist but could not be found!"); + throw new IllegalStateException(SolrPaths.USER_FILES_DIRECTORY + " directory used to load files must exist but could not be found!"); } } diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java index 5739651c7fa..f8c7e8c772a 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java @@ -321,7 +321,7 @@ enum CoreAdminOperation implements CoreAdminOp { try (SolrCore core = cores.getCore(cname)) { if (core != null) { info.add(NAME, core.getName()); - info.add("instanceDir", core.getResourceLoader().getInstancePath().toString()); + info.add("instanceDir", core.getInstancePath().toString()); info.add("dataDir", normalizePath(core.getDataDir())); info.add("config", core.getConfigResource()); info.add("schema", core.getSchemaResource()); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java index e27624c3177..0d417bd1995 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/SystemInfoHandler.java @@ -188,7 +188,7 @@ public class SystemInfoHandler extends RequestHandlerBase // Solr Home SimpleOrderedMap dirs = new SimpleOrderedMap<>(); dirs.add( "cwd" , new File( System.getProperty("user.dir")).getAbsolutePath() ); - dirs.add("instance", core.getResourceLoader().getInstancePath().toString()); + dirs.add("instance", core.getInstancePath().toString()); try { dirs.add( "data", core.getDirectoryFactory().normalize(core.getDataDir())); } catch (IOException e) { diff --git a/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java b/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java index 2be2eec8bdd..2ed85fe2995 100644 --- a/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java +++ b/solr/core/src/java/org/apache/solr/pkg/PackageLoader.java @@ -20,8 +20,8 @@ package org.apache.solr.pkg; import java.io.Closeable; import java.io.IOException; import java.lang.invoke.MethodHandles; -import java.net.MalformedURLException; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -265,15 +265,11 @@ public class PackageLoader implements Closeable { paths.add(coreContainer.getPackageStoreAPI().getPackageStore().getRealpath(file)); } - try { - loader = new SolrResourceLoader( - "PACKAGE_LOADER: " + parent.name() + ":" + version, - paths, - coreContainer.getResourceLoader().getInstancePath(), - coreContainer.getResourceLoader().getClassLoader()); - } catch (MalformedURLException e) { - log.error("Could not load classloader ", e); - } + loader = new SolrResourceLoader( + "PACKAGE_LOADER: " + parent.name() + ":" + version, + paths, + Paths.get(coreContainer.getSolrHome()), + coreContainer.getResourceLoader().getClassLoader()); } public String getVersion() { diff --git a/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java b/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java index cdbfd9888ac..e7a26b77c5d 100644 --- a/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java +++ b/solr/core/src/java/org/apache/solr/schema/ExternalFileField.java @@ -23,6 +23,7 @@ import org.apache.lucene.index.IndexableField; import org.apache.lucene.queries.function.ValueSource; import org.apache.lucene.search.SortField; import org.apache.solr.common.SolrException; +import org.apache.solr.request.SolrRequestInfo; import org.apache.solr.response.TextResponseWriter; import org.apache.solr.search.QParser; import org.apache.solr.search.function.FileFloatSource; @@ -95,7 +96,7 @@ public class ExternalFileField extends FieldType implements SchemaAware { * @return a FileFloatSource */ public FileFloatSource getFileFloatSource(SchemaField field) { - return getFileFloatSource(field, schema.getResourceLoader().getDataDir()); + return getFileFloatSource(field, SolrRequestInfo.getRequestInfo().getReq().getCore().getDataDir()); } /** diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java index 6bd2e79f031..302798f7c31 100644 --- a/solr/core/src/java/org/apache/solr/schema/IndexSchema.java +++ b/solr/core/src/java/org/apache/solr/schema/IndexSchema.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Properties; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -134,6 +135,7 @@ public class IndexSchema { protected final Version luceneVersion; protected float version; protected final SolrResourceLoader loader; + protected final Properties substitutableProperties; protected Map fields = new HashMap<>(); protected Map fieldTypes = new HashMap<>(); @@ -141,6 +143,7 @@ public class IndexSchema { protected List fieldsWithDefaultValue = new ArrayList<>(); protected Collection requiredFields = new HashSet<>(); protected DynamicField[] dynamicFields = new DynamicField[] {}; + public DynamicField[] getDynamicFields() { return dynamicFields; } protected Cache dynamicFieldCache = new ConcurrentLRUCache(10000, 8000, 9000,100, false,false, null); @@ -166,12 +169,11 @@ public class IndexSchema { /** * Constructs a schema using the specified resource name and stream. - * @see SolrResourceLoader#openSchema * By default, this follows the normal config path directory searching rules. * @see SolrResourceLoader#openResource */ - public IndexSchema(String name, InputSource is, Version luceneVersion, SolrResourceLoader resourceLoader) { - this(luceneVersion, resourceLoader); + public IndexSchema(String name, InputSource is, Version luceneVersion, SolrResourceLoader resourceLoader, Properties substitutableProperties) { + this(luceneVersion, resourceLoader, substitutableProperties); this.resourceName = Objects.requireNonNull(name); try { @@ -182,9 +184,10 @@ public class IndexSchema { } } - protected IndexSchema(Version luceneVersion, SolrResourceLoader loader) { + protected IndexSchema(Version luceneVersion, SolrResourceLoader loader, Properties substitutableProperties) { this.luceneVersion = Objects.requireNonNull(luceneVersion); this.loader = loader; + this.substitutableProperties = substitutableProperties; } /** @@ -468,17 +471,13 @@ public class IndexSchema { try { // pass the config resource loader to avoid building an empty one for no reason: // in the current case though, the stream is valid so we wont load the resource by name - XmlConfigFile schemaConf = new XmlConfigFile(loader, SCHEMA, is, SLASH+SCHEMA+SLASH); + XmlConfigFile schemaConf = new XmlConfigFile(loader, SCHEMA, is, SLASH+SCHEMA+SLASH, substitutableProperties); Document document = schemaConf.getDocument(); final XPath xpath = schemaConf.getXPath(); String expression = stepsToPath(SCHEMA, AT + NAME); Node nd = (Node) xpath.evaluate(expression, document, XPathConstants.NODE); - String coreName = getCoreName("null"); StringBuilder sb = new StringBuilder(); // Another case where the initialization from the test harness is different than the "real world" - sb.append("["); - sb.append(coreName); - sb.append("] "); if (nd==null) { sb.append("schema has no name!"); log.warn(sb.toString()); @@ -620,14 +619,6 @@ public class IndexSchema { log.info("Loaded schema {}/{} with uniqueid field {}", name, version, uniqueKeyFieldName); } - private String getCoreName(String defaultVal) { - if (loader != null && loader.getCoreProperties() != null) { - return loader.getCoreProperties().getProperty(SOLR_CORE_NAME, defaultVal); - } else { - return defaultVal; - } - } - protected void postReadInform() { //Run the callbacks on SchemaAware now that everything else is done for (SchemaAware aware : schemaAware) { diff --git a/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java index 7be2569998b..095efd4fcdf 100644 --- a/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/IndexSchemaFactory.java @@ -74,7 +74,7 @@ public abstract class IndexSchemaFactory implements NamedListInitializedPlugin { } try { - schemaInputStream = loader.openSchema(resourceName); + schemaInputStream = loader.openResource(resourceName); } catch (Exception e) { final String msg = "Error loading schema resource " + resourceName; log.error(msg, e); @@ -82,7 +82,7 @@ public abstract class IndexSchemaFactory implements NamedListInitializedPlugin { } InputSource inputSource = new InputSource(schemaInputStream); inputSource.setSystemId(SystemIdResolver.createSystemIdFromResourceName(resourceName)); - IndexSchema schema = new IndexSchema(resourceName, inputSource, config.luceneMatchVersion, loader); + IndexSchema schema = new IndexSchema(resourceName, inputSource, config.luceneMatchVersion, loader, config.getSubstituteProperties()); return schema; } diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java index 7e16880f35e..135a9006599 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java @@ -31,6 +31,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -96,13 +97,12 @@ public final class ManagedIndexSchema extends IndexSchema { /** * Constructs a schema using the specified resource name and stream. * - * @see org.apache.solr.core.SolrResourceLoader#openSchema - * By default, this follows the normal config path directory searching rules. + * By default, this follows the normal config path directory searching rules. * @see org.apache.solr.core.SolrResourceLoader#openResource */ - ManagedIndexSchema(SolrConfig solrConfig, String name, InputSource is, boolean isMutable, + ManagedIndexSchema(SolrConfig solrConfig, String name, InputSource is, boolean isMutable, String managedSchemaResourceName, int schemaZkVersion, Object schemaUpdateLock) { - super(name, is, solrConfig.luceneMatchVersion, solrConfig.getResourceLoader()); + super(name, is, solrConfig.luceneMatchVersion, solrConfig.getResourceLoader(), solrConfig.getSubstituteProperties()); this.isMutable = isMutable; this.managedSchemaResourceName = managedSchemaResourceName; this.schemaZkVersion = schemaZkVersion; @@ -1323,8 +1323,8 @@ public final class ManagedIndexSchema extends IndexSchema { } private ManagedIndexSchema(Version luceneVersion, SolrResourceLoader loader, boolean isMutable, - String managedSchemaResourceName, int schemaZkVersion, Object schemaUpdateLock) { - super(luceneVersion, loader); + String managedSchemaResourceName, int schemaZkVersion, Object schemaUpdateLock, Properties substitutableProps) { + super(luceneVersion, loader, substitutableProps); this.isMutable = isMutable; this.managedSchemaResourceName = managedSchemaResourceName; this.schemaZkVersion = schemaZkVersion; @@ -1342,7 +1342,7 @@ public final class ManagedIndexSchema extends IndexSchema { */ ManagedIndexSchema shallowCopy(boolean includeFieldDataStructures) { ManagedIndexSchema newSchema = new ManagedIndexSchema - (luceneVersion, loader, isMutable, managedSchemaResourceName, schemaZkVersion, getSchemaUpdateLock()); + (luceneVersion, loader, isMutable, managedSchemaResourceName, schemaZkVersion, getSchemaUpdateLock(), substitutableProperties); newSchema.name = name; newSchema.version = version; diff --git a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java index 4a8a1023a1c..44d4c8e3ce7 100644 --- a/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java +++ b/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java @@ -149,7 +149,7 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol if (null == schemaInputStream) { // The managed schema file could not be found - load the non-managed schema try { - schemaInputStream = loader.openSchema(resourceName); + schemaInputStream = loader.openResource(resourceName); loadedResource = resourceName; shouldUpgrade = true; } catch (Exception e) { @@ -190,7 +190,7 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol InputStream schemaInputStream = null; try { // Attempt to load the managed schema - schemaInputStream = loader.openSchema(managedSchemaResourceName); + schemaInputStream = loader.openResource(managedSchemaResourceName); loadedResource = managedSchemaResourceName; warnIfNonManagedSchemaExists(); } catch (IOException e) { @@ -200,7 +200,7 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol if (null == schemaInputStream) { // The managed schema file could not be found - load the non-managed schema try { - schemaInputStream = loader.openSchema(resourceName); + schemaInputStream = loader.openResource(resourceName); loadedResource = resourceName; shouldUpgrade = true; } catch (Exception e) { @@ -235,7 +235,7 @@ public class ManagedIndexSchemaFactory extends IndexSchemaFactory implements Sol } else { // Config is not in ZooKeeper InputStream nonManagedSchemaInputStream = null; try { - nonManagedSchemaInputStream = loader.openSchema(resourceName); + nonManagedSchemaInputStream = loader.openResource(resourceName); if (null != nonManagedSchemaInputStream) { exists = true; } diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index a3968d86840..d744484f5ca 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -72,8 +72,8 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.NodeConfig; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrInfoBean; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; +import org.apache.solr.core.SolrPaths; import org.apache.solr.metrics.AltBufferPoolMetricSet; import org.apache.solr.metrics.MetricsMap; import org.apache.solr.metrics.OperatingSystemMetricSet; @@ -179,9 +179,9 @@ public class SolrDispatchFilter extends BaseSolrFilter { extraProperties = new Properties(); String solrHome = (String) config.getServletContext().getAttribute(SOLRHOME_ATTRIBUTE); - final Path solrHomePath = solrHome == null ? SolrResourceLoader.locateSolrHome() : Paths.get(solrHome); + final Path solrHomePath = solrHome == null ? SolrPaths.locateSolrHome() : Paths.get(solrHome); coresInit = createCoreContainer(solrHomePath, extraProperties); - SolrResourceLoader.ensureUserFilesDataDir(solrHomePath); + SolrPaths.ensureUserFilesDataDir(solrHomePath); this.httpClient = coresInit.getUpdateShardHandler().getDefaultHttpClient(); setupJvmMetrics(coresInit); log.debug("user.dir=" + System.getProperty("user.dir")); @@ -259,7 +259,7 @@ public class SolrDispatchFilter extends BaseSolrFilter { */ protected CoreContainer createCoreContainer(Path solrHome, Properties extraProperties) { NodeConfig nodeConfig = loadNodeConfig(solrHome, extraProperties); - final CoreContainer coreContainer = new CoreContainer(nodeConfig, extraProperties, true); + final CoreContainer coreContainer = new CoreContainer(nodeConfig, true); coreContainer.load(); return coreContainer; } @@ -270,33 +270,28 @@ public class SolrDispatchFilter extends BaseSolrFilter { * @return the NodeConfig */ public static NodeConfig loadNodeConfig(Path solrHome, Properties nodeProperties) { - NodeConfig cfg = null; - try (SolrResourceLoader loader = new SolrResourceLoader(solrHome, SolrDispatchFilter.class.getClassLoader(), nodeProperties)) { - if (!StringUtils.isEmpty(System.getProperty("solr.solrxml.location"))) { - log.warn("Solr property solr.solrxml.location is no longer supported. " + - "Will automatically load solr.xml from ZooKeeper if it exists"); - } - - String zkHost = System.getProperty("zkHost"); - if (!StringUtils.isEmpty(zkHost)) { - int startUpZkTimeOut = Integer.getInteger("waitForZk", 30); - startUpZkTimeOut *= 1000; - try (SolrZkClient zkClient = new SolrZkClient(zkHost, startUpZkTimeOut)) { - if (zkClient.exists("/solr.xml", true)) { - log.info("solr.xml found in ZooKeeper. Loading..."); - byte[] data = zkClient.getData("/solr.xml", null, null, true); - return SolrXmlConfig.fromInputStream(loader, new ByteArrayInputStream(data)); - } - } catch (Exception e) { - throw new SolrException(ErrorCode.SERVER_ERROR, "Error occurred while loading solr.xml from zookeeper", e); - } - log.info("Loading solr.xml from SolrHome (not found in ZooKeeper)"); - } - cfg = SolrXmlConfig.fromSolrHome(loader, loader.getInstancePath()); - } catch (IOException e) { - // do nothing. + if (!StringUtils.isEmpty(System.getProperty("solr.solrxml.location"))) { + log.warn("Solr property solr.solrxml.location is no longer supported. " + + "Will automatically load solr.xml from ZooKeeper if it exists"); } - return cfg; + + String zkHost = System.getProperty("zkHost"); + if (!StringUtils.isEmpty(zkHost)) { + int startUpZkTimeOut = Integer.getInteger("waitForZk", 30); + startUpZkTimeOut *= 1000; + try (SolrZkClient zkClient = new SolrZkClient(zkHost, startUpZkTimeOut)) { + if (zkClient.exists("/solr.xml", true)) { + log.info("solr.xml found in ZooKeeper. Loading..."); + byte[] data = zkClient.getData("/solr.xml", null, null, true); + return SolrXmlConfig.fromInputStream(solrHome, new ByteArrayInputStream(data), nodeProperties); + } + } catch (Exception e) { + throw new SolrException(ErrorCode.SERVER_ERROR, "Error occurred while loading solr.xml from zookeeper", e); + } + log.info("Loading solr.xml from SolrHome (not found in ZooKeeper)"); + } + + return SolrXmlConfig.fromSolrHome(solrHome, nodeProperties); } public CoreContainer getCores() { diff --git a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerAdminHandler.java b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerAdminHandler.java index ca3634d51f2..6df6a6bf6b2 100644 --- a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerAdminHandler.java +++ b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerAdminHandler.java @@ -17,8 +17,6 @@ package org.apache.solr.client.solrj.embedded; import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.SolrClient; @@ -29,18 +27,15 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.params.SolrParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.NodeConfig; -import org.apache.solr.core.SolrResourceLoader; import org.junit.Test; public class TestEmbeddedSolrServerAdminHandler extends SolrTestCaseJ4 { @Test public void testPathIsAddedToContext() throws IOException, SolrServerException { - final Path path = createTempDir(); - final SolrResourceLoader loader = new SolrResourceLoader(path); - final NodeConfig config = new NodeConfig.NodeConfigBuilder("testnode", loader) - .setConfigSetBaseDirectory(Paths.get(TEST_HOME()).resolve("configsets").toString()) + final NodeConfig config = new NodeConfig.NodeConfigBuilder("testnode", TEST_PATH()) + .setConfigSetBaseDirectory(TEST_PATH().resolve("configsets").toString()) .build(); try (final EmbeddedSolrServer server = new EmbeddedSolrServer(config, "collection1")) { diff --git a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java index 0ce83d89aa8..951853248dd 100644 --- a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java +++ b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerConstructors.java @@ -25,7 +25,6 @@ import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.core.NodeConfig; -import org.apache.solr.core.SolrResourceLoader; import org.junit.Test; public class TestEmbeddedSolrServerConstructors extends SolrTestCaseJ4 { @@ -42,8 +41,7 @@ public class TestEmbeddedSolrServerConstructors extends SolrTestCaseJ4 { public void testNodeConfigConstructor() throws Exception { Path path = createTempDir(); - SolrResourceLoader loader = new SolrResourceLoader(path); - NodeConfig config = new NodeConfig.NodeConfigBuilder("testnode", loader) + NodeConfig config = new NodeConfig.NodeConfigBuilder("testnode", path) .setConfigSetBaseDirectory(Paths.get(TEST_HOME()).resolve("configsets").toString()) .build(); diff --git a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java index 8991b4f67b0..39b33188eeb 100644 --- a/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java @@ -361,7 +361,7 @@ public class ZkControllerTest extends SolrTestCaseJ4 { UpdateShardHandler updateShardHandler = new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT); public MockCoreContainer() { - super(SolrXmlConfig.fromString(null, "")); + super(SolrXmlConfig.fromString(TEST_PATH(), "")); this.shardHandlerFactory = new HttpShardHandlerFactory(); this.coreAdminHandler = new CoreAdminHandler(); } diff --git a/solr/core/src/test/org/apache/solr/cloud/api/collections/CollectionsAPIDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/api/collections/CollectionsAPIDistributedZkTest.java index 1899d8d4064..f549203aa62 100644 --- a/solr/core/src/test/org/apache/solr/cloud/api/collections/CollectionsAPIDistributedZkTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/api/collections/CollectionsAPIDistributedZkTest.java @@ -16,9 +16,9 @@ */ package org.apache.solr.cloud.api.collections; -import static org.apache.solr.common.cloud.ZkStateReader.CORE_NAME_PROP; -import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR; - +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; import java.io.IOException; import java.lang.invoke.MethodHandles; import java.lang.management.ManagementFactory; @@ -38,10 +38,7 @@ import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.ObjectName; - +import com.google.common.collect.ImmutableList; import org.apache.lucene.util.LuceneTestCase.Slow; import org.apache.lucene.util.TestUtil; import org.apache.solr.client.solrj.SolrQuery; @@ -81,7 +78,8 @@ import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.ImmutableList; +import static org.apache.solr.common.cloud.ZkStateReader.CORE_NAME_PROP; +import static org.apache.solr.common.cloud.ZkStateReader.REPLICATION_FACTOR; /** * Tests the Cloud Collections API. @@ -503,7 +501,7 @@ public class CollectionsAPIDistributedZkTest extends SolrCloudTestCase { Collection theCores = cores.getCores(); for (SolrCore core : theCores) { // look for core props file - Path instancedir = core.getResourceLoader().getInstancePath(); + Path instancedir = core.getInstancePath(); assertTrue("Could not find expected core.properties file", Files.exists(instancedir.resolve("core.properties"))); Path expected = Paths.get(jetty.getSolrHome()).toAbsolutePath().resolve(core.getName()); diff --git a/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java b/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java index 6e835180ca3..71bb73b0720 100755 --- a/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java +++ b/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java @@ -121,6 +121,6 @@ public class DirectoryFactoryTest extends SolrTestCase { private NodeConfig loadNodeConfig(String config) throws Exception { InputStream is = DirectoryFactoryTest.class.getResourceAsStream(config); - return SolrXmlConfig.fromInputStream(loader, is); + return SolrXmlConfig.fromInputStream(solrHome, is, new Properties()); } } diff --git a/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java b/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java index 0c175537713..5cca2293b30 100644 --- a/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java +++ b/solr/core/src/test/org/apache/solr/core/ResourceLoaderTest.java @@ -23,6 +23,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -169,12 +170,13 @@ public class ResourceLoaderTest extends SolrTestCaseJ4 { } SolrResourceLoader loader = new SolrResourceLoader(tmpRoot); + loader.addToClassLoader(SolrResourceLoader.getURLs(lib)); - // ./lib is accessible by default + // check "lib/aLibFile" assertNotNull(loader.getClassLoader().getResource("aLibFile")); // add inidividual jars from other paths - loader.addToClassLoader(otherLib.resolve("jar2.jar").toUri().toURL()); + loader.addToClassLoader(Collections.singletonList(otherLib.resolve("jar2.jar").toUri().toURL())); assertNotNull(loader.getClassLoader().getResource("explicitFile")); assertNull(loader.getClassLoader().getResource("otherFile")); diff --git a/solr/core/src/test/org/apache/solr/core/TestConfig.java b/solr/core/src/test/org/apache/solr/core/TestConfig.java index 38722cf2219..893cf0ab49a 100644 --- a/solr/core/src/test/org/apache/solr/core/TestConfig.java +++ b/solr/core/src/test/org/apache/solr/core/TestConfig.java @@ -110,7 +110,7 @@ public class TestConfig extends SolrTestCaseJ4 { @Test public void testCacheEnablingDisabling() throws Exception { // ensure if cache is not defined in the config then cache is disabled - SolrConfig sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-defaults.xml", null, true); + SolrConfig sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-defaults.xml"); assertNull(sc.filterCacheConfig); assertNull(sc.queryResultCacheConfig); assertNull(sc.documentCacheConfig); @@ -119,7 +119,7 @@ public class TestConfig extends SolrTestCaseJ4 { System.setProperty("filterCache.enabled", "true"); System.setProperty("queryResultCache.enabled", "true"); System.setProperty("documentCache.enabled", "true"); - sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-cache-enable-disable.xml", null, true); + sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-cache-enable-disable.xml"); assertNotNull(sc.filterCacheConfig); assertNotNull(sc.queryResultCacheConfig); assertNotNull(sc.documentCacheConfig); @@ -128,7 +128,7 @@ public class TestConfig extends SolrTestCaseJ4 { System.setProperty("filterCache.enabled", "false"); System.setProperty("queryResultCache.enabled", "false"); System.setProperty("documentCache.enabled", "false"); - sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-cache-enable-disable.xml", null, true); + sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-cache-enable-disable.xml"); assertNull(sc.filterCacheConfig); assertNull(sc.queryResultCacheConfig); assertNull(sc.documentCacheConfig); @@ -146,7 +146,7 @@ public class TestConfig extends SolrTestCaseJ4 { int numDefaultsTested = 0; int numNullDefaults = 0; - SolrConfig sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-defaults.xml", null, true); + SolrConfig sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-defaults.xml"); SolrIndexConfig sic = sc.indexConfig; ++numDefaultsTested; assertEquals("default useCompoundFile", false, sic.useCompoundFile); @@ -210,7 +210,7 @@ public class TestConfig extends SolrTestCaseJ4 { @Test public void testMaxSizeSettingWithoutAutoCommit() throws Exception { - SolrConfig solrConfig = new SolrConfig(TEST_PATH().resolve("collection1"), "bad-solrconfig-no-autocommit-tag.xml", null, true); + SolrConfig solrConfig = new SolrConfig(TEST_PATH().resolve("collection1"), "bad-solrconfig-no-autocommit-tag.xml"); Assert.assertEquals(-1, solrConfig.getUpdateHandlerInfo().autoCommitMaxSizeBytes); Assert.assertEquals(-1, solrConfig.getUpdateHandlerInfo().autoCommmitMaxDocs); Assert.assertEquals(-1, solrConfig.getUpdateHandlerInfo().autoCommmitMaxTime); @@ -219,7 +219,7 @@ public class TestConfig extends SolrTestCaseJ4 { // sanity check that sys properties are working as expected public void testSanityCheckTestSysPropsAreUsed() throws Exception { - SolrConfig sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-basic.xml", null, true); + SolrConfig sc = new SolrConfig(TEST_PATH().resolve("collection1"), "solrconfig-basic.xml"); SolrIndexConfig sic = sc.indexConfig; assertEquals("ramBufferSizeMB sysprop", diff --git a/solr/core/src/test/org/apache/solr/core/TestConfigSets.java b/solr/core/src/test/org/apache/solr/core/TestConfigSets.java index 84aa65d4998..e044cfb6b74 100644 --- a/solr/core/src/test/org/apache/solr/core/TestConfigSets.java +++ b/solr/core/src/test/org/apache/solr/core/TestConfigSets.java @@ -47,8 +47,7 @@ public class TestConfigSets extends SolrTestCaseJ4 { System.setProperty("configsets", configSetsBaseDir); - SolrResourceLoader loader = new SolrResourceLoader(testDirectory); - CoreContainer container = new CoreContainer(SolrXmlConfig.fromString(loader, solrxml)); + CoreContainer container = new CoreContainer(SolrXmlConfig.fromString(testDirectory, solrxml)); container.load(); return container; @@ -56,17 +55,17 @@ public class TestConfigSets extends SolrTestCaseJ4 { @Test public void testDefaultConfigSetBasePathResolution() throws IOException { - try (SolrResourceLoader loader = new SolrResourceLoader(Paths.get("/path/to/solr/home"))) { + Path solrHome = Paths.get("/path/to/solr/home"); - NodeConfig config - = SolrXmlConfig.fromString(loader, "configsets"); - assertThat(config.getConfigSetBaseDirectory().toAbsolutePath(), - is(Paths.get("/path/to/solr/home/configsets").toAbsolutePath())); + NodeConfig config + = SolrXmlConfig.fromString(solrHome, "configsets"); + assertThat(config.getConfigSetBaseDirectory().toAbsolutePath(), + is(Paths.get("/path/to/solr/home/configsets").toAbsolutePath())); + + NodeConfig absConfig + = SolrXmlConfig.fromString(solrHome, "/path/to/configsets"); + assertThat(absConfig.getConfigSetBaseDirectory().toAbsolutePath(), is(Paths.get("/path/to/configsets").toAbsolutePath())); - NodeConfig absConfig - = SolrXmlConfig.fromString(loader, "/path/to/configsets"); - assertThat(absConfig.getConfigSetBaseDirectory().toAbsolutePath(), is(Paths.get("/path/to/configsets").toAbsolutePath())); - } } @Test @@ -74,11 +73,11 @@ public class TestConfigSets extends SolrTestCaseJ4 { CoreContainer container = null; try { container = setupContainer(TEST_PATH().resolve("configsets").toString()); - Path testDirectory = container.getResourceLoader().getInstancePath(); + Path solrHome = Paths.get(container.getSolrHome()); SolrCore core1 = container.create("core1", ImmutableMap.of("configSet", "configset-2")); assertThat(core1.getCoreDescriptor().getName(), is("core1")); - assertThat(Paths.get(core1.getDataDir()).toString(), is(testDirectory.resolve("core1").resolve("data").toString())); + assertThat(Paths.get(core1.getDataDir()).toString(), is(solrHome.resolve("core1").resolve("data").toString())); } finally { if (container != null) @@ -90,8 +89,6 @@ public class TestConfigSets extends SolrTestCaseJ4 { public void testNonExistentConfigSetThrowsException() { final CoreContainer container = setupContainer(getFile("solr/configsets").getAbsolutePath()); try { - Path testDirectory = container.getResourceLoader().getInstancePath(); - Exception thrown = expectThrows(Exception.class, "Expected core creation to fail", () -> { container.create("core1", ImmutableMap.of("configSet", "nonexistent")); }); @@ -113,8 +110,7 @@ public class TestConfigSets extends SolrTestCaseJ4 { String csd = configSetsDir.getAbsolutePath(); System.setProperty("configsets", csd); - SolrResourceLoader loader = new SolrResourceLoader(testDirectory); - CoreContainer container = new CoreContainer(SolrXmlConfig.fromString(loader, solrxml)); + CoreContainer container = new CoreContainer(SolrXmlConfig.fromString(testDirectory, solrxml)); container.load(); // We initially don't have a /dump handler defined 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 c6e2d8cc554..6d1f0885bce 100644 --- a/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java +++ b/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.regex.Pattern; @@ -76,8 +75,7 @@ public class TestCoreContainer extends SolrTestCaseJ4 { } private CoreContainer init(Path homeDirectory, String xml) throws Exception { - SolrResourceLoader loader = new SolrResourceLoader(homeDirectory); - CoreContainer ret = new CoreContainer(SolrXmlConfig.fromString(loader, xml)); + CoreContainer ret = new CoreContainer(SolrXmlConfig.fromString(homeDirectory, xml)); ret.load(); return ret; } @@ -199,12 +197,11 @@ public class TestCoreContainer extends SolrTestCaseJ4 { MockCoresLocator cl = new MockCoresLocator(); - SolrResourceLoader resourceLoader = new SolrResourceLoader(createTempDir()); - + Path solrHome = createTempDir(); System.setProperty("configsets", getFile("solr/configsets").getAbsolutePath()); - final CoreContainer cc = new CoreContainer(SolrXmlConfig.fromString(resourceLoader, CONFIGSETS_SOLR_XML), new Properties(), cl); - Path corePath = resourceLoader.getInstancePath().resolve("badcore"); + final CoreContainer cc = new CoreContainer(SolrXmlConfig.fromString(solrHome, CONFIGSETS_SOLR_XML), cl); + Path corePath = solrHome.resolve("badcore"); CoreDescriptor badcore = new CoreDescriptor("badcore", corePath, cc, "configSet", "nosuchconfigset"); @@ -471,14 +468,14 @@ public class TestCoreContainer extends SolrTestCaseJ4 { // init the CoreContainer with the mix of ok/bad cores MockCoresLocator cl = new MockCoresLocator(); - SolrResourceLoader resourceLoader = new SolrResourceLoader(createTempDir()); + Path solrHome = createTempDir(); System.setProperty("configsets", getFile("solr/configsets").getAbsolutePath()); - final CoreContainer cc = new CoreContainer(SolrXmlConfig.fromString(resourceLoader, CONFIGSETS_SOLR_XML), new Properties(), cl); - cl.add(new CoreDescriptor("col_ok", resourceLoader.getInstancePath().resolve("col_ok"), cc, + final CoreContainer cc = new CoreContainer(SolrXmlConfig.fromString(solrHome, CONFIGSETS_SOLR_XML), cl); + cl.add(new CoreDescriptor("col_ok", solrHome.resolve("col_ok"), cc, "configSet", "minimal")); - cl.add(new CoreDescriptor("col_bad", resourceLoader.getInstancePath().resolve("col_bad"), cc, + cl.add(new CoreDescriptor("col_bad", solrHome.resolve("col_bad"), cc, "configSet", "bad-mergepolicy")); cc.load(); diff --git a/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java b/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java index 2b9bdc0e059..a9bd969144a 100644 --- a/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java +++ b/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java @@ -114,7 +114,7 @@ public class TestCoreDiscovery extends SolrTestCaseJ4 { } private CoreContainer init() throws Exception { - final CoreContainer container = new CoreContainer(); + final CoreContainer container = new CoreContainer(SolrPaths.locateSolrHome(), new Properties()); try { container.load(); } catch (Exception e) { @@ -298,7 +298,7 @@ public class TestCoreDiscovery extends SolrTestCaseJ4 { addCoreWithProps("coreT6", makeCoreProperties("coreT6", true, true, "dataDir=coreT6")); // Do this specially since we need to search. - final CoreContainer cc = new CoreContainer(solrHomeDirectory.toString()); + final CoreContainer cc = new CoreContainer(solrHomeDirectory, new Properties()); try { cc.load(); // Just check that the proper number of cores are loaded since making the test depend on order would be fragile @@ -547,13 +547,10 @@ public class TestCoreDiscovery extends SolrTestCaseJ4 { @Test public void testRootDirectoryResolution() { - - SolrResourceLoader loader = new SolrResourceLoader(solrHomeDirectory); - - NodeConfig config = SolrXmlConfig.fromString(loader, "relative"); + NodeConfig config = SolrXmlConfig.fromString(solrHomeDirectory, "relative"); assertThat(config.getCoreRootDirectory().toString(), containsString(solrHomeDirectory.toAbsolutePath().toString())); - NodeConfig absConfig = SolrXmlConfig.fromString(loader, "/absolute"); + NodeConfig absConfig = SolrXmlConfig.fromString(solrHomeDirectory, "/absolute"); assertThat(absConfig.getCoreRootDirectory().toString(), not(containsString(solrHomeDirectory.toAbsolutePath().toString()))); } diff --git a/solr/core/src/test/org/apache/solr/core/TestLazyCores.java b/solr/core/src/test/org/apache/solr/core/TestLazyCores.java index 8b715572d82..4120f3e124a 100644 --- a/solr/core/src/test/org/apache/solr/core/TestLazyCores.java +++ b/solr/core/src/test/org/apache/solr/core/TestLazyCores.java @@ -615,8 +615,7 @@ public class TestLazyCores extends SolrTestCaseJ4 { writeCustomConfig(coreName, min_config, bad_schema, rand_snip); } - SolrResourceLoader loader = new SolrResourceLoader(solrHomeDirectory.toPath()); - NodeConfig config = SolrXmlConfig.fromString(loader, ""); + NodeConfig config = SolrXmlConfig.fromString(solrHomeDirectory.toPath(), ""); // OK this should succeed, but at the end we should have recorded a series of errors. return createCoreContainer(config, new CorePropertiesLocator(config.getCoreRootDirectory())); 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 c714b0843b3..2fcf9715814 100644 --- a/solr/core/src/test/org/apache/solr/core/TestSolrXml.java +++ b/solr/core/src/test/org/apache/solr/core/TestSolrXml.java @@ -18,16 +18,17 @@ package org.apache.solr.core; import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.Locale; +import java.util.Properties; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; -import org.apache.commons.io.FileUtils; import org.apache.lucene.util.TestUtil; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrException; import org.apache.solr.update.UpdateShardHandlerConfig; -import org.junit.AfterClass; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.rules.ExpectedException; @@ -44,27 +45,18 @@ public class TestSolrXml extends SolrTestCaseJ4 { public ExpectedException expectedException = ExpectedException.none(); // tmp dir, cleaned up automatically. - private static File solrHome = null; - private static SolrResourceLoader loader = null; + private Path solrHome; - @BeforeClass - public static void setupLoader() throws Exception { - solrHome = createTempDir().toFile(); - loader = new SolrResourceLoader(solrHome.toPath()); - } - - @AfterClass - public static void cleanupLoader() throws Exception { - solrHome = null; - loader = null; + @Before + public void doBefore() { + solrHome = createTempDir(); } public void testAllInfoPresent() throws IOException { + Path testSrcRoot = TEST_PATH(); + Files.copy(testSrcRoot.resolve("solr-50-all.xml"), solrHome.resolve("solr.xml")); - File testSrcRoot = new File(SolrTestCaseJ4.TEST_HOME()); - FileUtils.copyFile(new File(testSrcRoot, "solr-50-all.xml"), new File(solrHome, "solr.xml")); - - NodeConfig cfg = SolrXmlConfig.fromSolrHome(loader, solrHome.toPath()); + NodeConfig cfg = SolrXmlConfig.fromSolrHome(solrHome, new Properties()); CloudConfig ccfg = cfg.getCloudConfig(); UpdateShardHandlerConfig ucfg = cfg.getUpdateShardHandlerConfig(); PluginInfo[] backupRepoConfigs = cfg.getBackupRepositoryPlugins(); @@ -117,16 +109,16 @@ public class TestSolrXml extends SolrTestCaseJ4 { System.setProperty("socketTimeout", "220"); System.setProperty("connTimeout", "200"); - File testSrcRoot = new File(SolrTestCaseJ4.TEST_HOME()); - FileUtils.copyFile(new File(testSrcRoot, "solr-50-all.xml"), new File(solrHome, "solr.xml")); + Path testSrcRoot = TEST_PATH(); + Files.copy(testSrcRoot.resolve("solr-50-all.xml"), solrHome.resolve("solr.xml")); - NodeConfig cfg = SolrXmlConfig.fromSolrHome(loader, solrHome.toPath()); + NodeConfig cfg = SolrXmlConfig.fromSolrHome(solrHome, new Properties()); assertThat(cfg.getCoreRootDirectory().toString(), containsString("myCoreRoot")); assertEquals("solr host port", 8888, cfg.getCloudConfig().getSolrHostPort()); assertEquals("schema cache", false, cfg.hasSchemaCache()); } - public void testExplicitNullGivesDefaults() throws IOException { + public void testExplicitNullGivesDefaults() { String solrXml = "" + "" + "" + @@ -136,48 +128,48 @@ public class TestSolrXml extends SolrTestCaseJ4 { "" + ""; - NodeConfig cfg = SolrXmlConfig.fromString(loader, solrXml); + NodeConfig cfg = SolrXmlConfig.fromString(solrHome, solrXml); assertNull("maxBooleanClauses", cfg.getBooleanQueryMaxClauseCount()); // default is null assertEquals("leaderVoteWait", 180000, cfg.getCloudConfig().getLeaderVoteWait()); } - public void testIntAsLongBad() throws IOException { + public void testIntAsLongBad() { String bad = ""+TestUtil.nextLong(random(), Integer.MAX_VALUE, Long.MAX_VALUE); String solrXml = ""+bad+""; expectedException.expect(SolrException.class); expectedException.expectMessage("transientCacheSize"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testIntAsLongOk() throws IOException { + public void testIntAsLongOk() { int ok = random().nextInt(); String solrXml = ""+ok+""; - NodeConfig cfg = SolrXmlConfig.fromString(loader, solrXml); + NodeConfig cfg = SolrXmlConfig.fromString(solrHome, solrXml); assertEquals(ok, cfg.getTransientCacheSize()); } - public void testMultiCloudSectionError() throws IOException { + public void testMultiCloudSectionError() { String solrXml = "" + "true" + "false" + ""; expectedException.expect(SolrException.class); expectedException.expectMessage("Multiple instances of solrcloud section found in solr.xml"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testMultiLoggingSectionError() throws IOException { + public void testMultiLoggingSectionError() { String solrXml = "" + "foo" + "foo" + ""; expectedException.expect(SolrException.class); expectedException.expectMessage("Multiple instances of logging section found in solr.xml"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testMultiLoggingWatcherSectionError() throws IOException { + public void testMultiLoggingWatcherSectionError() { String solrXml = "" + "42" + "42" @@ -186,42 +178,42 @@ public class TestSolrXml extends SolrTestCaseJ4 { expectedException.expect(SolrException.class); expectedException.expectMessage("Multiple instances of logging/watcher section found in solr.xml"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testValidStringValueWhenBoolTypeIsExpected() throws IOException { + public void testValidStringValueWhenBoolTypeIsExpected() { boolean schemaCache = random().nextBoolean(); String solrXml = String.format(Locale.ROOT, "%s", schemaCache); - NodeConfig nodeConfig = SolrXmlConfig.fromString(loader, solrXml); + NodeConfig nodeConfig = SolrXmlConfig.fromString(solrHome, solrXml); assertEquals("gen core node names", schemaCache, nodeConfig.hasSchemaCache()); } - public void testValidStringValueWhenIntTypeIsExpected() throws IOException { + public void testValidStringValueWhenIntTypeIsExpected() { int maxUpdateConnections = random().nextInt(); String solrXml = String.format(Locale.ROOT, "%d", maxUpdateConnections); - NodeConfig nodeConfig = SolrXmlConfig.fromString(loader, solrXml); + NodeConfig nodeConfig = SolrXmlConfig.fromString(solrHome, solrXml); assertEquals("max update conn", maxUpdateConnections, nodeConfig.getUpdateShardHandlerConfig().getMaxUpdateConnections()); } - public void testFailAtConfigParseTimeWhenIntTypeIsExpectedAndLongTypeIsGiven() throws IOException { + public void testFailAtConfigParseTimeWhenIntTypeIsExpectedAndLongTypeIsGiven() { long val = TestUtil.nextLong(random(), Integer.MAX_VALUE, Long.MAX_VALUE); String solrXml = String.format(Locale.ROOT, "%d", val); expectedException.expect(SolrException.class); expectedException.expectMessage("Error parsing 'maxUpdateConnections'"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenBoolTypeIsExpectedAndValueIsInvalidString() throws IOException { + public void testFailAtConfigParseTimeWhenBoolTypeIsExpectedAndValueIsInvalidString() { String solrXml = "NOT_A_BOOLEAN"; expectedException.expect(SolrException.class); expectedException.expectMessage("invalid boolean value: NOT_A_BOOLEAN"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenIntTypeIsExpectedAndBoolTypeIsGiven() throws IOException { + public void testFailAtConfigParseTimeWhenIntTypeIsExpectedAndBoolTypeIsGiven() { // given: boolean randomBoolean = random().nextBoolean(); String solrXml = String.format(Locale.ROOT, "%s", randomBoolean); @@ -229,37 +221,37 @@ public class TestSolrXml extends SolrTestCaseJ4 { expectedException.expect(SolrException.class); expectedException.expectMessage(String.format(Locale.ROOT, "Value of 'unknown-option' can not be parsed as 'int': \"%s\"", randomBoolean)); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenUnrecognizedSolrCloudOptionWasFound() throws IOException { + public void testFailAtConfigParseTimeWhenUnrecognizedSolrCloudOptionWasFound() { String solrXml = "host8983true"; expectedException.expect(SolrException.class); expectedException.expectMessage("Unknown configuration parameter in section of solr.xml: unknown-option"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenUnrecognizedSolrOptionWasFound() throws IOException { + public void testFailAtConfigParseTimeWhenUnrecognizedSolrOptionWasFound() { String solrXml = "truetrue"; expectedException.expect(SolrException.class); expectedException.expectMessage("Unknown configuration value in solr.xml: unknown-bool-option"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenUnrecognizedLoggingOptionWasFound() throws IOException { + public void testFailAtConfigParseTimeWhenUnrecognizedLoggingOptionWasFound() { String solrXml = String.format(Locale.ROOT, "%s", random().nextBoolean()); expectedException.expect(SolrException.class); expectedException.expectMessage("Unknown value in logwatcher config: unknown-option"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenLoggingConfigParamsAreDuplicated() throws IOException { + public void testFailAtConfigParseTimeWhenLoggingConfigParamsAreDuplicated() { String v1 = ""+random().nextInt(); String v2 = ""+random().nextInt(); String solrXml = String.format(Locale.ROOT, @@ -272,10 +264,10 @@ public class TestSolrXml extends SolrTestCaseJ4 { expectedException.expect(SolrException.class); expectedException.expectMessage(" section of solr.xml contains duplicated 'class'"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testFailAtConfigParseTimeWhenSolrCloudConfigParamsAreDuplicated() throws IOException { + public void testFailAtConfigParseTimeWhenSolrCloudConfigParamsAreDuplicated() { String v1 = ""+random().nextInt(); String v2 = ""+random().nextInt(); String v3 = ""+random().nextInt(); @@ -291,11 +283,11 @@ public class TestSolrXml extends SolrTestCaseJ4 { expectedException.expect(SolrException.class); expectedException.expectMessage(" section of solr.xml contains duplicated 'zkClientTimeout'"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } @Ignore - public void testFailAtConfigParseTimeWhenSolrConfigParamsAreDuplicated() throws IOException { + public void testFailAtConfigParseTimeWhenSolrConfigParamsAreDuplicated() { String v1 = ""+random().nextInt(); String v2 = ""+random().nextInt(); String solrXml = String.format(Locale.ROOT, @@ -308,34 +300,34 @@ public class TestSolrXml extends SolrTestCaseJ4 { expectedException.expect(SolrException.class); expectedException.expectMessage("Main section of solr.xml contains duplicated 'coreLoadThreads'"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } - public void testCloudConfigRequiresHost() throws Exception { + public void testCloudConfigRequiresHost() { expectedException.expect(SolrException.class); expectedException.expectMessage("solrcloud section missing required entry 'host'"); - SolrXmlConfig.fromString(loader, ""); + SolrXmlConfig.fromString(solrHome, ""); } - public void testCloudConfigRequiresHostPort() throws Exception { + public void testCloudConfigRequiresHostPort() { expectedException.expect(SolrException.class); expectedException.expectMessage("solrcloud section missing required entry 'hostPort'"); - SolrXmlConfig.fromString(loader, "host"); + SolrXmlConfig.fromString(solrHome, "host"); } - public void testCloudConfigRequiresHostContext() throws Exception { + public void testCloudConfigRequiresHostContext() { expectedException.expect(SolrException.class); expectedException.expectMessage("solrcloud section missing required entry 'hostContext'"); - SolrXmlConfig.fromString(loader, "host8983"); + SolrXmlConfig.fromString(solrHome, "host8983"); } - public void testMultiBackupSectionError() throws IOException { + public void testMultiBackupSectionError() { String solrXml = ""; expectedException.expect(SolrException.class); expectedException.expectMessage("Multiple instances of backup section found in solr.xml"); - SolrXmlConfig.fromString(loader, solrXml); // return not used, only for validation + SolrXmlConfig.fromString(solrHome, solrXml); // return not used, only for validation } } diff --git a/solr/core/src/test/org/apache/solr/filestore/TestDistribPackageStore.java b/solr/core/src/test/org/apache/solr/filestore/TestDistribPackageStore.java index 71df283c9ea..e7f7ab093e6 100644 --- a/solr/core/src/test/org/apache/solr/filestore/TestDistribPackageStore.java +++ b/solr/core/src/test/org/apache/solr/filestore/TestDistribPackageStore.java @@ -20,6 +20,7 @@ package org.apache.solr.filestore; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.file.Paths; import java.util.List; import java.util.Map; import java.util.Objects; @@ -252,7 +253,7 @@ public class TestDistribPackageStore extends SolrCloudTestCase { public static void uploadKey(byte[] bytes, String path, MiniSolrCloudCluster cluster) throws Exception { JettySolrRunner jetty = cluster.getRandomJetty(random()); try(HttpSolrClient client = (HttpSolrClient) jetty.newClient()) { - PackageUtils.uploadKey(bytes, path, jetty.getCoreContainer().getResourceLoader().getInstancePath(), client); + PackageUtils.uploadKey(bytes, path, Paths.get(jetty.getCoreContainer().getSolrHome()), client); Object resp = Utils.executeGET(client.getHttpClient(), jetty.getBaseURLV2().toString() + "/node/files" + path + "?sync=true", null); System.out.println("sync resp: "+jetty.getBaseURLV2().toString() + "/node/files" + path + "?sync=true"+" ,is: "+resp); } diff --git a/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java b/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java index 65649d8d57d..7c007cb00d0 100644 --- a/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/JvmMetricsTest.java @@ -26,7 +26,6 @@ import com.codahale.metrics.Metric; import org.apache.commons.io.FileUtils; import org.apache.solr.SolrJettyTestBase; import org.apache.solr.core.NodeConfig; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; import org.junit.BeforeClass; import org.junit.Test; @@ -118,18 +117,17 @@ public class JvmMetricsTest extends SolrJettyTestBase { @Test public void testHiddenSysProps() throws Exception { Path home = Paths.get(TEST_HOME()); - SolrResourceLoader loader = new SolrResourceLoader(home); // default config String solrXml = FileUtils.readFileToString(Paths.get(home.toString(), "solr.xml").toFile(), "UTF-8"); - NodeConfig config = SolrXmlConfig.fromString(loader, solrXml); + NodeConfig config = SolrXmlConfig.fromString(home, solrXml); NodeConfig.NodeConfigBuilder.DEFAULT_HIDDEN_SYS_PROPS.forEach(s -> { assertTrue(s, config.getMetricsConfig().getHiddenSysProps().contains(s)); }); // custom config - solrXml = FileUtils.readFileToString(Paths.get(home.toString(), "solr-hiddensysprops.xml").toFile(), "UTF-8"); - NodeConfig config2 = SolrXmlConfig.fromString(loader, solrXml); + solrXml = FileUtils.readFileToString(home.resolve("solr-hiddensysprops.xml").toFile(), "UTF-8"); + NodeConfig config2 = SolrXmlConfig.fromString(home, solrXml); Arrays.asList("foo", "bar", "baz").forEach(s -> { assertTrue(s, config2.getMetricsConfig().getHiddenSysProps().contains(s)); }); diff --git a/solr/core/src/test/org/apache/solr/metrics/MetricsConfigTest.java b/solr/core/src/test/org/apache/solr/metrics/MetricsConfigTest.java index 789e95ab9c4..2a3c6588cb4 100644 --- a/solr/core/src/test/org/apache/solr/metrics/MetricsConfigTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/MetricsConfigTest.java @@ -18,6 +18,7 @@ package org.apache.solr.metrics; import java.io.File; import java.io.InputStream; +import java.util.Properties; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; import com.codahale.metrics.Clock; @@ -27,7 +28,6 @@ import com.codahale.metrics.SlidingTimeWindowReservoir; import com.codahale.metrics.UniformReservoir; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.core.NodeConfig; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -45,24 +45,21 @@ public class MetricsConfigTest extends SolrTestCaseJ4 { // tmp dir, cleaned up automatically. private static File solrHome = null; - private static SolrResourceLoader loader = null; @BeforeClass public static void setupLoader() throws Exception { solrHome = createTempDir().toFile(); - loader = new SolrResourceLoader(solrHome.toPath()); } @AfterClass public static void cleanupLoader() throws Exception { solrHome = null; - loader = null; } @Test public void testDefaults() throws Exception { NodeConfig cfg = loadNodeConfig(); - SolrMetricManager mgr = new SolrMetricManager(loader, cfg.getMetricsConfig()); + SolrMetricManager mgr = new SolrMetricManager(cfg.getSolrResourceLoader(), cfg.getMetricsConfig()); assertTrue(mgr.getCounterSupplier() instanceof MetricSuppliers.DefaultCounterSupplier); assertTrue(mgr.getMeterSupplier() instanceof MetricSuppliers.DefaultMeterSupplier); assertTrue(mgr.getTimerSupplier() instanceof MetricSuppliers.DefaultTimerSupplier); @@ -80,7 +77,7 @@ public class MetricsConfigTest extends SolrTestCaseJ4 { System.setProperty("histogram.window", "600"); System.setProperty("histogram.reservoir", SlidingTimeWindowReservoir.class.getName()); NodeConfig cfg = loadNodeConfig(); - SolrMetricManager mgr = new SolrMetricManager(loader, cfg.getMetricsConfig()); + SolrMetricManager mgr = new SolrMetricManager(cfg.getSolrResourceLoader(), cfg.getMetricsConfig()); assertTrue(mgr.getCounterSupplier() instanceof MetricSuppliers.DefaultCounterSupplier); assertTrue(mgr.getMeterSupplier() instanceof MetricSuppliers.DefaultMeterSupplier); assertTrue(mgr.getTimerSupplier() instanceof MetricSuppliers.DefaultTimerSupplier); @@ -98,7 +95,7 @@ public class MetricsConfigTest extends SolrTestCaseJ4 { System.setProperty("timer.class", MockTimerSupplier.class.getName()); System.setProperty("histogram.class", MockHistogramSupplier.class.getName()); NodeConfig cfg = loadNodeConfig(); - SolrMetricManager mgr = new SolrMetricManager(loader, cfg.getMetricsConfig()); + SolrMetricManager mgr = new SolrMetricManager(cfg.getSolrResourceLoader(), cfg.getMetricsConfig()); assertTrue(mgr.getCounterSupplier() instanceof MockCounterSupplier); assertTrue(mgr.getMeterSupplier() instanceof MockMeterSupplier); assertTrue(mgr.getTimerSupplier() instanceof MockTimerSupplier); @@ -121,6 +118,6 @@ public class MetricsConfigTest extends SolrTestCaseJ4 { private NodeConfig loadNodeConfig() throws Exception { InputStream is = MetricsConfigTest.class.getResourceAsStream("/solr/solr-metricsconfig.xml"); - return SolrXmlConfig.fromInputStream(loader, is); + return SolrXmlConfig.fromInputStream(TEST_PATH(), is, new Properties()); //TODO pass in props } } diff --git a/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java b/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java index d71588c2549..21a80fa575c 100644 --- a/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/SolrMetricsIntegrationTest.java @@ -34,7 +34,6 @@ import org.apache.solr.core.CoreContainer; import org.apache.solr.core.NodeConfig; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrInfoBean; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; import org.apache.solr.metrics.reporters.MockMetricReporter; import org.apache.solr.util.JmxUtil; @@ -73,7 +72,7 @@ public class SolrMetricsIntegrationTest extends SolrTestCaseJ4 { System.setProperty("solr.test.sys.prop1", "propone"); System.setProperty("solr.test.sys.prop2", "proptwo"); String solrXml = FileUtils.readFileToString(Paths.get(home.toString(), "solr-metricreporter.xml").toFile(), "UTF-8"); - NodeConfig cfg = SolrXmlConfig.fromString(new SolrResourceLoader(home), solrXml); + NodeConfig cfg = SolrXmlConfig.fromString(home, solrXml); cc = createCoreContainer(cfg, new TestHarness.TestCoresLocator (DEFAULT_TEST_CORENAME, initAndGetDataDir().getAbsolutePath(), "solrconfig.xml", "schema.xml")); @@ -181,7 +180,7 @@ public class SolrMetricsIntegrationTest extends SolrTestCaseJ4 { assertTrue(metrics.containsKey("CONTAINER.version.specification")); assertTrue(metrics.containsKey("CONTAINER.version.implementation")); Gauge g = (Gauge)metrics.get("CONTAINER.fs.path"); - assertEquals(g.getValue(), cc.getResourceLoader().getInstancePath().toAbsolutePath().toString()); + assertEquals(g.getValue(), cc.getSolrHome()); boolean spins = IOUtils.spins(cc.getCoreRootDirectory()); g = (Gauge)metrics.get("CONTAINER.fs.coreRoot.spins"); assertEquals(spins, g.getValue()); diff --git a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java index df187063ab6..10e0179495e 100644 --- a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrGraphiteReporterTest.java @@ -32,7 +32,6 @@ import org.apache.commons.io.FileUtils; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.NodeConfig; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; import org.apache.solr.metrics.SolrMetricManager; import org.apache.solr.metrics.SolrMetricReporter; @@ -60,7 +59,7 @@ public class SolrGraphiteReporterTest extends SolrTestCaseJ4 { // define the port where MockGraphite is running System.setProperty("mock-graphite-port", String.valueOf(mock.port)); String solrXml = FileUtils.readFileToString(Paths.get(home.toString(), "solr-graphitereporter.xml").toFile(), "UTF-8"); - NodeConfig cfg = SolrXmlConfig.fromString(new SolrResourceLoader(home), solrXml); + NodeConfig cfg = SolrXmlConfig.fromString(home, solrXml); CoreContainer cc = createCoreContainer(cfg, new TestHarness.TestCoresLocator (DEFAULT_TEST_CORENAME, initAndGetDataDir().getAbsolutePath(), "solrconfig.xml", "schema.xml")); diff --git a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java index 5fe5e086dc9..e93938abf5d 100644 --- a/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java +++ b/solr/core/src/test/org/apache/solr/metrics/reporters/SolrSlf4jReporterTest.java @@ -27,7 +27,6 @@ import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.common.SolrDocumentList; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.NodeConfig; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; import org.apache.solr.logging.LogWatcher; import org.apache.solr.logging.LogWatcherConfig; @@ -53,7 +52,7 @@ public class SolrSlf4jReporterTest extends SolrTestCaseJ4 { System.setProperty("solr.test.sys.prop2", "proptwo"); String solrXml = FileUtils.readFileToString(Paths.get(home.toString(), "solr-slf4jreporter.xml").toFile(), "UTF-8"); - NodeConfig cfg = SolrXmlConfig.fromString(new SolrResourceLoader(home), solrXml); + NodeConfig cfg = SolrXmlConfig.fromString(home, solrXml); CoreContainer cc = createCoreContainer(cfg, new TestHarness.TestCoresLocator (DEFAULT_TEST_CORENAME, initAndGetDataDir().getAbsolutePath(), "solrconfig.xml", "schema.xml")); diff --git a/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java b/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java index a26c835ea64..dbff7e208e9 100644 --- a/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java +++ b/solr/core/src/test/org/apache/solr/schema/ChangedSchemaMergeTest.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.IOException; import java.lang.invoke.MethodHandles; import java.nio.charset.StandardCharsets; +import java.util.Properties; import org.apache.commons.io.FileUtils; import org.apache.solr.SolrTestCaseJ4; @@ -92,7 +93,7 @@ public class ChangedSchemaMergeTest extends SolrTestCaseJ4 { File solrXml = new File(solrHomeDirectory, "solr.xml"); FileUtils.write(solrXml, discoveryXml, StandardCharsets.UTF_8); - final CoreContainer cores = new CoreContainer(solrHomeDirectory.getAbsolutePath()); + final CoreContainer cores = new CoreContainer(solrHomeDirectory.toPath(), new Properties()); cores.load(); return cores; } diff --git a/solr/core/src/test/org/apache/solr/schema/DateFieldTest.java b/solr/core/src/test/org/apache/solr/schema/DateFieldTest.java index 8929ed3597b..a3aa96a6208 100644 --- a/solr/core/src/test/org/apache/solr/schema/DateFieldTest.java +++ b/solr/core/src/test/org/apache/solr/schema/DateFieldTest.java @@ -38,7 +38,7 @@ public class DateFieldTest extends SolrTestCaseJ4 { System.setProperty("solr.test.sys.prop1", "propone"); System.setProperty("solr.test.sys.prop2", "proptwo"); SolrConfig config = new SolrConfig - (Paths.get(testInstanceDir), testConfHome + "solrconfig.xml", null, true); + (Paths.get(testInstanceDir), testConfHome + "solrconfig.xml"); IndexSchema schema = IndexSchemaFactory.buildIndexSchema(testConfHome + "schema.xml", config); f = Boolean.getBoolean(NUMERIC_POINTS_SYSPROP) ? new DatePointField() : new TrieDateField(); diff --git a/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java b/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java index 6d2e8a6b9b2..4b9b2dcf646 100644 --- a/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java +++ b/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java @@ -45,7 +45,7 @@ public class PrimitiveFieldTypeTest extends SolrTestCaseJ4 { System.setProperty("solr.allow.unsafe.resourceloading", "true"); initMap = new HashMap<>(); - config = new SolrConfig(TEST_PATH().resolve("collection1"), testConfHome + "solrconfig.xml", null, true); + config = new SolrConfig(TEST_PATH().resolve("collection1"), testConfHome + "solrconfig.xml"); } @Override diff --git a/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java b/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java index 42d2a77f51f..811680a7356 100644 --- a/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java +++ b/solr/core/src/test/org/apache/solr/schema/TestManagedSchemaThreadSafety.java @@ -174,8 +174,8 @@ public class TestManagedSchemaThreadSafety extends SolrTestCaseJ4 { private Runnable indexSchemaLoader(String configsetName, final ZkController zkController) { return () -> { try { - SolrResourceLoader loader = new ZkSolrResourceLoader(loaderPath, configsetName, zkController); - SolrConfig solrConfig = SolrConfig.readFromResourceLoader(loader, "solrconfig.xml", true); + SolrResourceLoader loader = new ZkSolrResourceLoader(loaderPath, configsetName, null, zkController); + SolrConfig solrConfig = SolrConfig.readFromResourceLoader(loader, "solrconfig.xml", true, null); ManagedIndexSchemaFactory factory = new ManagedIndexSchemaFactory(); factory.init(new NamedList()); diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java index 27138ce51f8..5ae02aff2d2 100644 --- a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java +++ b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java @@ -62,7 +62,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { @Test public void testFailingSolrIndexConfigCreation() throws Exception { - SolrConfig solrConfig = new SolrConfig(instanceDir,"bad-mpf-solrconfig.xml", null, true); + SolrConfig solrConfig = new SolrConfig(instanceDir,"bad-mpf-solrconfig.xml"); SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null, null); IndexSchema indexSchema = IndexSchemaFactory.buildIndexSchema(schemaFileName, solrConfig); h.getCore().setLatestSchema(indexSchema); @@ -75,7 +75,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { @Test public void testTieredMPSolrIndexConfigCreation() throws Exception { String solrConfigFileName = solrConfigFileNameTieredMergePolicyFactory; - SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileName, null, true); + SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileName); SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null, null); IndexSchema indexSchema = IndexSchemaFactory.buildIndexSchema(schemaFileName, solrConfig); @@ -100,7 +100,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { @Test public void testConcurrentMergeSchedularSolrIndexConfigCreation() throws Exception { String solrConfigFileName = solrConfigFileNameConnMSPolicyFactory; - SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileName, null, true); + SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileName); SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null, null); IndexSchema indexSchema = IndexSchemaFactory.buildIndexSchema(schemaFileName, solrConfig); @@ -124,7 +124,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { final SortField.Type expectedFieldType = SortField.Type.INT; final boolean expectedFieldSortDescending = true; - SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileNameSortingMergePolicyFactory, null, true); + SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileNameSortingMergePolicyFactory); SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null, null); assertNotNull(solrIndexConfig); IndexSchema indexSchema = IndexSchemaFactory.buildIndexSchema(schemaFileName, solrConfig); @@ -142,7 +142,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { } public void testMergedSegmentWarmerIndexConfigCreation() throws Exception { - SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileNameWarmerRandomMergePolicyFactory, null, true); + SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileNameWarmerRandomMergePolicyFactory); SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null, null); assertNotNull(solrIndexConfig); assertNotNull(solrIndexConfig.mergedSegmentWarmerInfo); @@ -158,7 +158,7 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 { final String solrConfigFileNameWarmer = solrConfigFileNameWarmerRandomMergePolicyFactory; final String solrConfigFileNameTMP = solrConfigFileNameTieredMergePolicyFactory; final String solrConfigFileName = (random().nextBoolean() ? solrConfigFileNameWarmer : solrConfigFileNameTMP); - SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileName, null, true); + SolrConfig solrConfig = new SolrConfig(instanceDir, solrConfigFileName); SolrIndexConfig solrIndexConfig = new SolrIndexConfig(solrConfig, null, null); assertNotNull(solrIndexConfig); assertNotNull(solrIndexConfig.mergePolicyFactoryInfo); diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java b/solr/solrj/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java index 5f4a0a607d4..a39b33e60ab 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/MergeIndexesExampleTestBase.java @@ -31,7 +31,9 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.lang.invoke.MethodHandles; +import java.nio.file.Path; import java.util.Arrays; +import java.util.Properties; /** * Abstract base class for testing merge indexes command @@ -48,12 +50,12 @@ public abstract class MergeIndexesExampleTestBase extends SolrTestCaseJ4 { private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); - static String getSolrHome() { - return SolrTestCaseJ4.getFile("solrj/solr/multicore").getAbsolutePath(); + static Path getSolrHome() { + return SolrTestCaseJ4.getFile("solrj/solr/multicore").toPath(); } protected void setupCoreContainer() { - cores = new CoreContainer(getSolrHome()); + cores = new CoreContainer(getSolrHome(), new Properties()); cores.load(); //cores = CoreContainer.createAndLoad(getSolrHome(), new File(TEMP_DIR, "solr.xml")); } diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java index 884924bf24a..bc8b40d5922 100644 --- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java +++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/StreamExpressionTest.java @@ -55,7 +55,7 @@ import org.apache.solr.cloud.SolrCloudTestCase; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.core.CoreDescriptor; -import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.core.SolrPaths; import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; @@ -3296,7 +3296,7 @@ public class StreamExpressionTest extends SolrCloudTestCase { final String baseDir = cluster.getBaseDir().toAbsolutePath().toString(); for (CoreDescriptor coreDescriptor : jetty.getCoreContainer().getCoreDescriptors()) { if (coreDescriptor.getCollectionName().equals(FILESTREAM_COLLECTION)) { - return Paths.get(jetty.getSolrHome(), SolrResourceLoader.USER_FILES_DIRECTORY).toAbsolutePath().toString(); + return Paths.get(jetty.getSolrHome(), SolrPaths.USER_FILES_DIRECTORY).toAbsolutePath().toString(); } } } diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java index 71599fa3059..5903b2c0dea 100644 --- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java +++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java @@ -122,7 +122,6 @@ import org.apache.solr.core.CoresLocator; import org.apache.solr.core.NodeConfig; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrCore; -import org.apache.solr.core.SolrResourceLoader; import org.apache.solr.core.SolrXmlConfig; import org.apache.solr.handler.UpdateRequestHandler; import org.apache.solr.request.LocalSolrQueryRequest; @@ -555,7 +554,7 @@ public abstract class SolrTestCaseJ4 extends SolrTestCase { if (xmlStr == null) xmlStr = ""; Files.write(solrHome.resolve(SolrXmlConfig.SOLR_XML_FILE), xmlStr.getBytes(StandardCharsets.UTF_8)); - h = new TestHarness(SolrXmlConfig.fromSolrHome(solrHome)); + h = new TestHarness(SolrXmlConfig.fromSolrHome(solrHome, new Properties())); lrf = h.getRequestFactory("/select", 0, 20, CommonParams.VERSION, "2.2"); } @@ -817,14 +816,14 @@ public abstract class SolrTestCaseJ4 extends SolrTestCase { } public static CoreContainer createCoreContainer(NodeConfig config, CoresLocator locator) { - testSolrHome = config.getSolrResourceLoader().getInstancePath(); + testSolrHome = config.getSolrHome(); h = new TestHarness(config, locator); lrf = h.getRequestFactory("", 0, 20, CommonParams.VERSION, "2.2"); return h.getCoreContainer(); } public static CoreContainer createCoreContainer(String coreName, String dataDir, String solrConfig, String schema) { - NodeConfig nodeConfig = TestHarness.buildTestNodeConfig(new SolrResourceLoader(TEST_PATH())); + NodeConfig nodeConfig = TestHarness.buildTestNodeConfig(TEST_PATH()); CoresLocator locator = new TestHarness.TestCoresLocator(coreName, dataDir, solrConfig, schema); CoreContainer cc = createCoreContainer(nodeConfig, locator); h.coreName = coreName; 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 5ec863abd00..3044d139068 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 @@ -24,7 +24,6 @@ import java.nio.file.Path; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Properties; import com.google.common.collect.ImmutableList; import org.apache.solr.SolrTestCaseJ4; @@ -43,7 +42,7 @@ import org.apache.solr.core.NodeConfig; import org.apache.solr.core.PluginInfo; import org.apache.solr.core.SolrConfig; import org.apache.solr.core.SolrCore; -import org.apache.solr.core.SolrResourceLoader; +import org.apache.solr.core.SolrPaths; import org.apache.solr.core.SolrXmlConfig; import org.apache.solr.handler.UpdateRequestHandler; import org.apache.solr.metrics.reporters.SolrJmxReporter; @@ -86,7 +85,7 @@ public class TestHarness extends BaseTestHarness { System.setProperty("solr.test.sys.prop1", "propone"); System.setProperty("solr.test.sys.prop2", "proptwo"); try { - return new SolrConfig(solrHome.resolve(coreName), confFile, null, true); + return new SolrConfig(solrHome.resolve(coreName), confFile); } catch (Exception xany) { throw new RuntimeException(xany); } @@ -140,7 +139,7 @@ public class TestHarness extends BaseTestHarness { * @param indexSchema schema resource name */ public TestHarness(String coreName, String dataDir, String solrConfig, String indexSchema) { - this(buildTestNodeConfig(new SolrResourceLoader(SolrResourceLoader.locateSolrHome())), + this(buildTestNodeConfig(SolrPaths.locateSolrHome()), new TestCoresLocator(coreName, dataDir, solrConfig, indexSchema)); this.coreName = (coreName == null) ? SolrTestCaseJ4.DEFAULT_TEST_CORENAME : coreName; } @@ -155,16 +154,7 @@ public class TestHarness extends BaseTestHarness { * @param solrXml the text of a solrxml */ public TestHarness(Path solrHome, String solrXml) { - this(new SolrResourceLoader(solrHome), solrXml); - } - - /** - * Create a TestHarness using a specific solr resource loader and solr xml - * @param loader the SolrResourceLoader to use - * @param solrXml the text of a solrxml - */ - public TestHarness(SolrResourceLoader loader, String solrXml) { - this(SolrXmlConfig.fromString(loader, solrXml)); + this(SolrXmlConfig.fromString(solrHome, solrXml)); } public TestHarness(NodeConfig nodeConfig) { @@ -176,13 +166,13 @@ public class TestHarness extends BaseTestHarness { * @param config the ConfigSolr to use */ public TestHarness(NodeConfig config, CoresLocator coresLocator) { - container = new CoreContainer(config, new Properties(), coresLocator); + container = new CoreContainer(config, coresLocator); container.load(); updater = new UpdateRequestHandler(); updater.init(null); } - public static NodeConfig buildTestNodeConfig(SolrResourceLoader loader) { + public static NodeConfig buildTestNodeConfig(Path solrHome) { CloudConfig cloudConfig = new CloudConfig.CloudConfigBuilder(System.getProperty("host"), Integer.getInteger("hostPort", 8983), System.getProperty("hostContext", "")) @@ -204,7 +194,7 @@ public class TestHarness extends BaseTestHarness { .setMetricReporterPlugins(new PluginInfo[] {defaultPlugin}) .build(); - return new NodeConfig.NodeConfigBuilder("testNode", loader) + return new NodeConfig.NodeConfigBuilder("testNode", solrHome) .setUseSchemaCache(Boolean.getBoolean("shareSchema")) .setCloudConfig(cloudConfig) .setUpdateShardHandlerConfig(updateShardHandlerConfig)