Scripting: Rework joda time backcompat (#33486)

This commit switches the joda time backcompat in scripting to use
augmentation over ZonedDateTime. The augmentation methods provide
compatibility with the missing methods between joda's DateTime and
java's ZonedDateTime. Due to getDayOfWeek returning an enum in the java
API, ZonedDateTime is wrapped so that the method can return int like the
joda time does. The java time api version is renamed to
getDayOfWeekEnum, which will be kept through 7.x for compatibility while
users switch back to getDayOfWeek once joda compatibility is removed.
This commit is contained in:
Ryan Ernst 2018-09-16 19:18:00 -07:00 committed by GitHub
parent e5d82c3dea
commit 3046656ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 843 additions and 318 deletions

View File

@ -825,9 +825,6 @@ class BuildPlugin implements Plugin<Project> {
}
}
// TODO: remove this once joda time is removed from scripting in 7.0
systemProperty 'es.scripting.use_java_time', 'true'
// TODO: remove this once ctx isn't added to update script params in 7.0
systemProperty 'es.scripting.update.ctx_in_params', 'false'

View File

@ -55,7 +55,6 @@ integTestCluster {
setting 'reindex.remote.whitelist', '127.0.0.1:*'
// TODO: remove this for 7.0, this exists to allow the doc examples in 6.x to continue using the defaults
systemProperty 'es.scripting.use_java_time', 'false'
systemProperty 'es.scripting.update.ctx_in_params', 'false'
//TODO: remove this once the cname is prepended to the address by default in 7.0
systemProperty 'es.http.cname_in_publish_address', 'true'

View File

@ -220,11 +220,6 @@ GET hockey/_search
}
----------------------------------------------------------------
// CONSOLE
// TEST[warning:The joda time api for doc values is deprecated. Use -Des.scripting.use_java_time=true to use the java time api for date field doc values]
NOTE: Date fields are changing in 7.0 to be exposed as `ZonedDateTime`
from Java 8's time API. To switch to this functionality early,
add `-Des.scripting.use_java_time=true` to `jvm.options`.
[float]
[[modules-scripting-painless-regex]]

View File

@ -416,7 +416,7 @@ POST /sales/_search?size=0
"terms": {
"script": {
"lang": "painless",
"source": "doc['date'].value.dayOfWeek"
"source": "doc['date'].value.dayOfWeekEnum.value"
}
}
}
@ -425,7 +425,6 @@ POST /sales/_search?size=0
--------------------------------------------------
// CONSOLE
// TEST[setup:sales]
// TEST[warning:The joda time api for doc values is deprecated. Use -Des.scripting.use_java_time=true to use the java time api for date field doc values]
Response:

View File

