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 2015/02/25 15:45:51 UTC

svn commit: r1662232 [1/2] - in /lucene/dev/trunk/solr: core/src/java/org/apache/solr/cloud/ core/src/java/org/apache/solr/core/ core/src/java/org/apache/solr/handler/component/ core/src/java/org/apache/solr/servlet/ core/src/java/org/apache/solr/updat...

Author: romseygeek
Date: Wed Feb 25 14:45:51 2015
New Revision: 1662232

URL: http://svn.apache.org/r1662232
Log:
SOLR-7160: Decouple CoreContainer config from xml representation

Added:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CloudConfig.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/NodeConfig.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandlerConfig.java   (with props)
Removed:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolr.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSolrXml.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/util/MockConfigSolr.java
Modified:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCores.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ZkContainer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyShardSplitTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/SolrXmlInZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestLeaderElectionZkExpiry.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestConfigSets.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreContainer.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestCoreDiscovery.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestLazyCores.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestSolrXml.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/util/TestHarness.java

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java Wed Feb 25 14:45:51 2015
@@ -17,26 +17,6 @@ package org.apache.solr.cloud;
  * the License.
  */
 
-import static org.apache.solr.cloud.OverseerCollectionProcessor.SHARD_UNIQUE;
-import static org.apache.solr.cloud.OverseerCollectionProcessor.ONLY_ACTIVE_NODES;
-import static org.apache.solr.common.params.CollectionParams.CollectionAction.BALANCESHARDUNIQUE;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
 import org.apache.commons.lang.StringUtils;
 import org.apache.solr.client.solrj.SolrResponse;
 import org.apache.solr.cloud.overseer.ClusterStateMutator;
@@ -55,10 +35,10 @@ import org.apache.solr.common.cloud.Solr
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.CollectionParams;
-import org.apache.solr.core.ConfigSolr;
+import org.apache.solr.common.util.IOUtils;
+import org.apache.solr.core.CloudConfig;
 import org.apache.solr.handler.component.ShardHandler;
 import org.apache.solr.update.UpdateShardHandler;
-import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.util.stats.Clock;
 import org.apache.solr.util.stats.Timer;
 import org.apache.solr.util.stats.TimerContext;
@@ -67,6 +47,26 @@ import org.apache.zookeeper.KeeperExcept
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.apache.solr.cloud.OverseerCollectionProcessor.ONLY_ACTIVE_NODES;
+import static org.apache.solr.cloud.OverseerCollectionProcessor.SHARD_UNIQUE;
+import static org.apache.solr.common.params.CollectionParams.CollectionAction.BALANCESHARDUNIQUE;
+
 /**
  * Cluster leader. Responsible for processing state updates, node assignments, creating/deleting
  * collections, shards, replicas and setting various properties.
@@ -830,12 +830,12 @@ public class Overseer implements Closeab
   private Stats stats;
   private String id;
   private boolean closed;
-  private ConfigSolr config;
+  private CloudConfig config;
 
   // overseer not responsible for closing reader
   public Overseer(ShardHandler shardHandler,
       UpdateShardHandler updateShardHandler, String adminPath,
-      final ZkStateReader reader, ZkController zkController, ConfigSolr config)
+      final ZkStateReader reader, ZkController zkController, CloudConfig config)
       throws KeeperException, InterruptedException {
     this.reader = reader;
     this.shardHandler = shardHandler;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerAutoReplicaFailoverThread.java Wed Feb 25 14:45:51 2015
@@ -28,7 +28,7 @@ import org.apache.solr.common.cloud.DocC
 import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.ZkStateReader;
-import org.apache.solr.core.ConfigSolr;
+import org.apache.solr.core.CloudConfig;
 import org.apache.solr.update.UpdateShardHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,7 +90,7 @@ public class OverseerAutoReplicaFailover
   private final int workLoopDelay;
   private final int waitAfterExpiration;
   
-  public OverseerAutoReplicaFailoverThread(ConfigSolr config, ZkStateReader zkStateReader,
+  public OverseerAutoReplicaFailoverThread(CloudConfig config, ZkStateReader zkStateReader,
       UpdateShardHandler updateShardHandler) {
     this.zkStateReader = zkStateReader;
     

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/SolrZkServer.java Wed Feb 25 14:45:51 2015
@@ -17,6 +17,16 @@ package org.apache.solr.cloud;
  * the License.
  */
 
+import org.apache.solr.common.SolrException;
+import org.apache.zookeeper.server.ServerConfig;
+import org.apache.zookeeper.server.ZooKeeperServerMain;
+import org.apache.zookeeper.server.quorum.QuorumPeer;
+import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
+import org.apache.zookeeper.server.quorum.QuorumPeerMain;
+import org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical;
+import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
+import org.slf4j.LoggerFactory;
+
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -27,18 +37,8 @@ import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
 import java.nio.charset.StandardCharsets;
 import java.util.Map;
-import java.util.Properties;
 import java.util.Map.Entry;
-
-import org.apache.solr.common.SolrException;
-import org.apache.zookeeper.server.ServerConfig;
-import org.apache.zookeeper.server.ZooKeeperServerMain;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
-import org.apache.zookeeper.server.quorum.QuorumPeerConfig;
-import org.apache.zookeeper.server.quorum.QuorumPeerMain;
-import org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical;
-import org.apache.zookeeper.server.quorum.flexible.QuorumMaj;
-import org.slf4j.LoggerFactory;
+import java.util.Properties;
 
 
 public class SolrZkServer {
@@ -47,7 +47,7 @@ public class SolrZkServer {
   String zkRun;
   String zkHost;
 
-  String solrPort;
+  int solrPort;
   Properties props;
   SolrZkServerProps zkProps;
 
@@ -56,7 +56,7 @@ public class SolrZkServer {
   private String dataHome;
   private String confHome;
 
-  public SolrZkServer(String zkRun, String zkHost, String dataHome, String confHome, String solrPort) {
+  public SolrZkServer(String zkRun, String zkHost, String dataHome, String confHome, int solrPort) {
     this.zkRun = zkRun;
     this.zkHost = zkHost;
     this.dataHome = dataHome;
@@ -81,7 +81,7 @@ public class SolrZkServer {
       // TODO: use something based on IP+port???  support ensemble all from same solr home?
       zkProps.setDataDir(dataHome);
       zkProps.zkRun = zkRun;
-      zkProps.solrPort = solrPort;
+      zkProps.solrPort = Integer.toString(solrPort);
     }
     
     try {
@@ -89,7 +89,7 @@ public class SolrZkServer {
       SolrZkServerProps.injectServers(props, zkRun, zkHost);
       zkProps.parseProperties(props);
       if (zkProps.getClientPortAddress() == null) {
-        zkProps.setClientPort(Integer.parseInt(solrPort)+1000);
+        zkProps.setClientPort(solrPort + 1000);
       }
     } catch (QuorumPeerConfig.ConfigException | IOException e) {
       if (zkRun != null)

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkCLI.java Wed Feb 25 14:45:51 2015
@@ -165,7 +165,7 @@ public class ZkCLI {
       SolrZkServer zkServer = null;
       if (solrPort != null) {
         zkServer = new SolrZkServer("true", null, solrHome + "/zoo_data",
-            solrHome, solrPort);
+            solrHome, Integer.parseInt(solrPort));
         zkServer.parseConfig();
         zkServer.start();
       }

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java Wed Feb 25 14:45:51 2015
@@ -47,6 +47,7 @@ import org.apache.solr.common.params.Col
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.common.util.URLUtil;
 import org.apache.solr.core.CloseHook;
+import org.apache.solr.core.CloudConfig;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.CoreDescriptor;
 import org.apache.solr.core.SolrCore;
@@ -177,12 +178,12 @@ public final class ZkController {
   
   private final String zkServerAddress;          // example: 127.0.0.1:54062/solr
 
-  private final String localHostPort;      // example: 54065
-  private final String localHostContext;   // example: solr
+  private final int localHostPort;      // example: 54065
   private final String hostName;           // example: 127.0.0.1
   private final String nodeName;           // example: 127.0.0.1:54065_solr
   private final String baseURL;            // example: http://127.0.0.1:54065/solr
 
+  private final CloudConfig cloudConfig;
 
   private LeaderElector overseerElector;
   
@@ -214,33 +215,33 @@ public final class ZkController {
   // keeps track of a list of objects that need to know a new ZooKeeper session was created after expiration occurred
   private List<OnReconnect> reconnectListeners = new ArrayList<OnReconnect>();
 
-  public ZkController(final CoreContainer cc, String zkServerAddress, int zkClientTimeout, int zkClientConnectTimeout, String localHost, String locaHostPort,
-                      String localHostContext, int leaderVoteWait, int leaderConflictResolveWait, boolean genericCoreNodeNames, final CurrentCoreDescriptorProvider registerOnReconnect)
+  public ZkController(final CoreContainer cc, String zkServerAddress, int zkClientConnectTimeout, CloudConfig cloudConfig, final CurrentCoreDescriptorProvider registerOnReconnect)
       throws InterruptedException, TimeoutException, IOException {
 
     if (cc == null) throw new IllegalArgumentException("CoreContainer cannot be null.");
     this.cc = cc;
-    this.genericCoreNodeNames = genericCoreNodeNames;
+
+    this.cloudConfig = cloudConfig;
+
+    this.genericCoreNodeNames = cloudConfig.getGenericCoreNodeNames();
+
     // be forgiving and strip this off leading/trailing slashes
     // this allows us to support users specifying hostContext="/" in 
     // solr.xml to indicate the root context, instead of hostContext="" 
     // which means the default of "solr"
-    localHostContext = trimLeadingAndTrailingSlashes(localHostContext);
+    String localHostContext = trimLeadingAndTrailingSlashes(cloudConfig.getSolrHostContext());
 
     this.zkServerAddress = zkServerAddress;
-    this.localHostPort = locaHostPort;
-    this.localHostContext = localHostContext;
-    this.hostName = normalizeHostName(localHost);
-    this.nodeName = generateNodeName(this.hostName,
-        this.localHostPort,
-        this.localHostContext);
+    this.localHostPort = cloudConfig.getSolrHostPort();
+    this.hostName = normalizeHostName(cloudConfig.getHost());
+    this.nodeName = generateNodeName(this.hostName, Integer.toString(this.localHostPort), localHostContext);
 
-    this.leaderVoteWait = leaderVoteWait;
-    this.leaderConflictResolveWait = leaderConflictResolveWait;
+    this.leaderVoteWait = cloudConfig.getLeaderVoteWait();
+    this.leaderConflictResolveWait = cloudConfig.getLeaderConflictResolveWait();
 
-    this.clientTimeout = zkClientTimeout;
+    this.clientTimeout = cloudConfig.getZkClientTimeout();
     DefaultConnectionStrategy strat = new DefaultConnectionStrategy();
-    String zkACLProviderClass = cc.getConfig().getZkACLProviderClass();
+    String zkACLProviderClass = cloudConfig.getZkACLProviderClass();
     ZkACLProvider zkACLProvider = null;
     if (zkACLProviderClass != null && zkACLProviderClass.trim().length() > 0) {
       zkACLProvider = cc.getResourceLoader().newInstance(zkACLProviderClass, ZkACLProvider.class);
@@ -248,7 +249,7 @@ public final class ZkController {
       zkACLProvider = new DefaultZkACLProvider();
     }
 
-    String zkCredentialsProviderClass = cc.getConfig().getZkCredentialsProviderClass();
+    String zkCredentialsProviderClass = cloudConfig.getZkCredentialsProviderClass();
     if (zkCredentialsProviderClass != null && zkCredentialsProviderClass.trim().length() > 0) {
       strat.setZkCredentialsToAddAutomatically(cc.getResourceLoader().newInstance(zkCredentialsProviderClass, ZkCredentialsProvider.class));
     } else {
@@ -256,8 +257,7 @@ public final class ZkController {
     }
     addOnReconnectListener(getConfigDirListener());
 
-    zkClient = new SolrZkClient(zkServerAddress, zkClientTimeout,
-        zkClientConnectTimeout, strat,
+    zkClient = new SolrZkClient(zkServerAddress, clientTimeout, zkClientConnectTimeout, strat,
         // on reconnect, reload cloud info
         new OnReconnect() {
 
@@ -362,7 +362,7 @@ public final class ZkController {
     this.overseerRunningMap = Overseer.getRunningMap(zkClient);
     this.overseerCompletedMap = Overseer.getCompletedMap(zkClient);
     this.overseerFailureMap = Overseer.getFailureMap(zkClient);
-    cmdExecutor = new ZkCmdExecutor(zkClientTimeout);
+    cmdExecutor = new ZkCmdExecutor(clientTimeout);
     leaderElector = new LeaderElector(zkClient);
     zkStateReader = new ZkStateReader(zkClient);
 
@@ -584,7 +584,7 @@ public final class ZkController {
     return hostName;
   }
   
-  public String getHostPort() {
+  public int getHostPort() {
     return localHostPort;
   }
 
@@ -624,7 +624,7 @@ public final class ZkController {
       if (!zkRunOnly) {
         overseerElector = new LeaderElector(zkClient);
         this.overseer = new Overseer(shardHandler, updateShardHandler,
-            CoreContainer.CORES_HANDLER_PATH, zkStateReader, this, cc.getConfig());
+            CoreContainer.CORES_HANDLER_PATH, zkStateReader, this, cloudConfig);
         ElectionContext context = new OverseerElectionContext(zkClient,
             overseer, getNodeName());
         overseerElector.setup(context);

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CloudConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CloudConfig.java?rev=1662232&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CloudConfig.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CloudConfig.java Wed Feb 25 14:45:51 2015
@@ -0,0 +1,212 @@
+package org.apache.solr.core;
+
+/*
+ * 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.
+ */
+
+import org.apache.solr.common.SolrException;
+
+public class CloudConfig {
+
+  private final String zkHost;
+
+  private final int zkClientTimeout;
+
+  private final int hostPort;
+
+  private final String hostName;
+
+  private final String hostContext;
+
+  private final boolean useGenericCoreNames;
+
+  private final int leaderVoteWait;
+
+  private final int leaderConflictResolveWait;
+
+  private final int autoReplicaFailoverWaitAfterExpiration;
+
+  private final int autoReplicaFailoverWorkLoopDelay;
+
+  private final int autoReplicaFailoverBadNodeExpiration;
+
+  private final String zkCredentialsProviderClass;
+
+  private final String zkACLProviderClass;
+
+  CloudConfig(String zkHost, int zkClientTimeout, int hostPort, String hostName, String hostContext, boolean useGenericCoreNames, int leaderVoteWait, int leaderConflictResolveWait, int autoReplicaFailoverWaitAfterExpiration, int autoReplicaFailoverWorkLoopDelay, int autoReplicaFailoverBadNodeExpiration, String zkCredentialsProviderClass, String zkACLProviderClass) {
+    this.zkHost = zkHost;
+    this.zkClientTimeout = zkClientTimeout;
+    this.hostPort = hostPort;
+    this.hostName = hostName;
+    this.hostContext = hostContext;
+    this.useGenericCoreNames = useGenericCoreNames;
+    this.leaderVoteWait = leaderVoteWait;
+    this.leaderConflictResolveWait = leaderConflictResolveWait;
+    this.autoReplicaFailoverWaitAfterExpiration = autoReplicaFailoverWaitAfterExpiration;
+    this.autoReplicaFailoverWorkLoopDelay = autoReplicaFailoverWorkLoopDelay;
+    this.autoReplicaFailoverBadNodeExpiration = autoReplicaFailoverBadNodeExpiration;
+    this.zkCredentialsProviderClass = zkCredentialsProviderClass;
+    this.zkACLProviderClass = zkACLProviderClass;
+
+    if (this.hostPort == -1)
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "'hostPort' must be configured to run SolrCloud");
+    if (this.hostContext == null)
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "'hostContext' must be configured to run SolrCloud");
+  }
+
+  public String getZkHost() {
+    return zkHost;
+  }
+
+  public int getZkClientTimeout() {
+    return zkClientTimeout;
+  }
+
+  public int getSolrHostPort() {
+    return hostPort;
+  }
+
+  public String getSolrHostContext() {
+    return hostContext;
+  }
+
+  public String getHost() {
+    return hostName;
+  }
+
+  public String getZkCredentialsProviderClass() {
+    return zkCredentialsProviderClass;
+  }
+
+  public String getZkACLProviderClass() {
+    return zkACLProviderClass;
+  }
+
+  public int getLeaderVoteWait() {
+    return leaderVoteWait;
+  }
+
+  public int getLeaderConflictResolveWait() {
+    return leaderConflictResolveWait;
+  }
+
+  public int getAutoReplicaFailoverWaitAfterExpiration() {
+    return autoReplicaFailoverWaitAfterExpiration;
+  }
+
+  public int getAutoReplicaFailoverWorkLoopDelay() {
+    return autoReplicaFailoverWorkLoopDelay;
+  }
+
+  public int getAutoReplicaFailoverBadNodeExpiration() {
+    return autoReplicaFailoverBadNodeExpiration;
+  }
+
+  public boolean getGenericCoreNodeNames() {
+    return useGenericCoreNames;
+  }
+
+  public static class CloudConfigBuilder {
+
+    private static final int DEFAULT_ZK_CLIENT_TIMEOUT = 15000;
+    private static final int DEFAULT_LEADER_VOTE_WAIT = 180000;  // 3 minutes
+    private static final int DEFAULT_LEADER_CONFLICT_RESOLVE_WAIT = 180000;
+
+    // TODO: tune defaults
+    private static final int DEFAULT_AUTO_REPLICA_FAILOVER_WAIT_AFTER_EXPIRATION = 30000;
+    private static final int DEFAULT_AUTO_REPLICA_FAILOVER_WORKLOOP_DELAY = 10000;
+    private static final int DEFAULT_AUTO_REPLICA_FAILOVER_BAD_NODE_EXPIRATION = 60000;
+
+    private String zkHost = System.getProperty("zkHost");
+    private int zkClientTimeout = Integer.getInteger("zkClientTimeout", DEFAULT_ZK_CLIENT_TIMEOUT);
+    private final int hostPort;
+    private final String hostName;
+    private final String hostContext;
+    private boolean useGenericCoreNames;
+    private int leaderVoteWait = DEFAULT_LEADER_VOTE_WAIT;
+    private int leaderConflictResolveWait = DEFAULT_LEADER_CONFLICT_RESOLVE_WAIT;
+    private int autoReplicaFailoverWaitAfterExpiration = DEFAULT_AUTO_REPLICA_FAILOVER_WAIT_AFTER_EXPIRATION;
+    private int autoReplicaFailoverWorkLoopDelay = DEFAULT_AUTO_REPLICA_FAILOVER_WORKLOOP_DELAY;
+    private int autoReplicaFailoverBadNodeExpiration = DEFAULT_AUTO_REPLICA_FAILOVER_BAD_NODE_EXPIRATION;
+    private String zkCredentialsProviderClass;
+    private String zkACLProviderClass;
+
+    public CloudConfigBuilder(String hostName, int hostPort) {
+      this(hostName, hostPort, null);
+    }
+
+    public CloudConfigBuilder(String hostName, int hostPort, String hostContext) {
+      this.hostName = hostName;
+      this.hostPort = hostPort;
+      this.hostContext = hostContext;
+    }
+
+    public CloudConfigBuilder setZkHost(String zkHost) {
+      this.zkHost = zkHost;
+      return this;
+    }
+
+    public CloudConfigBuilder setZkClientTimeout(int zkClientTimeout) {
+      this.zkClientTimeout = zkClientTimeout;
+      return this;
+    }
+
+    public CloudConfigBuilder setUseGenericCoreNames(boolean useGenericCoreNames) {
+      this.useGenericCoreNames = useGenericCoreNames;
+      return this;
+    }
+
+    public CloudConfigBuilder setLeaderVoteWait(int leaderVoteWait) {
+      this.leaderVoteWait = leaderVoteWait;
+      return this;
+    }
+
+    public CloudConfigBuilder setLeaderConflictResolveWait(int leaderConflictResolveWait) {
+      this.leaderConflictResolveWait = leaderConflictResolveWait;
+      return this;
+    }
+
+    public CloudConfigBuilder setAutoReplicaFailoverWaitAfterExpiration(int autoReplicaFailoverWaitAfterExpiration) {
+      this.autoReplicaFailoverWaitAfterExpiration = autoReplicaFailoverWaitAfterExpiration;
+      return this;
+    }
+
+    public CloudConfigBuilder setAutoReplicaFailoverWorkLoopDelay(int autoReplicaFailoverWorkLoopDelay) {
+      this.autoReplicaFailoverWorkLoopDelay = autoReplicaFailoverWorkLoopDelay;
+      return this;
+    }
+
+    public CloudConfigBuilder setAutoReplicaFailoverBadNodeExpiration(int autoReplicaFailoverBadNodeExpiration) {
+      this.autoReplicaFailoverBadNodeExpiration = autoReplicaFailoverBadNodeExpiration;
+      return this;
+    }
+
+    public CloudConfigBuilder setZkCredentialsProviderClass(String zkCredentialsProviderClass) {
+      this.zkCredentialsProviderClass = zkCredentialsProviderClass;
+      return this;
+    }
+
+    public CloudConfigBuilder setZkACLProviderClass(String zkACLProviderClass) {
+      this.zkACLProviderClass = zkACLProviderClass;
+      return this;
+    }
+
+    public CloudConfig build() {
+      return new CloudConfig(zkHost, zkClientTimeout, hostPort, hostName, hostContext, useGenericCoreNames, leaderVoteWait, leaderConflictResolveWait, autoReplicaFailoverWaitAfterExpiration, autoReplicaFailoverWorkLoopDelay, autoReplicaFailoverBadNodeExpiration, zkCredentialsProviderClass, zkACLProviderClass);
+    }
+  }
+}

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSetService.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSetService.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSetService.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ConfigSetService.java Wed Feb 25 14:45:51 2015
@@ -19,6 +19,8 @@ package org.apache.solr.core;
 
 import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
+import org.apache.solr.cloud.CloudConfigSetService;
+import org.apache.solr.cloud.ZkController;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.IndexSchemaFactory;
@@ -38,6 +40,16 @@ import java.util.concurrent.ExecutionExc
  */
 public abstract class ConfigSetService {
 
+  public static ConfigSetService createConfigSetService(NodeConfig nodeConfig, SolrResourceLoader loader, ZkController zkController) {
+    if (zkController != null)
+      return new CloudConfigSetService(loader, zkController);
+
+    if (nodeConfig.hasSchemaCache())
+      return new SchemaCaching(loader, nodeConfig.getConfigSetBaseDirectory());
+
+    return new Default(loader, nodeConfig.getConfigSetBaseDirectory());
+  }
+
   protected final SolrResourceLoader parentLoader;
 
   /**

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/CoreContainer.java Wed Feb 25 14:45:51 2015
@@ -93,7 +93,7 @@ public class CoreContainer {
   protected LogWatcher logging = null;
 
   private CloserThread backgroundCloser = null;
-  protected final ConfigSolr cfg;
+  protected final NodeConfig cfg;
   protected final SolrResourceLoader loader;
 
   protected final String solrHome;
@@ -140,7 +140,7 @@ public class CoreContainer {
    * @see #load()
    */
   public CoreContainer(SolrResourceLoader loader) {
-    this(ConfigSolr.fromSolrHome(loader, loader.getInstanceDir()));
+    this(SolrXmlConfig.fromSolrHome(loader, loader.getInstanceDir()));
   }
 
   /**
@@ -160,11 +160,11 @@ public class CoreContainer {
    * @param config a ConfigSolr representation of this container's configuration
    * @see #load()
    */
-  public CoreContainer(ConfigSolr config) {
-    this(config, config.getCoresLocator());
+  public CoreContainer(NodeConfig config) {
+    this(config, new CorePropertiesLocator(config.getCoreRootDirectory()));
   }
 
-  public CoreContainer(ConfigSolr config, CoresLocator locator) {
+  public CoreContainer(NodeConfig config, CoresLocator locator) {
     this.loader = config.getSolrResourceLoader();
     this.solrHome = loader.getInstanceDir();
     this.cfg = checkNotNull(config);
@@ -193,7 +193,7 @@ public class CoreContainer {
    */
   public static CoreContainer createAndLoad(String solrHome, File configFile) {
     SolrResourceLoader loader = new SolrResourceLoader(solrHome);
-    CoreContainer cc = new CoreContainer(ConfigSolr.fromFile(loader, configFile));
+    CoreContainer cc = new CoreContainer(SolrXmlConfig.fromFile(loader, configFile));
     try {
       cc.load();
     } catch (Exception e) {
@@ -230,16 +230,16 @@ public class CoreContainer {
 
     shardHandlerFactory = ShardHandlerFactory.newInstance(cfg.getShardHandlerFactoryPluginInfo(), loader);
 
-    updateShardHandler = new UpdateShardHandler(cfg);
+    updateShardHandler = new UpdateShardHandler(cfg.getUpdateShardHandlerConfig());
 
     solrCores.allocateLazyCores(cfg.getTransientCacheSize(), loader);
 
     logging = LogWatcher.newRegisteredLogWatcher(cfg.getLogWatcherConfig(), loader);
 
-    hostName = cfg.getHost();
-    log.info("Host Name: " + hostName);
+    hostName = cfg.getNodeName();
+    log.info("Node Name: " + hostName);
 
-    zkSys.initZooKeeper(this, solrHome, cfg);
+    zkSys.initZooKeeper(this, solrHome, cfg.getCloudConfig());
 
     collectionsHandler = createHandler(cfg.getCollectionsHandlerClass(), CollectionsHandler.class);
     containerHandlers.put(COLLECTIONS_HANDLER_PATH, collectionsHandler);
@@ -248,7 +248,7 @@ public class CoreContainer {
     coreAdminHandler   = createHandler(cfg.getCoreAdminHandlerClass(), CoreAdminHandler.class);
     containerHandlers.put(CORES_HANDLER_PATH, coreAdminHandler);
 
-    coreConfigService = cfg.createCoreConfigService(loader, zkSys.getZkController());
+    coreConfigService = ConfigSetService.createConfigSetService(cfg, loader, zkSys.zkController);
 
     containerProperties = cfg.getSolrProperties();
 
@@ -860,7 +860,7 @@ public class CoreContainer {
     return zkSys.getZkController();
   }
   
-  public ConfigSolr getConfig() {
+  public NodeConfig getConfig() {
     return cfg;
   }
 
@@ -881,10 +881,10 @@ public class CoreContainer {
 class CloserThread extends Thread {
   CoreContainer container;
   SolrCores solrCores;
-  ConfigSolr cfg;
+  NodeConfig cfg;
 
 
-  CloserThread(CoreContainer container, SolrCores solrCores, ConfigSolr cfg) {
+  CloserThread(CoreContainer container, SolrCores solrCores, NodeConfig cfg) {
     this.container = container;
     this.solrCores = solrCores;
     this.cfg = cfg;

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/NodeConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/NodeConfig.java?rev=1662232&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/NodeConfig.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/NodeConfig.java Wed Feb 25 14:45:51 2015
@@ -0,0 +1,297 @@
+package org.apache.solr.core;
+
+/*
+ * 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.
+ */
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.logging.LogWatcherConfig;
+import org.apache.solr.update.UpdateShardHandlerConfig;
+
+import java.util.Properties;
+
+
+public class NodeConfig {
+
+  private final String nodeName;
+
+  private final String coreRootDirectory;
+
+  private final String configSetBaseDirectory;
+
+  private final String sharedLibDirectory;
+
+  private final PluginInfo shardHandlerFactoryConfig;
+
+  private final UpdateShardHandlerConfig updateShardHandlerConfig;
+
+  private final String coreAdminHandlerClass;
+
+  private final String collectionsAdminHandlerClass;
+
+  private final String infoHandlerClass;
+
+  private final LogWatcherConfig logWatcherConfig;
+
+  private final CloudConfig cloudConfig;
+
+  private final int coreLoadThreads;
+
+  private final int transientCacheSize;
+
+  private final boolean useSchemaCache;
+
+  private final String managementPath;
+
+  private NodeConfig(String nodeName, String coreRootDirectory, String configSetBaseDirectory, String sharedLibDirectory,
+                     PluginInfo shardHandlerFactoryConfig, UpdateShardHandlerConfig updateShardHandlerConfig,
+                     String coreAdminHandlerClass, String collectionsAdminHandlerClass, String infoHandlerClass,
+                     LogWatcherConfig logWatcherConfig, CloudConfig cloudConfig, int coreLoadThreads,
+                     int transientCacheSize, boolean useSchemaCache, String managementPath,
+                     SolrResourceLoader loader, Properties solrProperties) {
+    this.nodeName = nodeName;
+    this.coreRootDirectory = coreRootDirectory;
+    this.configSetBaseDirectory = configSetBaseDirectory;
+    this.sharedLibDirectory = sharedLibDirectory;
+    this.shardHandlerFactoryConfig = shardHandlerFactoryConfig;
+    this.updateShardHandlerConfig = updateShardHandlerConfig;
+    this.coreAdminHandlerClass = coreAdminHandlerClass;
+    this.collectionsAdminHandlerClass = collectionsAdminHandlerClass;
+    this.infoHandlerClass = infoHandlerClass;
+    this.logWatcherConfig = logWatcherConfig;
+    this.cloudConfig = cloudConfig;
+    this.coreLoadThreads = coreLoadThreads;
+    this.transientCacheSize = transientCacheSize;
+    this.useSchemaCache = useSchemaCache;
+    this.managementPath = managementPath;
+    this.loader = loader;
+    this.solrProperties = solrProperties;
+
+    if (this.cloudConfig != null && this.coreLoadThreads < 2) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+          "SolrCloud requires a value of at least 2 for coreLoadThreads (configured value = " + this.coreLoadThreads + ")");
+    }
+  }
+
+  public String getNodeName() {
+    return nodeName;
+  }
+
+  public String getCoreRootDirectory() {
+    return coreRootDirectory;
+  }
+
+  public PluginInfo getShardHandlerFactoryPluginInfo() {
+    return shardHandlerFactoryConfig;
+  }
+
+  public UpdateShardHandlerConfig getUpdateShardHandlerConfig() {
+    return updateShardHandlerConfig;
+  }
+
+  @Deprecated
+  public int getDistributedConnectionTimeout() {
+    return updateShardHandlerConfig.getDistributedConnectionTimeout();
+  }
+
+  @Deprecated
+  public int getDistributedSocketTimeout() {
+    return updateShardHandlerConfig.getDistributedSocketTimeout();
+  }
+
+  @Deprecated
+  public int getMaxUpdateConnections() {
+    return updateShardHandlerConfig.getMaxUpdateConnections();
+  }
+
+  @Deprecated
+  public int getMaxUpdateConnectionsPerHost() {
+    return updateShardHandlerConfig.getMaxUpdateConnectionsPerHost();
+  }
+
+  public int getCoreLoadThreadCount() {
+    return coreLoadThreads;
+  }
+
+  public String getSharedLibDirectory() {
+    return sharedLibDirectory;
+  }
+
+  public String getCoreAdminHandlerClass() {
+    return coreAdminHandlerClass;
+  }
+  
+  public String getCollectionsHandlerClass() {
+    return collectionsAdminHandlerClass;
+  }
+
+  public String getInfoHandlerClass() {
+    return infoHandlerClass;
+  }
+
+  public boolean hasSchemaCache() {
+    return useSchemaCache;
+  }
+
+  public String getManagementPath() {
+    return managementPath;
+  }
+
+  public String getConfigSetBaseDirectory() {
+    return configSetBaseDirectory;
+  }
+
+  public LogWatcherConfig getLogWatcherConfig() {
+    return logWatcherConfig;
+  }
+
+  public CloudConfig getCloudConfig() {
+    return cloudConfig;
+  }
+
+  public int getTransientCacheSize() {
+    return transientCacheSize;
+  }
+
+  protected final SolrResourceLoader loader;
+  protected final Properties solrProperties;
+
+  public Properties getSolrProperties() {
+    return solrProperties;
+  }
+
+  public SolrResourceLoader getSolrResourceLoader() {
+    return loader;
+  }
+
+  public static class NodeConfigBuilder {
+
+    private String coreRootDirectory = "";
+    private String configSetBaseDirectory = "configsets";
+    private String sharedLibDirectory = "lib";
+    private PluginInfo shardHandlerFactoryConfig;
+    private UpdateShardHandlerConfig updateShardHandlerConfig = UpdateShardHandlerConfig.DEFAULT;
+    private String coreAdminHandlerClass = DEFAULT_ADMINHANDLERCLASS;
+    private String collectionsAdminHandlerClass = DEFAULT_COLLECTIONSHANDLERCLASS;
+    private String infoHandlerClass = DEFAULT_INFOHANDLERCLASS;
+    private LogWatcherConfig logWatcherConfig = new LogWatcherConfig(true, null, null, 50);
+    private CloudConfig cloudConfig;
+    private int coreLoadThreads = DEFAULT_CORE_LOAD_THREADS;
+    private int transientCacheSize = DEFAULT_TRANSIENT_CACHE_SIZE;
+    private boolean useSchemaCache = false;
+    private String managementPath;
+    private Properties solrProperties = new Properties();
+
+    private final SolrResourceLoader loader;
+    private final String nodeName;
+
+    private static final int DEFAULT_CORE_LOAD_THREADS = 3;
+
+    private static final int DEFAULT_TRANSIENT_CACHE_SIZE = Integer.MAX_VALUE;
+
+    private static final String DEFAULT_ADMINHANDLERCLASS = "org.apache.solr.handler.admin.CoreAdminHandler";
+    private static final String DEFAULT_INFOHANDLERCLASS = "org.apache.solr.handler.admin.InfoHandler";
+    private static final String DEFAULT_COLLECTIONSHANDLERCLASS = "org.apache.solr.handler.admin.CollectionsHandler";
+
+    public NodeConfigBuilder(String nodeName, SolrResourceLoader loader) {
+      this.nodeName = nodeName;
+      this.loader = loader;
+      this.coreRootDirectory = loader.getInstanceDir();
+    }
+
+    public NodeConfigBuilder setCoreRootDirectory(String coreRootDirectory) {
+      this.coreRootDirectory = loader.resolve(coreRootDirectory);
+      return this;
+    }
+
+    public NodeConfigBuilder setConfigSetBaseDirectory(String configSetBaseDirectory) {
+      this.configSetBaseDirectory = configSetBaseDirectory;
+      return this;
+    }
+
+    public NodeConfigBuilder setSharedLibDirectory(String sharedLibDirectory) {
+      this.sharedLibDirectory = sharedLibDirectory;
+      return this;
+    }
+
+    public NodeConfigBuilder setShardHandlerFactoryConfig(PluginInfo shardHandlerFactoryConfig) {
+      this.shardHandlerFactoryConfig = shardHandlerFactoryConfig;
+      return this;
+    }
+
+    public NodeConfigBuilder setUpdateShardHandlerConfig(UpdateShardHandlerConfig updateShardHandlerConfig) {
+      this.updateShardHandlerConfig = updateShardHandlerConfig;
+      return this;
+    }
+
+    public NodeConfigBuilder setCoreAdminHandlerClass(String coreAdminHandlerClass) {
+      this.coreAdminHandlerClass = coreAdminHandlerClass;
+      return this;
+    }
+
+    public NodeConfigBuilder setCollectionsAdminHandlerClass(String collectionsAdminHandlerClass) {
+      this.collectionsAdminHandlerClass = collectionsAdminHandlerClass;
+      return this;
+    }
+
+    public NodeConfigBuilder setInfoHandlerClass(String infoHandlerClass) {
+      this.infoHandlerClass = infoHandlerClass;
+      return this;
+    }
+
+    public NodeConfigBuilder setLogWatcherConfig(LogWatcherConfig logWatcherConfig) {
+      this.logWatcherConfig = logWatcherConfig;
+      return this;
+    }
+
+    public NodeConfigBuilder setCloudConfig(CloudConfig cloudConfig) {
+      this.cloudConfig = cloudConfig;
+      return this;
+    }
+
+    public NodeConfigBuilder setCoreLoadThreads(int coreLoadThreads) {
+      this.coreLoadThreads = coreLoadThreads;
+      return this;
+    }
+
+    public NodeConfigBuilder setTransientCacheSize(int transientCacheSize) {
+      this.transientCacheSize = transientCacheSize;
+      return this;
+    }
+
+    public NodeConfigBuilder setUseSchemaCache(boolean useSchemaCache) {
+      this.useSchemaCache = useSchemaCache;
+      return this;
+    }
+
+    public NodeConfigBuilder setManagementPath(String managementPath) {
+      this.managementPath = managementPath;
+      return this;
+    }
+
+    public NodeConfigBuilder setSolrProperties(Properties solrProperties) {
+      this.solrProperties = solrProperties;
+      return this;
+    }
+
+    public NodeConfig build() {
+      return new NodeConfig(nodeName, coreRootDirectory, configSetBaseDirectory, sharedLibDirectory, shardHandlerFactoryConfig,
+                            updateShardHandlerConfig, coreAdminHandlerClass, collectionsAdminHandlerClass, infoHandlerClass,
+                            logWatcherConfig, cloudConfig, coreLoadThreads, transientCacheSize, useSchemaCache, managementPath, loader, solrProperties);
+    }
+  }
+}
+

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCores.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCores.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCores.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCores.java Wed Feb 25 14:45:51 2015
@@ -126,7 +126,7 @@ class SolrCores {
   }
 
   //WARNING! This should be the _only_ place you put anything into the list of transient cores!
-  protected SolrCore putTransientCore(ConfigSolr cfg, String name, SolrCore core, SolrResourceLoader loader) {
+  protected SolrCore putTransientCore(NodeConfig cfg, String name, SolrCore core, SolrResourceLoader loader) {
     SolrCore retCore;
     CoreContainer.log.info("Opening transient core {}", name);
     synchronized (modifyLock) {

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java?rev=1662232&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java Wed Feb 25 14:45:51 2015
@@ -0,0 +1,412 @@
+package org.apache.solr.core;
+
+/*
+ * 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.
+ */
+
+import com.google.common.base.Strings;
+import org.apache.commons.io.IOUtils;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.logging.LogWatcherConfig;
+import org.apache.solr.update.UpdateShardHandlerConfig;
+import org.apache.solr.util.DOMUtil;
+import org.apache.solr.util.PropertiesUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+
+/**
+ *
+ */
+public class SolrXmlConfig {
+
+  public final static String SOLR_XML_FILE = "solr.xml";
+
+  private static final Logger log = LoggerFactory.getLogger(SolrXmlConfig.class);
+
+  public static NodeConfig fromConfig(Config config) {
+
+    checkForIllegalConfig(config);
+
+    config.substituteProperties();
+
+    CloudConfig cloudConfig = null;
+    UpdateShardHandlerConfig deprecatedUpdateConfig = null;
+
+    if (config.getNodeList("solr/solrcloud", false).getLength() > 0) {
+      NamedList<Object> cloudSection = readNodeListAsNamedList(config, "solr/solrcloud/*[@name]", "<solrcloud>");
+      deprecatedUpdateConfig = loadUpdateConfig(cloudSection, false);
+      cloudConfig = fillSolrCloudSection(cloudSection);
+    }
+
+    NamedList<Object> entries = readNodeListAsNamedList(config, "solr/*[@name]", "<solr>");
+    String nodeName = (String) entries.remove("nodeName");
+    if (Strings.isNullOrEmpty(nodeName) && cloudConfig != null)
+      nodeName = cloudConfig.getHost();
+
+    UpdateShardHandlerConfig updateConfig;
+    if (deprecatedUpdateConfig == null) {
+      updateConfig = loadUpdateConfig(readNodeListAsNamedList(config, "solr/updateshardhandler/*[@name]", "<updateshardhandler>"), true);
+    }
+    else {
+      updateConfig = loadUpdateConfig(readNodeListAsNamedList(config, "solr/updateshardhandler/*[@name]", "<updateshardhandler>"), false);
+      if (updateConfig != null) {
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "UpdateShardHandler configuration defined twice in solr.xml");
+      }
+      updateConfig = deprecatedUpdateConfig;
+    }
+
+    NodeConfig.NodeConfigBuilder configBuilder = new NodeConfig.NodeConfigBuilder(nodeName, config.getResourceLoader());
+    configBuilder.setUpdateShardHandlerConfig(updateConfig);
+    configBuilder.setShardHandlerFactoryConfig(getShardHandlerFactoryPluginInfo(config));
+    configBuilder.setLogWatcherConfig(loadLogWatcherConfig(config, "solr/logging/*[@name]", "solr/logging/watcher/*[@name]"));
+    configBuilder.setSolrProperties(loadProperties(config));
+    if (cloudConfig != null)
+      configBuilder.setCloudConfig(cloudConfig);
+    return fillSolrSection(configBuilder, entries);
+  }
+
+  public static NodeConfig fromFile(SolrResourceLoader loader, File configFile) {
+
+    log.info("Loading container configuration from {}", configFile.getAbsolutePath());
+
+    if (!configFile.exists()) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+          "solr.xml does not exist in " + configFile.getAbsolutePath() + " cannot start Solr");
+    }
+
+    try (InputStream inputStream = new FileInputStream(configFile)) {
+      return fromInputStream(loader, inputStream);
+    } catch (SolrException exc) {
+      throw exc;
+    } catch (Exception exc) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+          "Could not load SOLR configuration", exc);
+    }
+  }
+
+  public static NodeConfig fromString(SolrResourceLoader loader, String xml) {
+    return fromInputStream(loader, new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
+  }
+
+  public static NodeConfig fromInputStream(SolrResourceLoader loader, InputStream is) {
+    try {
+      byte[] buf = IOUtils.toByteArray(is);
+      try (ByteArrayInputStream dup = new ByteArrayInputStream(buf)) {
+        Config config = new Config(loader, null, new InputSource(dup), null, false);
+        return fromConfig(config);
+      }
+    } catch (SolrException exc) {
+      throw exc;
+    } catch (Exception e) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
+    }
+  }
+
+  public static NodeConfig fromSolrHome(SolrResourceLoader loader, String solrHome) {
+    return fromFile(loader, new File(solrHome, SOLR_XML_FILE));
+  }
+
+  private static void checkForIllegalConfig(Config config) {
+    failIfFound(config, "solr/@coreLoadThreads");
+    failIfFound(config, "solr/@persistent");
+    failIfFound(config, "solr/@sharedLib");
+    failIfFound(config, "solr/@zkHost");
+    failIfFound(config, "solr/cores");
+
+    assertSingleInstance("solrcloud", config);
+    assertSingleInstance("logging", config);
+    assertSingleInstance("logging/watcher", config);
+  }
+
+  private static void assertSingleInstance(String section, Config config) {
+    if (config.getNodeList("/solr/" + section, false).getLength() > 1)
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Multiple instances of " + section + " section found in solr.xml");
+  }
+
+  private static void failIfFound(Config config, String xPath) {
+
+    if (config.getVal(xPath, false) != null) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Should not have found " + xPath +
+          "\n. Please upgrade your solr.xml: https://cwiki.apache.org/confluence/display/solr/Format+of+solr.xml");
+    }
+  }
+
+  private static Properties loadProperties(Config config) {
+    try {
+      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();
+      for (int i = 0; i < props.getLength(); i++) {
+        Node prop = props.item(i);
+        properties.setProperty(DOMUtil.getAttr(prop, "name"),
+            PropertiesUtil.substituteProperty(DOMUtil.getAttr(prop, "value"), null));
+      }
+      return properties;
+    }
+    catch (XPathExpressionException e) {
+      log.warn("Error parsing solr.xml: " + e.getMessage());
+      return null;
+    }
+  }
+
+  private static NamedList<Object> readNodeListAsNamedList(Config config, String path, String section) {
+    NodeList nodes = config.getNodeList(path, false);
+    if (nodes == null) {
+      return null;
+    }
+    return checkForDuplicates(section, DOMUtil.nodesToNamedList(nodes));
+  }
+
+  private static NamedList<Object> checkForDuplicates(String section, NamedList<Object> nl) {
+    Set<String> keys = new HashSet<>();
+    for (Map.Entry<String, Object> entry : nl) {
+      if (!keys.add(entry.getKey()))
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+            section + " section of solr.xml contains duplicated '" + entry.getKey() + "'");
+    }
+    return nl;
+  }
+
+  private static int parseInt(String field, String value) {
+    try {
+      return Integer.parseInt(value);
+    }
+    catch (NumberFormatException e) {
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+          "Error parsing '" + field + "', value '" + value + "' cannot be parsed as int");
+    }
+  }
+
+  private static NodeConfig fillSolrSection(NodeConfig.NodeConfigBuilder builder, NamedList<Object> nl) {
+
+    for (Map.Entry<String, Object> entry : nl) {
+      String name = entry.getKey();
+      if (entry.getValue() == null)
+        continue;
+      String value = entry.getValue().toString();
+      switch (name) {
+        case "adminHandler":
+          builder.setCoreAdminHandlerClass(value);
+          break;
+        case "collectionsHandler":
+          builder.setCollectionsAdminHandlerClass(value);
+          break;
+        case "infoHandler":
+          builder.setInfoHandlerClass(value);
+          break;
+        case "coreRootDirectory":
+          builder.setCoreRootDirectory(value);
+          break;
+        case "managementPath":
+          builder.setManagementPath(value);
+          break;
+        case "sharedLib":
+          builder.setSharedLibDirectory(value);
+          break;
+        case "configSetBaseDir":
+          builder.setConfigSetBaseDirectory(value);
+          break;
+        case "shareSchema":
+          builder.setUseSchemaCache(Boolean.parseBoolean(value));
+          break;
+        case "coreLoadThreads":
+          builder.setCoreLoadThreads(parseInt(name, value));
+          break;
+        case "transientCacheSize":
+          builder.setTransientCacheSize(parseInt(name, value));
+          break;
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown configuration value in solr.xml: " + name);
+      }
+    }
+
+    return builder.build();
+  }
+
+  private static UpdateShardHandlerConfig loadUpdateConfig(NamedList<Object> nl, boolean alwaysDefine) {
+
+    if (nl == null && !alwaysDefine)
+      return null;
+
+    if (nl == null)
+      return UpdateShardHandlerConfig.DEFAULT;
+
+    boolean defined = false;
+
+    int maxUpdateConnections = UpdateShardHandlerConfig.DEFAULT_MAXUPDATECONNECTIONS;
+    int maxUpdateConnectionsPerHost = UpdateShardHandlerConfig.DEFAULT_MAXUPDATECONNECTIONSPERHOST;
+    int distributedSocketTimeout = UpdateShardHandlerConfig.DEFAULT_DISTRIBUPDATESOTIMEOUT;
+    int distributedConnectionTimeout = UpdateShardHandlerConfig.DEFAULT_DISTRIBUPDATECONNTIMEOUT;
+
+    Object muc = nl.remove("maxUpdateConnections");
+    if (muc != null) {
+      maxUpdateConnections = parseInt("maxUpdateConnections", muc.toString());
+      defined = true;
+    }
+
+    Object mucph = nl.remove("maxUpdateConnectionsPerHost");
+    if (mucph != null) {
+      maxUpdateConnectionsPerHost = parseInt("maxUpdateConnectionsPerHost", mucph.toString());
+      defined = true;
+    }
+
+    Object dst = nl.remove("distribUpdateSoTimeout");
+    if (dst != null) {
+      distributedSocketTimeout = parseInt("distribUpdateSoTimeout", dst.toString());
+      defined = true;
+    }
+
+    Object dct = nl.remove("distribUpdateConnTimeout");
+    if (dct != null) {
+      distributedConnectionTimeout = parseInt("distribUpdateConnTimeout", dct.toString());
+      defined = true;
+    }
+
+    if (!defined && !alwaysDefine)
+      return null;
+
+    return new UpdateShardHandlerConfig(maxUpdateConnections, maxUpdateConnectionsPerHost, distributedSocketTimeout, distributedConnectionTimeout);
+
+  }
+
+  private static String removeValue(NamedList<Object> nl, String key) {
+    Object value = nl.remove(key);
+    if (value == null)
+      return null;
+    return value.toString();
+  }
+
+  private static String required(String section, String key, String value) {
+    if (value != null)
+      return value;
+    throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, section + " section missing required entry '" + key + "'");
+  }
+
+  private static CloudConfig fillSolrCloudSection(NamedList<Object> nl) {
+
+    String hostName = required("solrcloud", "host", removeValue(nl, "host"));
+    int hostPort = parseInt("hostPort", required("solrcloud", "hostPort", removeValue(nl, "hostPort")));
+    String hostContext = required("solrcloud", "hostContext", removeValue(nl, "hostContext"));
+
+    CloudConfig.CloudConfigBuilder builder = new CloudConfig.CloudConfigBuilder(hostName, hostPort, hostContext);
+
+    for (Map.Entry<String, Object> entry : nl) {
+      String name = entry.getKey();
+      if (entry.getValue() == null)
+        continue;
+      String value = entry.getValue().toString();
+      switch (name) {
+        case "leaderVoteWait":
+          builder.setLeaderVoteWait(parseInt(name, value));
+          break;
+        case "leaderConflictResolveWait":
+          builder.setLeaderConflictResolveWait(parseInt(name, value));
+          break;
+        case "zkClientTimeout":
+          builder.setZkClientTimeout(parseInt(name, value));
+          break;
+        case "autoReplicaFailoverBadNodeExpiration":
+          builder.setAutoReplicaFailoverBadNodeExpiration(parseInt(name, value));
+          break;
+        case "autoReplicaFailoverWaitAfterExpiration":
+          builder.setAutoReplicaFailoverWaitAfterExpiration(parseInt(name, value));
+          break;
+        case "autoReplicaFailoverWorkLoopDelay":
+          builder.setAutoReplicaFailoverWorkLoopDelay(parseInt(name, value));
+          break;
+        case "zkHost":
+          builder.setZkHost(value);
+          break;
+        case "genericCoreNodeNames":
+          builder.setUseGenericCoreNames(Boolean.parseBoolean(value));
+          break;
+        case "zkACLProvider":
+          builder.setZkACLProviderClass(value);
+          break;
+        case "zkCredientialsProvider":
+          builder.setZkCredentialsProviderClass(value);
+          break;
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown configuration parameter in <solrcloud> section of solr.xml: " + name);
+      }
+    }
+
+    return builder.build();
+  }
+
+  private static LogWatcherConfig loadLogWatcherConfig(Config config, String loggingPath, String watcherPath) {
+
+    String loggingClass = null;
+    boolean enabled = true;
+    int watcherQueueSize = 50;
+    String watcherThreshold = null;
+
+    for (Map.Entry<String, Object> entry : readNodeListAsNamedList(config, loggingPath, "<logging>")) {
+      String name = entry.getKey();
+      String value = entry.getValue().toString();
+      switch (name) {
+        case "class":
+          loggingClass = value; break;
+        case "enabled":
+          enabled = Boolean.parseBoolean(value); break;
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown value in logwatcher config: " + name);
+      }
+    }
+
+    for (Map.Entry<String, Object> entry : readNodeListAsNamedList(config, watcherPath, "<watcher>")) {
+      String name = entry.getKey();
+      String value = entry.getValue().toString();
+      switch (name) {
+        case "size":
+          watcherQueueSize = parseInt(name, value); break;
+        case "threshold":
+          watcherThreshold = value; break;
+        default:
+          throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Unknown value in logwatcher config: " + name);
+      }
+    }
+
+    return new LogWatcherConfig(enabled, loggingClass, watcherThreshold, watcherQueueSize);
+
+  }
+
+  private static PluginInfo getShardHandlerFactoryPluginInfo(Config config) {
+    Node node = config.getNode("solr/shardHandlerFactory", false);
+    return (node == null) ? null : new PluginInfo(node, "shardHandlerFactory", false, true);
+  }
+
+}
+

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ZkContainer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ZkContainer.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ZkContainer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/ZkContainer.java Wed Feb 25 14:45:51 2015
@@ -57,44 +57,19 @@ public class ZkContainer {
     
   }
 
-  public void initZooKeeper(final CoreContainer cc, String solrHome, ConfigSolr config) {
-
-    if (config.getCoreLoadThreadCount() <= 1) {
-      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
-          "SolrCloud requires a value of at least 2 in solr.xml for coreLoadThreads");
-    }
-
-    initZooKeeper(cc, solrHome,
-        config.getZkHost(), config.getZkClientTimeout(), config.getSolrHostPort(), config.getZkHostContext(),
-        config.getHost(), config.getLeaderVoteWait(), config.getLeaderConflictResolveWait(), config.getGenericCoreNodeNames());
-  }
-    
-  public void initZooKeeper(final CoreContainer cc, String solrHome, String zkHost, int zkClientTimeout, String solrHostPort,
-        String hostContext, String host, int leaderVoteWait, int leaderConflictResolveWait, boolean genericCoreNodeNames) {
+  public void initZooKeeper(final CoreContainer cc, String solrHome, CloudConfig config) {
 
     ZkController zkController = null;
-    
-    // if zkHost sys property is not set, we are not using ZooKeeper
-    String zookeeperHost;
-    if(zkHost == null) {
-      zookeeperHost = System.getProperty("zkHost");
-    } else {
-      zookeeperHost = zkHost;
-    }
 
     String zkRun = System.getProperty("zkRun");
+
+    if (zkRun != null && config == null)
+      throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Cannot start Solr in cloud mode - no cloud config provided");
     
-    if (zkRun == null && zookeeperHost == null)
+    if (config == null)
         return;  // not in zk mode
 
-    if (null == solrHostPort) {
-      throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-                   "'hostPort' must be configured to run SolrCloud");
-    }
-    if (null == hostContext) {
-      throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
-                   "'hostContext' must be configured to run SolrCloud");
-    }
+    String zookeeperHost = config.getZkHost();
 
     // zookeeper in quorum mode currently causes a failure when trying to
     // register log4j mbeans.  See SOLR-2369
@@ -104,7 +79,7 @@ public class ZkContainer {
     if (zkRun != null) {
       String zkDataHome = System.getProperty("zkServerDataDir", solrHome + "zoo_data");
       String zkConfHome = System.getProperty("zkServerConfDir", solrHome);
-      zkServer = new SolrZkServer(stripChroot(zkRun), stripChroot(zookeeperHost), zkDataHome, zkConfHome, solrHostPort);
+      zkServer = new SolrZkServer(stripChroot(zkRun), stripChroot(config.getZkHost()), zkDataHome, zkConfHome, config.getSolrHostPort());
       zkServer.parseConfig();
       zkServer.start();
       
@@ -134,9 +109,7 @@ public class ZkContainer {
           throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
               "A chroot was specified in ZkHost but the znode doesn't exist. " + zookeeperHost);
         }
-        zkController = new ZkController(cc, zookeeperHost, zkClientTimeout,
-            zkClientConnectTimeout, host, solrHostPort, hostContext,
-            leaderVoteWait, leaderConflictResolveWait, genericCoreNodeNames,
+        zkController = new ZkController(cc, zookeeperHost, zkClientConnectTimeout, config,
             new CurrentCoreDescriptorProvider() {
 
               @Override

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java Wed Feb 25 14:45:51 2015
@@ -29,8 +29,8 @@ import org.apache.solr.common.util.Execu
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.common.util.URLUtil;
-import org.apache.solr.core.ConfigSolr;
 import org.apache.solr.core.PluginInfo;
+import org.apache.solr.update.UpdateShardHandlerConfig;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -69,8 +69,8 @@ public class HttpShardHandlerFactory ext
   protected HttpClient defaultClient;
   private LBHttpSolrClient loadbalancer;
   //default values:
-  int soTimeout = ConfigSolr.DEFAULT_DISTRIBUPDATESOTIMEOUT;
-  int connectionTimeout = ConfigSolr.DEFAULT_DISTRIBUPDATECONNTIMEOUT;
+  int soTimeout = UpdateShardHandlerConfig.DEFAULT_DISTRIBUPDATESOTIMEOUT;
+  int connectionTimeout = UpdateShardHandlerConfig.DEFAULT_DISTRIBUPDATECONNTIMEOUT;
   int maxConnectionsPerHost = 20;
   int maxConnections = 10000;
   int corePoolSize = 0;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java Wed Feb 25 14:45:51 2015
@@ -17,30 +17,6 @@
 
 package org.apache.solr.servlet;
 
-import java.io.ByteArrayInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.http.Header;
@@ -77,11 +53,12 @@ import org.apache.solr.common.params.Sol
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.common.util.SimpleOrderedMap;
 import org.apache.solr.common.util.StrUtils;
-import org.apache.solr.core.ConfigSolr;
 import org.apache.solr.core.CoreContainer;
+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.ContentStreamHandlerBase;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrQueryRequestBase;
@@ -96,6 +73,29 @@ import org.apache.solr.update.processor.
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+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.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
 /**
  * This filter looks at the incoming URL maps them to handlers defined in solrconfig.xml
  *
@@ -141,12 +141,12 @@ public class SolrDispatchFilter extends
     log.info("SolrDispatchFilter.init() done");
   }
 
-  private ConfigSolr loadConfigSolr(SolrResourceLoader loader) {
+  private NodeConfig loadConfigSolr(SolrResourceLoader loader) {
 
     String solrxmlLocation = System.getProperty("solr.solrxml.location", "solrhome");
 
     if (solrxmlLocation == null || "solrhome".equalsIgnoreCase(solrxmlLocation))
-      return ConfigSolr.fromSolrHome(loader, loader.getInstanceDir());
+      return SolrXmlConfig.fromSolrHome(loader, loader.getInstanceDir());
 
     if ("zookeeper".equalsIgnoreCase(solrxmlLocation)) {
       String zkHost = System.getProperty("zkHost");
@@ -159,7 +159,7 @@ public class SolrDispatchFilter extends
         if (!zkClient.exists("/solr.xml", true))
           throw new SolrException(ErrorCode.SERVER_ERROR, "Could not load solr.xml from zookeeper: node not found");
         byte[] data = zkClient.getData("/solr.xml", null, null, true);
-        return ConfigSolr.fromInputStream(loader, new ByteArrayInputStream(data));
+        return SolrXmlConfig.fromInputStream(loader, new ByteArrayInputStream(data));
       } catch (Exception e) {
         throw new SolrException(ErrorCode.SERVER_ERROR, "Could not load solr.xml from zookeeper", e);
       } finally {
@@ -177,7 +177,7 @@ public class SolrDispatchFilter extends
    */
   protected CoreContainer createCoreContainer() {
     SolrResourceLoader loader = new SolrResourceLoader(SolrResourceLoader.locateSolrHome());
-    ConfigSolr config = loadConfigSolr(loader);
+    NodeConfig config = loadConfigSolr(loader);
     CoreContainer cores = new CoreContainer(config);
     cores.load();
     return cores;

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandler.java Wed Feb 25 14:45:51 2015
@@ -17,9 +17,6 @@ package org.apache.solr.update;
  * limitations under the License.
  */
 
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
 import org.apache.http.client.HttpClient;
 import org.apache.http.conn.ClientConnectionManager;
 import org.apache.http.impl.client.CloseableHttpClient;
@@ -31,10 +28,13 @@ import org.apache.solr.common.params.Mod
 import org.apache.solr.common.util.ExecutorUtil;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.SolrjNamedThreadFactory;
-import org.apache.solr.core.ConfigSolr;
+import org.apache.solr.core.NodeConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
 public class UpdateShardHandler {
   
   private static Logger log = LoggerFactory.getLogger(UpdateShardHandler.class);
@@ -46,7 +46,12 @@ public class UpdateShardHandler {
   
   private final CloseableHttpClient client;
 
-  public UpdateShardHandler(ConfigSolr cfg) {
+  @Deprecated
+  public UpdateShardHandler(NodeConfig cfg) {
+    this(cfg.getUpdateShardHandlerConfig());
+  }
+
+  public UpdateShardHandler(UpdateShardHandlerConfig cfg) {
     
     clientConnectionManager = new PoolingClientConnectionManager(SchemeRegistryFactory.createSystemDefault());
     if (cfg != null ) {

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandlerConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandlerConfig.java?rev=1662232&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandlerConfig.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateShardHandlerConfig.java Wed Feb 25 14:45:51 2015
@@ -0,0 +1,61 @@
+package org.apache.solr.update;
+
+/*
+ * 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.
+ */
+
+public class UpdateShardHandlerConfig {
+
+  public static final int DEFAULT_DISTRIBUPDATECONNTIMEOUT = 60000;
+  public static final int DEFAULT_DISTRIBUPDATESOTIMEOUT = 600000;
+  public static final int DEFAULT_MAXUPDATECONNECTIONS = 10000;
+  public static final int DEFAULT_MAXUPDATECONNECTIONSPERHOST = 100;
+
+  public static final UpdateShardHandlerConfig DEFAULT
+      = new UpdateShardHandlerConfig(DEFAULT_MAXUPDATECONNECTIONS, DEFAULT_MAXUPDATECONNECTIONSPERHOST,
+                                     DEFAULT_DISTRIBUPDATESOTIMEOUT, DEFAULT_DISTRIBUPDATECONNTIMEOUT);
+
+  private final int maxUpdateConnections;
+
+  private final int maxUpdateConnectionsPerHost;
+
+  private final int distributedSocketTimeout;
+
+  private final int distributedConnectionTimeout;
+
+  public UpdateShardHandlerConfig(int maxUpdateConnections, int maxUpdateConnectionsPerHost, int distributedSocketTimeout, int distributedConnectionTimeout) {
+    this.maxUpdateConnections = maxUpdateConnections;
+    this.maxUpdateConnectionsPerHost = maxUpdateConnectionsPerHost;
+    this.distributedSocketTimeout = distributedSocketTimeout;
+    this.distributedConnectionTimeout = distributedConnectionTimeout;
+  }
+
+  public int getMaxUpdateConnectionsPerHost() {
+    return maxUpdateConnectionsPerHost;
+  }
+
+  public int getMaxUpdateConnections() {
+    return maxUpdateConnections;
+  }
+
+  public int getDistributedSocketTimeout() {
+    return distributedSocketTimeout;
+  }
+
+  public int getDistributedConnectionTimeout() {
+    return distributedConnectionTimeout;
+  }
+}

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyShardSplitTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyShardSplitTest.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyShardSplitTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyShardSplitTest.java Wed Feb 25 14:45:51 2015
@@ -27,9 +27,10 @@ import org.apache.solr.common.cloud.Repl
 import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.core.CloudConfig;
 import org.apache.solr.handler.component.HttpShardHandlerFactory;
 import org.apache.solr.update.UpdateShardHandler;
-import org.apache.solr.util.MockConfigSolr;
+import org.apache.solr.update.UpdateShardHandlerConfig;
 import org.apache.zookeeper.KeeperException;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -242,10 +243,10 @@ public class ChaosMonkeyShardSplitTest e
     SolrZkClient zkClient = new SolrZkClient(address, TIMEOUT);
     ZkStateReader reader = new ZkStateReader(zkClient);
     LeaderElector overseerElector = new LeaderElector(zkClient);
-    UpdateShardHandler updateShardHandler = new UpdateShardHandler(null);
+    UpdateShardHandler updateShardHandler = new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT);
     // TODO: close Overseer
-    Overseer overseer = new Overseer(
-        new HttpShardHandlerFactory().getShardHandler(), updateShardHandler, "/admin/cores", reader, null, new MockConfigSolr());
+    Overseer overseer = new Overseer(new HttpShardHandlerFactory().getShardHandler(), updateShardHandler, "/admin/cores",
+        reader, null, new CloudConfig.CloudConfigBuilder("127.0.0.1", 8983, "solr").build());
     overseer.close();
     ElectionContext ec = new OverseerElectionContext(zkClient, overseer,
         address.replaceAll("/", "_"));

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java Wed Feb 25 14:45:51 2015
@@ -17,23 +17,6 @@ package org.apache.solr.cloud;
  * limitations under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-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.Set;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.xml.parsers.ParserConfigurationException;
-
 import org.apache.lucene.util.LuceneTestCase.Slow;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.cloud.overseer.OverseerAction;
@@ -45,10 +28,11 @@ import org.apache.solr.common.cloud.Solr
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.params.CollectionParams;
+import org.apache.solr.core.CloudConfig;
 import org.apache.solr.handler.component.HttpShardHandlerFactory;
 import org.apache.solr.update.UpdateShardHandler;
+import org.apache.solr.update.UpdateShardHandlerConfig;
 import org.apache.solr.util.DefaultSolrThreadFactory;
-import org.apache.solr.util.MockConfigSolr;
 import org.apache.solr.util.stats.Snapshot;
 import org.apache.solr.util.stats.Timer;
 import org.apache.solr.util.stats.TimerContext;
@@ -63,6 +47,22 @@ import org.junit.Ignore;
 import org.junit.Test;
 import org.xml.sax.SAXException;
 
+import javax.xml.parsers.ParserConfigurationException;
+import java.io.File;
+import java.io.IOException;
+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.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+
 @Slow
 public class OverseerTest extends SolrTestCaseJ4 {
 
@@ -1129,12 +1129,12 @@ public class OverseerTest extends SolrTe
       overseers.get(overseers.size() -1).close();
       overseers.get(overseers.size() -1).getZkStateReader().getZkClient().close();
     }
-    UpdateShardHandler updateShardHandler = new UpdateShardHandler(null);
+    UpdateShardHandler updateShardHandler = new UpdateShardHandler(UpdateShardHandlerConfig.DEFAULT);
     updateShardHandlers.add(updateShardHandler);
     HttpShardHandlerFactory httpShardHandlerFactory = new HttpShardHandlerFactory();
     httpShardHandlerFactorys.add(httpShardHandlerFactory);
-    Overseer overseer = new Overseer(
-        httpShardHandlerFactory.getShardHandler(), updateShardHandler, "/admin/cores", reader, null, new MockConfigSolr());
+    Overseer overseer = new Overseer(httpShardHandlerFactory.getShardHandler(), updateShardHandler, "/admin/cores", reader, null,
+        new CloudConfig.CloudConfigBuilder("127.0.0.1", 8983, "").build());
     overseers.add(overseer);
     ElectionContext ec = new OverseerElectionContext(zkClient, overseer,
         address.replaceAll("/", "_"));

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/SolrXmlInZkTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/SolrXmlInZkTest.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/SolrXmlInZkTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/SolrXmlInZkTest.java Wed Feb 25 14:45:51 2015
@@ -16,17 +16,13 @@ package org.apache.solr.cloud;
  * the License.
  */
 
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.charset.StandardCharsets;
-
+import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
 import org.apache.commons.io.FileUtils;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkStateReader;
-import org.apache.solr.core.ConfigSolr;
+import org.apache.solr.core.NodeConfig;
 import org.apache.solr.core.SolrResourceLoader;
 import org.apache.solr.servlet.SolrDispatchFilter;
 import org.junit.After;
@@ -36,7 +32,10 @@ import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TestRule;
 
-import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.charset.StandardCharsets;
 
 public class SolrXmlInZkTest extends SolrTestCaseJ4 {
 
@@ -51,7 +50,7 @@ public class SolrXmlInZkTest extends Sol
 
   private ZkStateReader reader;
 
-  private ConfigSolr cfg;
+  private NodeConfig cfg;
 
   private SolrDispatchFilter solrDispatchFilter;
 
@@ -109,7 +108,7 @@ public class SolrXmlInZkTest extends Sol
     if (solrDispatchFilter != null) solrDispatchFilter.destroy();
     solrDispatchFilter = new SolrDispatchFilter();
     Object obj = method.invoke(solrDispatchFilter, new SolrResourceLoader(null));
-    cfg = (ConfigSolr) obj;
+    cfg = (NodeConfig) obj;
 
     log.info("####SETUP_END " + getTestName());
   }
@@ -130,7 +129,7 @@ public class SolrXmlInZkTest extends Sol
     try {
       setUpZkAndDiskXml(true, true);
       assertEquals("Should have gotten a new port the xml file sent to ZK, overrides the copy on disk",
-          cfg.getSolrHostPort(), "9045");
+          cfg.getCloudConfig().getSolrHostPort(), 9045);
     } finally {
       closeZK();
     }
@@ -141,7 +140,7 @@ public class SolrXmlInZkTest extends Sol
     try {
       setUpZkAndDiskXml(true, false);
       assertEquals("Should have gotten a new port the xml file sent to ZK",
-          cfg.getSolrHostPort(), "9045");
+          cfg.getCloudConfig().getSolrHostPort(), 9045);
     } finally {
       closeZK();
     }
@@ -180,7 +179,7 @@ public class SolrXmlInZkTest extends Sol
     try {
       System.clearProperty("solr.solrxml.location");
       setUpZkAndDiskXml(false, true);
-      assertEquals("Should have gotten the default port", cfg.getSolrHostPort(), "8983");
+      assertEquals("Should have gotten the default port", cfg.getCloudConfig().getSolrHostPort(), 8983);
     } finally {
       closeZK();
     }

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestLeaderElectionZkExpiry.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestLeaderElectionZkExpiry.java?rev=1662232&r1=1662231&r2=1662232&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestLeaderElectionZkExpiry.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestLeaderElectionZkExpiry.java Wed Feb 25 14:45:51 2015
@@ -19,6 +19,7 @@ package org.apache.solr.cloud;
 
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.core.CloudConfig;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.CoreDescriptor;
 import org.apache.zookeeper.KeeperException;
@@ -46,7 +47,11 @@ public class TestLeaderElectionZkExpiry
       AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
       AbstractZkTestCase.makeSolrZkNode(server.getZkHost());
 
-      final ZkController zkController = new ZkController(cc, server.getZkAddress(), 15000, 30000, "dummy.host.com", "8984", "/solr", 180000, 180000, true, new CurrentCoreDescriptorProvider() {
+      CloudConfig cloudConfig = new CloudConfig.CloudConfigBuilder("dummy.host.com", 8984, "solr")
+          .setLeaderConflictResolveWait(180000)
+          .setLeaderVoteWait(180000)
+          .build();
+      final ZkController zkController = new ZkController(cc, server.getZkAddress(), 15000, cloudConfig, new CurrentCoreDescriptorProvider() {
         @Override
         public List<CoreDescriptor> getCurrentDescriptors() {
           return Collections.EMPTY_LIST;