You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2014/03/24 12:17:36 UTC

svn commit: r1580817 - in /lucene/dev/branches/branch_4x: ./ solr/ solr/core/ solr/core/src/java/org/apache/solr/cloud/ solr/core/src/java/org/apache/solr/core/ solr/core/src/java/org/apache/solr/handler/admin/ solr/core/src/java/org/apache/solr/servle...

Author: romseygeek
Date: Mon Mar 24 11:17:35 2014
New Revision: 1580817

URL: http://svn.apache.org/r1580817
Log:
SOLR-4478: Allow cores to use configurations specified outside their instance directory

Added:
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java
      - copied unchanged from r1580814, lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CloudConfigSetService.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSet.java
      - copied unchanged from r1580814, lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSet.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
      - copied unchanged from r1580814, lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
    lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/collection1/conf/solrconfig-withgethandler.xml
      - copied unchanged from r1580814, lucene/dev/trunk/solr/core/src/test-files/solr/collection1/conf/solrconfig-withgethandler.xml
    lucene/dev/branches/branch_4x/solr/core/src/test-files/solr/configsets/
      - copied from r1580814, lucene/dev/trunk/solr/core/src/test-files/solr/configsets/
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestConfigSets.java
      - copied unchanged from r1580814, lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestConfigSets.java
    lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/solr/configsets/
      - copied from r1580814, lucene/dev/trunk/solr/solrj/src/test-files/solrj/solr/configsets/
Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/solr/   (props changed)
    lucene/dev/branches/branch_4x/solr/CHANGES.txt   (contents, props changed)
    lucene/dev/branches/branch_4x/solr/core/   (props changed)
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrConfig.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrCore.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ZkContainer.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/CoreContainerCoreInitFailuresTest.java
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
    lucene/dev/branches/branch_4x/solr/solrj/   (props changed)
    lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
    lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
    lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java
    lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/solr/shared/solr.xml
    lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/AbstractEmbeddedSolrServerTestCase.java
    lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
    lucene/dev/branches/branch_4x/solr/test-framework/   (props changed)
    lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java

Modified: lucene/dev/branches/branch_4x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/CHANGES.txt?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/solr/CHANGES.txt Mon Mar 24 11:17:35 2014
@@ -64,10 +64,6 @@ System Requirements
 * LUCENE-4747, LUCENE-5514: Move to Java 7 as minimum Java version.
   (Robert Muir, Uwe Schindler)
 
-* SOLR-5858: Add a hl.qparser parameter to allow you to define a queryparser
-  for hl.q highlight queries. If no queryparser is defined, Solr will use
-  the overall query's defType. (Alan Woodward)
-
 New Features
 ----------------------
 
@@ -103,6 +99,13 @@ New Features
 * SOLR-5749: A new Overseer status collection API exposes overseer queue sizes, timing
   statistics, success and error counts and last N failures per operation. (shalin)
 
+* SOLR-5858: Add a hl.qparser parameter to allow you to define a queryparser
+  for hl.q highlight queries. If no queryparser is defined, Solr will use
+  the overall query's defType. (Alan Woodward)
+
+* SOLR-4478: Allow cores to use configuration from a configsets directory
+  outside their instance directory. (Alan Woodward, Erick Erickson)
+
 Bug Fixes
 ----------------------
 

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java Mon Mar 24 11:17:35 2014
@@ -1131,7 +1131,7 @@ public final class ZkController {
     zkClient.printLayoutToStdOut();
   }
 
