Skip to content

Commit f2d259b

Browse files
committed
Standardize IP fields.
1 parent f1ac140 commit f2d259b

File tree

7 files changed

+69
-19
lines changed

7 files changed

+69
-19
lines changed

server/src/main/java/org/elasticsearch/common/network/InetAddresses.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,17 @@ public static Tuple<InetAddress, Integer> parseCidr(String maskedAddress) {
384384
throw new IllegalArgumentException("Expected [ip/prefix] but was [" + maskedAddress + "]");
385385
}
386386
}
387+
388+
/**
389+
* Given an address and prefix length, returns the string representation of the range in CIDR notation.
390+
*
391+
* See {@link #toAddrString} for details on how the address is represented.
392+
*/
393+
public static String toCidrString(InetAddress address, int prefixLength) {
394+
return new StringBuilder()
395+
.append(toAddrString(address))
396+
.append("/")
397+
.append(prefixLength)
398+
.toString();
399+
}
387400
}

server/src/main/java/org/elasticsearch/index/mapper/IpFieldMapper.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,8 +398,9 @@ protected void parseCreateField(ParseContext context) throws IOException {
398398
}
399399

400400
@Override
401-
protected Object parseSourceValue(Object value) {
402-
return value;
401+
protected String parseSourceValue(Object value) {
402+
InetAddress address = InetAddresses.forString(value.toString());
403+
return InetAddresses.toAddrString(address);
403404
}
404405

405406
@Override

server/src/main/java/org/elasticsearch/index/mapper/RangeFieldMapper.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,8 @@
5050
import java.io.IOException;
5151
import java.net.InetAddress;
5252
import java.net.UnknownHostException;
53-
import java.time.Instant;
5453
import java.time.ZoneId;
5554
import java.time.ZoneOffset;
56-
import java.time.ZonedDateTime;
5755
import java.util.HashMap;
5856
import java.util.HashSet;
5957
import java.util.Iterator;
@@ -409,22 +407,18 @@ protected void parseCreateField(ParseContext context) throws IOException {
409407
@SuppressWarnings("unchecked")
410408
protected Object parseSourceValue(Object value) {
411409
RangeType rangeType = fieldType().rangeType();
412-
if (rangeType == RangeType.IP) {
413-
return value;
410+
if (!(value instanceof Map)) {
411+
assert rangeType == RangeType.IP;
412+
Tuple<InetAddress, Integer> ipRange = InetAddresses.parseCidr(value.toString());
413+
return InetAddresses.toCidrString(ipRange.v1(), ipRange.v2());
414414
}
415415

416416
Map<String, Object> range = (Map<String, Object>) value;
417417
Map<String, Object> parsedRange = new HashMap<>();
418418
for (Map.Entry<String, Object> entry : range.entrySet()) {
419419
Object parsedValue = rangeType.parseValue(entry.getValue(), coerce.value(), fieldType().dateMathParser);
420-
421-
if (rangeType == RangeType.DATE) {
422-
long timestamp = (long) parsedValue;
423-
ZonedDateTime dateTime = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.UTC);
424-
parsedValue = fieldType().dateTimeFormatter().format(dateTime);
425-
}
426-
427-
parsedRange.put(entry.getKey(), parsedValue);
420+
Object formattedValue = rangeType.formatValue(parsedValue, fieldType().dateTimeFormatter);
421+
parsedRange.put(entry.getKey(), formattedValue);
428422
}
429423
return parsedRange;
430424
}

server/src/main/java/org/elasticsearch/index/mapper/RangeType.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,17 @@
3636
import org.elasticsearch.common.Nullable;
3737
import org.elasticsearch.common.geo.ShapeRelation;
3838
import org.elasticsearch.common.network.InetAddresses;
39+
import org.elasticsearch.common.time.DateFormatter;
3940
import org.elasticsearch.common.time.DateMathParser;
4041
import org.elasticsearch.common.xcontent.XContentParser;
4142
import org.elasticsearch.index.query.QueryShardContext;
4243

4344
import java.io.IOException;
4445
import java.net.InetAddress;
46+
import java.time.Instant;
4547
import java.time.ZoneId;
4648
import java.time.ZoneOffset;
49+
import java.time.ZonedDateTime;
4750
import java.util.ArrayList;
4851
import java.util.Arrays;
4952
import java.util.List;
@@ -69,6 +72,7 @@ public InetAddress parseTo(RangeFieldMapper.RangeFieldType fieldType, XContentPa
6972
InetAddress address = InetAddresses.forString(parser.text());
7073
return included ? address : nextDown(address);
7174
}
75+
7276
@Override
7377
public InetAddress parseValue(Object value, boolean coerce, @Nullable DateMathParser dateMathParser) {
7478
if (value instanceof InetAddress) {
@@ -80,6 +84,12 @@ public InetAddress parseValue(Object value, boolean coerce, @Nullable DateMathPa
8084
return InetAddresses.forString(value.toString());
8185
}
8286
}
87+
88+
@Override
89+
public Object formatValue(Object value, DateFormatter dateFormatter) {
90+
return InetAddresses.toAddrString((InetAddress) value);
91+
}
92+
8393
@Override
8494
public InetAddress minValue() {
8595
return InetAddressPoint.MIN_VALUE;
@@ -191,6 +201,13 @@ public Long parseValue(Object dateStr, boolean coerce, @Nullable DateMathParser
191201
}).toEpochMilli();
192202
}
193203

204+
@Override
205+
public Object formatValue(Object value, DateFormatter dateFormatter) {
206+
long timestamp = (long) value;
207+
ZonedDateTime dateTime = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.UTC);
208+
return dateFormatter.format(dateTime);
209+
}
210+
194211
@Override
195212
public Long minValue() {
196213
return Long.MIN_VALUE;
@@ -609,6 +626,10 @@ public Object parseValue(Object value, boolean coerce, @Nullable DateMathParser
609626
return numberType.parse(value, coerce);
610627
}
611628

629+
public Object formatValue(Object value, DateFormatter formatter) {
630+
return value;
631+
}
632+
612633
/** parses from value. rounds according to included flag */
613634
public Object parseFrom(RangeFieldMapper.RangeFieldType fieldType, XContentParser parser, boolean coerce,
614635
boolean included) throws IOException {

server/src/test/java/org/elasticsearch/index/mapper/IpFieldMapperTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@
2323
import org.apache.lucene.index.DocValuesType;
2424
import org.apache.lucene.index.IndexableField;
2525
import org.apache.lucene.util.BytesRef;
26+
import org.elasticsearch.Version;
27+
import org.elasticsearch.cluster.metadata.IndexMetadata;
2628
import org.elasticsearch.common.Strings;
2729
import org.elasticsearch.common.bytes.BytesReference;
2830
import org.elasticsearch.common.compress.CompressedXContent;
2931
import org.elasticsearch.common.network.InetAddresses;
32+
import org.elasticsearch.common.settings.Settings;
3033
import org.elasticsearch.common.xcontent.ToXContent;
3134
import org.elasticsearch.common.xcontent.XContentBuilder;
3235
import org.elasticsearch.common.xcontent.XContentFactory;
@@ -278,4 +281,14 @@ public void testEmptyName() throws IOException {
278281
);
279282
assertThat(e.getMessage(), containsString("name cannot be empty string"));
280283
}
284+
285+
public void testParseSourceValue() {
286+
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
287+
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
288+
IpFieldMapper mapper = new IpFieldMapper.Builder("field").build(context);
289+
290+
assertEquals("2001:db8::2:1", mapper.parseSourceValue("2001:db8::2:1"));
291+
assertEquals("2001:db8::2:1", mapper.parseSourceValue("2001:db8:0:0:0:0:2:1"));
292+
assertEquals("::1", mapper.parseSourceValue("0:0:0:0:0:0:0:1"));
293+
}
281294
}

server/src/test/java/org/elasticsearch/index/mapper/IpRangeFieldMapperTests.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@
2020

2121
import org.apache.lucene.index.DocValuesType;
2222
import org.apache.lucene.index.IndexableField;
23+
import org.elasticsearch.Version;
24+
import org.elasticsearch.cluster.metadata.IndexMetadata;
2325
import org.elasticsearch.common.Strings;
2426
import org.elasticsearch.common.bytes.BytesReference;
2527
import org.elasticsearch.common.compress.CompressedXContent;
2628
import org.elasticsearch.common.network.InetAddresses;
29+
import org.elasticsearch.common.settings.Settings;
2730
import org.elasticsearch.common.xcontent.XContentBuilder;
2831
import org.elasticsearch.common.xcontent.XContentFactory;
2932
import org.elasticsearch.common.xcontent.XContentType;
@@ -80,4 +83,14 @@ public void testStoreCidr() throws Exception {
8083
assertThat(storedField.stringValue(), containsString(strVal));
8184
}
8285
}
86+
87+
public void testParseSourceValue() {
88+
Settings settings = Settings.builder().put(IndexMetadata.SETTING_VERSION_CREATED, Version.CURRENT.id).build();
89+
Mapper.BuilderContext context = new Mapper.BuilderContext(settings, new ContentPath());
90+
91+
RangeFieldMapper mapper = new RangeFieldMapper.Builder("field", RangeType.IP).build(context);
92+
Map<String, Object> range = Map.of("gte", "2001:db8:0:0:0:0:2:1");
93+
assertEquals(Map.of("gte", "2001:db8::2:1"), mapper.parseSourceValue(range));
94+
assertEquals("2001:db8::2:1/32", mapper.parseSourceValue("2001:db8:0:0:0:0:2:1/32"));
95+
}
8396
}

server/src/test/java/org/elasticsearch/index/mapper/RangeFieldMapperTests.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,11 +492,6 @@ public void testParseSourceValue() {
492492
Map<String, Object> longRange = Map.of("gte", 3.14, "lt", "42.9");
493493
assertEquals(Map.of("gte", 3L, "lt", 42L), longMapper.parseSourceValue(longRange));
494494

495-
RangeFieldMapper ipMapper = new RangeFieldMapper.Builder("field", RangeType.IP).build(context);
496-
Map<String, Object> ipRange = Map.of("gte", "127.0.0.1");
497-
assertEquals(Map.of("gte", "127.0.0.1"), ipMapper.parseSourceValue(ipRange));
498-
assertEquals("2001:db8::/32", ipMapper.parseSourceValue("2001:db8::/32"));
499-
500495
RangeFieldMapper dateMapper = new RangeFieldMapper.Builder("field", RangeType.DATE)
501496
.format("yyyy/MM/dd||epoch_millis")
502497
.build(context);

0 commit comments

Comments
 (0)