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

WIP Xpack spi request #60220

Closed
wants to merge 12 commits into from
Closed

Conversation

pgomulka
Copy link
Contributor

  • Have you signed the contributor license agreement?
  • Have you followed the contributor guidelines?
  • If submitting code, have you built your formula locally prior to submission with gradle check?
  • If submitting code, is your pull request against master? Unless there is a good reason otherwise, we prefer pull requests against master and will backport as needed.
  • If submitting code, have you checked that your submission is for an OS and architecture that we support?
  • If you are submitting this code for a class then read our policy for that.

@pgomulka pgomulka changed the title Xpack spi request WIP Xpack spi request Jul 27, 2020
@pgomulka pgomulka added the WIP label Jul 27, 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.

Looking good. I like this approach, but think it would be cleaner if we passed a Function<String,Version> from the plugin.

import org.elasticsearch.Version;

public interface RestCompatibilityPlugin {
Version minimumRestCompatibilityVersion();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I would suggest to just call this restCompatibleVersion including minimum implies there is a maximum and things in-between which there may be in future versions but for not a single version seems right.


public interface RestCompatibilityPlugin {
Version minimumRestCompatibilityVersion();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of a Version method, can this be a Function that accepts a String (the header) and returns Version such that that the function can passed into the RestController and applied as need. It will help to keep the logic encapsulated in the plugin, such that the OSS code only needs to know about the header so it can pass it to the function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am actually not convinced this will be a good idea. I know that we want to as much compatible code into xpack plugin, but from Object Oriented model of RestRequest that function really belongs there.
I made an attempt to show you how it would look if we extract this.
The main problem is that we essentially are exposing RestRequest details (although these are still public - hasContent and headers) and pass it over to a function implemented in a xpack plugin.
Take a look and let me know

Copy link
Contributor

Choose a reason for hiding this comment

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

@pgomulka I submitted a PR to your branch pgomulka#21 with some thoughts on how this can be tweaked to be a bit cleaner.

The changes suggested (in PR):

  • remove need for hasContent(), and simply look at the existence of Content-Type
  • pass only the Accept and Content-Type headers through the function
  • create the function as soon as possible and pass that around
  • minor naming/organization such that the plugin happens to implement the functional interface, (as opposed to IS the interface)
  • minor tweaking to the validation rules for the headers (since don't have hasContent())
  • move all parsing logic to plugin. (some may need to go back in xContent, but for now I think this should work)

I am still +1 to functional over OO, maybe the proposed changes will help to change your mind ? Let me know.



private boolean isRequestingCompatibility() {
/* String acceptHeader = header(CompatibleConstants.COMPATIBLE_ACCEPT_HEADER);
Copy link
Contributor

Choose a reason for hiding this comment

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

If we pass around a function we can put this logic in the plugin. Calling the function or not can be determined if the header exists at all or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

CompatibleApiVersionProvider compatibleApiVersionProvider = first.orElseGet(() -> () -> Version.CURRENT);
// TODO should we fetch that dynamically when calling minimumRestCompatibilityVersion() ?
minimumRestCompatibilityVersion = compatibleApiVersionProvider.minimumRestCompatibilityVersion();
System.out.println(minimumRestCompatibilityVersion);
Copy link
Contributor

Choose a reason for hiding this comment

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

this is nice to have ... but I don't think it is needed since it will always be current major-1. If i understand correctly this also requires an additional interface ?

Can we remove this ?

private Version getMinimumRestCompatibilityVersion(List<RestCompatibilityPlugin> restCompatPlugins) {
return restCompatPlugins.stream()
.map(RestCompatibilityPlugin::minimumRestCompatibilityVersion)
.max(Version::compareTo)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we through an exception if there are multiple plugins that implement the interface ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

right, that method always return current -1 so older APIs will not be accessible (verison -2 - compat apis present still in for a short period of time after version bump)


import org.elasticsearch.Version;

public interface CompatibleApiVersionProvider {
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 be removed if we remove the println from the Version class ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

++

this.headersToCopy = headersToCopy;
this.usageService = usageService;
this.minimumRestCompatibilityVersion = minimumRestCompatibilityVersion;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: restCompatibleVersion

* Only a major Versions are supported. Internally we use Versions objects, but only use Version(major,0,0)
* @return a version with what a client is compatible with.
*/
public Version getCompatibleApiVersion(Version minimumRestCompatibilityVersion) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: maybeGetCompatibleApiVersion


//TODO I don't think we want SPI approach. to load spi with ServiceLoader we need to fetch a plugin with the same classloader
// that means we can get the minimumRestCompatibilityVersion from the plugin itself
public class PreviousVersionCompatibleApiProvider implements CompatibleApiVersionProvider {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we get rid of this if we remove the println from Version ?


import org.elasticsearch.Version;

public interface CompatibleApiVersionProvider {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

O I don't think we want SPI approach. to load spi with ServiceLoader we need to fetch a plugin with the same classloader
we can use that plugin directly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants