You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ma...@apache.org on 2012/01/25 20:49:30 UTC

svn commit: r1235888 [1/12] - in /lucene/dev/trunk: dev-tools/eclipse/ dev-tools/maven/ solr/ solr/cloud-dev/ solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/ solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/da...

Author: markrmiller
Date: Wed Jan 25 19:49:26 2012
New Revision: 1235888

URL: http://svn.apache.org/viewvc?rev=1235888&view=rev
Log:
SOLR-2358: merge in solrcloud branch (watch out hudson!)

Added:
    lucene/dev/trunk/solr/cloud-dev/
    lucene/dev/trunk/solr/cloud-dev/example1.sh
    lucene/dev/trunk/solr/cloud-dev/example2.sh
    lucene/dev/trunk/solr/cloud-dev/example3.sh
    lucene/dev/trunk/solr/cloud-dev/solrcloud.sh
    lucene/dev/trunk/solr/cloud-dev/stop.sh
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/AssignShard.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CurrentCoreDescriptorProvider.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/NodeStateWatcher.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/RecoveryStrategy.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ShardLeaderWatcher.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/SyncStrategy.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/FunctionRangeQuery.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/PeerSync.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/SolrCmdDistributor.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/TransactionLog.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/VersionBucket.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/VersionInfo.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessor.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/DistributedUpdateProcessorFactory.java   (with props)
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/util/DefaultSolrThreadFactory.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkey.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeyNothingIsSafeTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ChaosMonkeySafeLeaderTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CloudStateTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudDistribCmdsTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/FullSolrCloudTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderElectionIntegrationTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/LeaderElectionTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/RecoveryZkTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/TestHashPartitioner.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestRecovery.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/PeerSyncTest.java   (with props)
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/SolrCmdDistributorTest.java   (with props)
    lucene/dev/trunk/solr/lib/apache-solr-noggit-r1211150.jar   (with props)
    lucene/dev/trunk/solr/lib/zookeeper-3.3.4.jar   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/UpdateRequestExt.java   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CoreState.java   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/HashPartitioner.java   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCmdExecutor.java   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ZkCoreNodeProps.java   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ZkOperation.java   (with props)
    lucene/dev/trunk/solr/solrj/src/java/org/apache/zookeeper/
    lucene/dev/trunk/solr/solrj/src/java/org/apache/zookeeper/SolrZooKeeper.java   (with props)
Removed:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/FSUpdateLog.java
    lucene/dev/trunk/solr/lib/apache-solr-noggit-r1209632.jar
    lucene/dev/trunk/solr/lib/zookeeper-3.3.3.jar
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZooKeeper.java
Modified:
    lucene/dev/trunk/dev-tools/eclipse/dot.classpath
    lucene/dev/trunk/dev-tools/maven/pom.xml.template
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/build.xml
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SolrWriter.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestContentStreamDataSource.java
    lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java
    lucene/dev/trunk/solr/core/build.xml
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkSolrResourceLoader.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/Config.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/CoreDescriptor.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/RequestHandlers.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrCore.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/BinaryUpdateRequestHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/JsonLoader.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/ReplicationHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/SnapPuller.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/XMLLoader.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/XmlUpdateRequestHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/admin/ShowFileRequestHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandler.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/handler/component/QueryComponent.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/RealTimeGetComponent.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/SearchHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/request/SimpleFacets.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/FunctionRangeQParserPlugin.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.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/AddUpdateCommand.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/CommitUpdateCommand.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/DefaultSolrCoreState.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/DeleteUpdateCommand.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/DirectUpdateHandler2.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/MergeIndexesCommand.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/RollbackUpdateCommand.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/SolrCoreState.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateCommand.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateHandler.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/UpdateLog.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/LogUpdateProcessorFactory.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/update/processor/RunUpdateProcessorFactory.java
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/schema12.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/solrconfig-basic.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/solrconfig-nocache.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/solrconfig-tlog.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/conf/solrconfig.xml
    lucene/dev/trunk/solr/core/src/test-files/solr/solr.xml
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/BasicFunctionalityTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/TestSolrCoreProperties.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractDistributedZkTestCase.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/AbstractZkTestCase.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/BasicZkTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CloudStateUpdateTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkNodePropsTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkSolrClientTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkTestServer.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestConfig.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestLegacyMergeSchedulerPolicyConfig.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestPropInject.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/core/TestPropInjectDefaults.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/schema/TestBinaryField.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/search/TestRealTimeGet.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/update/SoftAutoCommitTest.java
    lucene/dev/trunk/solr/example/solr/conf/schema.xml
    lucene/dev/trunk/solr/example/solr/conf/solrconfig.xml
    lucene/dev/trunk/solr/example/solr/solr.xml
    lucene/dev/trunk/solr/lib/apache-solr-noggit-pom.xml.template
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrServer.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CommonsHttpSolrServer.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrServer.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/impl/StreamingUpdateSolrServer.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreAdminRequest.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/client/solrj/util/ClientUtils.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/SolrException.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/CloudState.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ConnectionManager.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/DefaultConnectionStrategy.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/Slice.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/SolrZkClient.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ZkClientConnectionStrategy.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ZkNodeProps.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/params/CoreAdminParams.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/util/FastInputStream.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/util/FastOutputStream.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/util/Hash.java
    lucene/dev/trunk/solr/solrj/src/java/org/apache/solr/common/util/StrUtils.java
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/TestLBHttpSolrServer.java
    lucene/dev/trunk/solr/solrj/src/test/org/apache/solr/client/solrj/embedded/MultiCoreExampleJettyTest.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
    lucene/dev/trunk/solr/test-framework/src/java/org/apache/solr/SolrJettyTestBase.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
    lucene/dev/trunk/solr/webapp/web/admin/zookeeper.jsp
    lucene/dev/trunk/solr/webapp/web/zookeeper.jsp

Modified: lucene/dev/trunk/dev-tools/eclipse/dot.classpath
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/dev-tools/eclipse/dot.classpath?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/dev-tools/eclipse/dot.classpath (original)
+++ lucene/dev/trunk/dev-tools/eclipse/dot.classpath Wed Jan 25 19:49:26 2012
@@ -100,7 +100,7 @@
 	<classpathentry kind="lib" path="modules/benchmark/lib/commons-digester-1.7.jar"/>
 	<classpathentry kind="lib" path="modules/benchmark/lib/commons-logging-1.0.4.jar"/>
 	<classpathentry kind="lib" path="modules/benchmark/lib/xercesImpl-2.9.1-patched-XERCESJ-1257.jar"/>
-	<classpathentry kind="lib" path="solr/lib/apache-solr-noggit-r1209632.jar"/>
+	<classpathentry kind="lib" path="solr/lib/apache-solr-noggit-r1211150.jar"/>
 	<classpathentry kind="lib" path="solr/lib/commons-csv-1.0-SNAPSHOT-r966014.jar"/>
 	<classpathentry kind="lib" path="solr/lib/commons-fileupload-1.2.1.jar"/>
 	<classpathentry kind="lib" path="solr/lib/commons-httpclient-3.1.jar"/>
