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 13:28:56 UTC
svn commit: r1376443 - in /lucene/dev/branches/branch_4x/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 11:28:56 2012
New Revision: 1376443
URL: http://svn.apache.org/viewvc?rev=1376443&view=rev
Log:
SOLR-3731: disallow null CoreContainer, merge from trunk r1376432
Modified:
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1376443&r1=1376442&r2=1376443&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/ZkController.java Thu Aug 23 11:28:56 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/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java?rev=1376443&r1=1376442&r2=1376443&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/OverseerTest.java Thu Aug 23 11:28:56 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/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java?rev=1376443&r1=1376442&r2=1376443&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ZkControllerTest.java Thu Aug 23 11:28:56 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