Skip to content
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

Merged
merged 15 commits into from
Sep 17, 2018
Merged

Conversation

rjernst
Copy link
Member

@rjernst rjernst commented Sep 7, 2018

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.

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.
@rjernst rjernst added :Core/Infra/Scripting Scripting abstractions, Painless, and Mustache v7.0.0 >refactoring v6.5.0 labels Sep 7, 2018
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra

@rjernst rjernst requested a review from spinscale September 7, 2018 00:42
Copy link
Member

@nik9000 nik9000 left a 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()."]
Copy link
Member

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,
Copy link
Member

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>) () -> {
Copy link
Member

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 {
Copy link
Member

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 =
Copy link
Member

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);
Copy link
Member

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?

Copy link
Contributor

@spinscale spinscale left a 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()
Copy link
Contributor

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?

Copy link
Contributor

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);
Copy link
Contributor

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) {
Copy link
Contributor

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?

Copy link
Member Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough

@rjernst
Copy link
Member Author

rjernst commented Sep 8, 2018

@nik9000 @spinscale I believe I have addressed all of your comments.

@spinscale
Copy link
Contributor

I think the test failures are coming from this change (I am pretty much happy though, once CI passes)

Copy link
Member

@nik9000 nik9000 left a 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().]
Copy link
Member

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);
Copy link
Member

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?

Copy link
Member Author

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();
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Contributor

@spinscale spinscale left a 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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zoneId is unused here?

Copy link
Member Author

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed f105096

@rjernst
Copy link
Member Author

rjernst commented Sep 16, 2018

@elasticmachine test this please

@rjernst rjernst merged commit 3046656 into elastic:master Sep 17, 2018
@rjernst rjernst deleted the timeapi1 branch September 17, 2018 02:18
rjernst added a commit that referenced this pull request Sep 17, 2018
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.
@jimczi jimczi added v7.0.0-beta1 and removed v7.0.0 labels Feb 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Scripting Scripting abstractions, Painless, and Mustache >refactoring v6.5.0 v7.0.0-beta1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants