Jelajahi Sumber

Merge pull request #12430 from ruflin/ip_range-mask-fix

Fix cidr mask conversion issue for 0.0.0.0/0 and add tests #12005
Adrien Grand 10 tahun lalu
induk
melakukan
ec79568e6f

+ 5 - 0
core/src/main/java/org/elasticsearch/search/aggregations/bucket/range/ipv4/IPv4RangeBuilder.java

@@ -139,6 +139,10 @@ public class IPv4RangeBuilder extends AbstractRangeBuilder<IPv4RangeBuilder> {
 
         int mask = (-1) << (32 - Integer.parseInt(parts[4]));
 
+        if (Integer.parseInt(parts[4]) == 0) {
+            mask = 0 << 32;
+        }
+
         int from = addr & mask;
         long longFrom = intIpToLongIp(from);
         if (longFrom == 0) {
@@ -147,6 +151,7 @@ public class IPv4RangeBuilder extends AbstractRangeBuilder<IPv4RangeBuilder> {
 
         int to = from + (~mask);
         long longTo = intIpToLongIp(to) + 1; // we have to +1 here as the range is non-inclusive on the "to" side
+
         if (longTo == InternalIPv4Range.MAX_IP) {
             longTo = -1;
         }

+ 74 - 0
core/src/test/java/org/elasticsearch/search/aggregations/bucket/IPv4RangeTests.java

@@ -83,6 +83,33 @@ public class IPv4RangeTests extends ElasticsearchIntegrationTest {
             }
             indexRandom(true, builders.toArray(new IndexRequestBuilder[builders.size()]));
         }
+        {
+            assertAcked(prepareCreate("range_idx")
+                    .addMapping("type", "ip", "type=ip", "ips", "type=ip"));
+            IndexRequestBuilder[] builders = new IndexRequestBuilder[4];
+
+            builders[0] = client().prepareIndex("range_idx", "type").setSource(jsonBuilder()
+                    .startObject()
+                    .field("ip", "0.0.0.0")
+                    .endObject());
+
+            builders[1] = client().prepareIndex("range_idx", "type").setSource(jsonBuilder()
+                    .startObject()
+                    .field("ip", "0.0.0.255")
+                    .endObject());
+
+            builders[2] = client().prepareIndex("range_idx", "type").setSource(jsonBuilder()
+                    .startObject()
+                    .field("ip", "255.255.255.0")
+                    .endObject());
+
+            builders[3] = client().prepareIndex("range_idx", "type").setSource(jsonBuilder()
+                    .startObject()
+                    .field("ip", "255.255.255.255")
+                    .endObject());
+
+            indexRandom(true, builders);
+        }
         ensureSearchable();
     }
 
@@ -869,4 +896,51 @@ public class IPv4RangeTests extends ElasticsearchIntegrationTest {
         assertThat(buckets.get(0).getToAsString(), equalTo("10.0.0.10"));
         assertThat(buckets.get(0).getDocCount(), equalTo(0l));
     }
+
+    @Test
+    public void mask0() {
+        SearchResponse response = client().prepareSearch("idx")
+                .addAggregation(ipRange("range")
+                        .field("ip")
+                        .addMaskRange("0.0.0.0/0"))
+                .execute().actionGet();
+
+        assertSearchResponse(response);
+
+        Range range = response.getAggregations().get("range");
+        assertThat(range, notNullValue());
+        assertThat(range.getName(), equalTo("range"));
+        List<? extends Bucket> buckets = range.getBuckets();
+        assertThat(range.getBuckets().size(), equalTo(1));
+
+        Range.Bucket bucket = buckets.get(0);
+        assertThat((String) bucket.getKey(), equalTo("0.0.0.0/0"));
+        assertThat(bucket.getFromAsString(), nullValue());
+        assertThat(bucket.getToAsString(), nullValue());
+        assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
+        assertEquals(255l, bucket.getDocCount());
+    }
+
+
+    @Test
+    public void mask0SpecialIps() {
+
+        SearchResponse response = client().prepareSearch("range_idx")
+                .addAggregation(ipRange("range")
+                        .field("ip")
+                        .addMaskRange("0.0.0.0/0"))
+                .execute().actionGet();
+
+        assertSearchResponse(response);
+
+        Range range = response.getAggregations().get("range");
+
+        assertThat(range, notNullValue());
+        assertThat(range.getName(), equalTo("range"));
+        List<? extends Bucket> buckets = range.getBuckets();
+        assertThat(range.getBuckets().size(), equalTo(1));
+
+        Range.Bucket bucket = buckets.get(0);
+        assertEquals(4l, bucket.getDocCount());
+    }
 }