@ -24,7 +24,6 @@ esplugin {
integTestCluster {
module project.project(':modules:mapper-extras')
systemProperty 'es.scripting.use_java_time', 'true'
systemProperty 'es.scripting.update.ctx_in_params', 'false'
systemProperty 'es.http.cname_in_publish_address', 'true'
}

View File

@ -48,8 +48,7 @@ public final class Whitelist {
"java.util.txt",
"java.util.function.txt",
"java.util.regex.txt",
"java.util.stream.txt",
"joda.time.txt"
"java.util.stream.txt"
};
public static final List<Whitelist> BASE_WHITELISTS =

View File

@ -1,60 +0,0 @@
#
# Licensed to Elasticsearch under one or more contributor
# license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#
# Painless definition file. This defines the hierarchy of classes,
# what methods and fields they have, etc.
#
# NOTE: this just minimal whitelisting of joda time, just to provide
# convenient access via the scripting API. classes are fully qualified to avoid
# any confusion with java.time
class org.joda.time.ReadableInstant {
boolean equals(Object)
long getMillis()
int hashCode()
boolean isAfter(org.joda.time.ReadableInstant)
boolean isBefore(org.joda.time.ReadableInstant)
boolean isEqual(org.joda.time.ReadableInstant)
String toString()
}
class org.joda.time.ReadableDateTime {
int getCenturyOfEra()
int getDayOfMonth()
int getDayOfWeek()
int getDayOfYear()
int getEra()
int getHourOfDay()
int getMillisOfDay()
int getMillisOfSecond()
int getMinuteOfDay()
int getMinuteOfHour()
int getMonthOfYear()
int getSecondOfDay()
int getSecondOfMinute()
int getWeekOfWeekyear()
int getWeekyear()
int getYear()
int getYearOfCentury()
int getYearOfEra()
String toString(String)
String toString(String,Locale)
}

View File

@ -76,9 +76,93 @@ class org.elasticsearch.index.fielddata.ScriptDocValues$Longs {
List getValues()
}
class org.elasticsearch.script.JodaCompatibleZonedDateTime {
##### ZonedDateTime methods
int getDayOfMonth()
int getDayOfYear()
int getHour()
LocalDate toLocalDate()
LocalDateTime toLocalDateTime()
int getMinute()
Month getMonth()
int getMonthValue()
int getNano()
int getSecond()
int getYear()
ZonedDateTime minus(TemporalAmount)
ZonedDateTime minus(long,TemporalUnit)
ZonedDateTime minusYears(long)
ZonedDateTime minusMonths(long)
ZonedDateTime minusWeeks(long)
ZonedDateTime minusDays(long)
ZonedDateTime minusHours(long)
ZonedDateTime minusMinutes(long)
ZonedDateTime minusSeconds(long)
ZonedDateTime minusNanos(long)
ZonedDateTime plus(TemporalAmount)
ZonedDateTime plus(long,TemporalUnit)
ZonedDateTime plusDays(long)
ZonedDateTime plusHours(long)
ZonedDateTime plusMinutes(long)
ZonedDateTime plusMonths(long)
ZonedDateTime plusNanos(long)
ZonedDateTime plusSeconds(long)
ZonedDateTime plusWeeks(long)
ZonedDateTime plusYears(long)
Instant toInstant()
OffsetDateTime toOffsetDateTime()
ZonedDateTime truncatedTo(TemporalUnit)
ZonedDateTime with(TemporalAdjuster)
ZonedDateTime with(TemporalField,long)
ZonedDateTime withDayOfMonth(int)
ZonedDateTime withDayOfYear(int)
ZonedDateTime withEarlierOffsetAtOverlap()
ZonedDateTime withFixedOffsetZone()
ZonedDateTime withHour(int)
ZonedDateTime withLaterOffsetAtOverlap()
ZonedDateTime withMinute(int)
ZonedDateTime withMonth(int)
ZonedDateTime withNano(int)
ZonedDateTime withSecond(int)
ZonedDateTime withYear(int)
ZonedDateTime withZoneSameLocal(ZoneId)
ZonedDateTime withZoneSameInstant(ZoneId)
#### Joda methods that exist in java time
boolean equals(Object)
int hashCode()
boolean isAfter(ZonedDateTime)
boolean isBefore(ZonedDateTime)
boolean isEqual(ZonedDateTime)
String toString()
#### Joda time methods
long getMillis()
int getCenturyOfEra()
int getEra()
int getHourOfDay()
int getMillisOfDay()
int getMillisOfSecond()
int getMinuteOfDay()
int getMinuteOfHour()
int getMonthOfYear()
int getSecondOfDay()
int getSecondOfMinute()
int getWeekOfWeekyear()
int getWeekyear()
int getYearOfCentury()
int getYearOfEra()
String toString(String)
String toString(String,Locale)
# conflicting methods
DayOfWeek getDayOfWeekEnum()
int getDayOfWeek()
}
class org.elasticsearch.index.fielddata.ScriptDocValues$Dates {
Object get(int)
Object getValue()
JodaCompatibleZonedDateTime get(int)
JodaCompatibleZonedDateTime getValue()
List getValues()
}

View File

@ -19,10 +19,8 @@
package org.elasticsearch.painless;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.lang.invoke.LambdaConversionException;
import java.time.Instant;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.containsString;
@ -59,15 +57,15 @@ public class FunctionRefTests extends ScriptTestCase {
public void testQualifiedVirtualMethodReference() {
long instant = randomLong();
assertEquals(instant, exec(
"List l = [params.d]; return l.stream().mapToLong(org.joda.time.ReadableDateTime::getMillis).sum()",
singletonMap("d", new DateTime(instant, DateTimeZone.UTC)), true));
"List l = [params.d]; return l.stream().mapToLong(Instant::toEpochMilli).sum()",
singletonMap("d", Instant.ofEpochMilli(instant)), true));
}
public void testQualifiedVirtualMethodReferenceDef() {
long instant = randomLong();
assertEquals(instant, exec(
"def l = [params.d]; return l.stream().mapToLong(org.joda.time.ReadableDateTime::getMillis).sum()",
singletonMap("d", new DateTime(instant, DateTimeZone.UTC)), true));
"def l = [params.d]; return l.stream().mapToLong(Instant::toEpochMilli).sum()",
singletonMap("d", Instant.ofEpochMilli(instant)), true));
}
public void testCtorMethodReference() {
@ -197,10 +195,10 @@ public class FunctionRefTests extends ScriptTestCase {
public void testQualifiedMethodMissing() {
Exception e = expectScriptThrows(IllegalArgumentException.class, () -> {
exec("List l = [2, 1]; l.sort(org.joda.time.ReadableDateTime::bogus); return l.get(0);", false);
exec("List l = [2, 1]; l.sort(java.time.Instant::bogus); return l.get(0);", false);
});
assertThat(e.getMessage(),
containsString("function reference [org.joda.time.ReadableDateTime::bogus/2] matching [java.util.Comparator"));
containsString("function reference [java.time.Instant::bogus/2] matching [java.util.Comparator, compare/2"));
}
public void testClassMissing() {

View File

@ -108,7 +108,7 @@ setup:
script_fields:
bar:
script:
source: "doc.date.value.dayOfWeek.value"
source: "doc.date.value.dayOfWeekEnum.value"
- match: { hits.hits.0.fields.bar.0: 7}
@ -123,7 +123,7 @@ setup:
source: >
StringBuilder b = new StringBuilder();
for (def date : doc.dates) {
b.append(" ").append(date.getDayOfWeek().value);
b.append(" ").append(date.getDayOfWeekEnum().value);
}
return b.toString().trim()

View File

@ -39,6 +39,7 @@ import org.elasticsearch.common.io.stream.Writeable.Writer;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.concurrent.EsRejectedExecutionException;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.ReadableInstant;
@ -680,6 +681,15 @@ public abstract class StreamOutput extends OutputStream {
o.writeString(zonedDateTime.getZone().getId());
o.writeLong(zonedDateTime.toInstant().toEpochMilli());
});
writers.put(JodaCompatibleZonedDateTime.class, (o, v) -> {
// write the joda compatibility datetime as joda datetime
o.writeByte((byte) 13);
final JodaCompatibleZonedDateTime zonedDateTime = (JodaCompatibleZonedDateTime) v;
String zoneId = zonedDateTime.getZonedDateTime().getZone().getId();
// joda does not understand "Z" for utc, so we must special case
o.writeString(zoneId.equals("Z") ? DateTimeZone.UTC.getID() : zoneId);
o.writeLong(zonedDateTime.toInstant().toEpochMilli());
});
WRITERS = Collections.unmodifiableMap(writers);
}

View File

@ -25,6 +25,7 @@ import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.DateFormatters;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Instant;
@ -93,6 +94,7 @@ public class XContentElasticsearchExtension implements XContentBuilderExtension
writers.put(Year.class, (b, v) -> b.value(v.toString()));
writers.put(Duration.class, (b, v) -> b.value(v.toString()));
writers.put(Period.class, (b, v) -> b.value(v.toString()));
writers.put(JodaCompatibleZonedDateTime.class, XContentBuilder::timeValue);
writers.put(BytesReference.class, (b, v) -> {
if (v == null) {
@ -141,6 +143,8 @@ public class XContentElasticsearchExtension implements XContentBuilderExtension
d -> DEFAULT_FORMATTER.format(ZonedDateTime.ofInstant((java.time.Instant) d, ZoneOffset.UTC)));
transformers.put(LocalDate.class, d -> ((LocalDate) d).toString());
transformers.put(LocalTime.class, d -> LOCAL_TIME_FORMATTER.format((LocalTime) d));
transformers.put(JodaCompatibleZonedDateTime.class,
d -> DEFAULT_FORMATTER.format(((JodaCompatibleZonedDateTime) d).getZonedDateTime()));
return transformers;
}
}

