Skip to content

Conversation

@pgomulka
Copy link
Contributor

@pgomulka pgomulka commented Nov 2, 2020

A RestCompatibilityPlugin and its xpack implementation allow to calculate a version requested on REST request. It uses accept, content-type headers to return a version.
It also performs a validation of allowed combinations of versions and values provided on accept/content-type headers

relates #51816

@pgomulka pgomulka added the WIP label Nov 2, 2020
@pgomulka pgomulka self-assigned this Nov 2, 2020
@pgomulka
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/2

@pgomulka pgomulka changed the title WIP Introduce Compatible Version plugin Introduce Compatible Version plugin Nov 16, 2020
@pgomulka pgomulka added :Core/Infra/REST API REST infrastructure and utilities v8.0.0 and removed WIP labels Nov 16, 2020
@pgomulka pgomulka marked this pull request as ready for review November 16, 2020 12:11
@elasticmachine
Copy link
Collaborator

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

@elasticmachine elasticmachine added the Team:Core/Infra Meta label for core/infra team label Nov 16, 2020
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 - some nit picks and one possible extraneous if check. (please take any of the nit picks as suggestions not a requirement to change )

byte contentTypeVersion = cVersion == null ? Version.CURRENT.major : Integer.valueOf(cVersion).byteValue();

// accept version must be current or prior
if (acceptVersion > Version.CURRENT.major || acceptVersion < Version.CURRENT.major - 1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: can we use Version.CURRENT.minimumRestCompatibilityVersion() instead of Version.CURRENT.major -1 ? (to help encapsulate the logic)

// accept version must be current or prior
if (acceptVersion > Version.CURRENT.major || acceptVersion < Version.CURRENT.major - 1) {
throw new ElasticsearchStatusException(
"Compatible version must be equal or less then the current version. Accept={}} Content-Type={}}",
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: rather then saying "must be equal or less then the current version" , can it say "must be either version {} or {}, but found {}. Accept={}" , Version.CURRENT.major, Version.CURRENT.minimumRestCompatibilityVersion() , acceptVersion, acceptHeader (no need to put content-type here)

if (hasContent) {

// content-type version must be current or prior
if (contentTypeVersion > Version.CURRENT.major || contentTypeVersion < Version.CURRENT.major - 1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

same nitpicks as above... use the minumRestCompatibltyVersion and tweak the error message to be more precise (and no need for the accept header here)

// both headers should be versioned or none
if ((cVersion == null && aVersion != null) || (aVersion == null && cVersion != null)) {
throw new ElasticsearchStatusException(
"Versioning is required on both Content-Type and Accept headers. Accept={} Content-Type={}",
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: A compatible version is required on both Content-Type and Accept headers if either one has requested a compatible version. Accept={}, Content-Type={}

// if both accept and content-type are sent, the version must match
if (contentTypeVersion != acceptVersion) {
throw new ElasticsearchStatusException(
"Content-Type and Accept version requests have to match. Accept={} Content-Type={}",
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: A compatible version is required on both Content-Type and Accept headers if either one has requested a compatible version and the compatible versions must match. Accept={}, Content-Type={}

);
}
// both headers should be versioned or none
if ((cVersion == null && aVersion != null) || (aVersion == null && cVersion != null)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this ever evaluate true ? wouldn't the above if catch any this case ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the above if if (contentTypeVersion != acceptVersion) { would not catch the scenario when one of the headers is set to compatible-with=8 (current in general) and the other is not set (defaults to current)

   expectThrows(
            ElasticsearchStatusException.class,
            () -> requestWith(acceptHeader(CURRENT_VERSION), contentTypeHeader(null), bodyPresent())
        );
expectThrows(
            ElasticsearchStatusException.class,
            () -> requestWith(acceptHeader(null), contentTypeHeader(CURRENT_VERSION), bodyPresent())
        );

@pgomulka
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/1

Copy link
Member

@jaymode jaymode left a comment

Choose a reason for hiding this comment

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

LGTM

plugins.add(TestRestCompatibility1.class);
plugins.add(TestRestCompatibility2.class);

expectThrows(IllegalStateException.class, () -> new MockNode(settings.build(), plugins));
Copy link
Member

Choose a reason for hiding this comment

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

can you check the message? We've had tests like this before and didn't check the message and there was some other cause of the exception rather than the true cause.

@pgomulka
Copy link
Contributor Author

@elasticmachine run elasticsearch-ci/2 - random test failing

@pgomulka
Copy link
Contributor Author

@elasticmachine update branch

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