@@ -115,7 +115,7 @@
 	<classpathentry kind="lib" path="solr/lib/slf4j-api-1.6.1.jar"/>
 	<classpathentry kind="lib" path="solr/lib/slf4j-jdk14-1.6.1.jar"/>
 	<classpathentry kind="lib" path="solr/lib/wstx-asl-3.2.7.jar"/>
-	<classpathentry kind="lib" path="solr/lib/zookeeper-3.3.3.jar"/>
+	<classpathentry kind="lib" path="solr/lib/zookeeper-3.3.4.jar"/>
 	<classpathentry kind="lib" path="solr/example/lib/jetty-6.1.26-patched-JETTY-1340.jar"/>
 	<classpathentry kind="lib" path="solr/example/lib/jetty-util-6.1.26-patched-JETTY-1340.jar"/>
 	<classpathentry kind="lib" path="solr/example/lib/servlet-api-2.5-20081211.jar"/>

Modified: lucene/dev/trunk/dev-tools/maven/pom.xml.template
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/dev-tools/maven/pom.xml.template?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/dev-tools/maven/pom.xml.template (original)
+++ lucene/dev/trunk/dev-tools/maven/pom.xml.template Wed Jan 25 19:49:26 2012
@@ -283,7 +283,7 @@
       <dependency>
         <groupId>org.apache.zookeeper</groupId>
         <artifactId>zookeeper</artifactId>
-        <version>3.3.3</version>
+        <version>3.3.4</version>
       </dependency>
       <dependency>
         <groupId>org.carrot2</groupId>
@@ -670,7 +670,7 @@
                   <artifactId>solr-noggit</artifactId>
                   <version>${project.version}</version>
                   <packaging>jar</packaging>
-                  <file>solr/lib/apache-solr-noggit-r1209632.jar</file>
+                  <file>solr/lib/apache-solr-noggit-r1211150.jar</file>
                 </configuration>  
               </execution>
               <execution>

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Wed Jan 25 19:49:26 2012
@@ -28,7 +28,7 @@ Apache Tika 1.0
 Carrot2 3.5.0
 Velocity 1.6.4 and Velocity Tools 2.0
 Apache UIMA 2.3.1
-Apache ZooKeeper 3.3.3
+Apache ZooKeeper 3.3.4
 
 
 Upgrading from Solr 3.6-dev

Modified: lucene/dev/trunk/solr/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/build.xml?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/build.xml (original)
+++ lucene/dev/trunk/solr/build.xml Wed Jan 25 19:49:26 2012
@@ -482,7 +482,7 @@
           <packageset dir="contrib/langid/src/java"/>
           <packageset dir="contrib/uima/src/java"/>
           <group title="Core" packages="org.apache.*" />
-          <group title="SolrJ" packages="org.apache.solr.common.*,org.apache.solr.client.solrj*" />
+          <group title="SolrJ" packages="org.apache.solr.common.*,org.apache.solr.client.solrj.*,org.apache.zookeeper.*" />
           <group title="contrib: Clustering" packages="org.apache.solr.handler.clustering*" />
           <group title="contrib: DataImportHandler" packages="org.apache.solr.handler.dataimport*" />
           <group title="contrib: Solr Cell" packages="org.apache.solr.handler.extraction*" />

Added: lucene/dev/trunk/solr/cloud-dev/example1.sh
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/cloud-dev/example1.sh?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/cloud-dev/example1.sh (added)
+++ lucene/dev/trunk/solr/cloud-dev/example1.sh Wed Jan 25 19:49:26 2012
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+cd ..
+
+rm -r -f example2
+
+rm -r -f dist
+rm -r -f build
+rm -r -f example/solr/zoo_data
+rm -f example/example.log
+
+ant example dist
+
+cp -r -f example example2
+
+
+cd example
+java -DzkRun -DnumShards=2 -DSTOP.PORT=7983 -DSTOP.KEY=key -Dbootstrap_confdir=solr/conf -jar start.jar 1>example.log 2>&1 &
+
+sleep 10
+
+cd ../example2
+java -Djetty.port=9574 -DzkRun -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6574 -DSTOP.KEY=key -jar start.jar 1>example2.log 2>&1 &
+
+

Added: lucene/dev/trunk/solr/cloud-dev/example2.sh
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/cloud-dev/example2.sh?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/cloud-dev/example2.sh (added)
+++ lucene/dev/trunk/solr/cloud-dev/example2.sh Wed Jan 25 19:49:26 2012
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+cd ..
+
+rm -r -f example2
+rm -r -f example3
+rm -r -f example4
+
+rm -r -f dist
+rm -r -f build
+rm -r -f example/solr/zoo_data
+rm -f example/example.log
+
+ant example dist
+
+cp -r -f example example2
+cp -r -f example example3
+cp -r -f example example4
+
+
+cd example
+java -DzkRun -DnumShards=2 -DSTOP.PORT=7983 -DSTOP.KEY=key -Dbootstrap_confdir=solr/conf -jar start.jar 1>example.log 2>&1 &
+
+sleep 10
+
+cd ../example2
+java -Djetty.port=9574 -DzkRun -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6574 -DSTOP.KEY=key -jar start.jar 1>example2.log 2>&1 &
+
+cd ../example3
+java -Djetty.port=9575 -DzkRun -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6575 -DSTOP.KEY=key -jar start.jar 1>example3.log 2>&1 &
+
+cd ../example4
+java -Djetty.port=9576 -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6576 -DSTOP.KEY=key -jar start.jar 1>example4.log 2>&1 &
+

Added: lucene/dev/trunk/solr/cloud-dev/example3.sh
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/cloud-dev/example3.sh?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/cloud-dev/example3.sh (added)
+++ lucene/dev/trunk/solr/cloud-dev/example3.sh Wed Jan 25 19:49:26 2012
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+
+cd ..
+
+rm -r -f example2
+rm -r -f example3
+rm -r -f example4
+
+rm -r -f dist
+rm -r -f build
+rm -r -f example/solr/zoo_data
+rm -f example/example.log
+
+ant example dist
+
+cp -r -f example example2
+cp -r -f example example3
+cp -r -f example example4
+
+
+cd example
+java -DzkRun -DnumShards=2 -DSTOP.PORT=7983 -DSTOP.KEY=key -Dbootstrap_confdir=solr/conf -DzkHost=localhost:9983,localhost:14574,localhost:14585 -jar start.jar 1>example.log 2>&1 &
+
+sleep 10
+
+cd ../example2
+java -Djetty.port=13574 -DzkRun -DzkHost=localhost:9983,localhost:14574,localhost:14575 -DnumShards=2 -DSTOP.PORT=6574 -DSTOP.KEY=key -jar start.jar 1>example2.log 2>&1 &
+
+cd ../example3
+java -Djetty.port=13585 -DzkRun -DzkHost=localhost:9983,localhost:14574,localhost:14585 -DnumShards=2 -DSTOP.PORT=6575 -DSTOP.KEY=key -jar start.jar 1>example3.log 2>&1 &
+
+cd ../example4
+java -Djetty.port=13596 -DzkHost=localhost:9983,localhost:14574,localhost:14585 -DnumShards=2 -DSTOP.PORT=6576 -DSTOP.KEY=key -jar start.jar 1>example4.log 2>&1 &