View File

@ -28,10 +28,17 @@ import org.elasticsearch.common.lease.Releasable;
public interface AtomicFieldData extends Accountable, Releasable {
/**
* Returns a "scripting" based values.
* Returns field values for use in scripting.
*/
ScriptDocValues<?> getScriptValues();
/**
* Returns field values for use by returned hits.
*/
default ScriptDocValues<?> getLegacyFieldValues() {
return getScriptValues();
}
/**
* Return a String representation of the values.
*/

View File

@ -26,26 +26,17 @@ import org.apache.lucene.util.BytesRefBuilder;
import org.elasticsearch.common.geo.GeoHashUtils;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.joda.time.DateTimeZone;
import org.joda.time.MutableDateTime;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;
import static org.elasticsearch.common.Booleans.parseBoolean;
/**
* Script level doc values, the assumption is that any implementation will
* implement a <code>getValue</code> and a <code>getValues</code> that return
@ -147,55 +138,28 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
}
}
public static final class Dates extends ScriptDocValues<Object> {
/** Whether scripts should expose dates as java time objects instead of joda time. */
private static final boolean USE_JAVA_TIME = parseBoolean(System.getProperty("es.scripting.use_java_time"), false);
private static final DeprecationLogger deprecationLogger = new DeprecationLogger(ESLoggerFactory.getLogger(Dates.class));
public static final class Dates extends ScriptDocValues<JodaCompatibleZonedDateTime> {
private final SortedNumericDocValues in;
/**
* Method call to add deprecation message. Normally this is
* {@link #deprecationLogger} but tests override.
* Values wrapped in {@link java.time.ZonedDateTime} objects.
*/
private final Consumer<String> deprecationCallback;
/**
* Whether java time or joda time should be used. This is normally {@link #USE_JAVA_TIME} but tests override it.
*/
private final boolean useJavaTime;
/**
* Values wrapped in a date time object. The concrete type depends on the system property {@code es.scripting.use_java_time}.
* When that system property is {@code false}, the date time objects are of type {@link MutableDateTime}. When the system
* property is {@code true}, the date time objects are of type {@link java.time.ZonedDateTime}.
*/
private Object[] dates;
private JodaCompatibleZonedDateTime[] dates;
private int count;
/**
* Standard constructor.
*/
public Dates(SortedNumericDocValues in) {
this(in, message -> deprecationLogger.deprecatedAndMaybeLog("scripting_joda_time_deprecation", message), USE_JAVA_TIME);
}
/**
* Constructor for testing with a deprecation callback.
*/
Dates(SortedNumericDocValues in, Consumer<String> deprecationCallback, boolean useJavaTime) {
this.in = in;
this.deprecationCallback = deprecationCallback;
this.useJavaTime = useJavaTime;
}
/**
* Fetch the first field value or 0 millis after epoch if there are no
* in.
*/
public Object getValue() {
public JodaCompatibleZonedDateTime getValue() {
if (count == 0) {
throw new IllegalStateException("A document doesn't have a value for a field! " +
"Use doc[<field>].size()==0 to check if a document is missing a field!");
@ -204,7 +168,7 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
}
@Override
public Object get(int index) {
public JodaCompatibleZonedDateTime get(int index) {
if (index >= count) {
throw new IndexOutOfBoundsException(
"attempted to fetch the [" + index + "] date when there are only ["
@ -235,41 +199,13 @@ public abstract class ScriptDocValues<T> extends AbstractList<T> {
if (count == 0) {
return;
}
if (useJavaTime) {
if (dates == null || count > dates.length) {
// Happens for the document. We delay allocating dates so we can allocate it with a reasonable size.
dates = new ZonedDateTime[count];
}
for (int i = 0; i < count; ++i) {
dates[i] = ZonedDateTime.ofInstant(Instant.ofEpochMilli(in.nextValue()), ZoneOffset.UTC);
}
} else {
deprecated("The joda time api for doc values is deprecated. Use -Des.scripting.use_java_time=true" +
" to use the java time api for date field doc values");
if (dates == null || count > dates.length) {
// Happens for the document. We delay allocating dates so we can allocate it with a reasonable size.
dates = new MutableDateTime[count];
}
for (int i = 0; i < count; i++) {
dates[i] = new MutableDateTime(in.nextValue(), DateTimeZone.UTC);
}
if (dates == null || count > dates.length) {
// Happens for the document. We delay allocating dates so we can allocate it with a reasonable size.
dates = new JodaCompatibleZonedDateTime[count];
}
for (int i = 0; i < count; ++i) {
dates[i] = new JodaCompatibleZonedDateTime(Instant.ofEpochMilli(in.nextValue()), ZoneOffset.UTC);
}
}
/**
* Log a deprecation log, with the server's permissions, not the permissions of the
* script calling this method. We need to do this to prevent errors when rolling
* the log file.
*/
private void deprecated(String message) {
// Intentionally not calling SpecialPermission.check because this is supposed to be called by scripts
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
deprecationCallback.accept(message);
return null;
}
});
}
}

View File

@ -25,6 +25,11 @@ import org.elasticsearch.index.fielddata.IndexNumericFieldData.NumericType;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.index.fielddata.SortedBinaryDocValues;
import org.elasticsearch.index.fielddata.SortedNumericDoubleValues;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.io.IOException;
/**
* Specialization of {@link AtomicNumericFieldData} for integers.
@ -47,6 +52,34 @@ abstract class AtomicLongFieldData implements AtomicNumericFieldData {
return ramBytesUsed;
}
@Override
public final ScriptDocValues<?> getLegacyFieldValues() {
switch (numericType) {
case DATE:
final ScriptDocValues.Dates realDV = new ScriptDocValues.Dates(getLongValues());
return new ScriptDocValues<DateTime>() {
@Override
public int size() {
return realDV.size();
}
@Override
public DateTime get(int index) {
JodaCompatibleZonedDateTime dt = realDV.get(index);
return new DateTime(dt.toInstant().toEpochMilli(), DateTimeZone.UTC);
}
@Override
public void setNextDocId(int docId) throws IOException {
realDV.setNextDocId(docId);
}
};
default:
return getScriptValues();
}
}
@Override
public final ScriptDocValues<?> getScriptValues() {
switch (numericType) {

View File

@ -0,0 +1,414 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.script;
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.logging.DeprecationLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalField;
import java.time.temporal.TemporalUnit;
import java.time.temporal.WeekFields;
import java.util.Locale;
/**
* A wrapper around ZonedDateTime that exposes joda methods for backcompat.
*/
public class JodaCompatibleZonedDateTime {
private static final DeprecationLogger DEPRECATION_LOGGER =
new DeprecationLogger(ESLoggerFactory.getLogger(JodaCompatibleZonedDateTime.class));
private static void logDeprecated(String key, String message, Object... params) {
// NOTE: we don't check SpecialPermission because this will be called (indirectly) from scripts
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
DEPRECATION_LOGGER.deprecatedAndMaybeLog(key, message, params);
return null;
});
}
private static void logDeprecatedMethod(String oldMethod, String newMethod) {
logDeprecated(oldMethod, "Use of the joda time method [{}] is deprecated. Use [{}] instead.", oldMethod, newMethod);
}
private ZonedDateTime dt;
public JodaCompatibleZonedDateTime(Instant instant, ZoneId zone) {
this.dt = ZonedDateTime.ofInstant(instant, zone);
}
// access the underlying ZonedDateTime
public ZonedDateTime getZonedDateTime() {
return dt;
}
@Override
public boolean equals(Object o) {
return dt.equals(o);
}
@Override
public int hashCode() {
return dt.hashCode();
}
@Override
public String toString() {
return dt.toString();
}
public boolean isAfter(ZonedDateTime o) {
return dt.isAfter(o);
}
public boolean isBefore(ZonedDateTime o) {
return dt.isBefore(o);
}
public boolean isEqual(ZonedDateTime o) {
return dt.isEqual(o);
}
public int getDayOfMonth() {
return dt.getDayOfMonth();
}
public int getDayOfYear() {
return dt.getDayOfYear();
}
public int getHour() {
return dt.getHour();
}
public LocalDate toLocalDate() {
return dt.toLocalDate();
}
public LocalDateTime toLocalDateTime() {
return dt.toLocalDateTime();
}
public int getMinute() {
return dt.getMinute();
}
public Month getMonth() {
return dt.getMonth();
}
public int getMonthValue() {
return dt.getMonthValue();
}
public int getNano() {
return dt.getNano();
}
public int getSecond() {
return dt.getSecond();
}
public int getYear() {
return dt.getYear();
}
public ZonedDateTime minus(TemporalAmount delta) {
return dt.minus(delta);
}
public ZonedDateTime minus(long amount, TemporalUnit unit) {
return dt.minus(amount, unit);
}
public ZonedDateTime minusYears(long amount) {
return dt.minusYears(amount);
}
public ZonedDateTime minusMonths(long amount) {
return dt.minusMonths(amount);
}
public ZonedDateTime minusWeeks(long amount) {
return dt.minusWeeks(amount);
}
public ZonedDateTime minusDays(long amount) {
return dt.minusDays(amount);
}
public ZonedDateTime minusHours(long amount) {
return dt.minusHours(amount);
}
public ZonedDateTime minusMinutes(long amount) {
return dt.minusMinutes(amount);
}
public ZonedDateTime minusSeconds(long amount) {
return dt.minusSeconds(amount);
}
public ZonedDateTime minusNanos(long amount) {
return dt.minusNanos(amount);
}
public ZonedDateTime plus(TemporalAmount amount) {
return dt.plus(amount);
}
public ZonedDateTime plus(long amount,TemporalUnit unit) {
return dt.plus(amount, unit);
}
public ZonedDateTime plusDays(long amount) {
return dt.plusDays(amount);
}
public ZonedDateTime plusHours(long amount) {
return dt.plusHours(amount);
}
public ZonedDateTime plusMinutes(long amount) {
return dt.plusMinutes(amount);
}
public ZonedDateTime plusMonths(long amount) {
return dt.plusMonths(amount);
}
public ZonedDateTime plusNanos(long amount) {
return dt.plusNanos(amount);
}
public ZonedDateTime plusSeconds(long amount) {
return dt.plusSeconds(amount);
}
public ZonedDateTime plusWeeks(long amount) {
return dt.plusWeeks(amount);
}
public ZonedDateTime plusYears(long amount) {
return dt.plusYears(amount);
}
public Instant toInstant() {
return dt.toInstant();
}
public OffsetDateTime toOffsetDateTime() {
return dt.toOffsetDateTime();
}
@SuppressForbidden(reason = "only exposing the method as a passthrough")
public ZonedDateTime truncatedTo(TemporalUnit unit) {
return dt.truncatedTo(unit);
}
public ZonedDateTime with(TemporalAdjuster adjuster) {
return dt.with(adjuster);
}
public ZonedDateTime with(TemporalField field, long newValue) {
return dt.with(field, newValue);
}
public ZonedDateTime withDayOfMonth(int value) {
return dt.withDayOfMonth(value);
}
public ZonedDateTime withDayOfYear(int value) {
return dt.withDayOfYear(value);
}
public ZonedDateTime withEarlierOffsetAtOverlap() {
return dt.withEarlierOffsetAtOverlap();
}
public ZonedDateTime withFixedOffsetZone() {
return dt.withFixedOffsetZone();
}
public ZonedDateTime withHour(int value) {
return dt.withHour(value);
}
public ZonedDateTime withLaterOffsetAtOverlap() {
return dt.withLaterOffsetAtOverlap();
}
public ZonedDateTime withMinute(int value) {
return dt.withMinute(value);
}
public ZonedDateTime withMonth(int value) {
return dt.withMonth(value);
}
public ZonedDateTime withNano(int value) {
return dt.withNano(value);
}
public ZonedDateTime withSecond(int value) {
return dt.withSecond(value);
}
public ZonedDateTime withYear(int value) {
return dt.withYear(value);
}
public ZonedDateTime withZoneSameLocal(ZoneId zone) {
return dt.withZoneSameLocal(zone);
}
public ZonedDateTime withZoneSameInstant(ZoneId zone) {
return dt.withZoneSameInstant(zone);
}
@Deprecated
public long getMillis() {
logDeprecatedMethod("getMillis()", "toInstant().toEpochMilli()");
return dt.toInstant().toEpochMilli();
}
@Deprecated
public int getCenturyOfEra() {
logDeprecatedMethod("getCenturyOfEra()", "get(ChronoField.YEAR_OF_ERA) / 100");
return dt.get(ChronoField.YEAR_OF_ERA) / 100;
}
@Deprecated
public int getEra() {
logDeprecatedMethod("getEra()", "get(ChronoField.ERA)");
return dt.get(ChronoField.ERA);
}
@Deprecated
public int getHourOfDay() {
logDeprecatedMethod("getHourOfDay()", "getHour()");
return dt.getHour();
}
@Deprecated
public int getMillisOfDay() {
logDeprecatedMethod("getMillisOfDay()", "get(ChronoField.MILLI_OF_DAY)");
return dt.get(ChronoField.MILLI_OF_DAY);
}
@Deprecated
public int getMillisOfSecond() {
logDeprecatedMethod("getMillisOfSecond()", "get(ChronoField.MILLI_OF_SECOND)");
return dt.get(ChronoField.MILLI_OF_SECOND);
}
@Deprecated
public int getMinuteOfDay() {
logDeprecatedMethod("getMinuteOfDay()", "get(ChronoField.MINUTE_OF_DAY)");
return dt.get(ChronoField.MINUTE_OF_DAY);
}
@Deprecated
public int getMinuteOfHour() {
logDeprecatedMethod("getMinuteOfHour()", "getMinute()");
return dt.getMinute();
}
@Deprecated
public int getMonthOfYear() {
logDeprecatedMethod("getMonthOfYear()", "getMonthValue()");
return dt.getMonthValue();
}
@Deprecated
public int getSecondOfDay() {
logDeprecatedMethod("getSecondOfDay()", "get(ChronoField.SECOND_OF_DAY)");
return dt.get(ChronoField.SECOND_OF_DAY);
}
@Deprecated
public int getSecondOfMinute() {
logDeprecatedMethod("getSecondOfMinute()", "getSecond()");
return dt.getSecond();
}
@Deprecated
public int getWeekOfWeekyear() {
logDeprecatedMethod("getWeekOfWeekyear()", "get(WeekFields.ISO.weekOfWeekBasedYear())");
return dt.get(WeekFields.ISO.weekOfWeekBasedYear());
}
@Deprecated
public int getWeekyear() {
logDeprecatedMethod("getWeekyear()", "get(WeekFields.ISO.weekBasedYear())");
return dt.get(WeekFields.ISO.weekBasedYear());
}
@Deprecated
public int getYearOfCentury() {
logDeprecatedMethod("getYearOfCentury()", "get(ChronoField.YEAR_OF_ERA) % 100");
return dt.get(ChronoField.YEAR_OF_ERA) % 100;
}
@Deprecated
public int getYearOfEra() {
logDeprecatedMethod("getYearOfEra()", "get(ChronoField.YEAR_OF_ERA)");
return dt.get(ChronoField.YEAR_OF_ERA);
}
@Deprecated
public String toString(String format) {
logDeprecatedMethod("toString(String)", "a DateTimeFormatter");
// TODO: replace with bwc formatter
return new DateTime(dt.toInstant().toEpochMilli(), DateTimeZone.forID(dt.getZone().getId())).toString(format);
}
@Deprecated
public String toString(String format, Locale locale) {
logDeprecatedMethod("toString(String,Locale)", "a DateTimeFormatter");
// TODO: replace with bwc formatter
return new DateTime(dt.toInstant().toEpochMilli(), DateTimeZone.forID(dt.getZone().getId())).toString(format, locale);
}
public DayOfWeek getDayOfWeekEnum() {
return dt.getDayOfWeek();
}
@Deprecated
public int getDayOfWeek() {
logDeprecated("getDayOfWeek()",
"The return type of [getDayOfWeek()] will change to an enum in 7.0. Use getDayOfWeekEnum().getValue().");
return dt.getDayOfWeek().getValue();
}
}

View File

@ -21,6 +21,7 @@ package org.elasticsearch.search.aggregations.support.values;
import org.apache.lucene.search.Scorable;
import org.elasticsearch.common.lucene.ScorerAware;
import org.elasticsearch.index.fielddata.SortingNumericDoubleValues;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.aggregations.AggregationExecutionException;
import org.joda.time.ReadableInstant;
@ -95,6 +96,8 @@ public class ScriptDoubleValues extends SortingNumericDoubleValues implements Sc
return ((ReadableInstant) o).getMillis();
} else if (o instanceof ZonedDateTime) {
return ((ZonedDateTime) o).toInstant().toEpochMilli();
} else if (o instanceof JodaCompatibleZonedDateTime) {
return ((JodaCompatibleZonedDateTime) o).toInstant().toEpochMilli();
} else if (o instanceof Boolean) {
// We do expose boolean fields as boolean in scripts, however aggregations still expect
// that scripts return the same internal representation as regular fields, so boolean

View File

@ -22,6 +22,7 @@ import org.apache.lucene.search.Scorable;
import org.apache.lucene.util.LongValues;
import org.elasticsearch.common.lucene.ScorerAware;
import org.elasticsearch.index.fielddata.AbstractSortingNumericDocValues;
import org.elasticsearch.script.JodaCompatibleZonedDateTime;
import org.elasticsearch.script.SearchScript;
import org.elasticsearch.search.aggregations.AggregationExecutionException;
import org.joda.time.ReadableInstant;
@ -94,6 +95,8 @@ public class ScriptLongValues extends AbstractSortingNumericDocValues implements
return ((ReadableInstant) o).getMillis();
} else if (o instanceof ZonedDateTime) {
return ((ZonedDateTime) o).toInstant().toEpochMilli();
} else if (o instanceof JodaCompatibleZonedDateTime) {
return ((JodaCompatibleZonedDateTime) o).toInstant().toEpochMilli();
} else if (o instanceof Boolean) {
// We do expose boolean fields as boolean in scripts, however aggregations still expect
// that scripts return the same internal representation as regular fields, so boolean

View File

@ -115,7 +115,7 @@ public final class DocValueFieldsFetchSubPhase implements FetchSubPhase {
subReaderContext = context.searcher().getIndexReader().leaves().get(readerIndex);
data = indexFieldData.load(subReaderContext);
if (format == null) {
scriptValues = data.getScriptValues();
scriptValues = data.getLegacyFieldValues();
} else if (indexFieldData instanceof IndexNumericFieldData) {
if (((IndexNumericFieldData) indexFieldData).getNumericType().isFloatingPoint()) {
doubleValues = ((AtomicNumericFieldData) data).getDoubleValues();

View File

@ -1,137 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.index.fielddata;
import org.elasticsearch.index.fielddata.ScriptDocValues.Dates;
import org.elasticsearch.test.ESTestCase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import java.io.IOException;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import static org.hamcrest.Matchers.containsInAnyOrder;
public class ScriptDocValuesDatesTests extends ESTestCase {
public void testJavaTime() throws IOException {
assertDateDocValues(true);
}
public void testJodaTimeBwc() throws IOException {
assertDateDocValues(false, "The joda time api for doc values is deprecated." +
" Use -Des.scripting.use_java_time=true to use the java time api for date field doc values");
}
public void assertDateDocValues(boolean useJavaTime, String... expectedWarnings) throws IOException {
final Function<Long, Object> datetimeCtor;
if (useJavaTime) {
datetimeCtor = millis -> ZonedDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneOffset.UTC);
} else {
datetimeCtor = millis -> new DateTime(millis, DateTimeZone.UTC);
}
long[][] values = new long[between(3, 10)][];
Object[][] expectedDates = new Object[values.length][];
for (int d = 0; d < values.length; d++) {
values[d] = new long[randomBoolean() ? randomBoolean() ? 0 : 1 : between(2, 100)];
expectedDates[d] = new Object[values[d].length];
for (int i = 0; i < values[d].length; i++) {
values[d][i] = randomNonNegativeLong();
expectedDates[d][i] = datetimeCtor.apply(values[d][i]);
}
}
Set<String> warnings = new HashSet<>();
Dates dates = wrap(values, deprecationMessage -> {
warnings.add(deprecationMessage);
/* Create a temporary directory to prove we are running with the
* server's permissions. */
createTempDir();
}, useJavaTime);
// each call to get or getValue will be run with limited permissions, just as they are in scripts
PermissionCollection noPermissions = new Permissions();
AccessControlContext noPermissionsAcc = new AccessControlContext(
new ProtectionDomain[] {
new ProtectionDomain(null, noPermissions)
}
);
boolean valuesExist = false;
for (int round = 0; round < 10; round++) {
int d = between(0, values.length - 1);
dates.setNextDocId(d);
if (expectedDates[d].length > 0) {
Object dateValue = AccessController.doPrivileged((PrivilegedAction<Object>) dates::getValue, noPermissionsAcc);
assertEquals(expectedDates[d][0] , dateValue);
valuesExist = true;
} else {
Exception e = expectThrows(IllegalStateException.class, () -> dates.getValue());
assertEquals("A document doesn't have a value for a field! " +
"Use doc[<field>].size()==0 to check if a document is missing a field!", e.getMessage());
}
assertEquals(values[d].length, dates.size());
for (int i = 0; i < values[d].length; i++) {
final int ndx = i;
Object dateValue = AccessController.doPrivileged((PrivilegedAction<Object>) () -> dates.get(ndx), noPermissionsAcc);
assertEquals(expectedDates[d][i], dateValue);
}
}
if (valuesExist) {
assertThat(warnings, containsInAnyOrder(expectedWarnings));
}
}
private Dates wrap(long[][] values, Consumer<String> deprecationHandler, boolean useJavaTime) {
return new Dates(new AbstractSortedNumericDocValues() {
long[] current;
int i;
@Override
public boolean advanceExact(int doc) {
current = values[doc];
i = 0;
return current.length > 0;
}
@Override
public int docValueCount() {
return current.length;
}
@Override
public long nextValue() {
return current[i++];
}
}, deprecationHandler, useJavaTime);
}
}

View File

@ -0,0 +1,240 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.script;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.test.ESTestCase;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.ZoneOffset;
import java.util.Locale;
import static org.hamcrest.Matchers.equalTo;
public class JodaCompatibleZonedDateTimeTests extends ESTestCase {
private static final Logger DEPRECATION_LOGGER =
LogManager.getLogger("org.elasticsearch.deprecation.script.JodaCompatibleZonedDateTime");
// each call to get or getValue will be run with limited permissions, just as they are in scripts
private static PermissionCollection NO_PERMISSIONS = new Permissions();
private static AccessControlContext NO_PERMISSIONS_ACC = new AccessControlContext(
new ProtectionDomain[] {
new ProtectionDomain(null, NO_PERMISSIONS)
}
);
private JodaCompatibleZonedDateTime javaTime;
private DateTime jodaTime;
@Before
public void setupTime() {
long millis = randomIntBetween(0, Integer.MAX_VALUE);
javaTime = new JodaCompatibleZonedDateTime(Instant.ofEpochMilli(millis), ZoneOffset.ofHours(-7));
jodaTime = new DateTime(millis, DateTimeZone.forOffsetHours(-7));
}
void assertDeprecation(Runnable assertions, String message) {
Appender appender = new AbstractAppender("test", null, null) {
@Override
public void append(LogEvent event) {
/* Create a temporary directory to prove we are running with the
* server's permissions. */
createTempDir();
}
};
appender.start();
Loggers.addAppender(DEPRECATION_LOGGER, appender);
try {
// the assertions are run with the same reduced privileges scripts run with
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
assertions.run();
return null;
}, NO_PERMISSIONS_ACC);
} finally {
appender.stop();
Loggers.removeAppender(DEPRECATION_LOGGER, appender);
}
assertWarnings(message);
}
void assertMethodDeprecation(Runnable assertions, String oldMethod, String newMethod) {
assertDeprecation(assertions, "Use of the joda time method [" + oldMethod + "] is deprecated. Use [" + newMethod + "] instead.");
}
public void testDayOfMonth() {
assertThat(javaTime.getDayOfMonth(), equalTo(jodaTime.getDayOfMonth()));
}
public void testDayOfYear() {
assertThat(javaTime.getDayOfYear(), equalTo(jodaTime.getDayOfYear()));
}
public void testHour() {
assertThat(javaTime.getHour(), equalTo(jodaTime.getHourOfDay()));
}
public void testLocalDate() {
assertThat(javaTime.toLocalDate(), equalTo(LocalDate.of(jodaTime.getYear(), jodaTime.getMonthOfYear(), jodaTime.getDayOfMonth())));
}
public void testLocalDateTime() {
LocalDateTime dt = LocalDateTime.of(jodaTime.getYear(), jodaTime.getMonthOfYear(), jodaTime.getDayOfMonth(),
jodaTime.getHourOfDay(), jodaTime.getMinuteOfHour(), jodaTime.getSecondOfMinute(),
jodaTime.getMillisOfSecond() * 1000000);
assertThat(javaTime.toLocalDateTime(), equalTo(dt));
}
public void testMinute() {
assertThat(javaTime.getMinute(), equalTo(jodaTime.getMinuteOfHour()));
}
public void testMonth() {
assertThat(javaTime.getMonth(), equalTo(Month.of(jodaTime.getMonthOfYear())));
}
public void testMonthValue() {
assertThat(javaTime.getMonthValue(), equalTo(jodaTime.getMonthOfYear()));
}
public void testNano() {
assertThat(javaTime.getNano(), equalTo(jodaTime.getMillisOfSecond() * 1000000));
}
public void testSecond() {
assertThat(javaTime.getSecond(), equalTo(jodaTime.getSecondOfMinute()));
}
public void testYear() {
assertThat(javaTime.getYear(), equalTo(jodaTime.getYear()));
}
public void testMillis() {
assertMethodDeprecation(() -> assertThat(javaTime.getMillis(), equalTo(jodaTime.getMillis())),
"getMillis()", "toInstant().toEpochMilli()");
}
public void testCenturyOfEra() {
assertMethodDeprecation(() -> assertThat(javaTime.getCenturyOfEra(), equalTo(jodaTime.getCenturyOfEra())),
"getCenturyOfEra()", "get(ChronoField.YEAR_OF_ERA) / 100");
}
public void testEra() {
assertMethodDeprecation(() -> assertThat(javaTime.getEra(), equalTo(jodaTime.getEra())),
"getEra()", "get(ChronoField.ERA)");
}
public void testHourOfDay() {
assertMethodDeprecation(() -> assertThat(javaTime.getHourOfDay(), equalTo(jodaTime.getHourOfDay())),
"getHourOfDay()", "getHour()");
}
public void testMillisOfDay() {
assertMethodDeprecation(() -> assertThat(javaTime.getMillisOfDay(), equalTo(jodaTime.getMillisOfDay())),
"getMillisOfDay()", "get(ChronoField.MILLI_OF_DAY)");
}
public void testMillisOfSecond() {
assertMethodDeprecation(() -> assertThat(javaTime.getMillisOfSecond(), equalTo(jodaTime.getMillisOfSecond())),
"getMillisOfSecond()", "get(ChronoField.MILLI_OF_SECOND)");
}
public void testMinuteOfDay() {
assertMethodDeprecation(() -> assertThat(javaTime.getMinuteOfDay(), equalTo(jodaTime.getMinuteOfDay())),
"getMinuteOfDay()", "get(ChronoField.MINUTE_OF_DAY)");
}
public void testMinuteOfHour() {
assertMethodDeprecation(() -> assertThat(javaTime.getMinuteOfHour(), equalTo(jodaTime.getMinuteOfHour())),
"getMinuteOfHour()", "getMinute()");
}
public void testMonthOfYear() {
assertMethodDeprecation(() -> assertThat(javaTime.getMonthOfYear(), equalTo(jodaTime.getMonthOfYear())),
"getMonthOfYear()", "getMonthValue()");
}
public void testSecondOfDay() {
assertMethodDeprecation(() -> assertThat(javaTime.getSecondOfDay(), equalTo(jodaTime.getSecondOfDay())),
"getSecondOfDay()", "get(ChronoField.SECOND_OF_DAY)");
}
public void testSecondOfMinute() {
assertMethodDeprecation(() -> assertThat(javaTime.getSecondOfMinute(), equalTo(jodaTime.getSecondOfMinute())),
"getSecondOfMinute()", "getSecond()");
}
public void testWeekOfWeekyear() {
assertMethodDeprecation(() -> assertThat(javaTime.getWeekOfWeekyear(), equalTo(jodaTime.getWeekOfWeekyear())),
"getWeekOfWeekyear()", "get(WeekFields.ISO.weekOfWeekBasedYear())");
}
public void testWeekyear() {
assertMethodDeprecation(() -> assertThat(javaTime.getWeekyear(), equalTo(jodaTime.getWeekyear())),
"getWeekyear()", "get(WeekFields.ISO.weekBasedYear())");
}
public void testYearOfCentury() {
assertMethodDeprecation(() -> assertThat(javaTime.getYearOfCentury(), equalTo(jodaTime.getYearOfCentury())),
"getYearOfCentury()", "get(ChronoField.YEAR_OF_ERA) % 100");
}
public void testYearOfEra() {
assertMethodDeprecation(() -> assertThat(javaTime.getYearOfEra(), equalTo(jodaTime.getYearOfEra())),
"getYearOfEra()", "get(ChronoField.YEAR_OF_ERA)");
}
public void testToString1() {
assertMethodDeprecation(() -> assertThat(javaTime.toString("YYYY/MM/dd HH:mm:ss.SSS"),
equalTo(jodaTime.toString("YYYY/MM/dd HH:mm:ss.SSS"))), "toString(String)", "a DateTimeFormatter");
}
public void testToString2() {
assertMethodDeprecation(() -> assertThat(javaTime.toString("EEE", Locale.GERMANY),
equalTo(jodaTime.toString("EEE", Locale.GERMANY))), "toString(String,Locale)", "a DateTimeFormatter");
}
public void testDayOfWeek() {
assertDeprecation(() -> assertThat(javaTime.getDayOfWeek(), equalTo(jodaTime.getDayOfWeek())),
"The return type of [getDayOfWeek()] will change to an enum in 7.0. Use getDayOfWeekEnum().getValue().");
}
public void testDayOfWeekEnum() {
assertThat(javaTime.getDayOfWeekEnum(), equalTo(DayOfWeek.of(jodaTime.getDayOfWeek())));
}
}

View File

@ -47,10 +47,13 @@ import org.elasticsearch.search.lookup.FieldLookup;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.InternalSettingsPlugin;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.ReadableDateTime;
import org.joda.time.format.DateTimeFormat;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
@ -59,7 +62,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@ -111,7 +113,7 @@ public class SearchFieldsIT extends ESIntegTestCase {
scripts.put("doc['date'].date.millis", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Dates dates = (ScriptDocValues.Dates) doc.get("date");
return ((ZonedDateTime) dates.getValue()).toInstant().toEpochMilli();
return dates.getValue().toInstant().toEpochMilli();
});
scripts.put("_fields['num1'].value", vars -> fieldsScript(vars, "num1"));
@ -801,8 +803,8 @@ public class SearchFieldsIT extends ESIntegTestCase {
assertThat(searchResponse.getHits().getAt(0).getFields().get("long_field").getValue(), equalTo((Object) 4L));
assertThat(searchResponse.getHits().getAt(0).getFields().get("float_field").getValue(), equalTo((Object) 5.0));
assertThat(searchResponse.getHits().getAt(0).getFields().get("double_field").getValue(), equalTo((Object) 6.0d));
ZonedDateTime dateField = searchResponse.getHits().getAt(0).getFields().get("date_field").getValue();
assertThat(dateField.toInstant().toEpochMilli(), equalTo(date.toInstant().toEpochMilli()));
DateTime dateField = searchResponse.getHits().getAt(0).getFields().get("date_field").getValue();
assertThat(dateField.getMillis(), equalTo(date.toInstant().toEpochMilli()));
assertThat(searchResponse.getHits().getAt(0).getFields().get("boolean_field").getValue(), equalTo((Object) true));
assertThat(searchResponse.getHits().getAt(0).getFields().get("text_field").getValue(), equalTo("foo"));
assertThat(searchResponse.getHits().getAt(0).getFields().get("keyword_field").getValue(), equalTo("foo"));
@ -828,7 +830,7 @@ public class SearchFieldsIT extends ESIntegTestCase {
assertThat(searchResponse.getHits().getAt(0).getFields().get("float_field").getValue(), equalTo((Object) 5.0));
assertThat(searchResponse.getHits().getAt(0).getFields().get("double_field").getValue(), equalTo((Object) 6.0d));
dateField = searchResponse.getHits().getAt(0).getFields().get("date_field").getValue();
assertThat(dateField.toInstant().toEpochMilli(), equalTo(date.toInstant().toEpochMilli()));
assertThat(dateField.getMillis(), equalTo(date.toInstant().toEpochMilli()));
assertThat(searchResponse.getHits().getAt(0).getFields().get("boolean_field").getValue(), equalTo((Object) true));
assertThat(searchResponse.getHits().getAt(0).getFields().get("text_field").getValue(), equalTo("foo"));
assertThat(searchResponse.getHits().getAt(0).getFields().get("keyword_field").getValue(), equalTo("foo"));
@ -968,10 +970,10 @@ public class SearchFieldsIT extends ESIntegTestCase {
assertAcked(prepareCreate("test").addMapping("type", mapping));
ensureGreen("test");
ZonedDateTime date = ZonedDateTime.of(1990, 12, 29, 0, 0, 0, 0, ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ROOT);
DateTime date = new DateTime(1990, 12, 29, 0, 0, DateTimeZone.UTC);
org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
index("test", "type", "1", "text_field", "foo", "date_field", formatter.format(date));
index("test", "type", "1", "text_field", "foo", "date_field", formatter.print(date));
refresh("test");
SearchRequestBuilder builder = client().prepareSearch().setQuery(matchAllQuery())
@ -999,8 +1001,8 @@ public class SearchFieldsIT extends ESIntegTestCase {
DocumentField dateField = fields.get("date_field");
assertThat(dateField.getName(), equalTo("date_field"));
ZonedDateTime fetchedDate = dateField.getValue();
assertThat(fetchedDate, equalTo(date));
ReadableDateTime fetchedDate = dateField.getValue();
assertThat(fetchedDate.getMillis(), equalTo(date.toInstant().getMillis()));
}
public void testWildcardDocValueFieldsWithFieldAlias() throws Exception {
@ -1033,10 +1035,10 @@ public class SearchFieldsIT extends ESIntegTestCase {
assertAcked(prepareCreate("test").addMapping("type", mapping));
ensureGreen("test");
ZonedDateTime date = ZonedDateTime.of(1990, 12, 29, 0, 0, 0, 0, ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ROOT);
DateTime date = new DateTime(1990, 12, 29, 0, 0, DateTimeZone.UTC);
org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
index("test", "type", "1", "text_field", "foo", "date_field", formatter.format(date));
index("test", "type", "1", "text_field", "foo", "date_field", formatter.print(date));
refresh("test");
SearchRequestBuilder builder = client().prepareSearch().setQuery(matchAllQuery())
@ -1063,8 +1065,8 @@ public class SearchFieldsIT extends ESIntegTestCase {
DocumentField dateField = fields.get("date_field");
assertThat(dateField.getName(), equalTo("date_field"));
ZonedDateTime fetchedDate = dateField.getValue();
assertThat(fetchedDate, equalTo(date));
ReadableDateTime fetchedDate = dateField.getValue();
assertThat(fetchedDate.getMillis(), equalTo(date.toInstant().getMillis()));
}