-
Notifications
You must be signed in to change notification settings - Fork 25.6k
Allow for field declaration for future compatible versions #69774
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
Allow for field declaration for future compatible versions #69774
Conversation
When renaming/removing a field, a new field might be declared which should be parseable starting with the current version. This commit changes the way ParseField is declared for compatible Version. Instead of concrete version a boolean function has to be used to indicate for what version a field is parseable. The onOrAfter and equalTo functions are declared on RestApiCompatibleVersion to allow for this.
|
Pinging @elastic/es-core-infra (Team:Core/Infra) |
| } | ||
| } | ||
|
|
||
| // protected boolean enableWarningsCheck() { |
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.
how do we test for future version? A class instead of enum would allow for Spying, but would not look too great..
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 don't think you need to test the future version. Since it does not exist (yet) it can not be set. Once current == 9 it will get tested via the current(). However, i realize that is not the spirit of what you are trying to test here ... you are trying to test the "after" part of onOrAfter right ?
I think to test the spirit of what you want here is to declare a Parse field with .onOrAfter(RestApiCompatibleVersion.minimumSupported()))); and a createParserWithCompatibilityFor(..., currentVersion()) and ensure it still parses correctly.
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.
good idea, I created a test that uses minimumSupported ('pretending this being the version when a new field is introduced) and then I test that is being parsed for current version (which is the "future" version)
|
@elasticmachine run elasticsearch-ci/rest-compat |
jakelandis
left a comment
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.
Looking good. One comment around the use of collection or not and possible way to test a "future" version.
Also, sorry you got the short straw w.r.t. to the massive rename.
| return fromMajorVersion(major - 1); | ||
| } | ||
|
|
||
| public boolean matches(Collection<Function<RestApiCompatibleVersion, Boolean>> restApiCompatibleVersionFunctions){ |
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.
Is the Collection here necessary ? with only two versions and only two functions, it seems redundant to send both equalTo and onOrAfter (note this applies through all the interfaces ... i think singular is sufficient. )
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.
good point, onOrAfter can replace the only usage of two versions at once (the regular field without version specified which is matching V7 and V8)
| } | ||
| } | ||
|
|
||
| // protected boolean enableWarningsCheck() { |
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 don't think you need to test the future version. Since it does not exist (yet) it can not be set. Once current == 9 it will get tested via the current(). However, i realize that is not the spirit of what you are trying to test here ... you are trying to test the "after" part of onOrAfter right ?
I think to test the spirit of what you want here is to declare a Parse field with .onOrAfter(RestApiCompatibleVersion.minimumSupported()))); and a createParserWithCompatibilityFor(..., currentVersion()) and ensure it still parses correctly.
| private final String name; | ||
| private final String[] deprecatedNames; | ||
| private final Set<RestApiVersion> restApiVersions = new HashSet<>(2); | ||
| private final Function<RestApiVersion, Boolean> restApiVersionMatcher; |
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.
any suggestions for a better name? restApiVersionMatcher? restApiVersionFunction? restApiVersionRange ?
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.
how about forRestApiVersion see comment below.
|
@elasticmachine update branch |
jakelandis
left a comment
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.
a couple naming suggestions
| return fromMajorVersion(major - 1); | ||
| } | ||
|
|
||
| public boolean matches(Function<RestApiVersion, Boolean> restApiVersionFunctions){ |
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.
nit: s/Functions/Function
| */ | ||
| public ParseField withRestApiVersions(RestApiVersion... restApiVersions) { | ||
| return new ParseField(this.name, Arrays.asList(restApiVersions), this.deprecatedNames); | ||
| public ParseField withRestApiVersionMacher(Function<RestApiVersion, Boolean> restApiVersionMatcher) { |
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.
how about forRestApiVersion( Function<RestApiVersion, Boolean> forRestApiVersion)
so
PARSER.declareInt(StructWithCompatibleFields::setIntField,
new ParseField("new_name").forRestApiVersion(RestApiVersion.onOrAfter(RestApiVersion.V_8)));
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.
that looks really good - will rename in all the places accordingly
| private final String name; | ||
| private final String[] deprecatedNames; | ||
| private final Set<RestApiVersion> restApiVersions = new HashSet<>(2); | ||
| private final Function<RestApiVersion, Boolean> restApiVersionMatcher; |
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.
how about forRestApiVersion see comment below.
…sticsearch into compat/field_future_version
| .field("format", "epoch_second"))); | ||
|
|
||
| ParsedDocument doc = mapper.parse(source(b -> b.field("field", 1457654400))); | ||
| ParsedDocument doc = mapper.parse(source(b -> b.field("field", 1614774616.0585806))); |
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.
is this intentional ?
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 assume not and changed it back for you since it was failing a test and is unrelated to this change: 60ea56f (#69774)
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.
Omg yes. It was totally unrelated and slipped by accident. Thanks for a fix
jakelandis
left a comment
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.
LGTM.
However, there may be a rouge change to a test. (see comnent)
server/src/test/java/org/elasticsearch/index/mapper/DateFieldMapperTests.java
Outdated
Show resolved
Hide resolved
|
@elasticmachine run elasticsearch-ci/2 |
When renaming/removing a field, a new field might be declared which
should be parseable starting with the current version.
This commit changes the way ParseField is declared for compatible
Version. Instead of concrete version a boolean function has to be used
to indicate for what version a field is parseable. The onOrAfter and
equalTo functions are declared on RestApiVersion to allow for
this.
#51816