-  public void createCollectionZkNode(CloudDescriptor cd) throws KeeperException, InterruptedException {
+  public void createCollectionZkNode(CloudDescriptor cd) {
     String collection = cd.getCollectionName();
     
     log.info("Check for collection zkNode:" + collection);
@@ -1204,9 +1204,14 @@ public final class ZkController {
       
     } catch (KeeperException e) {
       // its okay if another beats us creating the node
-      if (e.code() != KeeperException.Code.NODEEXISTS) {
-        throw e;
+      if (e.code() == KeeperException.Code.NODEEXISTS) {
+        return;
       }
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error creating collection node in Zookeeper", e);
+    }
+    catch (InterruptedException e) {
+      Thread.interrupted();
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error creating collection node in Zookeeper", e);
     }
     
   }

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolr.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolr.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolr.java Mon Mar 24 11:17:35 2014
@@ -21,6 +21,8 @@ import com.google.common.base.Charsets;
 import com.google.common.io.ByteStreams;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.solr.cloud.CloudConfigSetService;
+import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.logging.LogWatcherConfig;
 import org.apache.solr.util.DOMUtil;
@@ -225,6 +227,10 @@ public abstract class ConfigSolr {
     return get(CfgProp.SOLR_MANAGEMENTPATH, null);
   }
 
+  public String getConfigSetBaseDirectory() {
+    return get(CfgProp.SOLR_CONFIGSETBASEDIR, "configsets");
+  }
+
   public LogWatcherConfig getLogWatcherConfig() {
     return new LogWatcherConfig(
         getBool(CfgProp.SOLR_LOGGING_ENABLED, true),
@@ -238,6 +244,14 @@ public abstract class ConfigSolr {
     return getInt(CfgProp.SOLR_TRANSIENTCACHESIZE, Integer.MAX_VALUE);
   }
 
+  public ConfigSetService createCoreConfigService(SolrResourceLoader loader, ZkController zkController) {
+    if (getZkHost() != null)
+      return new CloudConfigSetService(loader, zkController);
+    if (hasSchemaCache())
+      return new ConfigSetService.SchemaCaching(loader, getConfigSetBaseDirectory());
+    return new ConfigSetService.Default(loader, getConfigSetBaseDirectory());
+  }
+
   // Ugly for now, but we'll at least be able to centralize all of the differences between 4x and 5x.
   protected static enum CfgProp {
     SOLR_ADMINHANDLER,
@@ -265,6 +279,7 @@ public abstract class ConfigSolr {
     SOLR_ZKCLIENTTIMEOUT,
     SOLR_ZKHOST,
     SOLR_LEADERCONFLICTRESOLVEWAIT,
+    SOLR_CONFIGSETBASEDIR,
 
     //TODO: Remove all of these elements for 5.0
     SOLR_PERSISTENT,

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java Mon Mar 24 11:17:35 2014
@@ -122,6 +122,7 @@ public class ConfigSolrXml extends Confi
     propMap.put(CfgProp.SOLR_TRANSIENTCACHESIZE, doSub("solr/int[@name='transientCacheSize']"));
     propMap.put(CfgProp.SOLR_ZKCLIENTTIMEOUT, doSub("solr/solrcloud/int[@name='zkClientTimeout']"));
     propMap.put(CfgProp.SOLR_ZKHOST, doSub("solr/solrcloud/str[@name='zkHost']"));
+    propMap.put(CfgProp.SOLR_CONFIGSETBASEDIR, doSub("solr/str[@name='configSetBaseDir']"));
 
     propMap.put(CfgProp.SOLR_LOGGING_CLASS, doSub("solr/logging/str[@name='class']"));
     propMap.put(CfgProp.SOLR_LOGGING_ENABLED, doSub("solr/logging/str[@name='enabled']"));

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ConfigSolrXmlOld.java Mon Mar 24 11:17:35 2014
@@ -166,6 +166,7 @@ public class ConfigSolrXmlOld extends Co
         config.getVal("solr/cores/@transientCacheSize", false));
     propMap.put(CfgProp.SOLR_ZKCLIENTTIMEOUT,
         config.getVal("solr/cores/@zkClientTimeout", false));
+    propMap.put(CfgProp.SOLR_CONFIGSETBASEDIR, config.getVal("solr/cores/@configSetBaseDir", false));
 
     // These have no counterpart in 5.0, asking, for any of these in Solr 5.0
     // will result in an error being

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreContainer.java Mon Mar 24 11:17:35 2014
@@ -20,30 +20,23 @@ package org.apache.solr.core;
 import com.google.common.collect.Maps;
 
 import org.apache.solr.cloud.ZkController;
-import org.apache.solr.cloud.ZkSolrResourceLoader;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.cloud.ZooKeeperException;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.handler.admin.CollectionsHandler;
 import org.apache.solr.handler.admin.CoreAdminHandler;
 import org.apache.solr.handler.admin.InfoHandler;
 import org.apache.solr.handler.component.ShardHandlerFactory;
 import org.apache.solr.logging.LogWatcher;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.IndexSchemaFactory;
 import org.apache.solr.update.UpdateShardHandler;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.solr.util.FileUtils;
-import org.apache.zookeeper.KeeperException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
-import java.text.SimpleDateFormat;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Date;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -53,7 +46,6 @@ import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletionService;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.ExecutorService;
@@ -82,9 +74,8 @@ public class CoreContainer {
 
   protected Properties containerProperties;
 
-  protected Map<String ,IndexSchema> indexSchemaCache;
-  protected boolean shareSchema;
-
+  private ConfigSetService coreConfigService;
+  
   protected ZkContainer zkSys = new ZkContainer();
   protected ShardHandlerFactory shardHandlerFactory;
   
@@ -210,20 +201,15 @@ public class CoreContainer {
       loader.reloadLuceneSPI();
     }
 
+
     shardHandlerFactory = ShardHandlerFactory.newInstance(cfg.getShardHandlerFactoryPluginInfo(), loader);
-    
+
     updateShardHandler = new UpdateShardHandler(cfg);
 
     solrCores.allocateLazyCores(cfg.getTransientCacheSize(), loader);
 
     logging = LogWatcher.newRegisteredLogWatcher(cfg.getLogWatcherConfig(), loader);
 
-    shareSchema = cfg.hasSchemaCache();
-
-    if (shareSchema) {
-      indexSchemaCache = new ConcurrentHashMap<>();
-    }
-    
     hostName = cfg.getHost();
     log.info("Host Name: " + hostName);
 
@@ -233,6 +219,8 @@ public class CoreContainer {
     infoHandler        = createHandler(cfg.getInfoHandlerClass(), InfoHandler.class);
     coreAdminHandler   = createHandler(cfg.getCoreAdminHandlerClass(), CoreAdminHandler.class);
 
+    coreConfigService = cfg.createCoreConfigService(loader, zkSys.getZkController());
+
     containerProperties = cfg.getSolrProperties("solr");
 
     // setup executor to load cores in parallel
@@ -540,55 +528,13 @@ public class CoreContainer {
     return registerCore(core.getCoreDescriptor().isTransient(), name, core, returnPrev);
   }
 
-  // Helper method to separate out creating a core from local configuration files. See create()
-  private SolrCore createFromLocal(String instanceDir, CoreDescriptor dcore) {
-    SolrResourceLoader solrLoader = null;
-
-    SolrConfig config = null;
-    solrLoader = new SolrResourceLoader(instanceDir, loader.getClassLoader(), dcore.getSubstitutableProperties());
-    try {
-      config = new SolrConfig(solrLoader, dcore.getConfigName(), null);
-    } catch (Exception e) {
-      log.error("Failed to load file {}", new File(instanceDir, dcore.getConfigName()).getAbsolutePath());
-      throw new SolrException(ErrorCode.SERVER_ERROR,
-          "Could not load config file " + new File(instanceDir, dcore.getConfigName()).getAbsolutePath(),
-          e);
-    }
-
-    IndexSchema schema = null;
-    if (indexSchemaCache != null) {
-      final String resourceNameToBeUsed = IndexSchemaFactory.getResourceNameToBeUsed(dcore.getSchemaName(), config);
-      File schemaFile = new File(resourceNameToBeUsed);
-      if (!schemaFile.isAbsolute()) {
-        schemaFile = new File(solrLoader.getConfigDir(), schemaFile.getPath());
-      }
-      if (schemaFile.exists()) {
-        String key = schemaFile.getAbsolutePath()
-            + ":"
-            + new SimpleDateFormat("yyyyMMddHHmmss", Locale.ROOT).format(new Date(
-            schemaFile.lastModified()));
-        schema = indexSchemaCache.get(key);
-        if (schema == null) {
-          log.info("creating new schema object for core: " + dcore.getName());
-          schema = IndexSchemaFactory.buildIndexSchema(dcore.getSchemaName(), config);
-          indexSchemaCache.put(key, schema);
-        } else {
-          log.info("re-using schema object for core: " + dcore.getName());
-        }
-      }
-    }
-
-    if (schema == null) {
-      schema = IndexSchemaFactory.buildIndexSchema(dcore.getSchemaName(), config);
+  public SolrCore create(String name, String instanceDir, String... properties) {
+    Properties props = new Properties();
+    assert properties.length % 2 == 0;
+    for (int i = 0; i < properties.length; i += 2) {
+      props.setProperty(properties[i], properties[i+1]);
     }
-
-    SolrCore core = new SolrCore(dcore.getName(), null, config, schema, dcore);
-
-    if (core.getUpdateHandler().getUpdateLog() != null) {
-      // always kick off recovery if we are in standalone mode.
-      core.getUpdateHandler().getUpdateLog().recoverFromLog();
-    }
-    return core;
+    return create(new CoreDescriptor(this, name, instanceDir, props));
   }
 
   /**
@@ -602,32 +548,26 @@ public class CoreContainer {
     if (isShutDown) {
       throw new SolrException(ErrorCode.SERVICE_UNAVAILABLE, "Solr has shutdown.");
     }
-    
-    final String name = dcore.getName();
 
     try {
-      // Make the instanceDir relative to the cores instanceDir if not absolute
-      File idir = new File(dcore.getInstanceDir());
-      String instanceDir = idir.getPath();
-      log.info("Creating SolrCore '{}' using instanceDir: {}",
-               dcore.getName(), instanceDir);
-
-      // Initialize the solr config
-      SolrCore created = null;
-      if (zkSys.getZkController() != null) {
-        created = zkSys.createFromZk(instanceDir, dcore, loader);
-      } else {
-        created = createFromLocal(instanceDir, dcore);
+
+      ConfigSet coreConfig = coreConfigService.getConfig(dcore);
+      log.info("Creating SolrCore '{}' using configuration from {}", dcore.getName(), coreConfig.getName());
+      SolrCore core = new SolrCore(dcore, coreConfig);
+      solrCores.addCreated(core);
+
+      // always kick off recovery if we are in non-Cloud mode
+      if (!isZooKeeperAware() && core.getUpdateHandler().getUpdateLog() != null) {
+        core.getUpdateHandler().getUpdateLog().recoverFromLog();
       }
 
-      solrCores.addCreated(created); // For persisting newly-created cores.
-      return created;
+      return core;
 
-      // :TODO: Java7...
-      // http://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
-    } catch (Exception ex) {
-      throw recordAndThrow(name, "Unable to create core: " + name, ex);
     }
+    catch (Exception e) {
+      throw recordAndThrow(dcore.getName(), "Unable to create core: " + dcore.getName(), e);
+    }
+
   }
 
   /**
@@ -705,41 +645,9 @@ public class CoreContainer {
       try {
         solrCores.waitAddPendingCoreOps(name);
         CoreDescriptor cd = core.getCoreDescriptor();
-
-        File instanceDir = new File(cd.getInstanceDir());
-
-        log.info("Reloading SolrCore '{}' using instanceDir: {}",
-                 cd.getName(), instanceDir.getAbsolutePath());
-        SolrResourceLoader solrLoader;
-        if(zkSys.getZkController() == null) {
-          solrLoader = new SolrResourceLoader(instanceDir.getAbsolutePath(), loader.getClassLoader(),
-                                                cd.getSubstitutableProperties());
-        } else {
-          try {
-            String collection = cd.getCloudDescriptor().getCollectionName();
-            zkSys.getZkController().createCollectionZkNode(cd.getCloudDescriptor());
-
-            String zkConfigName = zkSys.getZkController().getZkStateReader().readConfigName(collection);
-            if (zkConfigName == null) {
-              log.error("Could not find config name for collection:" + collection);
-              throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-                                           "Could not find config name for collection:" + collection);
-            }
-            solrLoader = new ZkSolrResourceLoader(instanceDir.getAbsolutePath(), zkConfigName, loader.getClassLoader(),
-                cd.getSubstitutableProperties(), zkSys.getZkController());
-          } catch (KeeperException e) {
-            log.error("", e);
-            throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-                                         "", e);
-          } catch (InterruptedException e) {
-            // Restore the interrupted status
-            Thread.currentThread().interrupt();
-            log.error("", e);
-            throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-                                         "", e);
-          }
-        }
-        SolrCore newCore = core.reload(solrLoader, core);
+        ConfigSet coreConfig = coreConfigService.getConfig(cd);
+        log.info("Reloading SolrCore '{}' using configuration from {}", cd.getName(), coreConfig.getName());
+        SolrCore newCore = core.reload(coreConfig, core);
         // keep core to orig name link
         solrCores.removeCoreToOrigName(newCore, core);
         registerCore(false, name, newCore, false, false);
@@ -988,10 +896,6 @@ public class CoreContainer {
   public ZkController getZkController() {
     return zkSys.getZkController();
   }
-  
-  public boolean isShareSchema() {
-    return shareSchema;
-  }
 
   /** The default ShardHandlerFactory used to communicate with other solr instances */
   public ShardHandlerFactory getShardHandlerFactory() {
@@ -1015,6 +919,10 @@ public class CoreContainer {
   String getCoreToOrigName(SolrCore core) {
     return solrCores.getCoreToOrigName(core);
   }
+
+  public SolrResourceLoader getResourceLoader() {
+    return loader;
+  }
 }
 
 class CloserThread extends Thread {

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/CoreDescriptor.java Mon Mar 24 11:17:35 2014
@@ -58,6 +58,7 @@ public class CoreDescriptor {
   public static final String CORE_LOADONSTARTUP = "loadOnStartup";
   public static final String CORE_TRANSIENT = "transient";
   public static final String CORE_NODE_NAME = "coreNodeName";
+  public static final String CORE_CONFIGSET = "configSet";
   public static final String SOLR_CORE_PROP_PREFIX = "solr.core.";
 
   public static final String DEFAULT_EXTERNAL_PROPERTIES_FILE = "conf" + File.separator + "solrcore.properties";
@@ -100,6 +101,7 @@ public class CoreDescriptor {
       CORE_PROPERTIES,
       CORE_LOADONSTARTUP,
       CORE_TRANSIENT,
+      CORE_CONFIGSET,
       // cloud props
       CORE_SHARD,
       CORE_COLLECTION,
@@ -390,4 +392,8 @@ public class CoreDescriptor {
         .append("]")
         .toString();
   }
+
+  public String getConfigSet() {
+    return coreProperties.getProperty(CORE_CONFIGSET);
+  }
 }

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrConfig.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrConfig.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrConfig.java Mon Mar 24 11:17:35 2014
@@ -17,30 +17,29 @@
 
 package org.apache.solr.core;
 
-import static org.apache.solr.core.SolrConfig.PluginOpts.*;
 
+import org.apache.lucene.index.IndexDeletionPolicy;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.util.Version;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.schema.IndexSchemaFactory;
-import org.apache.solr.util.DOMUtil;
-import org.apache.solr.util.FileUtils;
-import org.apache.solr.util.RegexFileFilter;
 import org.apache.solr.handler.component.SearchComponent;
 import org.apache.solr.request.SolrRequestHandler;
 import org.apache.solr.response.QueryResponseWriter;
 import org.apache.solr.response.transform.TransformerFactory;
+import org.apache.solr.schema.IndexSchemaFactory;
 import org.apache.solr.search.CacheConfig;
 import org.apache.solr.search.FastLRUCache;
 import org.apache.solr.search.QParserPlugin;
 import org.apache.solr.search.ValueSourceParser;
 import org.apache.solr.servlet.SolrRequestParsers;
+import org.apache.solr.spelling.QueryConverter;
 import org.apache.solr.update.SolrIndexConfig;
 import org.apache.solr.update.UpdateLog;
 import org.apache.solr.update.processor.UpdateRequestProcessorChain;
-import org.apache.solr.spelling.QueryConverter;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.index.IndexDeletionPolicy;
-import org.apache.lucene.util.Version;
+import org.apache.solr.util.DOMUtil;
+import org.apache.solr.util.FileUtils;
+import org.apache.solr.util.RegexFileFilter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Node;
@@ -50,13 +49,24 @@ import org.xml.sax.SAXException;
 
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.xpath.XPathConstants;
-
 import java.io.File;
-import java.util.*;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
 import java.io.FileFilter;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.apache.solr.core.SolrConfig.PluginOpts.MULTI_OK;
+import static org.apache.solr.core.SolrConfig.PluginOpts.NOOP;
+import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_CLASS;
+import static org.apache.solr.core.SolrConfig.PluginOpts.REQUIRE_NAME;
 
 
 /**
@@ -127,6 +137,16 @@ public class SolrConfig extends Config {
   throws ParserConfigurationException, IOException, SAXException {
     this(new SolrResourceLoader(instanceDir), name, is);
   }
+
+  public static SolrConfig readFromResourceLoader(SolrResourceLoader loader, String name) {
+    try {
+      return new SolrConfig(loader, name, null);
+    }
+    catch (Exception e) {
+      String resource = loader.getInstanceDir() + name;
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error loading solr config from " + resource, e);
+    }
+  }
   
    /** 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.
@@ -145,7 +165,7 @@ public class SolrConfig extends Config {
     // Old indexDefaults and mainIndex sections are deprecated and fails fast for luceneMatchVersion=>LUCENE_40.
     // For older solrconfig.xml's we allow the old sections, but never mixed with the new <indexConfig>
     boolean hasDeprecatedIndexConfig = (getNode("indexDefaults", false) != null) || (getNode("mainIndex", false) != null);
-    boolean hasNewIndexConfig = getNode("indexConfig", false) != null; 
+    boolean hasNewIndexConfig = getNode("indexConfig", false) != null;
     if(hasDeprecatedIndexConfig){
       if(luceneMatchVersion.onOrAfter(Version.LUCENE_40)) {
         throw new SolrException(ErrorCode.FORBIDDEN, "<indexDefaults> and <mainIndex> configuration sections are discontinued. Use <indexConfig> instead.");
@@ -166,12 +186,12 @@ public class SolrConfig extends Config {
     nrtMode = getBool(indexConfigPrefix+"/nrtMode", true);
     // Parse indexConfig section, using mainIndex as backup in case old config is used
     indexConfig = new SolrIndexConfig(this, "indexConfig", mainIndexConfig);
-   
+
     booleanQueryMaxClauseCount = getInt("query/maxBooleanClauses", BooleanQuery.getMaxClauseCount());
     log.info("Using Lucene MatchVersion: " + luceneMatchVersion);
 
     // Warn about deprecated / discontinued parameters
-    // boolToFilterOptimizer has had no effect since 3.1 
+    // boolToFilterOptimizer has had no effect since 3.1
     if(get("query/boolTofilterOptimizer", null) != null)
       log.warn("solrconfig.xml: <boolTofilterOptimizer> is currently not implemented and has no effect.");
     if(get("query/HashDocSet", null) != null)
@@ -181,13 +201,13 @@ public class SolrConfig extends Config {
 //    filtOptEnabled = getBool("query/boolTofilterOptimizer/@enabled", false);
 //    filtOptCacheSize = getInt("query/boolTofilterOptimizer/@cacheSize",32);
 //    filtOptThreshold = getFloat("query/boolTofilterOptimizer/@threshold",.05f);
-    
+
     useFilterForSortedQuery = getBool("query/useFilterForSortedQuery", false);
     queryResultWindowSize = Math.max(1, getInt("query/queryResultWindowSize", 1));
     queryResultMaxDocsCached = getInt("query/queryResultMaxDocsCached", Integer.MAX_VALUE);
     enableLazyFieldLoading = getBool("query/enableLazyFieldLoading", false);
 
-    
+
     filterCacheConfig = CacheConfig.getConfig(this, "query/filterCache");
     queryResultCacheConfig = CacheConfig.getConfig(this, "query/queryResultCache");
     documentCacheConfig = CacheConfig.getConfig(this, "query/documentCache");
@@ -214,14 +234,14 @@ public class SolrConfig extends Config {
     hashDocSetMaxSize= getInt("//HashDocSet/@maxSize",3000);
 
     httpCachingConfig = new HttpCachingConfig(this);
-    
+
     Node jmx = getNode("jmx", false);
     if (jmx != null) {
-      jmxConfig = new JmxConfiguration(true, 
-                                       get("jmx/@agentId", null), 
+      jmxConfig = new JmxConfiguration(true,
+                                       get("jmx/@agentId", null),
                                        get("jmx/@serviceUrl", null),
                                        get("jmx/@rootName", null));
-                                           
+
     } else {
       jmxConfig = new JmxConfiguration(false, null, null, null);
     }
@@ -248,24 +268,24 @@ public class SolrConfig extends Config {
                     REQUIRE_NAME, REQUIRE_CLASS);
 
      // this is hackish, since it picks up all SolrEventListeners,
-     // regardless of when/how/why they are used (or even if they are 
-     // declared outside of the appropriate context) but there's no nice 
+     // regardless of when/how/why they are used (or even if they are
+     // declared outside of the appropriate context) but there's no nice
      // way around that in the PluginInfo framework
-     loadPluginInfo(SolrEventListener.class, "//listener", 
+     loadPluginInfo(SolrEventListener.class, "//listener",
                     REQUIRE_CLASS, MULTI_OK);
 
-     loadPluginInfo(DirectoryFactory.class,"directoryFactory", 
+     loadPluginInfo(DirectoryFactory.class,"directoryFactory",
                     REQUIRE_CLASS);
-     loadPluginInfo(IndexDeletionPolicy.class,indexConfigPrefix+"/deletionPolicy", 
+     loadPluginInfo(IndexDeletionPolicy.class,indexConfigPrefix+"/deletionPolicy",
                     REQUIRE_CLASS);
-     loadPluginInfo(CodecFactory.class,"codecFactory", 
+     loadPluginInfo(CodecFactory.class,"codecFactory",
                     REQUIRE_CLASS);
-     loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory", 
+     loadPluginInfo(IndexReaderFactory.class,"indexReaderFactory",
                     REQUIRE_CLASS);
-     loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain", 
+     loadPluginInfo(UpdateRequestProcessorChain.class,"updateRequestProcessorChain",
                     MULTI_OK);
      loadPluginInfo(UpdateLog.class,"updateHandler/updateLog");
-     loadPluginInfo(IndexSchemaFactory.class,"schemaFactory", 
+     loadPluginInfo(IndexSchemaFactory.class,"schemaFactory",
                     REQUIRE_CLASS);
 
      updateHandlerInfo = loadUpdatehandlerInfo();

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrCore.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrCore.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrCore.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/SolrCore.java Mon Mar 24 11:17:35 2014
@@ -17,46 +17,8 @@
 
 package org.apache.solr.core;
 
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Writer;
-import java.lang.reflect.Constructor;
-import java.net.URL;
-import java.nio.file.NoSuchFileException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.ParserConfigurationException;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.lucene.codecs.Codec;
-import org.apache.lucene.index.AtomicReaderContext;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.index.IndexDeletionPolicy;
 import org.apache.lucene.index.IndexWriter;
@@ -69,8 +31,8 @@ import org.apache.solr.cloud.CloudDescri
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.Slice;
-import org.apache.solr.common.params.CommonParams.EchoParamStyle;
 import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.CommonParams.EchoParamStyle;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.NamedList;
@@ -112,8 +74,8 @@ import org.apache.solr.search.SolrIndexS
 import org.apache.solr.search.ValueSourceParser;
 import org.apache.solr.update.DefaultSolrCoreState;
 import org.apache.solr.update.DirectUpdateHandler2;
-import org.apache.solr.update.SolrCoreState.IndexWriterCloser;
 import org.apache.solr.update.SolrCoreState;
+import org.apache.solr.update.SolrCoreState.IndexWriterCloser;
 import org.apache.solr.update.SolrIndexWriter;
 import org.apache.solr.update.UpdateHandler;
 import org.apache.solr.update.VersionInfo;
@@ -132,6 +94,42 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXException;
 
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.nio.file.NoSuchFileException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.ReentrantLock;
+
 /**
  *
  */
@@ -403,19 +401,10 @@ public final class SolrCore implements S
   public QueryResponseWriter registerResponseWriter( String name, QueryResponseWriter responseWriter ){
     return responseWriters.put(name, responseWriter);
   }
-  
-  public SolrCore reload(SolrCore prev) throws IOException,
-      ParserConfigurationException, SAXException {
-    return reload(prev.getResourceLoader(), prev);
-  }
-  
-  public SolrCore reload(SolrResourceLoader resourceLoader, SolrCore prev) throws IOException,
+
+  public SolrCore reload(ConfigSet coreConfig, SolrCore prev) throws IOException,
       ParserConfigurationException, SAXException {
     
-    SolrConfig config = new SolrConfig(resourceLoader, getSolrConfig().getName(), null);
-    
-    IndexSchema schema = IndexSchemaFactory.buildIndexSchema(getLatestSchema().getResourceName(), config);
-    
     solrCoreState.increfSolrCoreState();
     
     if (!getNewIndexDir().equals(getIndexDir())) {
@@ -423,8 +412,8 @@ public final class SolrCore implements S
       prev = null;
     }
     
-    SolrCore core = new SolrCore(getName(), getDataDir(), config,
-        schema, coreDescriptor, updateHandler, this.solrDelPolicy, prev);
+    SolrCore core = new SolrCore(getName(), getDataDir(), coreConfig.getSolrConfig(),
+        coreConfig.getIndexSchema(), coreDescriptor, updateHandler, this.solrDelPolicy, prev);
     core.solrDelPolicy = this.solrDelPolicy;
     
     core.getUpdateHandler().getSolrCoreState().newIndexWriter(core, false);
@@ -637,6 +626,10 @@ public final class SolrCore implements S
     this(name, dataDir, config, schema, cd, null, null, null);
   }
 
+  public SolrCore(CoreDescriptor cd, ConfigSet coreConfig) {
+    this(cd.getName(), null, coreConfig.getSolrConfig(), coreConfig.getIndexSchema(), cd, null, null, null);
+  }
+
 
   /**
    * Creates a new core that is to be loaded lazily. i.e. lazyLoad="true" in solr.xml

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ZkContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ZkContainer.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ZkContainer.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/core/ZkContainer.java Mon Mar 24 11:17:35 2014
@@ -21,21 +21,15 @@ import org.apache.commons.lang.StringUti
 import org.apache.solr.cloud.CurrentCoreDescriptorProvider;
 import org.apache.solr.cloud.SolrZkServer;
 import org.apache.solr.cloud.ZkController;
-import org.apache.solr.cloud.ZkSolrResourceLoader;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.cloud.ZooKeeperException;
 import org.apache.solr.common.util.ExecutorUtil;
-import org.apache.solr.schema.IndexSchema;
-import org.apache.solr.schema.IndexSchemaFactory;
 import org.apache.solr.util.DefaultSolrThreadFactory;
-import org.apache.solr.util.SystemIdResolver;
 import org.apache.zookeeper.KeeperException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
 
-import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -219,42 +213,6 @@ public class ZkContainer {
     this.zkController = zkController;
   }
   
-  // Helper method to separate out creating a core from ZK as opposed to the
-  // "usual" way. See create()
-  SolrCore createFromZk(String instanceDir, CoreDescriptor dcore, SolrResourceLoader loader) {
-    try {
-      SolrResourceLoader solrLoader = null;
-      SolrConfig config = null;
-      String zkConfigName = null;
-      IndexSchema schema;
-      String collection = dcore.getCloudDescriptor().getCollectionName();
-      zkController.createCollectionZkNode(dcore.getCloudDescriptor());
-      
-      zkConfigName = zkController.getZkStateReader().readConfigName(collection);
-      if (zkConfigName == null) {
-        log.error("Could not find config name for collection:" + collection);
-        throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-            "Could not find config name for collection:" + collection);
-      }
-      solrLoader = new ZkSolrResourceLoader(instanceDir, zkConfigName,
-          loader.getClassLoader(), dcore.getSubstitutableProperties(), zkController);
-      config = getSolrConfigFromZk(zkConfigName, dcore.getConfigName(),
-          solrLoader);
-      schema = IndexSchemaFactory.buildIndexSchema(dcore.getSchemaName(),
-          config);
-      return new SolrCore(dcore.getName(), null, config, schema, dcore);
-      
-    } catch (KeeperException e) {
-      log.error("", e);
-      throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e);
-    } catch (InterruptedException e) {
-      // Restore the interrupted status
-      Thread.currentThread().interrupt();
-      log.error("", e);
-      throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR, "", e);
-    }
-  }
-  
   public void registerInZk(final SolrCore core, boolean background) {
     Thread thread = new Thread() {
       @Override
@@ -289,26 +247,6 @@ public class ZkContainer {
     }
   }
   
-  public SolrConfig getSolrConfigFromZk(String zkConfigName, String solrConfigFileName,
-      SolrResourceLoader resourceLoader) {
-    SolrConfig cfg = null;
-    try {
-      byte[] config = zkController.getConfigFileData(zkConfigName,
-          solrConfigFileName);
-      InputSource is = new InputSource(new ByteArrayInputStream(config));
-      is.setSystemId(SystemIdResolver
-          .createSystemIdFromResourceName(solrConfigFileName));
-      cfg = solrConfigFileName == null ? new SolrConfig(resourceLoader,
-          SolrConfig.DEFAULT_CONF_FILE, is) : new SolrConfig(resourceLoader,
-          solrConfigFileName, is);
-    } catch (Exception e) {
-      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
-          "getSolrConfigFromZK failed for " + zkConfigName + " "
-              + solrConfigFileName, e);
-    }
-    return cfg;
-  }
-  
   public ZkController getZkController() {
     return zkController;
   }
@@ -321,6 +259,7 @@ public class ZkContainer {
       } catch (KeeperException e) {
         CoreContainer.log.error("", e);
       } catch (InterruptedException e) {
+        Thread.interrupted();
         CoreContainer.log.error("", e);
       }
     }

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java Mon Mar 24 11:17:35 2014
@@ -86,7 +86,6 @@ import java.util.Properties;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
 
 import static org.apache.solr.common.cloud.DocCollection.DOC_ROUTER;
 
@@ -488,6 +487,7 @@ public class CoreAdminHandler extends Re
       .put(CoreAdminParams.SCHEMA, CoreDescriptor.CORE_SCHEMA)
       .put(CoreAdminParams.DATA_DIR, CoreDescriptor.CORE_DATADIR)
       .put(CoreAdminParams.ULOG_DIR, CoreDescriptor.CORE_ULOGDIR)
+      .put(CoreAdminParams.CONFIGSET, CoreDescriptor.CORE_CONFIGSET)
       .put(CoreAdminParams.LOAD_ON_STARTUP, CoreDescriptor.CORE_LOADONSTARTUP)
       .put(CoreAdminParams.TRANSIENT, CoreDescriptor.CORE_TRANSIENT)
       .put(CoreAdminParams.SHARD, CoreDescriptor.CORE_SHARD)

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java Mon Mar 24 11:17:35 2014
@@ -80,7 +80,6 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;

Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/CoreContainerCoreInitFailuresTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/CoreContainerCoreInitFailuresTest.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/CoreContainerCoreInitFailuresTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/CoreContainerCoreInitFailuresTest.java Mon Mar 24 11:17:35 2014
@@ -287,9 +287,10 @@ public class CoreContainerCoreInitFailur
       cc.reload("col_bad");
       fail("corrupt solrconfig.xml failed to trigger exception from reload");
     } catch (SolrException e) {
+      Throwable rootException = getWrappedException(e);
       assertTrue("We're supposed to have a wrapped SAXParserException here, but we don't",
-          e.getCause().getCause() instanceof SAXParseException);
-      SAXParseException se = (SAXParseException)e.getCause().getCause();
+          rootException instanceof SAXParseException);
+      SAXParseException se = (SAXParseException) rootException;
       assertTrue("reload exception doesn't refer to slrconfig.xml " + se.getSystemId(),
           0 < se.getSystemId().indexOf("solrconfig.xml"));
 
@@ -310,12 +311,12 @@ public class CoreContainerCoreInitFailur
     failures = cc.getCoreInitFailures();
     assertNotNull("core failures is a null map", failures);
     assertEquals("wrong number of core failures", 1, failures.size());
-    fail = failures.get("col_bad");
-    assertNotNull("null failure for test core", fail);
+    Throwable ex = getWrappedException(failures.get("col_bad"));
+    assertNotNull("null failure for test core", ex);
     assertTrue("init failure isn't SAXParseException",
-               fail.getCause() instanceof SAXParseException);
-    assertTrue("init failure doesn't mention problem: " + fail.toString(),
-               0 < ((SAXParseException)fail.getCause()).getSystemId().indexOf("solrconfig.xml"));
+               ex instanceof SAXParseException);
+    SAXParseException saxEx = (SAXParseException) ex;
+    assertTrue("init failure doesn't mention problem: " + saxEx.toString(), saxEx.getSystemId().contains("solrconfig.xml"));
 
     // ----
     // fix col_bad's config (again) and RELOAD to fix failure
@@ -351,7 +352,7 @@ public class CoreContainerCoreInitFailur
       tmp.close();
     }
   }
-  
+
   private static final String EMPTY_SOLR_XML ="<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
       "<solr persistent=\"false\">\n" +
       "  <cores adminPath=\"/admin/cores\">\n" +

Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java Mon Mar 24 11:17:35 2014
@@ -89,8 +89,6 @@ public class TestCoreContainer extends S
     System.setProperty("shareSchema", "true");
     final CoreContainer cores = init("_shareSchema");
     try {
-      assertTrue(cores.isShareSchema());
-      
       CoreDescriptor descriptor1 = new CoreDescriptor(cores, "core1", "./collection1");
       SolrCore core1 = cores.create(descriptor1);
       

Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestLazyCores.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestLazyCores.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/core/TestLazyCores.java Mon Mar 24 11:17:35 2014
@@ -27,11 +27,9 @@ import org.apache.solr.handler.admin.Cor
 import org.apache.solr.request.LocalSolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
-import org.apache.solr.search.SolrIndexSearcher;
 import org.apache.solr.update.AddUpdateCommand;
 import org.apache.solr.update.CommitUpdateCommand;
 import org.apache.solr.update.UpdateHandler;
-import org.apache.solr.util.RefCounted;
 import org.apache.solr.util.TestHarness;
 import org.junit.After;
 import org.junit.BeforeClass;
@@ -560,10 +558,13 @@ public class TestLazyCores extends SolrT
 
   // See fi the message you expect is in the list of failures
   private void testMessage(Map<String, Exception> failures, String lookFor) {
+    List<String> messages = new ArrayList<>();
     for (Exception e : failures.values()) {
-      if (e.getMessage().indexOf(lookFor) != -1) return;
+      String message = e.getCause().getMessage();
+      messages.add(message);
+      if (message.contains(lookFor)) return;
     }
-    fail("Should have found message containing these tokens " + lookFor + " in the failure messages");
+    fail("Should have found message containing these tokens " + lookFor + " in the failure messages: " + messages);
   }
 
   // Just localizes writing a configuration rather than repeating it for good and bad files.

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java Mon Mar 24 11:17:35 2014
@@ -53,6 +53,7 @@ public class CoreAdminRequest extends So
     protected String schemaName = null;
     protected String dataDir = null;
     protected String ulogDir = null;
+    protected String configSet = null;
     protected String collection;
     private Integer numShards;
     private String shardId;
@@ -71,6 +72,9 @@ public class CoreAdminRequest extends So
     public void setConfigName(String config) { this.configName = config; }
     public void setDataDir(String dataDir) { this.dataDir = dataDir; }
     public void setUlogDir(String ulogDir) { this.ulogDir = ulogDir; }
+    public void setConfigSet(String configSet) {
+      this.configSet = configSet;
+    }
     public void setCollection(String collection) { this.collection = collection; }
     public void setNumShards(int numShards) {this.numShards = numShards;}
     public void setShardId(String shardId) {this.shardId = shardId;}
@@ -85,6 +89,9 @@ public class CoreAdminRequest extends So
     public String getConfigName()  { return configName; }
     public String getDataDir() { return dataDir; }
     public String getUlogDir() { return ulogDir; }
+    public String getConfigSet() {
+      return configSet;
+    }
     public String getCollection() { return collection; }
     public String getShardId() { return shardId; }
     public String getRoles() { return roles; }
@@ -118,6 +125,9 @@ public class CoreAdminRequest extends So
       if (ulogDir != null) {
         params.set( CoreAdminParams.ULOG_DIR, ulogDir);
       }
+      if (configSet != null) {
+        params.set( CoreAdminParams.CONFIGSET, configSet);
+      }
       if (collection != null) {
         params.set( CoreAdminParams.COLLECTION, collection);
       }

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java Mon Mar 24 11:17:35 2014
@@ -17,6 +17,21 @@ package org.apache.solr.common.cloud;
  * limitations under the License.
  */
 
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.util.ByteUtils;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.data.Stat;
+import org.noggit.CharArr;
+import org.noggit.JSONParser;
+import org.noggit.JSONWriter;
+import org.noggit.ObjectBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
@@ -34,21 +49,6 @@ import java.util.concurrent.ThreadFactor
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import org.noggit.CharArr;
-import org.noggit.JSONParser;
-import org.noggit.JSONWriter;
-import org.noggit.ObjectBuilder;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
-import org.apache.solr.common.util.ByteUtils;
-import org.apache.zookeeper.KeeperException;
-import org.apache.zookeeper.WatchedEvent;
-import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.Watcher.Event.EventType;
-import org.apache.zookeeper.data.Stat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 public class ZkStateReader {
   private static Logger log = LoggerFactory.getLogger(ZkStateReader.class);
   
@@ -134,8 +134,7 @@ public class ZkStateReader {
    * 
    * @param collection to return config set name for
    */
-  public String readConfigName(String collection) throws KeeperException,
-      InterruptedException {
+  public String readConfigName(String collection) {
 
     String configName = null;
 
@@ -143,22 +142,33 @@ public class ZkStateReader {
     if (log.isInfoEnabled()) {
       log.info("Load collection config from:" + path);
     }
-    byte[] data = zkClient.getData(path, null, null, true);
 
-    if(data != null) {
-      ZkNodeProps props = ZkNodeProps.load(data);
-      configName = props.getStr(CONFIGNAME_PROP);
-    }
+    try {
+      byte[] data = zkClient.getData(path, null, null, true);
 
-    if (configName != null) {
-      if (!zkClient.exists(CONFIGS_ZKNODE + "/" + configName, true)) {
-        log.error("Specified config does not exist in ZooKeeper:" + configName);
-        throw new ZooKeeperException(ErrorCode.SERVER_ERROR,
-            "Specified config does not exist in ZooKeeper:" + configName);
-      } else if (log.isInfoEnabled()) {
-        log.info("path={} {}={} specified config exists in ZooKeeper",
-            new Object[] {path, CONFIGNAME_PROP, configName});
+      if(data != null) {
+        ZkNodeProps props = ZkNodeProps.load(data);
+        configName = props.getStr(CONFIGNAME_PROP);
       }
+
+      if (configName != null) {
+        if (!zkClient.exists(CONFIGS_ZKNODE + "/" + configName, true)) {
+          log.error("Specified config does not exist in ZooKeeper:" + configName);
+          throw new ZooKeeperException(ErrorCode.SERVER_ERROR,
+              "Specified config does not exist in ZooKeeper:" + configName);
+        } else if (log.isInfoEnabled()) {
+          log.info("path={} {}={} specified config exists in ZooKeeper",
+              new Object[] {path, CONFIGNAME_PROP, configName});
+        }
+
+      }
+    }
+    catch (KeeperException e) {
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error loading config name for collection " + collection, e);
+    }
+    catch (InterruptedException e) {
+      Thread.interrupted();
+      throw new SolrException(ErrorCode.SERVER_ERROR, "Error loading config name for collection " + collection, e);
     }
 
     return configName;

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java Mon Mar 24 11:17:35 2014
@@ -37,9 +37,10 @@ public abstract class CoreAdminParams
   /** If you rename something, what is the new name **/
   public final static String NAME = "name";
 
-  /** If you rename something, what is the new name **/
+  /** Core data directory **/
   public final static String DATA_DIR = "dataDir";
-  
+
+  /** Core updatelog directory **/
   public final static String ULOG_DIR = "ulogDir";
 
   /** Name of the other core in actions involving 2 cores **/
@@ -50,6 +51,9 @@ public abstract class CoreAdminParams
   
   /** If you specify a schema, what is its name **/
   public final static String SCHEMA = "schema";
+
+  /** If you specify a configset, what is its name **/
+  public final static String CONFIGSET = "configSet";
   
   /** If you specify a config, what is its name **/
   public final static String CONFIG = "config";

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/solr/shared/solr.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/solr/shared/solr.xml?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/solr/shared/solr.xml (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/test-files/solrj/solr/shared/solr.xml Mon Mar 24 11:17:35 2014
@@ -30,7 +30,7 @@
   adminPath: RequestHandler path to manage cores.  
     If 'null' (or absent), cores will not be manageable via REST
   -->
-  <cores adminPath="/admin/cores" defaultCoreName="core0" host="127.0.0.1" hostPort="${hostPort:8983}" hostContext="${hostContext:solr}" zkClientTimeout="8000" genericCoreNodeNames="${genericCoreNodeNames:true}">
+  <cores adminPath="/admin/cores" defaultCoreName="core0" host="127.0.0.1" hostPort="${hostPort:8983}" hostContext="${hostContext:solr}" zkClientTimeout="8000" genericCoreNodeNames="${genericCoreNodeNames:true}" configSetBaseDir="${configSetBase:configsets}">
     <core name="collection1" instanceDir="." />
     <core name="core0" instanceDir="${theInstanceDir:./}" dataDir="${dataDir1}" collection="${collection:acollection}">
       <property name="version" value="3.5"/>

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/AbstractEmbeddedSolrServerTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/AbstractEmbeddedSolrServerTestCase.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/AbstractEmbeddedSolrServerTestCase.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/AbstractEmbeddedSolrServerTestCase.java Mon Mar 24 11:17:35 2014
@@ -51,6 +51,7 @@ public abstract class AbstractEmbeddedSo
     super.setUp();
 
     System.setProperty("solr.solr.home", SOLR_HOME.getAbsolutePath());
+    System.setProperty("configSetBase", SolrTestCaseJ4.getFile("solrj/solr/configsets").getAbsolutePath());
     System.out.println("Solr home: " + SOLR_HOME.getAbsolutePath());
 
     //The index is always stored within a temporary directory

Modified: lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/test/org/apache/solr/client/solrj/request/TestCoreAdmin.java Mon Mar 24 11:17:35 2014
@@ -18,23 +18,31 @@
 package org.apache.solr.client.solrj.request;
 
 import com.carrotsearch.randomizedtesting.annotations.ThreadLeakFilters;
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.commons.io.FileUtils;
 import org.apache.solr.SolrIgnoredThreadsFilter;
 import org.apache.solr.client.solrj.SolrServer;
 import org.apache.solr.client.solrj.embedded.AbstractEmbeddedSolrServerTestCase;
 import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
+import org.apache.solr.client.solrj.response.CoreAdminResponse;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.ModifiableSolrParams;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.junit.After;
 import org.junit.BeforeClass;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.File;
 
+import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.core.Is.is;
+
 @ThreadLeakFilters(defaultFilters = true, filters = {SolrIgnoredThreadsFilter.class})
 public class TestCoreAdmin extends AbstractEmbeddedSolrServerTestCase {
   protected static Logger log = LoggerFactory.getLogger(TestCoreAdmin.class);
@@ -42,6 +50,9 @@ public class TestCoreAdmin extends Abstr
   private static final String SOLR_XML = "solr.xml";
 
   private static String tempDirProp;
+
+  @Rule
+  public TestRule testRule = RuleChain.outerRule(new SystemPropertiesRestoreRule());
   
   @Override
   protected File getSolrXml() throws Exception {
@@ -57,15 +68,47 @@ public class TestCoreAdmin extends Abstr
   protected SolrServer getSolrAdmin() {
     return new EmbeddedSolrServer(cores, "core0");
   }
+
+  @Test
+  public void testConfigSet() throws Exception {
+
+    SolrServer server = getSolrAdmin();
+    File testDir = createTestDirectory();
+
+    File newCoreInstanceDir = new File(testDir, "newcore");
+
+    CoreAdminRequest.Create req = new CoreAdminRequest.Create();
+    req.setCoreName("corewithconfigset");
+    req.setInstanceDir(newCoreInstanceDir.getAbsolutePath());
+    req.setConfigSet("configset-2");
+
+    CoreAdminResponse response = req.process(server);
+    assertThat((String) response.getResponse().get("core"), is("corewithconfigset"));
+
+    SolrCore core = null;
+    try {
+      core = cores.getCore("corewithconfigset");
+      assertThat(core, is(notNullValue()));
+    }
+    finally {
+      if (core != null)
+        core.close();
+    }
+
+  }
+
+  private File createTestDirectory() {
+    File tmp = new File(TEMP_DIR, "solrtest-" + getTestClass().getSimpleName() + "-" + System.currentTimeMillis());
+    assertTrue("Couldn't create temporary directory " + tmp.getAbsolutePath(), tmp.mkdirs());
+    return tmp;
+  }
   
   @Test
   public void testCustomUlogDir() throws Exception {
     
     SolrServer server = getSolrAdmin();
     
-    
-    File tmp = new File(TEMP_DIR, "solrtest-" + getTestClass().getSimpleName() + "-" + System.currentTimeMillis());
-    tmp.mkdirs();
+    File tmp = createTestDirectory();
 
     log.info("Creating cores underneath {}", tmp);
     

Modified: lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java?rev=1580817&r1=1580816&r2=1580817&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java (original)
+++ lucene/dev/branches/branch_4x/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java Mon Mar 24 11:17:35 2014
@@ -286,6 +286,13 @@ public abstract class SolrTestCaseJ4 ext
     System.setProperty("solr.tests.maxIndexingThreads", String.valueOf(maxIndexingThreads));
   }
 
+  public static Throwable getWrappedException(Throwable e) {
+    while (e != null && e.getCause() != e && e.getCause() != null) {
+      e = e.getCause();
+    }
+    return e;
+  }
+
   @Override
   public void setUp() throws Exception {
     super.setUp();