Added: lucene/dev/trunk/solr/cloud-dev/solrcloud.sh
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/cloud-dev/solrcloud.sh?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/cloud-dev/solrcloud.sh (added)
+++ lucene/dev/trunk/solr/cloud-dev/solrcloud.sh Wed Jan 25 19:49:26 2012
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+
+cd ..
+
+rm -r -f example2
+rm -r -f example3
+rm -r -f example4
+rm -r -f example5
+rm -r -f example6
+
+rm -r -f dist
+rm -r -f build
+rm -r -f example/solr/zoo_data
+rm -f example/example.log
+
+ant example dist
+
+cp -r -f example example2
+cp -r -f example example3
+cp -r -f example example4
+cp -r -f example example5
+cp -r -f example example6
+
+java -classpath lib/*:dist/*:build/lucene-libs/* org.apache.solr.cloud.ZkController 127.0.0.1:9983 example/solr 8983 example/solr/conf conf1
+
+cd example
+java -DzkRun -DnumShards=2 -DSTOP.PORT=7983 -DSTOP.KEY=key -jar start.jar 1>example.log 2>&1 &
+
+cd ../example2
+java -Djetty.port=7574 -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6574 -DSTOP.KEY=key -jar start.jar 1>example2.log 2>&1 &
+
+cd ../example3
+java -Djetty.port=7575 -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6575 -DSTOP.KEY=key -jar start.jar 1>example3.log 2>&1 &
+
+cd ../example4
+java -Djetty.port=7576 -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6576 -DSTOP.KEY=key -jar start.jar 1>example4.log 2>&1 &
+
+cd ../example5
+java -Djetty.port=7577 -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6577 -DSTOP.KEY=key -jar start.jar 1>example5.log 2>&1 &
+
+cd ../example6
+java -Djetty.port=7578 -DzkHost=localhost:9983 -DnumShards=2 -DSTOP.PORT=6578 -DSTOP.KEY=key -jar start.jar 1>example6.log 2>&1 &

Added: lucene/dev/trunk/solr/cloud-dev/stop.sh
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/cloud-dev/stop.sh?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/cloud-dev/stop.sh (added)
+++ lucene/dev/trunk/solr/cloud-dev/stop.sh Wed Jan 25 19:49:26 2012
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+
+cd ../example
+
+java -DSTOP.PORT=7983 -DSTOP.KEY=key -jar start.jar --stop
+java -DSTOP.PORT=6574 -DSTOP.KEY=key -jar start.jar --stop
+java -DSTOP.PORT=6575 -DSTOP.KEY=key -jar start.jar --stop
+java -DSTOP.PORT=6576 -DSTOP.KEY=key -jar start.jar --stop
+java -DSTOP.PORT=6577 -DSTOP.KEY=key -jar start.jar --stop
+java -DSTOP.PORT=6578 -DSTOP.KEY=key -jar start.jar --stop
\ No newline at end of file

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SolrWriter.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SolrWriter.java?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SolrWriter.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/SolrWriter.java Wed Jan 25 19:49:26 2012
@@ -81,7 +81,7 @@ public class SolrWriter extends DIHWrite
     try {
       log.info("Deleting document: " + id);
       DeleteUpdateCommand delCmd = new DeleteUpdateCommand(req);
-      delCmd.id = id.toString();
+      delCmd.setId(id.toString());
       processor.processDelete(delCmd);
     } catch (IOException e) {
       log.error("Exception while deleteing: " + id, e);

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestContentStreamDataSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestContentStreamDataSource.java?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestContentStreamDataSource.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestContentStreamDataSource.java Wed Jan 25 19:49:26 2012
@@ -173,9 +173,8 @@ public class TestContentStreamDataSource
   }
 
   private JettySolrRunner createJetty(SolrInstance instance) throws Exception {
-    System.setProperty("solr.solr.home", instance.getHomeDir());
     System.setProperty("solr.data.dir", instance.getDataDir());
-    JettySolrRunner jetty = new JettySolrRunner("/solr", 0);
+    JettySolrRunner jetty = new JettySolrRunner(instance.getHomeDir(), "/solr", 0);
     jetty.start();
     return jetty;
   }

Modified: lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java (original)
+++ lucene/dev/trunk/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestSolrEntityProcessorEndToEnd.java Wed Jan 25 19:49:26 2012
@@ -47,7 +47,7 @@ public class TestSolrEntityProcessorEndT
   
   private static Logger LOG = LoggerFactory.getLogger(TestSolrEntityProcessorEndToEnd.class);
   
-  private static final String SOLR_SOURCE_URL = "http://localhost:8983/solr";
+  //rivate static final String SOLR_SOURCE_URL = "http://localhost:8983/solr";
   private static final String SOLR_CONFIG = "dataimport-solrconfig.xml";
   private static final String SOLR_SCHEMA = "dataimport-schema.xml";
   private static final String SOLR_HOME = "dih/solr";
@@ -68,29 +68,36 @@ public class TestSolrEntityProcessorEndT
     solrDoc.put("desc", "SolrDescription");
     SOLR_DOCS.add(solrDoc);
   }
-  
-  private static final String DIH_CONFIG_TAGS_INNER_ENTITY = "<dataConfig>\r\n"
-      + "  <dataSource type='MockDataSource' />\r\n"
-      + "  <document>\r\n"
-      + "    <entity name='db' query='select * from x'>\r\n"
-      + "      <field column='dbid_s' />\r\n"
-      + "      <field column='dbdesc_s' />\r\n"
-      + "      <entity name='se' processor='SolrEntityProcessor' query='id:${db.dbid_s}'\n"
-      + "     url='" + SOLR_SOURCE_URL + "' fields='id,desc'>\r\n"
-      + "        <field column='id' />\r\n"
-      + "        <field column='desc' />\r\n" + "      </entity>\r\n"
-      + "    </entity>\r\n" + "  </document>\r\n" + "</dataConfig>\r\n";
+
   
   private SolrInstance instance = null;
   private JettySolrRunner jetty;
   
-  private static String generateDIHConfig(String options) {
+  private static String getDihConfigTagsInnerEntity(int port) {
+    return  "<dataConfig>\r\n"
+        + "  <dataSource type='MockDataSource' />\r\n"
+        + "  <document>\r\n"
+        + "    <entity name='db' query='select * from x'>\r\n"
+        + "      <field column='dbid_s' />\r\n"
+        + "      <field column='dbdesc_s' />\r\n"
+        + "      <entity name='se' processor='SolrEntityProcessor' query='id:${db.dbid_s}'\n"
+        + "     url='" + getSourceUrl(port) + "' fields='id,desc'>\r\n"
+        + "        <field column='id' />\r\n"
+        + "        <field column='desc' />\r\n" + "      </entity>\r\n"
+        + "    </entity>\r\n" + "  </document>\r\n" + "</dataConfig>\r\n";
+  }
+  
+  private static String generateDIHConfig(String options, int port) {
     return "<dataConfig>\r\n" + "  <document>\r\n"
         + "    <entity name='se' processor='SolrEntityProcessor'" + "   url='"
-        + SOLR_SOURCE_URL + "' " + options + " />\r\n" + "  </document>\r\n"
+        + getSourceUrl(port) + "' " + options + " />\r\n" + "  </document>\r\n"
         + "</dataConfig>\r\n";
   }
   
+  private static String getSourceUrl(int port) {
+    return "http://localhost:" + port + "/solr";
+  }
+  
   //TODO: fix this test to close its directories
   static String savedFactory;
   @BeforeClass
@@ -107,7 +114,7 @@ public class TestSolrEntityProcessorEndT
       System.setProperty("solr.directoryFactory", savedFactory);
     }
   }
-  
+
   @Override
   @Before
   public void setUp() throws Exception {
@@ -138,7 +145,7 @@ public class TestSolrEntityProcessorEndT
     
     try {
       addDocumentsToSolr(SOLR_DOCS);
-      runFullImport(generateDIHConfig("query='*:*' rows='2' fields='id,desc' onError='skip'"));
+      runFullImport(generateDIHConfig("query='*:*' rows='2' fields='id,desc' onError='skip'", jetty.getLocalPort()));
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -156,7 +163,7 @@ public class TestSolrEntityProcessorEndT
       addDocumentsToSolr(generateSolrDocuments(30));
       Map<String,String> map = new HashMap<String,String>();
       map.put("rows", "50");
-      runFullImport(generateDIHConfig("query='*:*' fq='desc:Description1*,desc:Description*2' rows='2'"), map);
+      runFullImport(generateDIHConfig("query='*:*' fq='desc:Description1*,desc:Description*2' rows='2'", jetty.getLocalPort()), map);
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -171,7 +178,7 @@ public class TestSolrEntityProcessorEndT
     
     try {
       addDocumentsToSolr(generateSolrDocuments(7));
-      runFullImport(generateDIHConfig("query='*:*' fields='id' rows='2'"));
+      runFullImport(generateDIHConfig("query='*:*' fields='id' rows='2'", jetty.getLocalPort()));
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -197,7 +204,7 @@ public class TestSolrEntityProcessorEndT
     try {
       MockDataSource.setIterator("select * from x", DB_DOCS.iterator());
       addDocumentsToSolr(SOLR_DOCS);
-      runFullImport(DIH_CONFIG_TAGS_INNER_ENTITY);
+      runFullImport(getDihConfigTagsInnerEntity(jetty.getLocalPort()));
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -224,7 +231,7 @@ public class TestSolrEntityProcessorEndT
     assertQ(req("*:*"), "//result[@numFound='0']");
     
     try {
-      runFullImport(generateDIHConfig("query='*:*' rows='2' fields='id,desc' onError='skip'"));
+      runFullImport(generateDIHConfig("query='*:*' rows='2' fields='id,desc' onError='skip'", jetty.getLocalPort()));
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -237,7 +244,7 @@ public class TestSolrEntityProcessorEndT
     assertQ(req("*:*"), "//result[@numFound='0']");
     
     try {
-      runFullImport(generateDIHConfig("query='bogus:3' rows='2' fields='id,desc' onError='abort'"));
+      runFullImport(generateDIHConfig("query='bogus:3' rows='2' fields='id,desc' onError='abort'", jetty.getLocalPort()));
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -255,8 +262,7 @@ public class TestSolrEntityProcessorEndT
       addDocumentsToSolr(docList);
       Map<String,String> map = new HashMap<String,String>();
       map.put("rows", "50");
-      runFullImport(generateDIHConfig("query='*:*' rows='6' numThreads='4'"),
-          map);
+      runFullImport(generateDIHConfig("query='*:*' rows='6' numThreads='4'", jetty.getLocalPort()), map);
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       fail(e.getMessage());
@@ -287,7 +293,7 @@ public class TestSolrEntityProcessorEndT
     }
     
     HttpClient client = new HttpClient(new MultiThreadedHttpConnectionManager());
-    URL url = new URL(SOLR_SOURCE_URL);
+    URL url = new URL(getSourceUrl(jetty.getLocalPort()));
     CommonsHttpSolrServer solrServer = new CommonsHttpSolrServer(url, client);
     solrServer.add(sidl);
     solrServer.commit(true, true);
@@ -343,9 +349,8 @@ public class TestSolrEntityProcessorEndT
   }
   
   private JettySolrRunner createJetty(SolrInstance instance) throws Exception {
-    System.setProperty("solr.solr.home", instance.getHomeDir());
     System.setProperty("solr.data.dir", instance.getDataDir());
-    JettySolrRunner jetty = new JettySolrRunner("/solr", 8983);
+    JettySolrRunner jetty = new JettySolrRunner(instance.getHomeDir(), "/solr", 0);
     jetty.start();
     return jetty;
   }

Modified: lucene/dev/trunk/solr/core/build.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/build.xml?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/build.xml (original)
+++ lucene/dev/trunk/solr/core/build.xml Wed Jan 25 19:49:26 2012
@@ -27,6 +27,6 @@
                                  jar.file="${common-solr.dir}/lib/commons-csv-1.0-SNAPSHOT-r966014.jar" />
 
     <m2-deploy-with-pom-template pom.xml="${common-solr.dir}/lib/apache-solr-noggit-pom.xml.template"
-                                 jar.file="${common-solr.dir}/lib/apache-solr-noggit-r1209632.jar" />
+                                 jar.file="${common-solr.dir}/lib/apache-solr-noggit-r1211150.jar" />
   </target>
 </project>

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/JettySolrRunner.java Wed Jan 25 19:49:26 2012
@@ -34,6 +34,7 @@ import org.mortbay.jetty.servlet.Context
 import org.mortbay.jetty.servlet.FilterHolder;
 import org.mortbay.jetty.servlet.HashSessionIdManager;
 import org.mortbay.log.Logger;
+import org.mortbay.thread.QueuedThreadPool;
 
 /**
  * Run solr using jetty
@@ -48,30 +49,76 @@ public class JettySolrRunner {
   String context;
 
   private String solrConfigFilename;
+  private String schemaFilename;
 
   private boolean waitOnSolr = false;
 
-  public JettySolrRunner(String context, int port) {
-    this.init(context, port);
+  private int lastPort = -1;
+
+  private String shards;
+
+  private String dataDir;
+  
+  private volatile boolean startedBefore = false;
+
+  private String solrHome;
+
+  private boolean stopAtShutdown;
+
+  public JettySolrRunner(String solrHome, String context, int port) {
+    this.init(solrHome, context, port, true);
   }
 
-  public JettySolrRunner(String context, int port, String solrConfigFilename) {
-    this.init(context, port);
+  public JettySolrRunner(String solrHome, String context, int port, String solrConfigFilename, String schemaFileName) {
+    this.init(solrHome, context, port, true);
+    this.solrConfigFilename = solrConfigFilename;
+    this.schemaFilename = schemaFileName;
+  }
+  
+  public JettySolrRunner(String solrHome, String context, int port,
+      String solrConfigFilename, String schemaFileName, boolean stopAtShutdown) {
+    this.init(solrHome, context, port, stopAtShutdown);
     this.solrConfigFilename = solrConfigFilename;
+    this.schemaFilename = schemaFileName;
   }
 
-  private void init(String context, int port) {
+  private void init(String solrHome, String context, int port, boolean stopAtShutdown) {
     this.context = context;
     server = new Server(port);
-    server.setStopAtShutdown(true);
+    this.solrHome = solrHome;
+    this.stopAtShutdown = stopAtShutdown;
+    server.setStopAtShutdown(stopAtShutdown);
+    if (!stopAtShutdown) {
+      server.setGracefulShutdown(0);
+    }
+    System.setProperty("solr.solr.home", solrHome);
     if (System.getProperty("jetty.testMode") != null) {
       // SelectChannelConnector connector = new SelectChannelConnector();
       // Normal SocketConnector is what solr's example server uses by default
       SocketConnector connector = new SocketConnector();
       connector.setPort(port);
       connector.setReuseAddress(true);
-      server.setConnectors(new Connector[] { connector });
+      if (!stopAtShutdown) {
+        QueuedThreadPool threadPool = (QueuedThreadPool) connector
+            .getThreadPool();
+        if (threadPool != null) {
+          threadPool.setMaxStopTimeMs(100);
+        }
+      }
+      server.setConnectors(new Connector[] {connector});
       server.setSessionIdManager(new HashSessionIdManager(new Random()));
+    } else {
+      if (!stopAtShutdown) {
+        for (Connector connector : server.getConnectors()) {
+          if (connector instanceof SocketConnector) {
+            QueuedThreadPool threadPool = (QueuedThreadPool) ((SocketConnector) connector)
+                .getThreadPool();
+            if (threadPool != null) {
+              threadPool.setMaxStopTimeMs(100);
+            }
+          }
+        }
+      }
     }
 
     // Initialize the servlets
@@ -92,13 +139,20 @@ public class JettySolrRunner {
       }
 
       public void lifeCycleStarted(LifeCycle arg0) {
-        System.setProperty("hostPort", Integer.toString(getLocalPort()));
-        if (solrConfigFilename != null)
-          System.setProperty("solrconfig", solrConfigFilename);
+        lastPort = getFirstConnectorPort();
+        System.setProperty("hostPort", Integer.toString(lastPort));
+        if (solrConfigFilename != null) System.setProperty("solrconfig",
+            solrConfigFilename);
+        if (schemaFilename != null) System.setProperty("schema", 
+            schemaFilename);
+//        SolrDispatchFilter filter = new SolrDispatchFilter();
+//        FilterHolder fh = new FilterHolder(filter);
         dispatchFilter = root.addFilter(SolrDispatchFilter.class, "*",
             Handler.REQUEST);
-        if (solrConfigFilename != null)
-          System.clearProperty("solrconfig");
+        if (solrConfigFilename != null) System.clearProperty("solrconfig");
+        if (schemaFilename != null) System.clearProperty("schema");
+        System.clearProperty("solr.solr.home");
+        
       }
 
       public void lifeCycleFailure(LifeCycle arg0, Throwable arg1) {
@@ -111,6 +165,18 @@ public class JettySolrRunner {
 
   }
 
+  public FilterHolder getDispatchFilter() {
+    return dispatchFilter;
+  }
+
+  public boolean isRunning() {
+    return server.isRunning();
+  }
+  
+  public boolean isStopped() {
+    return server.isStopped();
+  }
+
   // ------------------------------------------------------------------------------------------------
   // ------------------------------------------------------------------------------------------------
 
@@ -119,6 +185,21 @@ public class JettySolrRunner {
   }
 
   public void start(boolean waitForSolr) throws Exception {
+    // if started before, make a new server
+    if (startedBefore) {
+      waitOnSolr = false;
+      init(solrHome, context, lastPort, stopAtShutdown);
+    } else {
+      startedBefore = true;
+    }
+    
+    if( dataDir != null) {
+      System.setProperty("solr.data.dir", dataDir);
+    }
+    if(shards != null) {
+      System.setProperty("shard", shards);
+    }
+    
     if (!server.isRunning()) {
       server.start();
     }
@@ -131,27 +212,42 @@ public class JettySolrRunner {
         }
       }
     }
+    
+    System.clearProperty("shard");
+    System.clearProperty("solr.data.dir");
   }
 
   public void stop() throws Exception {
-    if (server.isRunning()) {
+    if (!server.isStopped() && !server.isStopping()) {
       server.stop();
-      server.join();
     }
+    server.join();
   }
 
   /**
-   * Returns the Local Port of the first Connector found for the jetty Server.
+   * Returns the Local Port of the jetty Server.
    * 
    * @exception RuntimeException if there is no Connector
    */
