You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/08/23 12:52:38 UTC

svn commit: r1376432 - in /lucene/dev/trunk/solr/core/src: java/org/apache/solr/cloud/ZkController.java test/org/apache/solr/cloud/OverseerTest.java test/org/apache/solr/cloud/ZkControllerTest.java

Author: siren
Date: Thu Aug 23 10:52:37 2012
New Revision: 1376432

URL: http://svn.apache.org/viewvc?rev=1376432&view=rev
Log:
SOLR-3731: disallow null CoreContainer

Modified:
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/ZkController.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/ZkControllerTest.java

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=1376432&r1=1376431&r2=1376432&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 Thu Aug 23 10:52:37 2012
@@ -51,7 +51,6 @@ import org.apache.solr.core.Config;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.CoreDescriptor;
 import org.apache.solr.core.SolrCore;
-import org.apache.solr.handler.component.HttpShardHandlerFactory;
 
 import org.apache.solr.handler.component.ShardHandler;
 import org.apache.solr.update.UpdateLog;
@@ -113,18 +112,14 @@ public final class ZkController {
   private final String nodeName;           // example: 127.0.0.1:54065_solr
   private final String baseURL;            // example: http://127.0.0.1:54065/solr
 
-
   private LeaderElector overseerElector;
-  
 
-  // for now, this can be null in tests, in which case recovery will be inactive, and other features
-  // may accept defaults or use mocks rather than pulling things from a CoreContainer
   private CoreContainer cc;
 
   protected volatile Overseer overseer;
 
   /**
-   * @param cc if null, recovery will not be enabled
+   * @param cc
    * @param zkServerAddress
    * @param zkClientTimeout
    * @param zkClientConnectTimeout
@@ -139,6 +134,7 @@ public final class ZkController {
   public ZkController(final CoreContainer cc, String zkServerAddress, int zkClientTimeout, int zkClientConnectTimeout, String localHost, String locaHostPort,
       String localHostContext, final CurrentCoreDescriptorProvider registerOnReconnect) throws InterruptedException,
       TimeoutException, IOException {
+    if (cc == null) throw new IllegalArgumentException("CoreContainer cannot be null.");
     this.cc = cc;
     if (localHostContext.contains("/")) {
       throw new IllegalArgumentException("localHostContext ("
@@ -165,13 +161,8 @@ public final class ZkController {
               //Overseer.createClientNodes(zkClient, getNodeName());
               ShardHandler shardHandler;
               String adminPath;
-              if (cc == null) {
-                shardHandler = new HttpShardHandlerFactory().getShardHandler();
-                adminPath = "/admin/cores";
-              } else {
-                shardHandler = cc.getShardHandlerFactory().getShardHandler();
-                adminPath = cc.getAdminPath();
-              }
+              shardHandler = cc.getShardHandlerFactory().getShardHandler();
+              adminPath = cc.getAdminPath();
               ZkController.this.overseer = new Overseer(shardHandler, adminPath, zkStateReader);
               ElectionContext context = new OverseerElectionContext(zkClient, overseer, getNodeName());
               overseerElector.joinElection(context);
@@ -354,13 +345,8 @@ public final class ZkController {
 
       ShardHandler shardHandler;
       String adminPath;
-      if (cc == null) {
-        shardHandler = new HttpShardHandlerFactory().getShardHandler();
-        adminPath = "/admin/cores";
-      } else {
-        shardHandler = cc.getShardHandlerFactory().getShardHandler();
-        adminPath = cc.getAdminPath();
-      }
+      shardHandler = cc.getShardHandlerFactory().getShardHandler();
+      adminPath = cc.getAdminPath();
       
       overseerElector = new LeaderElector(zkClient);
       this.overseer = new Overseer(shardHandler, adminPath, zkStateReader);
@@ -557,46 +543,42 @@ public final class ZkController {
     
 
     SolrCore core = null;
-    if (cc != null) { // CoreContainer only null in tests
-      try {
-        core = cc.getCore(desc.getName());
+    try {
+      core = cc.getCore(desc.getName());
 
  
-        // recover from local transaction log and wait for it to complete before
-        // going active
-        // TODO: should this be moved to another thread? To recoveryStrat?
-        // TODO: should this actually be done earlier, before (or as part of)
-        // leader election perhaps?
-        // TODO: if I'm the leader, ensure that a replica that is trying to recover waits until I'm
-        // active (or don't make me the
-        // leader until my local replay is done.
-
-        UpdateLog ulog = core.getUpdateHandler().getUpdateLog();
-        if (!core.isReloaded() && ulog != null) {
-          Future<UpdateLog.RecoveryInfo> recoveryFuture = core.getUpdateHandler()
-              .getUpdateLog().recoverFromLog();
-          if (recoveryFuture != null) {
-            recoveryFuture.get(); // NOTE: this could potentially block for
-            // minutes or more!
-            // TODO: public as recovering in the mean time?
-            // TODO: in the future we could do peerync in parallel with recoverFromLog
-          } else {
-            log.info("No LogReplay needed for core="+core.getName() + " baseURL=" + baseUrl);
-          }
-        }
-        
-        boolean didRecovery = checkRecovery(coreName, desc, recoverReloadedCores, isLeader, cloudDesc,
-            collection, coreZkNodeName, shardId, leaderProps, core, cc);
-        if (!didRecovery) {
-          publish(desc, ZkStateReader.ACTIVE);
-        }
-      } finally {
-        if (core != null) {
-          core.close();
+      // recover from local transaction log and wait for it to complete before
+      // going active
+      // TODO: should this be moved to another thread? To recoveryStrat?
+      // TODO: should this actually be done earlier, before (or as part of)
+      // leader election perhaps?
+      // TODO: if I'm the leader, ensure that a replica that is trying to recover waits until I'm
+      // active (or don't make me the
+      // leader until my local replay is done.
+
+      UpdateLog ulog = core.getUpdateHandler().getUpdateLog();
+      if (!core.isReloaded() && ulog != null) {
+        Future<UpdateLog.RecoveryInfo> recoveryFuture = core.getUpdateHandler()
+            .getUpdateLog().recoverFromLog();
+        if (recoveryFuture != null) {
+          recoveryFuture.get(); // NOTE: this could potentially block for
+          // minutes or more!
+          // TODO: public as recovering in the mean time?
+          // TODO: in the future we could do peerync in parallel with recoverFromLog
+        } else {
+          log.info("No LogReplay needed for core="+core.getName() + " baseURL=" + baseUrl);
         }
       }
-    } else {
-      publish(desc, ZkStateReader.ACTIVE);
+      
+      boolean didRecovery = checkRecovery(coreName, desc, recoverReloadedCores, isLeader, cloudDesc,
+          collection, coreZkNodeName, shardId, leaderProps, core, cc);
+      if (!didRecovery) {
+        publish(desc, ZkStateReader.ACTIVE);
+      }
+    } finally {
+      if (core != null) {
+        core.close();
+      }
     }
     
     // make sure we have an update cluster state right away

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=1376432&r1=1376431&r2=1376432&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 Thu Aug 23 10:52:37 2012
@@ -22,7 +22,6 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Random;
 import java.util.Set;
@@ -41,7 +40,6 @@ import org.apache.solr.common.cloud.Slic
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkNodeProps;
 import org.apache.solr.common.cloud.ZkStateReader;
-import org.apache.solr.core.CoreDescriptor;
 import org.apache.solr.handler.component.HttpShardHandlerFactory;
 import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.apache.zookeeper.CreateMode;
@@ -100,7 +98,7 @@ public class OverseerTest extends SolrTe
       zkClient.close();
     }
     
-    public void publishState(String coreName, String stateName, int numShards)
+    public String publishState(String coreName, String stateName, int numShards)
         throws KeeperException, InterruptedException, IOException {
       if (stateName == null) {
         ElectionContext ec = electionContext.remove(coreName);
@@ -143,10 +141,11 @@ public class OverseerTest extends SolrTe
               elector, shardId, collection, nodeName + "_" + coreName, props,
               zkStateReader);
           elector.joinElection(ctx);
-          break;
+          return shardId;
         }
         Thread.sleep(200);
       }
+      return null;
     }
     
     private String getShardId(final String coreName) {
@@ -165,14 +164,13 @@ public class OverseerTest extends SolrTe
   
   @BeforeClass
   public static void beforeClass() throws Exception {
-    System.setProperty("solrcloud.skip.autorecovery", "true");
     initCore();
   }
   
   @AfterClass
   public static void afterClass() throws Exception {
-    System.clearProperty("solrcloud.skip.autorecovery");
     initCore();
+    Thread.sleep(3000); //XXX wait for threads to die...
   }
 
   @Test
@@ -182,53 +180,34 @@ public class OverseerTest extends SolrTe
 
     ZkTestServer server = new ZkTestServer(zkDir);
 
-    ZkController zkController = null;
+    MockZKController zkController = null;
     SolrZkClient zkClient = null;
+    SolrZkClient overseerClient = null;
+
     try {
       server.run();
       AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
       AbstractZkTestCase.makeSolrZkNode(server.getZkHost());
-
+      
       zkClient = new SolrZkClient(server.getZkAddress(), TIMEOUT);
       zkClient.makePath(ZkStateReader.LIVE_NODES_ZKNODE, true);
 
+      overseerClient = electNewOverseer(server.getZkAddress());
+
       ZkStateReader reader = new ZkStateReader(zkClient);
       reader.createClusterStateWatchersAndUpdate();
-
-      zkController = new ZkController(null, server.getZkAddress(), TIMEOUT, 10000,
-          "localhost", "8983", "solr", new CurrentCoreDescriptorProvider() {
-
-            @Override
-            public List<CoreDescriptor> getCurrentDescriptors() {
-              // do nothing
-              return null;
-            }
-          });
-
-      System.setProperty("bootstrap_confdir", getFile("solr/collection1/conf")
-          .getAbsolutePath());
+      
+      zkController = new MockZKController(server.getZkAddress(), "localhost", "collection1");
 
       final int numShards=6;
-      final String[] ids = new String[numShards];
       
       for (int i = 0; i < numShards; i++) {
-        CloudDescriptor collection1Desc = new CloudDescriptor();
-        collection1Desc.setNumShards(3);
-        collection1Desc.setCollectionName("collection1");
-        CoreDescriptor desc1 = new CoreDescriptor(null, "core" + (i + 1), "");
-        desc1.setCloudDescriptor(collection1Desc);
-        zkController.preRegister(desc1);
-        ids[i] = zkController.register("core" + (i + 1), desc1);
+        assertNotNull("shard got no id?", zkController.publishState("core" + (i+1), ZkStateReader.ACTIVE, 3));
       }
-      
-      assertEquals("shard1", ids[0]);
-      assertEquals("shard2", ids[1]);
-      assertEquals("shard3", ids[2]);
-      assertEquals("shard1", ids[3]);
-      assertEquals("shard2", ids[4]);
-      assertEquals("shard3", ids[5]);
 
-      waitForCollections(reader, "collection1");
+      assertEquals(2, reader.getClusterState().getSlice("collection1", "shard1").getShards().size());
+      assertEquals(2, reader.getClusterState().getSlice("collection1", "shard2").getShards().size());
+      assertEquals(2, reader.getClusterState().getSlice("collection1", "shard3").getShards().size());
       
       //make sure leaders are in cloud state
       assertNotNull(reader.getLeaderUrl("collection1", "shard1", 15000));
@@ -236,7 +215,6 @@ public class OverseerTest extends SolrTe
       assertNotNull(reader.getLeaderUrl("collection1", "shard3", 15000));
       
     } finally {
-      System.clearProperty("bootstrap_confdir");
       if (DEBUG) {
         if (zkController != null) {
           zkClient.printLayoutToStdOut();
@@ -246,6 +224,7 @@ public class OverseerTest extends SolrTe
       if (zkController != null) {
         zkController.close();
       }
+      close(overseerClient);
       server.shutdown();
     }
   }
@@ -261,10 +240,11 @@ public class OverseerTest extends SolrTe
     
     ZkTestServer server = new ZkTestServer(zkDir);
 
-    System.setProperty(ZkStateReader.NUM_SHARDS_PROP, Integer.toString(sliceCount));
     SolrZkClient zkClient = null;
     ZkStateReader reader = null;
-    final ZkController[] controllers = new ZkController[nodeCount];
+    SolrZkClient overseerClient = null;
+
+    final MockZKController[] controllers = new MockZKController[nodeCount];
     final ExecutorService[] nodeExecutors = new ExecutorService[nodeCount];
     try {
       server.run();
@@ -273,27 +253,15 @@ public class OverseerTest extends SolrTe
 
       zkClient = new SolrZkClient(server.getZkAddress(), TIMEOUT);
       zkClient.makePath(ZkStateReader.LIVE_NODES_ZKNODE, true);
+      
+      overseerClient = electNewOverseer(server.getZkAddress());
 
       reader = new ZkStateReader(zkClient);
       reader.createClusterStateWatchersAndUpdate();
 
       for (int i = 0; i < nodeCount; i++) {
-      
-      controllers[i] = new ZkController(null, server.getZkAddress(), TIMEOUT, 10000,
-          "localhost", "898" + i, "solr", new CurrentCoreDescriptorProvider() {
-
-            @Override
-            public List<CoreDescriptor> getCurrentDescriptors() {
-              // do nothing
-              return null;
-            }
-          });
-      }
-
-      System.setProperty("bootstrap_confdir", getFile("solr/collection1/conf")
-          .getAbsolutePath());
-
-      
+        controllers[i] = new MockZKController(server.getZkAddress(), "node" + i, "collection1");
+      }      
       for (int i = 0; i < nodeCount; i++) {
         nodeExecutors[i] = Executors.newFixedThreadPool(1, new DefaultSolrThreadFactory("testShardAssignment"));
       }
@@ -305,18 +273,11 @@ public class OverseerTest extends SolrTe
         Runnable coreStarter = new Runnable() {
           @Override
           public void run() {
-            final CloudDescriptor collection1Desc = new CloudDescriptor();
-            collection1Desc.setCollectionName("collection1");
-            collection1Desc.setNumShards(sliceCount);
 
             final String coreName = "core" + slot;
             
-            final CoreDescriptor desc = new CoreDescriptor(null, coreName, "");
-            desc.setCloudDescriptor(collection1Desc);
             try {
-              controllers[slot % nodeCount].preRegister(desc);
-              ids[slot] = controllers[slot % nodeCount]
-                  .register(coreName, desc);
+              ids[slot]=controllers[slot % nodeCount].publishState(coreName, ZkStateReader.ACTIVE, sliceCount);
             } catch (Throwable e) {
               e.printStackTrace();
               fail("register threw exception:" + e.getClass());
@@ -390,14 +351,13 @@ public class OverseerTest extends SolrTe
       }
 
     } finally {
-      System.clearProperty(ZkStateReader.NUM_SHARDS_PROP);
-      System.clearProperty("bootstrap_confdir");
       if (DEBUG) {
         if (controllers[0] != null) {
           zkClient.printLayoutToStdOut();
         }
       }
       close(zkClient);
+      close(overseerClient);
       close(reader);
       for (int i = 0; i < controllers.length; i++)
         if (controllers[i] != null) {
@@ -889,9 +849,9 @@ public class OverseerTest extends SolrTe
     }
   }
 
-  private void close(SolrZkClient overseerClient) throws InterruptedException {
-    if (overseerClient != null) {
-      overseerClient.close();
+  private void close(SolrZkClient client) throws InterruptedException {
+    if (client != null) {
+      client.close();
     }
   }
   

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java?rev=1376432&r1=1376431&r2=1376432&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java Thu Aug 23 10:52:37 2012
@@ -22,13 +22,12 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import junit.framework.Assert;
-
 import org.apache.lucene.util.LuceneTestCase.Slow;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.cloud.SolrZkClient;
 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.CoreDescriptor;
 import org.apache.solr.util.ExternalPaths;
 import org.apache.zookeeper.CreateMode;
@@ -54,6 +53,7 @@ public class ZkControllerTest extends So
   public void testReadConfigName() throws Exception {
     String zkDir = dataDir.getAbsolutePath() + File.separator
         + "zookeeper/server1/data";
+    CoreContainer cc = null;
 
     ZkTestServer server = new ZkTestServer(zkDir);
     try {
@@ -78,7 +78,10 @@ public class ZkControllerTest extends So
         zkClient.printLayoutToStdOut();
       }
       zkClient.close();
-      ZkController zkController = new ZkController(null, server.getZkAddress(), TIMEOUT, 10000,
+      
+      cc = getCoreContainer();
+      
+      ZkController zkController = new ZkController(cc, server.getZkAddress(), TIMEOUT, 10000,
           "localhost", "8983", "solr", new CurrentCoreDescriptorProvider() {
             
             @Override
@@ -94,7 +97,9 @@ public class ZkControllerTest extends So
         zkController.close();
       }
     } finally {
-
+      if (cc != null) {
+        cc.shutdown();
+      }
       server.shutdown();
     }
 
@@ -108,12 +113,15 @@ public class ZkControllerTest extends So
     ZkTestServer server = new ZkTestServer(zkDir);
     ZkController zkController = null;
     boolean testFinished = false;
+    CoreContainer cc = null;
     try {
       server.run();
 
       AbstractZkTestCase.makeSolrZkNode(server.getZkHost());
 
-      zkController = new ZkController(null, server.getZkAddress(),
+      cc = getCoreContainer();
+      
+      zkController = new ZkController(cc, server.getZkAddress(),
           TIMEOUT, 10000, "localhost", "8983", "solr", new CurrentCoreDescriptorProvider() {
             
             @Override
@@ -142,109 +150,16 @@ public class ZkControllerTest extends So
       if (zkController != null) {
         zkController.close();
       }
+      if (cc != null) {
+        cc.shutdown();
+      }
       server.shutdown();
     }
 
   }
-  
-  @Test
-  public void testCoreUnload() throws Exception {
-    
-    String zkDir = dataDir.getAbsolutePath() + File.separator
-        + "zookeeper/server1/data";
-    
-    ZkTestServer server = new ZkTestServer(zkDir);
-    
-    ZkController zkController = null;
-    SolrZkClient zkClient = null;
-    try {
-      server.run();
-      AbstractZkTestCase.tryCleanSolrZkNode(server.getZkHost());
-      AbstractZkTestCase.makeSolrZkNode(server.getZkHost());
-      
-      zkClient = new SolrZkClient(server.getZkAddress(), TIMEOUT);
-      zkClient.makePath(ZkStateReader.LIVE_NODES_ZKNODE, true);
-      
-      ZkStateReader reader = new ZkStateReader(zkClient);
-      reader.createClusterStateWatchersAndUpdate();
-      
-      System.setProperty(ZkStateReader.NUM_SHARDS_PROP, "1");
-      System.setProperty("solrcloud.skip.autorecovery", "true");
-      
-      zkController = new ZkController(null, server.getZkAddress(), TIMEOUT,
-          10000, "localhost", "8983", "solr",
-          new CurrentCoreDescriptorProvider() {
-            
-            @Override
-            public List<CoreDescriptor> getCurrentDescriptors() {
-              // do nothing
-              return null;
-            }
-          });
-      
-      System.setProperty("bootstrap_confdir", getFile("solr/collection1/conf")
-          .getAbsolutePath());
-      
-      final int numShards = 2;
-      final String[] ids = new String[numShards];
-      
-      for (int i = 0; i < numShards; i++) {
-        CloudDescriptor collection1Desc = new CloudDescriptor();
-        collection1Desc.setCollectionName("collection1");
-        CoreDescriptor desc1 = new CoreDescriptor(null, "core" + (i + 1), "");
-        desc1.setCloudDescriptor(collection1Desc);
-        zkController.preRegister(desc1);
-        ids[i] = zkController.register("core" + (i + 1), desc1);
-      }
-      
-      assertEquals("shard1", ids[0]);
-      assertEquals("shard1", ids[1]);
-      
-      assertNotNull(reader.getLeaderUrl("collection1", "shard1", 15000));
-      
-      assertEquals("Shard(s) missing from cloudstate", 2, zkController.getZkStateReader().getClusterState().getSlice("collection1", "shard1").getShards().size());
-      
-      // unregister current leader
-      final ZkNodeProps shard1LeaderProps = reader.getLeaderProps(
-          "collection1", "shard1");
-      final String leaderUrl = reader.getLeaderUrl("collection1", "shard1",
-          15000);
-      
-      final CloudDescriptor collection1Desc = new CloudDescriptor();
-      collection1Desc.setCollectionName("collection1");
-      final CoreDescriptor desc1 = new CoreDescriptor(null,
-          shard1LeaderProps.get(ZkStateReader.CORE_NAME_PROP), "");
-      desc1.setCloudDescriptor(collection1Desc);
-      zkController.unregister(
-          shard1LeaderProps.get(ZkStateReader.CORE_NAME_PROP), collection1Desc);
-      assertNotSame(
-          "New leader was not promoted after unregistering the current leader.",
-          leaderUrl, reader.getLeaderUrl("collection1", "shard1", 15000));
-      assertNotNull("New leader was null.",
-          reader.getLeaderUrl("collection1", "shard1", 15000));
-
-      for(int i=0;i<30;i++) {
-        if(zkController.getZkStateReader().getClusterState().getSlice("collection1", "shard1").getShards().size()==1) break; 
-        Thread.sleep(500);
-      }
-      assertEquals("shard was not unregistered", 1, zkController.getZkStateReader().getClusterState().getSlice("collection1", "shard1").getShards().size());
-    } finally {
-      System.clearProperty("solrcloud.skip.autorecovery");
-      System.clearProperty(ZkStateReader.NUM_SHARDS_PROP);
-      System.clearProperty("bootstrap_confdir");
-      if (DEBUG) {
-        if (zkController != null) {
-          zkClient.printLayoutToStdOut();
-        }
-      }
-      if (zkClient != null) {
-        zkClient.close();
-      }
-      if (zkController != null) {
-        zkController.close();
-      }
-      server.shutdown();
-    }
+
+  private CoreContainer getCoreContainer() {
+    return new CoreContainer(TEMP_DIR.getAbsolutePath());
   }
 
   @Override