You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2013/10/23 12:27:20 UTC
svn commit: r1534975 - in /lucene/dev/branches/branch_4x: ./ solr/
solr/core/ solr/core/src/java/org/apache/solr/cloud/
solr/core/src/test/org/apache/solr/cloud/ solr/solrj/
solr/solrj/src/java/org/apache/solr/common/cloud/
Author: shalin
Date: Wed Oct 23 10:27:19 2013
New Revision: 1534975
URL: http://svn.apache.org/r1534975
Log:
SOLR-5300: Check that the supplied hash ranges actually cover the entire range of the shard
Modified:
lucene/dev/branches/branch_4x/ (props changed)
lucene/dev/branches/branch_4x/solr/ (props changed)
lucene/dev/branches/branch_4x/solr/core/ (props changed)
lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java
lucene/dev/branches/branch_4x/solr/solrj/ (props changed)
lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java
Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java?rev=1534975&r1=1534974&r2=1534975&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionProcessor.java Wed Oct 23 10:27:19 2013
@@ -552,6 +552,19 @@ public class OverseerCollectionProcessor
"Specified hash range: " + r + " is not a subset of parent shard's range: " + range.toString());
}
}
+ List<DocRouter.Range> temp = new ArrayList<DocRouter.Range>(subRanges); // copy to preserve original order
+ Collections.sort(temp);
+ if (!range.equals(new DocRouter.Range(temp.get(0).min, temp.get(temp.size() - 1).max))) {
+ throw new SolrException(ErrorCode.BAD_REQUEST,
+ "Specified hash ranges: " + rangesStr + " do not cover the entire range of parent shard: " + range);
+ }
+ for (int i = 1; i < temp.size(); i++) {
+ if (temp.get(i - 1).max + 1 != temp.get(i).min) {
+ throw new SolrException(ErrorCode.BAD_REQUEST,
+ "Specified hash ranges: " + rangesStr + " either overlap with each other or " +
+ "do not cover the entire range of parent shard: " + range);
+ }
+ }
}
} else if (splitKey != null) {
if (router instanceof CompositeIdRouter) {
Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java?rev=1534975&r1=1534974&r2=1534975&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/cloud/ShardSplitTest.java Wed Oct 23 10:27:19 2013
@@ -109,6 +109,7 @@ public class ShardSplitTest extends Basi
public void doTest() throws Exception {
waitForThingsToLevelOut(15);
+ incompleteOrOverlappingCustomRangeTest();
splitByUniqueKeyTest();
splitByRouteFieldTest();
splitByRouteKeyTest();
@@ -120,6 +121,50 @@ public class ShardSplitTest extends Basi
}
+ private void incompleteOrOverlappingCustomRangeTest() throws Exception {
+ ClusterState clusterState = cloudClient.getZkStateReader().getClusterState();
+ final DocRouter router = clusterState.getCollection(AbstractDistribZkTestBase.DEFAULT_COLLECTION).getRouter();
+ Slice shard1 = clusterState.getSlice(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD1);
+ DocRouter.Range shard1Range = shard1.getRange() != null ? shard1.getRange() : router.fullRange();
+
+ List<DocRouter.Range> subRanges = new ArrayList<DocRouter.Range>();
+ List<DocRouter.Range> ranges = router.partitionRange(4, shard1Range);
+
+ // test with only one range
+ subRanges.add(ranges.get(0));
+ try {
+ splitShard(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD1, subRanges, null);
+ fail("Shard splitting with just one custom hash range should not succeed");
+ } catch (HttpSolrServer.RemoteSolrException e) {
+ log.info("Expected exception:", e);
+ }
+ subRanges.clear();
+
+ // test with ranges with a hole in between them
+ subRanges.add(ranges.get(3)); // order shouldn't matter
+ subRanges.add(ranges.get(0));
+ try {
+ splitShard(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD1, subRanges, null);
+ fail("Shard splitting with missing hashes in between given ranges should not succeed");
+ } catch (HttpSolrServer.RemoteSolrException e) {
+ log.info("Expected exception:", e);
+ }
+ subRanges.clear();
+
+ // test with overlapping ranges
+ subRanges.add(ranges.get(0));
+ subRanges.add(ranges.get(1));
+ subRanges.add(ranges.get(2));
+ subRanges.add(new DocRouter.Range(ranges.get(3).min - 15, ranges.get(3).max));
+ try {
+ splitShard(AbstractDistribZkTestBase.DEFAULT_COLLECTION, SHARD1, subRanges, null);
+ fail("Shard splitting with overlapping ranges should not succeed");
+ } catch (HttpSolrServer.RemoteSolrException e) {
+ log.info("Expected exception:", e);
+ }
+ subRanges.clear();
+ }
+
private void splitByUniqueKeyTest() throws Exception {
ClusterState clusterState = cloudClient.getZkStateReader().getClusterState();
final DocRouter router = clusterState.getCollection(AbstractDistribZkTestBase.DEFAULT_COLLECTION).getRouter();
Modified: lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java?rev=1534975&r1=1534974&r2=1534975&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java (original)
+++ lucene/dev/branches/branch_4x/solr/solrj/src/java/org/apache/solr/common/cloud/DocRouter.java Wed Oct 23 10:27:19 2013
@@ -95,7 +95,7 @@ public abstract class DocRouter {
// Hash ranges can't currently "wrap" - i.e. max must be greater or equal to min.
// TODO: ranges may not be all contiguous in the future (either that or we will
// need an extra class to model a collection of ranges)
- public static class Range implements JSONWriter.Writable {
+ public static class Range implements JSONWriter.Writable, Comparable<Range> {
public int min; // inclusive
public int max; // inclusive
@@ -141,6 +141,12 @@ public abstract class DocRouter {
public void write(JSONWriter writer) {
writer.write(toString());
}
+
+ @Override
+ public int compareTo(Range that) {
+ int mincomp = Integer.valueOf(this.min).compareTo(that.min);
+ return mincomp == 0 ? Integer.valueOf(this.max).compareTo(that.max) : mincomp;
+ }
}
public Range fromString(String range) {