From f1db918e2072e35295cd53376822b83f7e438927 Mon Sep 17 00:00:00 2001 From: David Smiley Date: Wed, 22 Jan 2020 15:26:37 -0500 Subject: [PATCH] SOLR-14040: restore legacy Collection auto-creation --- .../solr/cloud/CloudConfigSetService.java | 31 ++++++++++++++++++- .../apache/solr/cloud/CloudDescriptor.java | 20 +----------- .../org/apache/solr/core/CoreDescriptor.java | 7 ++++- .../org/apache/solr/core/CoreSorterTest.java | 2 +- 4 files changed, 38 insertions(+), 22 deletions(-) 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 b229b5a9c87..41beed737ac 100644 --- a/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java +++ b/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java @@ -18,8 +18,11 @@ package org.apache.solr.cloud; import java.lang.invoke.MethodHandles; +import org.apache.solr.cloud.api.collections.CreateCollectionCmd; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ZkConfigManager; +import org.apache.solr.common.cloud.ZkStateReader; +import org.apache.solr.common.cloud.ZooKeeperException; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.ConfigSetProperties; import org.apache.solr.core.ConfigSetService; @@ -46,7 +49,33 @@ public class CloudConfigSetService extends ConfigSetService { @Override public SolrResourceLoader createCoreResourceLoader(CoreDescriptor cd) { - return new ZkSolrResourceLoader(cd.getInstanceDir(), cd.getConfigSet(), parentLoader.getClassLoader(), + final String colName = cd.getCollectionName(); + + // For back compat with cores that can create collections without the collections API + try { + if (!zkController.getZkClient().exists(ZkStateReader.COLLECTIONS_ZKNODE + "/" + colName, true)) { + // TODO remove this functionality or maybe move to a CLI mechanism + log.warn("Auto-creating collection (in ZK) from core descriptor (on disk). This feature may go away!"); + CreateCollectionCmd.createCollectionZkNode(zkController.getSolrCloudManager().getDistribStateManager(), colName, cd.getCloudDescriptor().getParams()); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "Interrupted auto-creating collection", e); + } catch (KeeperException e) { + throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "Failure auto-creating collection", e); + } + + // The configSet is read from ZK and populated. Ignore CD's pre-existing configSet; only populated in standalone + final String configSetName; + try { + //TODO readConfigName() also validates the configSet exists but seems needless. We'll get errors soon enough. + configSetName = zkController.getZkStateReader().readConfigName(colName); + cd.setConfigSet(configSetName); + } catch (KeeperException ex) { + 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); } diff --git a/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java b/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java index 2396038b160..cec8dbd5766 100644 --- a/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java +++ b/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java @@ -21,15 +21,10 @@ import java.util.Map; import java.util.Properties; import com.google.common.base.Strings; -import org.apache.solr.common.SolrException; import org.apache.solr.common.StringUtils; import org.apache.solr.common.cloud.Replica; -import org.apache.solr.common.cloud.ZooKeeperException; import org.apache.solr.core.CoreDescriptor; import org.apache.solr.util.PropertiesUtil; -import org.apache.zookeeper.KeeperException; - -import static org.apache.solr.core.CoreDescriptor.CORE_CONFIGSET; /** * SolrCloud metadata attached to a {@link CoreDescriptor}. @@ -61,7 +56,7 @@ public class CloudDescriptor { */ private final Replica.Type replicaType; - public CloudDescriptor(CoreDescriptor cd, String coreName, Properties props, ZkController zkController) { + public CloudDescriptor(CoreDescriptor cd, String coreName, Properties props) { this.cd = cd; this.shardId = props.getProperty(CoreDescriptor.CORE_SHARD, null); if (Strings.isNullOrEmpty(shardId)) @@ -84,19 +79,6 @@ public class CloudDescriptor { collectionParams.put(propName.substring(ZkController.COLLECTION_PARAM_PREFIX.length()), props.getProperty(propName)); } } - // The configSet comes from ZK, not from CD's properties like it does in standalone. - // But we want to put it on CD because CD has getConfigSet() which is sensible; don't want that to return null. - if (zkController != null) { // there's a test where we pass null 'cause it wanted a dummy instance. Yuck? - try { - //TODO readConfigName() also validates the configSet exists but seems needless. We'll get errors soon enough. - String configSetName = zkController.getZkStateReader().readConfigName(collectionName); - props.setProperty(CORE_CONFIGSET, configSetName); - //noinspection StringEquality - assert cd.getConfigSet() == configSetName; - } catch (KeeperException ex) { - throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "Trouble resolving configSet for collection " + collectionName + ": " + ex.getMessage()); - } - } } public boolean requiresTransactionLog() { diff --git a/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java b/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java index 7deab728189..10729295bce 100644 --- a/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java +++ b/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java @@ -211,7 +211,7 @@ public class CoreDescriptor { // TODO maybe make this a CloudCoreDescriptor subclass? if (zkController != null) { - cloudDesc = new CloudDescriptor(this, name, coreProperties, zkController); + cloudDesc = new CloudDescriptor(this, name, coreProperties); } else { cloudDesc = null; } @@ -371,6 +371,11 @@ public class CoreDescriptor { return coreProperties.getProperty(CORE_CONFIGSET); } + /** TODO remove mutability or at least make this non-public? */ + public void setConfigSet(String configSetName) { + coreProperties.setProperty(CORE_CONFIGSET, configSetName); + } + public String getConfigSetPropertiesName() { return coreProperties.getProperty(CORE_CONFIGSET_PROPERTIES); } diff --git a/solr/core/src/test/org/apache/solr/core/CoreSorterTest.java b/solr/core/src/test/org/apache/solr/core/CoreSorterTest.java index 513903f4894..5f86eb0c8ec 100644 --- a/solr/core/src/test/org/apache/solr/core/CoreSorterTest.java +++ b/solr/core/src/test/org/apache/solr/core/CoreSorterTest.java @@ -128,7 +128,7 @@ public class CoreSorterTest extends SolrTestCaseJ4 { p.setProperty(CoreDescriptor.CORE_SHARD, "shard_" + slice); p.setProperty(CoreDescriptor.CORE_COLLECTION, "coll_" + slice); p.setProperty(CoreDescriptor.CORE_NODE_NAME, replicaName); - cd = new CloudDescriptor(null, replicaName, p, null); + cd = new CloudDescriptor(null, replicaName, p); } @Override