From 86a40c1cd5691ce8c9c233c9a8186a4f50aa4f5f Mon Sep 17 00:00:00 2001 From: Shalin Shekhar Mangar Date: Fri, 18 Oct 2019 14:48:37 +0530 Subject: [PATCH] SOLR-13843: The MOVEREPLICA API ignores replica type and always adds 'nrt' replicas --- solr/CHANGES.txt | 2 + .../cloud/api/collections/MoveReplicaCmd.java | 8 ++- .../handler/admin/CoreAdminOperation.java | 2 + .../apache/solr/cloud/MoveReplicaTest.java | 49 +++++++++++++------ 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 98f6dae0edc..6a99ddca856 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -331,6 +331,8 @@ Bug Fixes * SOLR-13835: HttpSolrCall produces incorrect extra AuditEvent on AuthorizationResponse.PROMPT (janhoy, hossman) +* SOLR-13843: The MOVEREPLICA API ignores replica type and always adds 'nrt' replicas (Amrit Sarkar via shalin) + Other Changes ---------------------- diff --git a/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java index 4e462f63829..9d5a049b060 100644 --- a/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java +++ b/solr/core/src/java/org/apache/solr/cloud/api/collections/MoveReplicaCmd.java @@ -218,7 +218,9 @@ public class MoveReplicaCmd implements OverseerCollectionMessageHandler.Cmd { WAIT_FOR_FINAL_STATE, String.valueOf(waitForFinalState), SKIP_CREATE_REPLICA_IN_CLUSTER_STATE, skipCreateReplicaInClusterState, CoreAdminParams.ULOG_DIR, ulogDir.substring(0, ulogDir.lastIndexOf(UpdateLog.TLOG_NAME)), - CoreAdminParams.DATA_DIR, dataDir); + CoreAdminParams.DATA_DIR, dataDir, + ZkStateReader.REPLICA_TYPE, replica.getType().name()); + if(async!=null) addReplicasProps.getProperties().put(ASYNC, async); NamedList addResult = new NamedList(); try { @@ -272,7 +274,9 @@ public class MoveReplicaCmd implements OverseerCollectionMessageHandler.Cmd { COLLECTION_PROP, coll.getName(), SHARD_ID_PROP, slice.getName(), CoreAdminParams.NODE, targetNode, - CoreAdminParams.NAME, newCoreName); + CoreAdminParams.NAME, newCoreName, + ZkStateReader.REPLICA_TYPE, replica.getType().name()); + if (async != null) addReplicasProps.getProperties().put(ASYNC, async); NamedList addResult = new NamedList(); SolrCloseableLatch countDownLatch = new SolrCloseableLatch(1, ocmh); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java index 81e6c924191..5739651c7fa 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminOperation.java @@ -55,6 +55,7 @@ import static org.apache.solr.common.params.CommonParams.NAME; import static org.apache.solr.common.params.CoreAdminParams.COLLECTION; import static org.apache.solr.common.params.CoreAdminParams.CoreAdminAction.*; import static org.apache.solr.common.params.CoreAdminParams.REPLICA; +import static org.apache.solr.common.params.CoreAdminParams.REPLICA_TYPE; import static org.apache.solr.common.params.CoreAdminParams.SHARD; import static org.apache.solr.handler.admin.CoreAdminHandler.COMPLETED; import static org.apache.solr.handler.admin.CoreAdminHandler.CallInfo; @@ -333,6 +334,7 @@ enum CoreAdminOperation implements CoreAdminOp { cloudInfo.add(COLLECTION, core.getCoreDescriptor().getCloudDescriptor().getCollectionName()); cloudInfo.add(SHARD, core.getCoreDescriptor().getCloudDescriptor().getShardId()); cloudInfo.add(REPLICA, core.getCoreDescriptor().getCloudDescriptor().getCoreNodeName()); + cloudInfo.add(REPLICA_TYPE, core.getCoreDescriptor().getCloudDescriptor().getReplicaType().name()); info.add("cloud", cloudInfo); } if (isIndexInfoNeeded) { diff --git a/solr/core/src/test/org/apache/solr/cloud/MoveReplicaTest.java b/solr/core/src/test/org/apache/solr/cloud/MoveReplicaTest.java index 843b238ad83..025460c895b 100644 --- a/solr/core/src/test/org/apache/solr/cloud/MoveReplicaTest.java +++ b/solr/core/src/test/org/apache/solr/cloud/MoveReplicaTest.java @@ -81,7 +81,7 @@ public class MoveReplicaTest extends SolrCloudTestCase { fail("no overseer leader!"); } } - + @After public void afterTest() throws Exception { try { @@ -100,7 +100,9 @@ public class MoveReplicaTest extends SolrCloudTestCase { CloudSolrClient cloudClient = cluster.getSolrClient(); - CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(coll, "conf1", 2, REPLICATION); + // random create tlog or pull type replicas with nrt + boolean isTlog = random().nextBoolean(); + CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(coll, "conf1", 2, 1, isTlog ? 1 : 0, !isTlog ? 1 : 0); create.setMaxShardsPerNode(2); create.setAutoAddReplicas(false); cloudClient.request(create); @@ -126,8 +128,8 @@ public class MoveReplicaTest extends SolrCloudTestCase { } } - int sourceNumCores = getNumOfCores(cloudClient, replica.getNodeName(), coll); - int targetNumCores = getNumOfCores(cloudClient, targetNode, coll); + int sourceNumCores = getNumOfCores(cloudClient, replica.getNodeName(), coll, replica.getType().name()); + int targetNumCores = getNumOfCores(cloudClient, targetNode, coll, replica.getType().name()); CollectionAdminRequest.MoveReplica moveReplica = createMoveReplicaRequest(coll, replica, targetNode); moveReplica.setInPlaceMove(inPlaceMove); @@ -146,8 +148,8 @@ public class MoveReplicaTest extends SolrCloudTestCase { Thread.sleep(500); } assertTrue(success); - assertEquals("should be one less core on the source node!", sourceNumCores - 1, getNumOfCores(cloudClient, replica.getNodeName(), coll)); - assertEquals("should be one more core on target node!", targetNumCores + 1, getNumOfCores(cloudClient, targetNode, coll)); + assertEquals("should be one less core on the source node!", sourceNumCores - 1, getNumOfCores(cloudClient, replica.getNodeName(), coll, replica.getType().name())); + assertEquals("should be one more core on target node!", targetNumCores + 1, getNumOfCores(cloudClient, targetNode, coll, replica.getType().name())); // wait for recovery boolean recovered = false; for (int i = 0; i < 300; i++) { @@ -230,6 +232,7 @@ public class MoveReplicaTest extends SolrCloudTestCase { assertEquals(100, cluster.getSolrClient().query(coll, new SolrQuery("*:*")).getResults().getNumFound()); } + //Commented out 5-Dec-2017 // @AwaitsFix(bugUrl = "https://issues.apache.org/jira/browse/SOLR-11458") @Test @@ -242,7 +245,9 @@ public class MoveReplicaTest extends SolrCloudTestCase { CloudSolrClient cloudClient = cluster.getSolrClient(); - CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(coll, "conf1", 2, REPLICATION); + // random create tlog or pull type replicas with nrt + boolean isTlog = random().nextBoolean(); + CollectionAdminRequest.Create create = CollectionAdminRequest.createCollection(coll, "conf1", 2, 1, isTlog ? 1 : 0, !isTlog ? 1 : 0); create.setAutoAddReplicas(false); cloudClient.request(create); @@ -315,28 +320,40 @@ public class MoveReplicaTest extends SolrCloudTestCase { } private void checkNumOfCores(CloudSolrClient cloudClient, String nodeName, String collectionName, int expectedCores) throws IOException, SolrServerException { - assertEquals(nodeName + " does not have expected number of cores",expectedCores, getNumOfCores(cloudClient, nodeName, collectionName)); + assertEquals(nodeName + " does not have expected number of cores", expectedCores, getNumOfCores(cloudClient, nodeName, collectionName)); } private int getNumOfCores(CloudSolrClient cloudClient, String nodeName, String collectionName) throws IOException, SolrServerException { + return getNumOfCores(cloudClient, nodeName, collectionName, null); + } + + private int getNumOfCores(CloudSolrClient cloudClient, String nodeName, String collectionName, String replicaType) throws IOException, SolrServerException { try (HttpSolrClient coreclient = getHttpSolrClient(cloudClient.getZkStateReader().getBaseUrlForNodeName(nodeName))) { CoreAdminResponse status = CoreAdminRequest.getStatus(null, coreclient); if (status.getCoreStatus().size() == 0) { return 0; } - // filter size by collection name - if (collectionName == null) { + if (collectionName == null && replicaType == null) { return status.getCoreStatus().size(); - } else { - int size = 0; - for (Map.Entry> stringNamedListEntry : status.getCoreStatus()) { + } + // filter size by collection name + int size = 0; + for (Map.Entry> stringNamedListEntry : status.getCoreStatus()) { + if (collectionName != null) { String coll = (String) stringNamedListEntry.getValue().findRecursive("cloud", "collection"); - if (collectionName.equals(coll)) { - size++; + if (!collectionName.equals(coll)) { + continue; } } - return size; + if (replicaType != null) { + String type = (String) stringNamedListEntry.getValue().findRecursive("cloud", "replicaType"); + if (!replicaType.equals(type)) { + continue; + } + } + size++; } + return size; } }