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) {