-
Notifications
You must be signed in to change notification settings - Fork 25k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scripting: Rework joda time backcompat #33486
Conversation
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.
Pinging @elastic/es-core-infra |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes me so happy!
I left a few smallish suggestions in line.
@@ -425,7 +425,7 @@ 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] | |||
// TEST[warning:getDayOfWeek() is incompatible with the java time api. Use getDayOfWeekEnum().getValue()."] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe "the return type of getDayOfWeek will change in 7.0. Call getDayOfWeekEnum().getValue() to be compatible with 7.0."
# | ||
|
||
# | ||
# Painless definition file. This defines the hierarchy of classes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
new DeprecationLogger(ESLoggerFactory.getLogger(JodaCompatibleZonedDateTime.class)); | ||
|
||
private static void logDeprecated(String key, String message, Object... params) { | ||
AccessController.doPrivileged((PrivilegedAction<Void>) () -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is worth a comment about why this doesn't check special permission: namely that we expect this to be called by scripts which won't have it.
}; | ||
appender.start(); | ||
Loggers.addAppender(DEPRECATION_LOGGER, appender); | ||
try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a comment here like "now run the block with the same permissions as a script".
); | ||
|
||
// Thursday, September 6, 2018 3:01:20.617 PM GMT-07:00 DST | ||
private static JodaCompatibleZonedDateTime TIME = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be nice if every test built a random time with the Java time and then the same time with Joda and then asserted that the methods return the same thing.
} | ||
|
||
private static void logDeprecatedMethod(String method) { | ||
logDeprecated(method, "Use of joda time method [{}] is deprecated. Use the java time api instead.", method); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you point folks to the right java API to use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great work! I really like this solution!
I agree with randomizing the tests and comparing the output against joda and left two pretty minor comments.
ZonedDateTime plusSeconds(long) | ||
ZonedDateTime plusWeeks(long) | ||
ZonedDateTime plusYears(long) | ||
Instant toInstant() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this one coming from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignore this, misread it as being something for BWC, but it's a new method
} | ||
|
||
public ZonedDateTime truncatedTo(TemporalUnit unit) { | ||
return dt.truncatedTo(unit); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will fail due to forbidden APIs - I remember playing with it for the formatters
|
||
private ZonedDateTime dt; | ||
|
||
public JodaCompatibleZonedDateTime(Instant instant, ZoneId zone) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will the zone id always be UTC for non test code? If so, we could change the visibility for this ctor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to keep the signature the same as ZonedDateTime.ofInstant
, since that is what the uses will go back to in 7.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair enough
@nik9000 @spinscale I believe I have addressed all of your comments. |
I think the test failures are coming from this change (I am pretty much happy though, once CI passes) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few small things.
@@ -425,7 +425,7 @@ 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] | |||
// TEST[warning:The return type of [getDayOfWeek()] will change to an enum in 7.0. Use getDayOfWeekEnum().getValue().] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should update this to the ES 7 compatible call.
@@ -93,6 +93,7 @@ | |||
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to uncomment this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will be removing it. I added it originally because I thought it was needed due to the api leakage I mentioned in my other comment, but I found a way around that and don't want to expose this compatibility class at all.
@@ -115,7 +115,7 @@ public void hitsExecute(SearchContext context, SearchHit[] hits) throws IOExcept | |||
subReaderContext = context.searcher().getIndexReader().leaves().get(readerIndex); | |||
data = indexFieldData.load(subReaderContext); | |||
if (format == null) { | |||
scriptValues = data.getScriptValues(); | |||
scriptValues = data.getLegacyFieldValues(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will you change this in a follow up just for 7?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won't, but this will be removed when not specifying format is removed, separate from any scripting/joda changes. The problem was ScriptDocValues were used for more than just scripts, and it leaks into the transport client api. I fixed this by keeping the fields fetch phase returning DateTime objects through this getLegacyFieldValues(). You can see not specifying format is already deprecated, so I expect it will be removed for 7.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found one more issue where you always use UTC and do not use the timezone of a zoned date time.
Apart from that I am good (no further review needed on my side).
// write the joda compatibility datetime as joda datetime | ||
o.writeByte((byte) 13); | ||
final JodaCompatibleZonedDateTime zonedDateTime = (JodaCompatibleZonedDateTime) v; | ||
String zoneId = zonedDateTime.getZonedDateTime().getZone().getId(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zoneId
is unused here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. This was because the zoneId used by joda doesn't appear to always be the same as java time. Joda does not know how to parse "Z". I'll add special casing for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed f105096
@elasticmachine test this please |
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 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.
Usage of the joda time methods trigger a deprecation warning.