SOLR-6732: back compat support needed in trunk and 5x to support upgrades from 4.10.1 to 5x

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1642917 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Timothy Potter 2014-12-02 15:41:58 +00:00
parent da3f0749d5
commit 7ff7ab4a31
2 changed files with 71 additions and 10 deletions

View File

@ -24,6 +24,7 @@ import java.net.InetAddress;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -2010,15 +2011,17 @@ public final class ZkController {
Map<String,Object> stateObj = null; Map<String,Object> stateObj = null;
if (stateData != null && stateData.length > 0) { if (stateData != null && stateData.length > 0) {
Object parsedJson = ZkStateReader.fromJSON(stateData); // TODO: Remove later ... this is for upgrading from 4.8.x to 4.10.3 (see: SOLR-6732)
if (parsedJson instanceof Map) { if (stateData[0] == (byte)'{') {
stateObj = (Map<String,Object>)parsedJson; Object parsedJson = ZkStateReader.fromJSON(stateData);
} else if (parsedJson instanceof String) { if (parsedJson instanceof Map) {
// old format still in ZK stateObj = (Map<String,Object>)parsedJson;
stateObj = new LinkedHashMap<>(); } else {
stateObj.put("state", (String)parsedJson); throw new SolrException(ErrorCode.SERVER_ERROR, "Leader-initiated recovery state data is invalid! "+parsedJson);
}
} else { } else {
throw new SolrException(ErrorCode.SERVER_ERROR, "Leader-initiated recovery state data is invalid! "+parsedJson); // old format still in ZK
stateObj = ZkNodeProps.makeMap("state", new String(stateData, StandardCharsets.UTF_8));
} }
} }
@ -2051,7 +2054,7 @@ public final class ZkController {
log.warn(exc.getMessage(), exc); log.warn(exc.getMessage(), exc);
} }
if (stateObj == null) if (stateObj == null)
stateObj = new LinkedHashMap<>(); stateObj = ZkNodeProps.makeMap();
stateObj.put("state", state); stateObj.put("state", state);
// only update the createdBy value if its not set // only update the createdBy value if its not set

View File

@ -18,6 +18,7 @@ package org.apache.solr.cloud;
*/ */
import java.io.File; import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -40,9 +41,12 @@ import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.ClusterState; import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica; import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice; 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.ZkCoreNodeProps;
import org.apache.solr.common.cloud.ZkStateReader; import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.util.NamedList; import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.servlet.SolrDispatchFilter;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -104,6 +108,8 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase {
public void doTest() throws Exception { public void doTest() throws Exception {
waitForThingsToLevelOut(30000); waitForThingsToLevelOut(30000);
testLeaderInitiatedRecoveryCRUD();
// test a 1x2 collection // test a 1x2 collection
testRf2(); testRf2();
@ -122,7 +128,59 @@ public class HttpPartitionTest extends AbstractFullDistribZkTestBase {
log.info("HttpParitionTest succeeded ... shutting down now!"); log.info("HttpParitionTest succeeded ... shutting down now!");
} }
/**
* Tests handling of lir state znodes.
*/
protected void testLeaderInitiatedRecoveryCRUD() throws Exception {
String testCollectionName = "c8n_crud_1x2";
String shardId = "shard1";
createCollection(testCollectionName, 1, 2, 1);
cloudClient.setDefaultCollection(testCollectionName);
Replica leader =
cloudClient.getZkStateReader().getLeaderRetry(testCollectionName, shardId);
JettySolrRunner leaderJetty = getJettyOnPort(getReplicaPort(leader));
CoreContainer cores = ((SolrDispatchFilter)leaderJetty.getDispatchFilter().getFilter()).getCores();
ZkController zkController = cores.getZkController();
assertNotNull("ZkController is null", zkController);
Replica notLeader =
ensureAllReplicasAreActive(testCollectionName, shardId, 1, 2, maxWaitSecsToSeeAllActive).get(0);
ZkCoreNodeProps replicaCoreNodeProps = new ZkCoreNodeProps(notLeader);
String replicaUrl = replicaCoreNodeProps.getCoreUrl();
assertTrue(!zkController.isReplicaInRecoveryHandling(replicaUrl));
assertTrue(zkController.ensureReplicaInLeaderInitiatedRecovery(testCollectionName, shardId, replicaUrl, replicaCoreNodeProps, false));
assertTrue(zkController.isReplicaInRecoveryHandling(replicaUrl));
Map<String,Object> lirStateMap = zkController.getLeaderInitiatedRecoveryStateObject(testCollectionName, shardId, notLeader.getName());
assertNotNull(lirStateMap);
assertEquals(ZkStateReader.DOWN, lirStateMap.get("state"));
zkController.removeReplicaFromLeaderInitiatedRecoveryHandling(replicaUrl);
assertTrue(!zkController.isReplicaInRecoveryHandling(replicaUrl));
// test old non-json format handling
SolrZkClient zkClient = zkController.getZkClient();
String znodePath = zkController.getLeaderInitiatedRecoveryZnodePath(testCollectionName, shardId, notLeader.getName());
zkClient.setData(znodePath, "down".getBytes(StandardCharsets.UTF_8), true);
lirStateMap = zkController.getLeaderInitiatedRecoveryStateObject(testCollectionName, shardId, notLeader.getName());
assertNotNull(lirStateMap);
assertEquals(ZkStateReader.DOWN, lirStateMap.get("state"));
zkClient.delete(znodePath, -1, false);
// try to clean up
try {
CollectionAdminRequest req = new CollectionAdminRequest.Delete();
req.setCollectionName(testCollectionName);
req.process(cloudClient);
} catch (Exception e) {
// don't fail the test
log.warn("Could not delete collection {} after test completed", testCollectionName);
}
}
protected void testRf2() throws Exception { protected void testRf2() throws Exception {
// create a collection that has 1 shard but 2 replicas // create a collection that has 1 shard but 2 replicas
String testCollectionName = "c8n_1x2"; String testCollectionName = "c8n_1x2";