-  public int getLocalPort() {
+  private int getFirstConnectorPort() {
     Connector[] conns = server.getConnectors();
     if (0 == conns.length) {
       throw new RuntimeException("Jetty Server has no Connectors");
     }
     return conns[0].getLocalPort();
   }
+  
+  /**
+   * Returns the Local Port of the jetty Server.
+   * 
+   * @exception RuntimeException if there is no Connector
+   */
+  public int getLocalPort() {
+    if (lastPort == -1) {
+      throw new IllegalStateException("You cannot get the port until this instance has started");
+    }
+    return lastPort;
+  }
 
   // --------------------------------------------------------------
   // --------------------------------------------------------------
@@ -172,12 +268,20 @@ public class JettySolrRunner {
    */
   public static void main(String[] args) {
     try {
-      JettySolrRunner jetty = new JettySolrRunner("/solr", 8983);
+      JettySolrRunner jetty = new JettySolrRunner(".", "/solr", 8983);
       jetty.start();
     } catch (Exception ex) {
       ex.printStackTrace();
     }
   }
+
+  public void setShards(String shardList) {
+     this.shards = shardList;
+  }
+
+  public void setDataDir(String dataDir) {
+    this.dataDir = dataDir;
+  }
 }
 
 class NoLog implements Logger {

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/AssignShard.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/AssignShard.java?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/AssignShard.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/AssignShard.java Wed Jan 25 19:49:26 2012
@@ -0,0 +1,81 @@
+package org.apache.solr.cloud;
+
+/**
+ * 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.solr.common.cloud.CloudState;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.zookeeper.KeeperException;
+
+public class AssignShard {
+
+  /**
+   * Assign a new unique id up to slices count - then add replicas evenly.
+   * 
+   * @param collection
+   * 
+   * @param slices
+   * @return
+   * @throws InterruptedException
+   * @throws KeeperException
+   */
+  public static String assignShard(String collection, CloudState state) {
+
+    int shards = Integer.getInteger(ZkStateReader.NUM_SHARDS_PROP,1);
+
+    String returnShardId = null;
+    Map<String, Slice> sliceMap = state.getSlices(collection);
+
+    if (sliceMap == null) {
+      return "shard1";
+    }
+
+    List<String> shardIdNames = new ArrayList<String>(sliceMap.keySet());
+
+    if (shardIdNames.size() < shards) {
+      return "shard" + (shardIdNames.size() + 1);
+    }
+
+    // else figure out which shard needs more replicas
+    final Map<String, Integer> map = new HashMap<String, Integer>();
+    for (String shardId : shardIdNames) {
+      int cnt = sliceMap.get(shardId).getShards().size();
+      map.put(shardId, cnt);
+    }
+
+    Collections.sort(shardIdNames, new Comparator<String>() {
+
+      @Override
+      public int compare(String o1, String o2) {
+        Integer one = map.get(o1);
+        Integer two = map.get(o2);
+        return one.compareTo(two);
+      }
+    });
+
+    returnShardId = shardIdNames.get(0);
+    return returnShardId;
+  }
+}

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java?rev=1235888&r1=1235887&r2=1235888&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CloudDescriptor.java Wed Jan 25 19:49:26 2012
@@ -1,8 +1,5 @@
 package org.apache.solr.cloud;
 
-import org.apache.solr.common.params.SolrParams;
-
-
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -20,11 +17,14 @@ import org.apache.solr.common.params.Sol
  * limitations under the License.
  */
 
+import org.apache.solr.common.params.SolrParams;
+
 public class CloudDescriptor {
   private String shardId;
   private String collectionName;
   private SolrParams params;
-
+  private String roles = "";
+  
   public void setShardId(String shardId) {
     this.shardId = shardId;
   }
@@ -41,6 +41,14 @@ public class CloudDescriptor {
     this.collectionName = collectionName;
   }
 
+  public String getRoles(){
+	  return roles;
+  }
+  
+  public void setRoles(String roles){
+	  this.roles = roles;
+  }
+  
   /** Optional parameters that can change how a core is created. */
   public SolrParams getParams() {
     return params;

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CurrentCoreDescriptorProvider.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CurrentCoreDescriptorProvider.java?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CurrentCoreDescriptorProvider.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/CurrentCoreDescriptorProvider.java Wed Jan 25 19:49:26 2012
@@ -0,0 +1,29 @@
+package org.apache.solr.cloud;
+
+/**
+ * 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 java.util.List;
+
+import org.apache.solr.core.CoreDescriptor;
+
+/**
+ * Provide the current list of registered {@link CoreDescriptor}s.
+ */
+public abstract class CurrentCoreDescriptorProvider {
+  public abstract List<CoreDescriptor> getCurrentDescriptors();
+}

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ElectionContext.java Wed Jan 25 19:49:26 2012
@@ -0,0 +1,222 @@
+package org.apache.solr.cloud;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.SolrException.ErrorCode;
+import org.apache.solr.common.cloud.CloudState;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.ZkCoreNodeProps;
+import org.apache.solr.common.cloud.ZkNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.SolrCore;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.NodeExistsException;
+
+/**
+ * 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 abstract class ElectionContext {
+  
+  final String electionPath;
+  final ZkNodeProps leaderProps;
+  final String id;
+  final String leaderPath;
+  
+  public ElectionContext(final String shardZkNodeName,
+      final String electionPath, final String leaderPath, final ZkNodeProps leaderProps) {
+    this.id = shardZkNodeName;
+    this.electionPath = electionPath;
+    this.leaderPath = leaderPath;
+    this.leaderProps = leaderProps;
+  }
+  
+  abstract void runLeaderProcess(String leaderSeqPath, boolean weAreReplacement) throws KeeperException, InterruptedException, IOException;
+}
+
+class ShardLeaderElectionContextBase extends ElectionContext {
+  
+  protected final SolrZkClient zkClient;
+  protected String shardId;
+  protected String collection;
+  protected LeaderElector leaderElector;
+
+  public ShardLeaderElectionContextBase(LeaderElector leaderElector, final String shardId,
+      final String collection, final String shardZkNodeName, ZkNodeProps props, ZkStateReader zkStateReader) {
+    super(shardZkNodeName, ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection + "/leader_elect/"
+        + shardId, ZkStateReader.getShardLeadersPath(collection, shardId),
+        props);
+    this.leaderElector = leaderElector;
+    this.zkClient = zkStateReader.getZkClient();
+    this.shardId = shardId;
+    this.collection = collection;
+  }
+
+  @Override
+  void runLeaderProcess(String leaderSeqPath, boolean weAreReplacement)
+      throws KeeperException, InterruptedException, IOException {
+
+    try {
+      zkClient.makePath(leaderPath,
+          leaderProps == null ? null : ZkStateReader.toJSON(leaderProps),
+          CreateMode.EPHEMERAL, true);
+    } catch (NodeExistsException e) {
+      // if a previous leader ephemeral still exists for some reason, try and
+      // remove it
+      zkClient.delete(leaderPath, -1, true);
+      zkClient.makePath(leaderPath,
+          leaderProps == null ? null : ZkStateReader.toJSON(leaderProps),
+          CreateMode.EPHEMERAL, true);
+    }
+  } 
+
+}
+
+// add core container and stop passing core around...
+final class ShardLeaderElectionContext extends ShardLeaderElectionContextBase {
+  private ZkController zkController;
+  private CoreContainer cc;
+  private SyncStrategy syncStrategy = new SyncStrategy();
+  
+  public ShardLeaderElectionContext(LeaderElector leaderElector, 
+      final String shardId, final String collection,
+      final String shardZkNodeName, ZkNodeProps props, ZkController zkController, CoreContainer cc) {
+    super(leaderElector, shardId, collection, shardZkNodeName, props,
+        zkController.getZkStateReader());
+    this.zkController = zkController;
+    this.cc = cc;
+  }
+  
+  @Override
+  void runLeaderProcess(String leaderSeqPath, boolean weAreReplacement)
+      throws KeeperException, InterruptedException, IOException {
+    if (cc != null) {
+      SolrCore core = null;
+      String coreName = leaderProps.get(ZkStateReader.CORE_NAME_PROP);
+      try {
+        core = cc.getCore(coreName);
+        if (core == null) {
+          throw new SolrException(ErrorCode.SERVER_ERROR, "Core not found:" + coreName);
+        }
+        // should I be leader?
+        if (weAreReplacement && !shouldIBeLeader(leaderProps)) {
+          System.out.println("there is a better leader candidate it appears");
+          rejoinLeaderElection(leaderSeqPath, core);
+          return;
+        }
+        
+        if (weAreReplacement) {
+          if (zkClient.exists(leaderPath, true)) {
+            zkClient.delete(leaderPath, -1, true);
+          }
+//          System.out.println("I may be the new Leader:" + leaderPath
+//              + " - I need to try and sync");
+          boolean success = syncStrategy.sync(zkController, core, leaderProps);
+          if (!success) {
+            // TODO: what if no one can be the leader in a loop?
+            // perhaps we look down the list and if no one is active, we
+            // accept leader role anyhow
+            core.getUpdateHandler().getSolrCoreState().doRecovery(core);
+            
+            rejoinLeaderElection(leaderSeqPath, core);
+            return;
+          } 
+        }
+        
+        // If I am going to be the leader I have to be active
+        
+        core.getUpdateHandler().getSolrCoreState().cancelRecovery();
+        zkController.publish(core, ZkStateReader.ACTIVE);
+        
+      } finally {
+        if (core != null) {
+          core.close();
+        }
+      }
+      
+    }
+    
+    super.runLeaderProcess(leaderSeqPath, weAreReplacement);
+  }
+
+  private void rejoinLeaderElection(String leaderSeqPath, SolrCore core)
+      throws InterruptedException, KeeperException, IOException {
+    // remove our ephemeral and re join the election
+   // System.out.println("sync failed, delete our election node:"
+   //     + leaderSeqPath);
+    zkController.publish(core, ZkStateReader.DOWN);
+    zkClient.delete(leaderSeqPath, -1, true);
+    
+    core.getUpdateHandler().getSolrCoreState().doRecovery(core);
+    
+    leaderElector.joinElection(this);
+  }
+  
+  private boolean shouldIBeLeader(ZkNodeProps leaderProps) {
+    CloudState cloudState = zkController.getZkStateReader().getCloudState();
+    Map<String,Slice> slices = cloudState.getSlices(this.collection);
+    Slice slice = slices.get(shardId);
+    Map<String,ZkNodeProps> shards = slice.getShards();
+    boolean foundSomeoneElseActive = false;
+    for (Map.Entry<String,ZkNodeProps> shard : shards.entrySet()) {
+      String state = shard.getValue().get(ZkStateReader.STATE_PROP);
+
+      if (new ZkCoreNodeProps(shard.getValue()).getCoreUrl().equals(
+              new ZkCoreNodeProps(leaderProps).getCoreUrl())) {
+        if (state.equals(ZkStateReader.ACTIVE)
+          && cloudState.liveNodesContain(shard.getValue().get(
+              ZkStateReader.NODE_NAME_PROP))) {
+          // we are alive
+          return true;
+        }
+      }
+      
+      if ((state.equals(ZkStateReader.ACTIVE))
+          && cloudState.liveNodesContain(shard.getValue().get(
+              ZkStateReader.NODE_NAME_PROP))
+          && !new ZkCoreNodeProps(shard.getValue()).getCoreUrl().equals(
+              new ZkCoreNodeProps(leaderProps).getCoreUrl())) {
+        foundSomeoneElseActive = true;
+      }
+    }
+    
+    return !foundSomeoneElseActive;
+  }
+  
+}
+
+final class OverseerElectionContext extends ElectionContext {
+  
+  private final SolrZkClient zkClient;
+  private final ZkStateReader stateReader;
+
+  public OverseerElectionContext(final String zkNodeName, SolrZkClient zkClient, ZkStateReader stateReader) {
+    super(zkNodeName, "/overseer_elect", null, null);
+    this.zkClient = zkClient;
+    this.stateReader = stateReader;
+  }
+
+  @Override
+  void runLeaderProcess(String leaderSeqPath, boolean weAreReplacement) throws KeeperException, InterruptedException {
+    new Overseer(zkClient, stateReader);
+  }
+  
+}

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/LeaderElector.java Wed Jan 25 19:49:26 2012
@@ -0,0 +1,286 @@
+package org.apache.solr.cloud;
+
+/**
+ * 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 java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.solr.common.cloud.ZkCmdExecutor;
+import org.apache.solr.common.cloud.ZooKeeperException;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.ConnectionLossException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Leader Election process. This class contains the logic by which a
+ * leader is chosen. First call * {@link #setup(ElectionContext)} to ensure
+ * the election process is init'd. Next call
+ * {@link #joinElection(ElectionContext)} to start the leader election.
+ * 
+ * The implementation follows the classic ZooKeeper recipe of creating an
+ * ephemeral, sequential node for each candidate and then looking at the set
+ * of such nodes - if the created node is the lowest sequential node, the
+ * candidate that created the node is the leader. If not, the candidate puts
+ * a watch on the next lowest node it finds, and if that node goes down, 
+ * starts the whole process over by checking if it's the lowest sequential node, etc.
+ * 
+ * TODO: now we could just reuse the lock package code for leader election
+ */
+public  class LeaderElector {
+  private static Logger log = LoggerFactory.getLogger(LeaderElector.class);
+  
+  private static final String ELECTION_NODE = "/election";
+  
+  private final static Pattern LEADER_SEQ = Pattern.compile(".*?/?.*?-n_(\\d+)");
+  private final static Pattern SESSION_ID = Pattern.compile(".*?/?(.*?-.*?)-n_\\d+");
+  
+  protected SolrZkClient zkClient;
+  
+  private ZkCmdExecutor zkCmdExecutor = new ZkCmdExecutor();
+  
+  public LeaderElector(SolrZkClient zkClient) {
+    this.zkClient = zkClient;
+  }
+  
+  /**
+   * Check if the candidate with the given n_* sequence number is the leader.
+   * If it is, set the leaderId on the leader zk node. If it is not, start
+   * watching the candidate that is in line before this one - if it goes down, check
+   * if this candidate is the leader again.
+   * @param leaderSeqPath 
+   * 
+   * @param seq
+   * @param context 
+   * @param replacement has someone else been the leader already?
+   * @throws KeeperException
+   * @throws InterruptedException
+   * @throws IOException 
+   * @throws UnsupportedEncodingException
+   */
+  private void checkIfIamLeader(final String leaderSeqPath, final int seq, final ElectionContext context, boolean replacement) throws KeeperException,
+      InterruptedException, IOException {
+    // get all other numbers...
+    final String holdElectionPath = context.electionPath + ELECTION_NODE;
+    List<String> seqs = zkClient.getChildren(holdElectionPath, null, true);
+    
+    sortSeqs(seqs);
+    List<Integer> intSeqs = getSeqs(seqs);
+    if (seq <= intSeqs.get(0)) {
+      runIamLeaderProcess(leaderSeqPath, context, replacement);
+    } else {
+      // I am not the leader - watch the node below me
+      int i = 1;
+      for (; i < intSeqs.size(); i++) {
+        int s = intSeqs.get(i);
+        if (seq < s) {
+          // we found who we come before - watch the guy in front
+          break;
+        }
+      }
+      int index = i - 2;
+      if (index < 0) {
+        log.warn("Our node is no longer in line to be leader");
+        return;
+      }
+      try {
+        zkClient.getData(holdElectionPath + "/" + seqs.get(index),
+            new Watcher() {
+              
+              @Override
+              public void process(WatchedEvent event) {
+                // am I the next leader?
+                try {
+                  checkIfIamLeader(leaderSeqPath, seq, context, true);
+                } catch (InterruptedException e) {
+                  // Restore the interrupted status
+                  Thread.currentThread().interrupt();
+                  log.warn("", e);
+                } catch (IOException e) {
+                  log.warn("", e);
+                } catch (Exception e) {
+                  log.warn("", e);
+                }
+              }
+              
+            }, null, true);
+      } catch (KeeperException.SessionExpiredException e) {
+        throw e;
+      } catch (KeeperException e) {
+        // we couldn't set our watch - the node before us may already be down?
+        // we need to check if we are the leader again
+        checkIfIamLeader(leaderSeqPath, seq, context, true);
+      }
+    }
+  }
+
+  // TODO: get this core param out of here
+  protected void runIamLeaderProcess(String leaderSeqPath, final ElectionContext context, boolean weAreReplacement) throws KeeperException,
+      InterruptedException, IOException {
+
+    context.runLeaderProcess(leaderSeqPath, weAreReplacement);
+  }
+  
+  /**
+   * Returns int given String of form n_0000000001 or n_0000000003, etc.
+   * 
+   * @param nStringSequence
+   * @return
+   */
+  private int getSeq(String nStringSequence) {
+    int seq = 0;
+    Matcher m = LEADER_SEQ.matcher(nStringSequence);
+    if (m.matches()) {
+      seq = Integer.parseInt(m.group(1));
+    } else {
+      throw new IllegalStateException("Could not find regex match in:"
+          + nStringSequence);
+    }
+    return seq;
+  }
+  
+  private String getNodeId(String nStringSequence) {
+    String id;
+    Matcher m = SESSION_ID.matcher(nStringSequence);
+    if (m.matches()) {
+      id = m.group(1);
+    } else {
+      throw new IllegalStateException("Could not find regex match in:"
+          + nStringSequence);
+    }
+    return id;
+  }
+  
+  /**
+   * Returns int list given list of form n_0000000001, n_0000000003, etc.
+   * 
+   * @param seqs
+   * @return
+   */
+  private List<Integer> getSeqs(List<String> seqs) {
+    List<Integer> intSeqs = new ArrayList<Integer>(seqs.size());
+    for (String seq : seqs) {
+      intSeqs.add(getSeq(seq));
+    }
+    return intSeqs;
+  }
+  
+  /**
+   * Begin participating in the election process. Gets a new sequential number
+   * and begins watching the node with the sequence number before it, unless it
+   * is the lowest number, in which case, initiates the leader process. If the
+   * node that is watched goes down, check if we are the new lowest node, else
+   * watch the next lowest numbered node.
+   * 
+   * @param context
+   * @param SolrCore - optional - sometimes null
+   * @return sequential node number
+   * @throws KeeperException
+   * @throws InterruptedException
+   * @throws IOException 
+   * @throws UnsupportedEncodingException
+   */
+  public int joinElection(ElectionContext context) throws KeeperException, InterruptedException, IOException {
+    final String shardsElectZkPath = context.electionPath + LeaderElector.ELECTION_NODE;
+    
+    long sessionId = zkClient.getSolrZooKeeper().getSessionId();
+    String id = sessionId + "-" + context.id;
+    String leaderSeqPath = null;
+    boolean cont = true;
+    int tries = 0;
+    while (cont) {
+      try {
+        leaderSeqPath = zkClient.create(shardsElectZkPath + "/" + id + "-n_", null,
+            CreateMode.EPHEMERAL_SEQUENTIAL, false);
+        cont = false;
+      } catch (ConnectionLossException e) {
+        // we don't know if we made our node or not...
+        List<String> entries = zkClient.getChildren(shardsElectZkPath, null, true);
+        
+        boolean foundId = false;
+        for (String entry : entries) {
+          String nodeId = getNodeId(entry);
+          if (id.equals(nodeId)) {
+            // we did create our node...
+            foundId  = true;
+            break;
+          }
+        }
+        if (!foundId) {
+          throw e;
+        }
+
+      } catch (KeeperException.NoNodeException e) {
+        // we must have failed in creating the election node - someone else must
+        // be working on it, lets try again
+        if (tries++ > 9) {
+          throw new ZooKeeperException(SolrException.ErrorCode.SERVER_ERROR,
+              "", e);
+        }
+        cont = true;
+        Thread.sleep(50);
+      }
+    }
+    int seq = getSeq(leaderSeqPath);
+    checkIfIamLeader(leaderSeqPath, seq, context, false);
+    
+    return seq;
+  }
+  
+  /**
+   * Set up any ZooKeeper nodes needed for leader election.
+   * 
+   * @param shardId
+   * @param collection
+   * @throws InterruptedException
+   * @throws KeeperException
+   */
+  public void setup(final ElectionContext context) throws InterruptedException,
+      KeeperException {
+    String electZKPath = context.electionPath + LeaderElector.ELECTION_NODE;
+    
+    zkCmdExecutor.ensureExists(electZKPath, zkClient);
+  }
+  
+  /**
+   * Sort n string sequence list.
+   * 
+   * @param seqs
+   */
+  private void sortSeqs(List<String> seqs) {
+    Collections.sort(seqs, new Comparator<String>() {
+      
+      @Override
+      public int compare(String o1, String o2) {
+        return Integer.valueOf(getSeq(o1)).compareTo(
+            Integer.valueOf(getSeq(o2)));
+      }
+    });
+  }
+}

Added: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/NodeStateWatcher.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/NodeStateWatcher.java?rev=1235888&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/NodeStateWatcher.java (added)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/NodeStateWatcher.java Wed Jan 25 19:49:26 2012
@@ -0,0 +1,124 @@
+package org.apache.solr.cloud;
+
+/**
+ * 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.solr.common.cloud.CoreState;
+import org.apache.solr.common.cloud.SolrZkClient;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Watcher for node state changes.
+ */
+public class NodeStateWatcher implements Watcher {
+
+  private static Logger log = LoggerFactory.getLogger(NodeStateWatcher.class);
+
+  public static interface NodeStateChangeListener {
+    void coreChanged(String nodeName, Set<CoreState> states)
+        throws KeeperException, InterruptedException;
+  }
+
+  private final SolrZkClient zkClient;
+  private final String path;
+  private volatile Set<CoreState> currentState = new HashSet<CoreState>();
+  private final NodeStateChangeListener listener;
+  private final String nodeName;
+
+  
+  public Set<CoreState> getCurrentState() {
+    return currentState;
+  }
+
+  public NodeStateWatcher(SolrZkClient zkClient, String nodeName, String path,
+      NodeStateChangeListener listener) throws KeeperException, InterruptedException {
+    this.nodeName = nodeName;
+    this.zkClient = zkClient;
+    this.path = path;
+    this.listener = listener;
+    processStateChange();
+  }
+
+  @Override
+  public void process(WatchedEvent event) {
+    try {
+      processStateChange();
+    } catch (InterruptedException e) {
+      // Restore the interrupted status
+      Thread.currentThread().interrupt();
+      return;
+    } catch (Exception e) {
+      log.warn("Error processing state change", e);
+    } 
+  }
+
+  private void processStateChange() throws KeeperException, InterruptedException {
+    byte[] data = zkClient.getData(path, this, null, true);
+
+    if (data != null) {
+        CoreState[] states = CoreState.load(data);
+        List<CoreState> stateList = Arrays.asList(states);
+        HashSet<CoreState> modifiedCores = new HashSet<CoreState>();
+        modifiedCores.addAll(stateList);
+        modifiedCores.removeAll(currentState);
+
+        HashSet<CoreState> newState = new HashSet<CoreState>();
+        newState.addAll(stateList);
+        
+        HashMap<String, CoreState> lookup = new HashMap<String, CoreState>();
+        for(CoreState state: states) {
+          lookup.put(state.getCoreName(), state);
+        }
+
+        //check for status change
+        for(CoreState state: currentState) {
+          if(lookup.containsKey(state.getCoreName())) {
+            if(!state.getProperties().equals(lookup.get(state.getCoreName()).getProperties())) {
+              modifiedCores.add(lookup.get(state.getCoreName()));
+            }
+          }
+        }
+        
+        currentState = Collections.unmodifiableSet(newState);
+
+        if (modifiedCores.size() > 0) {
+          try {
+            listener.coreChanged(nodeName, Collections.unmodifiableSet(modifiedCores));
+          } catch (KeeperException e) {
+            log.warn("Could not talk to ZK", e);
+          } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            log.warn("Could not talk to ZK", e);
+          }
+        }
+
+    } else {
+      // ignore null state
+    }
+  }
+}