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 2013/08/14 15:11:15 UTC
svn commit: r1513864 - in /lucene/dev/trunk/solr: CHANGES.txt
core/src/java/org/apache/solr/cloud/Overseer.java
core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
Author: markrmiller
Date: Wed Aug 14 13:11:14 2013
New Revision: 1513864
URL: http://svn.apache.org/r1513864
Log:
SOLR-5135: Harden Collection API deletion of /collections/$collection ZooKeeper node
Modified:
lucene/dev/trunk/solr/CHANGES.txt
lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java
lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1513864&r1=1513863&r2=1513864&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Wed Aug 14 13:11:14 2013
@@ -119,6 +119,9 @@ Bug Fixes
* SOLR-5133: HdfsUpdateLog can fail to close a FileSystem instance if init
is called more than once. (Mark Miller)
+
+* SOLR-5135: Harden Collection API deletion of /collections/$collection
+ ZooKeeper node. (Mark Miller)
Optimizations
----------------------
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java?rev=1513864&r1=1513863&r2=1513864&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/Overseer.java Wed Aug 14 13:11:14 2013
@@ -17,8 +17,17 @@ package org.apache.solr.cloud;
* the License.
*/
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
import org.apache.solr.common.SolrException;
-import org.apache.solr.common.SolrException.ErrorCode;
import org.apache.solr.common.cloud.ClosableThread;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.DocCollection;
@@ -36,16 +45,6 @@ import org.apache.zookeeper.KeeperExcept
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
/**
* Cluster leader. Responsible node assignments, cluster state file?
*/
@@ -295,17 +294,6 @@ public class Overseer {
final String collection = message.getStr(ZkStateReader.COLLECTION_PROP);
assert collection.length() > 0 : message;
- try {
- if (!zkClient.exists(ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection, true)) {
- log.warn("Could not find collection node for " + collection + ", skipping publish state");
- }
- } catch (KeeperException e) {
- throw new SolrException(ErrorCode.SERVER_ERROR, e);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new SolrException(ErrorCode.SERVER_ERROR, e);
- }
-
String coreNodeName = message.getStr(ZkStateReader.CORE_NODE_NAME_PROP);
if (coreNodeName == null) {
coreNodeName = getAssignedCoreNodeName(state, message);
Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java?rev=1513864&r1=1513863&r2=1513864&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java Wed Aug 14 13:11:14 2013
@@ -232,31 +232,57 @@ public class OverseerCollectionProcessor
return new OverseerSolrResponse(results);
}
- private void deleteCollection(ZkNodeProps message, NamedList results) throws KeeperException, InterruptedException {
- ModifiableSolrParams params = new ModifiableSolrParams();
- params.set(CoreAdminParams.ACTION, CoreAdminAction.UNLOAD.toString());
- params.set(CoreAdminParams.DELETE_INSTANCE_DIR, true);
- params.set(CoreAdminParams.DELETE_DATA_DIR, true);
- collectionCmd(zkStateReader.getClusterState(), message, params, results, null);
-
- ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION,
- Overseer.REMOVECOLLECTION, "name", message.getStr("name"));
- Overseer.getInQueue(zkStateReader.getZkClient()).offer(ZkStateReader.toJSON(m));
-
- // wait for a while until we don't see the collection
- long now = System.currentTimeMillis();
- long timeout = now + 30000;
- boolean removed = false;
- while (System.currentTimeMillis() < timeout) {
- Thread.sleep(100);
- removed = !zkStateReader.getClusterState().getCollections().contains(message.getStr("name"));
- if (removed) {
- Thread.sleep(100); // just a bit of time so it's more likely other readers see on return
- break;
+ private void deleteCollection(ZkNodeProps message, NamedList results)
+ throws KeeperException, InterruptedException {
+ String collection = message.getStr("name");
+ try {
+ ModifiableSolrParams params = new ModifiableSolrParams();
+ params.set(CoreAdminParams.ACTION, CoreAdminAction.UNLOAD.toString());
+ params.set(CoreAdminParams.DELETE_INSTANCE_DIR, true);
+ params.set(CoreAdminParams.DELETE_DATA_DIR, true);
+ collectionCmd(zkStateReader.getClusterState(), message, params, results,
+ null);
+
+ ZkNodeProps m = new ZkNodeProps(Overseer.QUEUE_OPERATION,
+ Overseer.REMOVECOLLECTION, "name", collection);
+ Overseer.getInQueue(zkStateReader.getZkClient()).offer(
+ ZkStateReader.toJSON(m));
+
+ // wait for a while until we don't see the collection
+ long now = System.currentTimeMillis();
+ long timeout = now + 30000;
+ boolean removed = false;
+ while (System.currentTimeMillis() < timeout) {
+ Thread.sleep(100);
+ removed = !zkStateReader.getClusterState().getCollections()
+ .contains(message.getStr("name"));
+ if (removed) {
+ Thread.sleep(100); // just a bit of time so it's more likely other
+ // readers see on return
+ break;
+ }
+ }
+ if (!removed) {
+ throw new SolrException(ErrorCode.SERVER_ERROR,
+ "Could not fully remove collection: " + message.getStr("name"));
+ }
+
+ } finally {
+
+ try {
+ if (zkStateReader.getZkClient().exists(
+ ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection, true)) {
+ zkStateReader.getZkClient().clean(
+ ZkStateReader.COLLECTIONS_ZKNODE + "/" + collection);
+ }
+ } catch (InterruptedException e) {
+ SolrException.log(log, "Cleaning up collection in zk was interrupted:"
+ + collection, e);
+ Thread.currentThread().interrupt();
+ } catch (KeeperException e) {
+ SolrException.log(log, "Problem cleaning up collection in zk:"
+ + collection, e);
}
- }
- if (!removed) {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Could not fully remove collection: " + message.getStr("name"));
}
}
@@ -992,11 +1018,6 @@ public class OverseerCollectionProcessor
DocCollection coll = clusterState.getCollection(collectionName);
- if (coll == null) {
- throw new SolrException(ErrorCode.BAD_REQUEST,
- "Could not find collection:" + collectionName);
- }
-
for (Map.Entry<String,Slice> entry : coll.getSlicesMap().entrySet()) {
Slice slice = entry.getValue();
sliceCmd(clusterState, params, stateMatcher, slice);
Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java?rev=1513864&r1=1513863&r2=1513864&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/cloud/CollectionsAPIDistributedZkTest.java Wed Aug 14 13:11:14 2013
@@ -25,6 +25,7 @@ import org.apache.solr.client.solrj.Solr
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.impl.HttpSolrServer.RemoteSolrException;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
import org.apache.solr.client.solrj.request.CoreAdminRequest.Create;
import org.apache.solr.client.solrj.request.QueryRequest;
@@ -57,6 +58,7 @@ import org.junit.BeforeClass;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
+
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
@@ -147,12 +149,49 @@ public class CollectionsAPIDistributedZk
testCollectionsAPI();
testErrorHandling();
deletePartiallyCreatedCollection();
+ deleteCollectionRemovesStaleZkCollectionsNode();
+
+ // last
deleteCollectionWithDownNodes();
if (DEBUG) {
super.printLayout();
}
}
+ private void deleteCollectionRemovesStaleZkCollectionsNode() throws Exception {
+
+ // we can use this client because we just want base url
+ final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0));
+
+ String collectionName = "out_of_sync_collection";
+
+ List<Integer> numShardsNumReplicaList = new ArrayList<Integer>();
+ numShardsNumReplicaList.add(2);
+ numShardsNumReplicaList.add(1);
+
+
+ cloudClient.getZkStateReader().getZkClient().makePath(ZkStateReader.COLLECTIONS_ZKNODE + "/" + collectionName, true);
+
+ ModifiableSolrParams params = new ModifiableSolrParams();
+ params.set("action", CollectionAction.DELETE.toString());
+ params.set("name", collectionName);
+ QueryRequest request = new QueryRequest(params);
+ request.setPath("/admin/collections");
+
+ try {
+ NamedList<Object> resp = createNewSolrServer("", baseUrl)
+ .request(request);
+ fail("Expected to fail, because collection is not in clusterstate");
+ } catch (RemoteSolrException e) {
+
+ }
+
+ checkForMissingCollection(collectionName);
+
+ assertFalse(cloudClient.getZkStateReader().getZkClient().exists(ZkStateReader.COLLECTIONS_ZKNODE + "/" + collectionName, true));
+
+ }
+
private void deletePartiallyCreatedCollection() throws Exception {
final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0));
String collectionName = "halfdeletedcollection";