-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
WIP Xpack spi request #60220
Conversation
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. 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(); |
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: 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(); | ||
} |
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.
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.
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 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
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.
@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); |
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.
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.
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.
see #60220 (comment)
CompatibleApiVersionProvider compatibleApiVersionProvider = first.orElseGet(() -> () -> Version.CURRENT); | ||
// TODO should we fetch that dynamically when calling minimumRestCompatibilityVersion() ? | ||
minimumRestCompatibilityVersion = compatibleApiVersionProvider.minimumRestCompatibilityVersion(); | ||
System.out.println(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.
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) |
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 we through an exception if there are multiple plugins that implement the interface ?
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.
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 { |
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 removed if we remove the println from the Version class ?
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.
++
this.headersToCopy = headersToCopy; | ||
this.usageService = usageService; | ||
this.minimumRestCompatibilityVersion = 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: 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) { |
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: 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 { |
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 we get rid of this if we remove the println from Version ?
|
||
import org.elasticsearch.Version; | ||
|
||
public interface CompatibleApiVersionProvider { |
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.
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
Some revisions to the idea of using a function
gradle check
?