Return-Path: X-Original-To: apmail-lucene-commits-archive@www.apache.org Delivered-To: apmail-lucene-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2AFDE10BF0 for ; Tue, 18 Nov 2014 22:13:39 +0000 (UTC) Received: (qmail 66170 invoked by uid 500); 18 Nov 2014 22:13:39 -0000 Mailing-List: contact commits-help@lucene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@lucene.apache.org Delivered-To: mailing list commits@lucene.apache.org Received: (qmail 66160 invoked by uid 99); 18 Nov 2014 22:13:39 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 18 Nov 2014 22:13:39 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 18 Nov 2014 22:13:37 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 27A4D238899C; Tue, 18 Nov 2014 22:11:47 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1640432 - in /lucene/dev/branches/lucene_solr_4_10/solr/core/src: java/org/apache/solr/cloud/ZkController.java test/org/apache/solr/cloud/HttpPartitionTest.java Date: Tue, 18 Nov 2014 22:11:47 -0000 To: commits@lucene.apache.org From: thelabdude@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141118221147.27A4D238899C@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: thelabdude Date: Tue Nov 18 22:11:46 2014 New Revision: 1640432 URL: http://svn.apache.org/r1640432 Log: SOLR-6732: fix back-compat issue with unit test to verify solution Modified: lucene/dev/branches/lucene_solr_4_10/solr/core/src/java/org/apache/solr/cloud/ZkController.java lucene/dev/branches/lucene_solr_4_10/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java Modified: lucene/dev/branches/lucene_solr_4_10/solr/core/src/java/org/apache/solr/cloud/ZkController.java URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_10/solr/core/src/java/org/apache/solr/cloud/ZkController.java?rev=1640432&r1=1640431&r2=1640432&view=diff ============================================================================== --- lucene/dev/branches/lucene_solr_4_10/solr/core/src/java/org/apache/solr/cloud/ZkController.java (original) +++ lucene/dev/branches/lucene_solr_4_10/solr/core/src/java/org/apache/solr/cloud/ZkController.java Tue Nov 18 22:11:46 2014 @@ -24,6 +24,7 @@ import java.net.InetAddress; import java.net.NetworkInterface; import java.net.URLEncoder; import java.net.UnknownHostException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -62,6 +63,7 @@ import org.apache.solr.common.cloud.ZkSt import org.apache.solr.common.cloud.ZooKeeperException; import org.apache.solr.common.params.CollectionParams; import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.util.ByteUtils; import org.apache.solr.common.util.URLUtil; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.CoreDescriptor; @@ -75,6 +77,7 @@ import org.apache.zookeeper.KeeperExcept import org.apache.zookeeper.KeeperException.NoNodeException; import org.apache.zookeeper.KeeperException.SessionExpiredException; import org.apache.zookeeper.data.Stat; +import org.noggit.CharArr; import org.noggit.JSONParser; import org.noggit.ObjectBuilder; import org.slf4j.Logger; @@ -1922,15 +1925,17 @@ public final class ZkController { Map stateObj = null; if (stateData != null && stateData.length > 0) { - Object parsedJson = ZkStateReader.fromJSON(stateData); - if (parsedJson instanceof Map) { - stateObj = (Map)parsedJson; - } else if (parsedJson instanceof String) { - // old format still in ZK - stateObj = new LinkedHashMap<>(); - stateObj.put("state", (String)parsedJson); + // TODO: Remove later ... this is for upgrading from 4.8.x to 4.10.3 (see: SOLR-6732) + if (stateData[0] == (byte)'{') { + Object parsedJson = ZkStateReader.fromJSON(stateData); + if (parsedJson instanceof Map) { + stateObj = (Map)parsedJson; + } else { + throw new SolrException(ErrorCode.SERVER_ERROR, "Leader-initiated recovery state data is invalid! "+parsedJson); + } } 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)); } } @@ -1963,7 +1968,7 @@ public final class ZkController { log.warn(exc.getMessage(), exc); } if (stateObj == null) - stateObj = new LinkedHashMap(); + stateObj = ZkNodeProps.makeMap(); stateObj.put("state", state); // only update the createdBy value if its not set Modified: lucene/dev/branches/lucene_solr_4_10/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_4_10/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java?rev=1640432&r1=1640431&r2=1640432&view=diff ============================================================================== --- lucene/dev/branches/lucene_solr_4_10/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java (original) +++ lucene/dev/branches/lucene_solr_4_10/solr/core/src/test/org/apache/solr/cloud/HttpPartitionTest.java Tue Nov 18 22:11:46 2014 @@ -18,6 +18,7 @@ package org.apache.solr.cloud; */ import java.io.File; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -40,9 +41,12 @@ import org.apache.solr.common.SolrInputD import org.apache.solr.common.cloud.ClusterState; import org.apache.solr.common.cloud.Replica; 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.ZkStateReader; 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.Before; import org.slf4j.Logger; @@ -104,6 +108,8 @@ public class HttpPartitionTest extends A public void doTest() throws Exception { waitForThingsToLevelOut(30000); + testLeaderInitiatedRecoveryCRUD(); + // test a 1x2 collection testRf2(); @@ -122,13 +128,65 @@ public class HttpPartitionTest extends A 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 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 { // create a collection that has 1 shard but 2 replicas String testCollectionName = "c8n_1x2"; createCollection(testCollectionName, 1, 2, 1); cloudClient.setDefaultCollection(testCollectionName); - + sendDoc(1); Replica notLeader =