You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2019/06/11 10:14:02 UTC
[lucene-solr] branch master updated: Improve the test by actually
checking that the version of Aliases is more recent,
instead of simply waiting.
This is an automated email from the ASF dual-hosted git repository.
ab pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git
The following commit(s) were added to refs/heads/master by this push:
new 6527e74 Improve the test by actually checking that the version of Aliases is more recent, instead of simply waiting.
6527e74 is described below
commit 6527e74ed8742ef2acbc1bcfaf1ef1a82ae0f4f9
Author: Andrzej Bialecki <ab...@apache.org>
AuthorDate: Tue Jun 11 12:13:22 2019 +0200
Improve the test by actually checking that the version of Aliases is
more recent, instead of simply waiting.
---
.../apache/solr/cloud/AliasIntegrationTest.java | 80 +++++++++++++++-------
.../apache/solr/common/cloud/ZkStateReader.java | 1 +
2 files changed, 55 insertions(+), 26 deletions(-)
diff --git a/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java b/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java
index a64ed7a..c0d63ba 100644
--- a/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/AliasIntegrationTest.java
@@ -19,6 +19,7 @@ package org.apache.solr.cloud;
import java.io.IOException;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
@@ -51,7 +52,9 @@ import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.common.params.CollectionAdminParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.TimeSource;
import org.apache.solr.common.util.Utils;
+import org.apache.solr.util.TimeOut;
import org.apache.zookeeper.KeeperException;
import org.junit.After;
import org.junit.Before;
@@ -275,7 +278,14 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
@Test
public void testClusterStateProviderAPI() throws Exception {
final String aliasName = getSaferTestName();
- ZkStateReader zkStateReader = createColectionsAndAlias(aliasName);
+ ZkStateReader zkStateReader = cluster.getSolrClient().getZkStateReader();
+ Aliases aliases = zkStateReader.getAliases();
+ int lastVersion = aliases.getZNodeVersion();
+
+ createColectionsAndAlias(aliasName);
+
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
+
CollectionAdminRequest.SetAliasProperty setAliasProperty = CollectionAdminRequest.setAliasProperty(aliasName);
setAliasProperty.addProperty("foo","baz");
setAliasProperty.addProperty("bar","bam");
@@ -283,7 +293,7 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
checkFooAndBarMeta(aliasName, zkStateReader);
SolrCloudManager cloudManager = cluster.getJettySolrRunner(0).getCoreContainer().getZkController().getSolrCloudManager();
// make sure we have the latest version in cache
- zkStateReader.aliasesManager.update();
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
ClusterStateProvider stateProvider = cloudManager.getClusterStateProvider();
List<String> collections = stateProvider.resolveAlias(aliasName);
assertEquals(collections.toString(), 2, collections.size());
@@ -300,7 +310,7 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
setAliasProperty.addProperty(CollectionAdminParams.ROUTER_PREFIX + "foo","baz");
setAliasProperty.process(cluster.getSolrClient());
// refresh
- zkStateReader.aliasesManager.update();
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
stateProvider = cloudManager.getClusterStateProvider();
assertTrue("should be a routed alias", stateProvider.isRoutedAlias(aliasName));
@@ -312,6 +322,24 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
}
}
+ private int waitForAliasesUpdate(int lastVersion, ZkStateReader zkStateReader) throws Exception {
+ TimeOut timeOut = new TimeOut(30, TimeUnit.SECONDS, TimeSource.NANO_TIME);
+ while (!timeOut.hasTimedOut()) {
+ zkStateReader.aliasesManager.update();
+ Aliases aliases = zkStateReader.getAliases();
+ if (aliases.getZNodeVersion() > lastVersion) {
+ return aliases.getZNodeVersion();
+ } else if (aliases.getZNodeVersion() < lastVersion) {
+ fail("unexpected znode version, expected greater than " + lastVersion + " but was " + aliases.getZNodeVersion());
+ }
+ timeOut.sleep(1000);
+ }
+ if (timeOut.hasTimedOut()) {
+ fail("timed out waiting for aliases to update");
+ }
+ return -1;
+ }
+
private void checkFooAndBarMeta(String aliasName, ZkStateReader zkStateReader) throws Exception {
zkStateReader.aliasesManager.update(); // ensure our view is up to date
Map<String, String> meta = zkStateReader.getAliases().getCollectionAliasProperties(aliasName);
@@ -397,11 +425,15 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
QueryResponse res = cluster.getSolrClient().query("collection_old", new SolrQuery("*:*"));
assertEquals(3, res.getResults().getNumFound());
+ ZkStateReader zkStateReader = cluster.getSolrClient().getZkStateReader();
+ int lastVersion = zkStateReader.aliasesManager.getAliases().getZNodeVersion();
// Let's insure we have a "handle" to the old collection
CollectionAdminRequest.createAlias("collection_old_reserve", "collection_old").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
// This is the critical bit. The alias uses the _old collection name.
CollectionAdminRequest.createAlias("collection_old", "collection_new").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
// aliases: collection_old->collection_new, collection_old_reserve -> collection_old -> collection_new
// collections: collection_new and collection_old
@@ -433,7 +465,9 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
// Clean up
CollectionAdminRequest.deleteAlias("collection_old_reserve").processAndWait(cluster.getSolrClient(), 60);
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
CollectionAdminRequest.deleteAlias("collection_old").processAndWait(cluster.getSolrClient(), 60);
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
CollectionAdminRequest.deleteCollection("collection_new").processAndWait(cluster.getSolrClient(), 60);
CollectionAdminRequest.deleteCollection("collection_old").processAndWait(cluster.getSolrClient(), 60);
// collection_old already deleted as well as collection_old_reserve
@@ -471,8 +505,12 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
.add("id", "11", "a_t", "humpty dumpy sat on a low wall")
.commit(cluster.getSolrClient(), "collection_two");
+ ZkStateReader zkStateReader = cluster.getSolrClient().getZkStateReader();
+ int lastVersion = zkStateReader.aliasesManager.getAliases().getZNodeVersion();
+
// Create an alias pointing to both
CollectionAdminRequest.createAlias("collection_alias_pair", "collection_one,collection_two").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
QueryResponse res = cluster.getSolrClient().query("collection_alias_pair", new SolrQuery("*:*"));
assertEquals(3, res.getResults().getNumFound());
@@ -484,6 +522,7 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
// Now redefine the alias to only point to colletion two
CollectionAdminRequest.createAlias("collection_alias_pair", "collection_two").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
//Delete collection_one.
delResp = CollectionAdminRequest.deleteCollection("collection_one").processAndWait(cluster.getSolrClient(), 60);
@@ -507,6 +546,7 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
CollectionAdminRequest.deleteAlias("collection_alias_pair").processAndWait(cluster.getSolrClient(), 60);
CollectionAdminRequest.deleteCollection("collection_two").processAndWait(cluster.getSolrClient(), 60);
// collection_one already deleted
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
assertNull("collection_alias_pair should be gone",
cluster.getSolrClient().getZkStateReader().getAliases().getCollectionAliasMap().get("collection_alias_pair"));
@@ -544,12 +584,15 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
///////////////
// make sure there's only one level of alias
+ ZkStateReader zkStateReader = cluster.getSolrClient().getZkStateReader();
+ int lastVersion = zkStateReader.aliasesManager.getAliases().getZNodeVersion();
+
CollectionAdminRequest.deleteAlias("collection1").process(cluster.getSolrClient());
CollectionAdminRequest.createAlias("testalias1", "collection1").process(cluster.getSolrClient());
// verify proper resolution on the server-side
- ZkStateReader zkStateReader = cluster.getSolrClient().getZkStateReader();
- zkStateReader.aliasesManager.update();
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
+
Aliases aliases = zkStateReader.getAliases();
List<String> collections = aliases.resolveAliases("testalias1");
assertEquals(collections.toString(), 1, collections.size());
@@ -569,27 +612,29 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
// test alias pointing to two collections. collection2 first because it's not on every node
CollectionAdminRequest.createAlias("testalias2", "collection2,collection1").process(cluster.getSolrClient());
- Thread.sleep(100);
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
searchSeveralWays("testalias2", new SolrQuery("*:*"), 5);
///////////////
// update alias
CollectionAdminRequest.createAlias("testalias2", "collection2").process(cluster.getSolrClient());
- sleepToAllowZkPropagation();
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
searchSeveralWays("testalias2", new SolrQuery("*:*"), 2);
///////////////
// alias pointing to alias. One level of indirection is supported; more than that is not (may or may not work)
- // TODO dubious; remove?
CollectionAdminRequest.createAlias("testalias3", "testalias2").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
searchSeveralWays("testalias3", new SolrQuery("*:*"), 2);
///////////////
// Test 2 aliases pointing to the same collection
CollectionAdminRequest.createAlias("testalias4", "collection2").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
CollectionAdminRequest.createAlias("testalias5", "collection2").process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
// add one document to testalias4, thus to collection2
new UpdateRequest()
@@ -622,8 +667,8 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
///////////////
for (int i = 1; i <= 6 ; i++) {
CollectionAdminRequest.deleteAlias("testalias" + i).process(cluster.getSolrClient());
+ lastVersion = waitForAliasesUpdate(lastVersion, zkStateReader);
}
- sleepToAllowZkPropagation();
SolrException e = expectThrows(SolrException.class, () -> {
SolrQuery q = new SolrQuery("*:*");
@@ -633,23 +678,6 @@ public class AliasIntegrationTest extends SolrCloudTestCase {
assertTrue("Unexpected exception message: " + e.getMessage(), e.getMessage().contains("Collection not found: testalias1"));
}
- /**
- * Sleep a bit to allow Zookeeper state propagation.
- *
- * Solr's view of the cluster is eventually consistent. *Eventually* all nodes and CloudSolrClients will be aware of
- * alias changes, but not immediately. If a newly created alias is queried, things should work right away since Solr
- * will attempt to see if it needs to get the latest aliases when it can't otherwise resolve the name. However
- * modifications to an alias will take some time.
- */
- private void sleepToAllowZkPropagation() {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(e);
- }
- }
-
private void searchSeveralWays(String collectionList, SolrParams solrQuery, int expectedNumFound) throws IOException, SolrServerException {
searchSeveralWays(collectionList, solrQuery, res -> assertEquals(expectedNumFound, res.getResults().getNumFound()));
}
diff --git a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
index cf914e4..f00cdff 100644
--- a/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
+++ b/solr/solrj/src/java/org/apache/solr/common/cloud/ZkStateReader.java
@@ -1950,6 +1950,7 @@ public class ZkStateReader implements SolrCloseable {
* Update the internal aliases reference with a new one, provided that its ZK version has increased.
*
* @param newAliases the potentially newer version of Aliases
+ * @return true if aliases have been updated to a new version, false otherwise
*/
private boolean setIfNewer(Aliases newAliases) {
assert newAliases.getZNodeVersion() >= 0;