-
Notifications
You must be signed in to change notification settings - Fork 25.4k
Refactor usage of compatible version #68648
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
Refactor usage of compatible version #68648
Conversation
Compatible API version is at the moment represented by both Version and byte - representing a major version. This can lead to a confusion which representation to use, as well as to incorrect assumptions that minor versions are supperted (with the use of Version.V_7_0_0) Current usage of XContentParser.useCompatible is also not allowing to define two compatibile implementations. This is not about support N-2 compatibility, but to allow to continue development when a major release is performed. This commit is introducing the CompatibleVersion object responsible for wrapping around a major version of compatible API.
Pinging @elastic/es-core-infra (Team: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.
I like the enumeration... as mentioned in the comment, I think it addresses all the concerns I had that motivated the use for a boolean
I think
if([builder|parser|request].getRestApiCompatibleVersion() == RestApiCompatibileVersion.V7)
{ //
reads pretty nice and no need for the boolean.
Otherwise just a few nit picks.
libs/core/src/main/java/org/elasticsearch/common/compatibility/CompatibleVersion.java
Outdated
Show resolved
Hide resolved
return restCompatibilityVersion; | ||
} | ||
|
||
public boolean useCompatibility(CompatibleVersion codeChangeVersion) { |
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.
hmm... now seeing this with the new enum, not sure if like the boolean approach.
if(builder.getRestApiCompatibleVersion() == RestApiCompatibileVersion.V7)
{ //do something special
I think reads pretty well, and looks alot (different enough) from the wire protocol ...its a bit verbose, but such is Java.
I think the enum introduced here resolved any issues I had that led me to suggest the boolean approach.
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 agree, I personally prefer to replace boolean expressions with named methods, but in this case it would be an overdo.
I also realised that we can apply the same 'getter' style to parser
|
||
V_8(8), | ||
V_7(7), | ||
V_6(6);//used in testing, to prove validation |
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 there any way to avoid declaring this even for testing ? Having 6 in here, even with the comment is a bit misleading since it will show up in the auto complete.
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 agree that this should ideally be removed, but at the same time I won't be able to test the validation against incorrect registration RestController#registerHandlerNoWrap
This is a real scenario that we will have during the major release (3 versions present)
private void registerHandlerNoWrap(RestRequest.Method method, String path, RestHandler maybeWrappedHandler) {
final RestApiCompatibleVersion version = maybeWrappedHandler.compatibleWithVersion();
assert RestApiCompatibleVersion.minimumSupported() == version || RestApiCompatibleVersion.currentVersion() == version
: "REST API compatibility is only supported for version " + RestApiCompatibleVersion.minimumSupported().major;
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.
my point is that I expect that declaration within Plugin.getRestHandlers of compatible handlers must be done under if statements. If we forget about this the assertion in registerHandlerNoWrap should fail
if(RestApiCompatibleVersion.minimumSupported == RestApiCompatibleVersion.V_8)
//register v8
if(RestApiCompatibleVersion.currentVersion == RestApiCompatibleVersion.V_7)
//register v7
Even thought those handlers would not be accessible when requested anyway (the validation in RestCompatibleVersionHandler would prevent a request with application/vnd.elasticsearch+json;compatible-with=6 )
I would prefer we don't even try to register them.
V_7(7), | ||
V_6(6);//used in testing, to prove validation | ||
|
||
// This needs to be aligned with Version.CURRENT |
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.
Can this be codified with an assert ? It will trip when cutting the new branch, but here I think that is desirable.
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.
agree, but the assert will have to be in Version class (dependency direction)
return valueOf("V_" + majorVersion); | ||
} | ||
|
||
public static CompatibleVersion minimumRestCompatibilityVersion() { |
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:
RestApiCompatibleVersion getMinimumSupported()
To avoid duplication in the naming.
@@ -155,7 +157,7 @@ public static XContentBuilder builder(XContentType xContentType, Set<String> inc | |||
*/ | |||
private boolean humanReadable = false; | |||
|
|||
private byte compatibleMajorVersion; | |||
private CompatibleVersion restCompatibilityVersion; |
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: restApiCompatibility
public XContentBuilder withCompatibleVersion(CompatibleVersion compatibleVersion) { | ||
assert this.restCompatibilityVersion == null : "Compatible version has already been set"; | ||
if (compatibleVersion == null) { | ||
throw new IllegalArgumentException("Compatible major version must not be null"); |
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: the message needs to be updated. Also, can probably use Objects.requireNonNull
V_6(6);//used in testing, to prove validation | ||
|
||
// This needs to be aligned with Version.CURRENT | ||
public static final CompatibleVersion CURRENT = 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.
It would be great if we could hide the CURRENT, so a user can't type CompatibleVersion.CURRENT
since in all but the core cases (like parsing the header) it would be incorrect to do so.
It's a pretty minor concern ... maybe a simple comment would suffice ? , or maybe a getCurrentVersion() (with java doc saying dont use this) instead to avoid it looking like one of the enum options?
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, I feel getCurrentVersion
can help here.
@elasticmachine update branch |
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.
2 last comments (remove v_6 (and associated test), and boolean method)... assuming that LGTM. I like really like this approach, thanks for the iterations.
|
||
V_8(8), | ||
V_7(7), | ||
V_6(6);//used in testing, to prove validation |
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.
as discussed in person, we can remove this (V_6) and the associated test, we can have other ways to ensure elder version are not in use, and this would probably cause more confusion (even with the comment) then would help.
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.
agree, removed the instance and the test
return restApiCompatibilityVersion; | ||
} | ||
|
||
public boolean useCompatibility(RestApiCompatibleVersion codeChangeVersion) { |
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.
should this be removed ?
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.
yes, missed it. thanks
…nto compat/use_compatible_check
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 went ahead and looked even though its been merged. Looks great!
Compatible API version is at the moment represented by both Version and
byte - representing a major version. This can lead to a confusion which
representation to use, as well as to incorrect assumptions that minor
versions are supported (with the use of Version.V_7_0_0)
Current usage of XContentParser.useCompatible is also not allowing to
define two compatible implementations. This is not about
support N-2 compatibility, but to allow to continue development when a
major release is performed.
This commit is introducing the CompatibleVersion object responsible for
wrapping around a major version of compatible API.
relates #68100