Skip to content

Conversation

@pgomulka
Copy link
Contributor

@pgomulka pgomulka commented Mar 2, 2021

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

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.
@pgomulka pgomulka added :Core/Infra/REST API REST infrastructure and utilities v8.0.0 labels Mar 2, 2021
@pgomulka pgomulka self-assigned this Mar 2, 2021
@elasticmachine elasticmachine added the Team:Core/Infra Meta label for core/infra team label Mar 2, 2021
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (Team:Core/Infra)

}
}

// protected boolean enableWarningsCheck() {
Copy link
Contributor Author

@pgomulka pgomulka Mar 2, 2021

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..

Copy link
Contributor

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.

Copy link
Contributor Author

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)

@pgomulka
Copy link
Contributor Author

pgomulka commented Mar 3, 2021

@elasticmachine run elasticsearch-ci/rest-compat

@pgomulka pgomulka requested review from jakelandis and joegallo March 3, 2021 15:53
Copy link
Contributor

@jakelandis jakelandis left a 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){
Copy link
Contributor

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. )

Copy link
Contributor Author

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

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

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 ?

Copy link
Contributor

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.

@pgomulka
Copy link
Contributor Author

pgomulka commented Mar 4, 2021

@elasticmachine update branch

Copy link
Contributor

@jakelandis jakelandis left a 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){
Copy link
Contributor

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

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)));

Copy link
Contributor Author

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

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.

@pgomulka pgomulka requested a review from jakelandis March 4, 2021 19:48
.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)));
Copy link
Contributor

Choose a reason for hiding this comment

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

is this intentional ?

Copy link
Contributor

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)

Copy link
Contributor Author

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

Copy link
Contributor

@jakelandis jakelandis left a 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)

@jakelandis
Copy link
Contributor

@elasticmachine run elasticsearch-ci/2

@pgomulka pgomulka merged commit 8d09fbf into elastic:master Mar 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Core/Infra/REST API REST infrastructure and utilities >enhancement Team:Core/Infra Meta label for core/infra team v8.0.0-alpha1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants