diff --git a/core/src/main/java/org/elasticsearch/ingest/processor/DateFormat.java b/core/src/main/java/org/elasticsearch/ingest/processor/DateFormat.java index 5748d3788ab..282b29176bf 100644 --- a/core/src/main/java/org/elasticsearch/ingest/processor/DateFormat.java +++ b/core/src/main/java/org/elasticsearch/ingest/processor/DateFormat.java @@ -25,36 +25,30 @@ import org.joda.time.format.DateTimeFormat; import org.joda.time.format.ISODateTimeFormat; import java.util.Locale; -import java.util.Optional; import java.util.function.Function; enum DateFormat { Iso8601 { @Override - Function getFunction(DateTimeZone timezone) { + Function getFunction(String format, DateTimeZone timezone, Locale locale) { return ISODateTimeFormat.dateTimeParser().withZone(timezone)::parseDateTime; } }, Unix { @Override - Function getFunction(DateTimeZone timezone) { + Function getFunction(String format, DateTimeZone timezone, Locale locale) { return (date) -> new DateTime((long)(Float.parseFloat(date) * 1000), timezone); } }, UnixMs { @Override - Function getFunction(DateTimeZone timezone) { + Function getFunction(String format, DateTimeZone timezone, Locale locale) { return (date) -> new DateTime(Long.parseLong(date), timezone); } - - @Override - public String toString() { - return "UNIX_MS"; - } }, Tai64n { @Override - Function getFunction(DateTimeZone timezone) { + Function getFunction(String format, DateTimeZone timezone, Locale locale) { return (date) -> new DateTime(parseMillis(date), timezone); } @@ -67,33 +61,30 @@ enum DateFormat { long rest = Long.parseLong(date.substring(16, 24), 16); return ((base * 1000) - 10000) + (rest/1000000); } - }; - - abstract Function getFunction(DateTimeZone timezone); - - static Optional fromString(String format) { - switch (format) { - case "ISO8601": - return Optional.of(Iso8601); - case "UNIX": - return Optional.of(Unix); - case "UNIX_MS": - return Optional.of(UnixMs); - case "TAI64N": - return Optional.of(Tai64n); - default: - return Optional.empty(); - } - } - - static Function getJodaFunction(String matchFormat, DateTimeZone timezone, Locale locale) { - return DateTimeFormat.forPattern(matchFormat) + }, + Joda { + @Override + Function getFunction(String format, DateTimeZone timezone, Locale locale) { + return DateTimeFormat.forPattern(format) .withDefaultYear((new DateTime(DateTimeZone.UTC)).getYear()) .withZone(timezone).withLocale(locale)::parseDateTime; - } + } + }; - @Override - public String toString() { - return name().toUpperCase(Locale.ROOT); + abstract Function getFunction(String format, DateTimeZone timezone, Locale locale); + + static DateFormat fromString(String format) { + switch (format) { + case "ISO8601": + return Iso8601; + case "UNIX": + return Unix; + case "UNIX_MS": + return UnixMs; + case "TAI64N": + return Tai64n; + default: + return Joda; + } } } diff --git a/core/src/main/java/org/elasticsearch/ingest/processor/DateProcessor.java b/core/src/main/java/org/elasticsearch/ingest/processor/DateProcessor.java index 16b7e52b75d..9fc0378d774 100644 --- a/core/src/main/java/org/elasticsearch/ingest/processor/DateProcessor.java +++ b/core/src/main/java/org/elasticsearch/ingest/processor/DateProcessor.java @@ -22,8 +22,8 @@ package org.elasticsearch.ingest.processor; import org.elasticsearch.ExceptionsHelper; import org.elasticsearch.ingest.core.AbstractProcessor; import org.elasticsearch.ingest.core.AbstractProcessorFactory; -import org.elasticsearch.ingest.core.IngestDocument; import org.elasticsearch.ingest.core.ConfigurationUtils; +import org.elasticsearch.ingest.core.IngestDocument; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.format.ISODateTimeFormat; @@ -33,7 +33,6 @@ import java.util.IllformedLocaleException; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Optional; import java.util.function.Function; public final class DateProcessor extends AbstractProcessor { @@ -57,14 +56,8 @@ public final class DateProcessor extends AbstractProcessor { this.matchFormats = matchFormats; this.dateParsers = new ArrayList<>(); for (String matchFormat : matchFormats) { - Optional dateFormat = DateFormat.fromString(matchFormat); - Function stringToDateFunction; - if (dateFormat.isPresent()) { - stringToDateFunction = dateFormat.get().getFunction(timezone); - } else { - stringToDateFunction = DateFormat.getJodaFunction(matchFormat, timezone, locale); - } - dateParsers.add(stringToDateFunction); + DateFormat dateFormat = DateFormat.fromString(matchFormat); + dateParsers.add(dateFormat.getFunction(matchFormat, timezone, locale)); } } diff --git a/core/src/test/java/org/elasticsearch/ingest/processor/DateFormatTests.java b/core/src/test/java/org/elasticsearch/ingest/processor/DateFormatTests.java index c53b420b244..401dd44d44a 100644 --- a/core/src/test/java/org/elasticsearch/ingest/processor/DateFormatTests.java +++ b/core/src/test/java/org/elasticsearch/ingest/processor/DateFormatTests.java @@ -19,7 +19,6 @@ package org.elasticsearch.ingest.processor; -import org.elasticsearch.ingest.processor.DateFormat; import org.elasticsearch.test.ESTestCase; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -28,7 +27,6 @@ import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Locale; -import java.util.Optional; import java.util.function.Function; import static org.hamcrest.core.IsEqual.equalTo; @@ -36,7 +34,7 @@ import static org.hamcrest.core.IsEqual.equalTo; public class DateFormatTests extends ESTestCase { public void testParseJoda() { - Function jodaFunction = DateFormat.getJodaFunction("MMM dd HH:mm:ss Z", DateTimeZone.forOffsetHours(-8), Locale.ENGLISH); + Function jodaFunction = DateFormat.Joda.getFunction("MMM dd HH:mm:ss Z", DateTimeZone.forOffsetHours(-8), Locale.ENGLISH); assertThat(Instant.ofEpochMilli(jodaFunction.apply("Nov 24 01:29:01 -0800").getMillis()) .atZone(ZoneId.of("GMT-8")) .format(DateTimeFormatter.ofPattern("MM dd HH:mm:ss", Locale.ENGLISH)), @@ -44,19 +42,19 @@ public class DateFormatTests extends ESTestCase { } public void testParseUnixMs() { - assertThat(DateFormat.UnixMs.getFunction(DateTimeZone.UTC).apply("1000500").getMillis(), equalTo(1000500L)); + assertThat(DateFormat.UnixMs.getFunction(null, DateTimeZone.UTC, null).apply("1000500").getMillis(), equalTo(1000500L)); } public void testParseUnix() { - assertThat(DateFormat.Unix.getFunction(DateTimeZone.UTC).apply("1000.5").getMillis(), equalTo(1000500L)); + assertThat(DateFormat.Unix.getFunction(null, DateTimeZone.UTC, null).apply("1000.5").getMillis(), equalTo(1000500L)); } public void testParseISO8601() { - assertThat(DateFormat.Iso8601.getFunction(DateTimeZone.UTC).apply("2001-01-01T00:00:00-0800").getMillis(), equalTo(978336000000L)); + assertThat(DateFormat.Iso8601.getFunction(null, DateTimeZone.UTC, null).apply("2001-01-01T00:00:00-0800").getMillis(), equalTo(978336000000L)); } public void testParseISO8601Failure() { - Function function = DateFormat.Iso8601.getFunction(DateTimeZone.UTC); + Function function = DateFormat.Iso8601.getFunction(null, DateTimeZone.UTC, null); try { function.apply("2001-01-0:00-0800"); fail("parse should have failed"); @@ -68,18 +66,18 @@ public class DateFormatTests extends ESTestCase { public void testTAI64NParse() { String input = "4000000050d506482dbdf024"; String expected = "2012-12-22T03:00:46.767+02:00"; - assertThat(DateFormat.Tai64n.getFunction(DateTimeZone.forOffsetHours(2)).apply((randomBoolean() ? "@" : "") + input).toString(), equalTo(expected)); + assertThat(DateFormat.Tai64n.getFunction(null, DateTimeZone.forOffsetHours(2), null).apply((randomBoolean() ? "@" : "") + input).toString(), equalTo(expected)); } public void testFromString() { - assertThat(DateFormat.fromString("UNIX_MS"), equalTo(Optional.of(DateFormat.UnixMs))); - assertThat(DateFormat.fromString("unix_ms"), equalTo(Optional.empty())); - assertThat(DateFormat.fromString("UNIX"), equalTo(Optional.of(DateFormat.Unix))); - assertThat(DateFormat.fromString("unix"), equalTo(Optional.empty())); - assertThat(DateFormat.fromString("ISO8601"), equalTo(Optional.of(DateFormat.Iso8601))); - assertThat(DateFormat.fromString("iso8601"), equalTo(Optional.empty())); - assertThat(DateFormat.fromString("TAI64N"), equalTo(Optional.of(DateFormat.Tai64n))); - assertThat(DateFormat.fromString("tai64n"), equalTo(Optional.empty())); - assertThat(DateFormat.fromString("prefix-" + randomAsciiOfLengthBetween(1, 10)), equalTo(Optional.empty())); + assertThat(DateFormat.fromString("UNIX_MS"), equalTo(DateFormat.UnixMs)); + assertThat(DateFormat.fromString("unix_ms"), equalTo(DateFormat.Joda)); + assertThat(DateFormat.fromString("UNIX"), equalTo(DateFormat.Unix)); + assertThat(DateFormat.fromString("unix"), equalTo(DateFormat.Joda)); + assertThat(DateFormat.fromString("ISO8601"), equalTo(DateFormat.Iso8601)); + assertThat(DateFormat.fromString("iso8601"), equalTo(DateFormat.Joda)); + assertThat(DateFormat.fromString("TAI64N"), equalTo(DateFormat.Tai64n)); + assertThat(DateFormat.fromString("tai64n"), equalTo(DateFormat.Joda)); + assertThat(DateFormat.fromString("prefix-" + randomAsciiOfLengthBetween(1, 10)), equalTo(DateFormat.Joda)); } } diff --git a/core/src/test/java/org/elasticsearch/ingest/processor/DateProcessorTests.java b/core/src/test/java/org/elasticsearch/ingest/processor/DateProcessorTests.java index ff108e61bfc..5daab95a5d0 100644 --- a/core/src/test/java/org/elasticsearch/ingest/processor/DateProcessorTests.java +++ b/core/src/test/java/org/elasticsearch/ingest/processor/DateProcessorTests.java @@ -84,6 +84,16 @@ public class DateProcessorTests extends ESTestCase { } } + public void testInvalidJodaPattern() { + try { + new DateProcessor(randomAsciiOfLength(10), DateTimeZone.UTC, randomLocale(random()), + "date_as_string", Collections.singletonList("invalid pattern"), "date_as_date"); + fail("date processor initialization should have failed"); + } catch(IllegalArgumentException e) { + assertThat(e.getMessage(), equalTo("Illegal pattern component: i")); + } + } + public void testJodaPatternLocale() { DateProcessor dateProcessor = new DateProcessor(randomAsciiOfLength(10), DateTimeZone.forID("Europe/Amsterdam"), Locale.ITALIAN, "date_as_string", Collections.singletonList("yyyy dd MMM"), "date_as_date"); @@ -106,7 +116,7 @@ public class DateProcessorTests extends ESTestCase { public void testTAI64N() { DateProcessor dateProcessor = new DateProcessor(randomAsciiOfLength(10), DateTimeZone.forOffsetHours(2), randomLocale(random()), - "date_as_string", Collections.singletonList(DateFormat.Tai64n.toString()), "date_as_date"); + "date_as_string", Collections.singletonList("TAI64N"), "date_as_date"); Map document = new HashMap<>(); String dateAsString = (randomBoolean() ? "@" : "") + "4000000050d506482dbdf024"; document.put("date_as_string", dateAsString); @@ -117,7 +127,7 @@ public class DateProcessorTests extends ESTestCase { public void testUnixMs() { DateProcessor dateProcessor = new DateProcessor(randomAsciiOfLength(10), DateTimeZone.UTC, randomLocale(random()), - "date_as_string", Collections.singletonList(DateFormat.UnixMs.toString()), "date_as_date"); + "date_as_string", Collections.singletonList("UNIX_MS"), "date_as_date"); Map document = new HashMap<>(); document.put("date_as_string", "1000500"); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); @@ -127,7 +137,7 @@ public class DateProcessorTests extends ESTestCase { public void testUnix() { DateProcessor dateProcessor = new DateProcessor(randomAsciiOfLength(10), DateTimeZone.UTC, randomLocale(random()), - "date_as_string", Collections.singletonList(DateFormat.Unix.toString()), "date_as_date"); + "date_as_string", Collections.singletonList("UNIX"), "date_as_date"); Map document = new HashMap<>(); document.put("date_as_string", "1000.5"); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document);