-
Notifications
You must be signed in to change notification settings - Fork 58
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
Handle named wildcards (REST path parameters) #123
Conversation
Signed-off-by: Daniel Widdis <[email protected]>
Signed-off-by: Daniel Widdis <[email protected]>
Signed-off-by: Daniel Widdis <[email protected]>
Signed-off-by: Daniel Widdis <[email protected]>
Codecov Report
@@ Coverage Diff @@
## main #123 +/- ##
============================================
+ Coverage 65.81% 69.62% +3.81%
- Complexity 60 73 +13
============================================
Files 14 16 +2
Lines 313 349 +36
Branches 9 11 +2
============================================
+ Hits 206 243 +37
+ Misses 100 99 -1
Partials 7 7
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. |
Signed-off-by: Daniel Widdis <[email protected]>
ac0a4c2
to
67e5b3a
Compare
Rocking the code coverage 💪 Also poor-man's integration test:
|
@dbwiddis do you think we should have break this PR into smaller pieces? |
Possibly, but some of the pieces might break as they depend on each other. The first commit is the main part of the implementation and is only 4 files (2 changes + 2 tests) and is most of what needs to be reviewed. The rest is implementing/demoing/documenting/bugfixing that first commit. For ease of reviewing, you can click on each commit separately:
|
@owaiskazi19 I added some notes to the outline in the first comment noting which commit they correspond to. I think that should help reviewers logically piece together all the changes.) |
Probably comments on specific commits are not visible here. Something new I learned :) |
Yeah, bummer. Click on the "Commits" tab up top :) I did see and reply to your comments, though... |
Signed-off-by: Daniel Widdis <[email protected]>
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.
Thanks @dbwiddis for the changes.
@@ -0,0 +1,89 @@ | |||
{ |
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.
For my learning: Why do we need specs with .json
and .yml
?
Is it mostly of different clients to generate APIs?
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.
We don't need both. It's probably an either-or. I find the YAML one easier to read/edit, but the JSON one seems common for the OpenSearch spec. Also there is discussion about using other tools to generate either of these from a simpler format. This is mostly just a prompt/reminder for the future. See #127
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.
assertNull(extensionRestPathRegistry.getHandler(Method.PUT, "/bar/mars/bar")); | ||
|
||
assertEquals(bazHandler, extensionRestPathRegistry.getHandler(Method.POST, "/baz/europa/qux")); | ||
assertNull(extensionRestPathRegistry.getHandler(Method.POST, "/bar/europa")); |
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 was like why doesn't this work and I realized the Method is POST.
For few paths, folks usually want to support multiple Methods like GET, DELETE etc.
Is this something you plan on to add ?
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.
The capability is there, you just add it in routes()
and handle it appropriately in handleRequest()
. I'm trying not to overcomplicate hello world, though! :)
Co-authored-by: Sarat Vemulapalli <[email protected]> Signed-off-by: Daniel Widdis <[email protected]>
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.
One nit, great forward progress.
// PathTrie to match paths to handlers | ||
private PathTrie<ExtensionRestHandler> pathTrie = new PathTrie<>(RestUtils.REST_DECODER); | ||
// List to return registered handlers | ||
private List<String> registeredPaths = new ArrayList<>(); |
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 gives off a code smell where this class is additional functionality to the data structure, can we add getKeys()
to the PathTrie implementation?
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.
@peternied I tried that route. Unfortunately the PathTrie
does not have functionality to list keys. You can insert, but the retrieve functionality requires you to give it a path (and possibly parameters to match). There is no way to generate a list of paths (short of a brute force dictionary attack of all possible strings to see which ones work).
This lack of functionality on the PathTrie is also a challenge in testing (no way to validate/confirm that a path has been inserted, other than an IT) and might be a reasonable feature request to OpenSearch. But for now, for the purposes of deserializing the extension REST API to pass it over, this slightly smelly code is really the only reasonable option.
* Register REST paths including named wildcards Signed-off-by: Daniel Widdis <[email protected]> * Move HelloWorld extension to subpackage Signed-off-by: Daniel Widdis <[email protected]> * Update Hello World example with named wildcard example Signed-off-by: Daniel Widdis <[email protected]> * Pass consumed params in RestResponse header Signed-off-by: Daniel Widdis <[email protected]> * Linelint hates me and web tool exports Signed-off-by: Daniel Widdis <[email protected]> * Code Review tweaks Signed-off-by: Daniel Widdis <[email protected]> * Update DESIGN.md Co-authored-by: Sarat Vemulapalli <[email protected]> Signed-off-by: Daniel Widdis <[email protected]> Signed-off-by: Daniel Widdis <[email protected]> Co-authored-by: Sarat Vemulapalli <[email protected]>
Companion PR: opensearch-project/OpenSearch#4415
Description
Adds the ability to handle REST path parameters (named wildcards). It is necessary to indicate which parameters were consumed. If the user provides too many parameters, they receive an error.
In local/plugin operation, simply fetching the parameter via
param(key)
consumes it. Since the parameters are being consumed remotely, this requires communicating the list of consumed parameters, which is done in the response header (normally unused and provided for purposes such as this!)Primary changes:
pathMap
inExtensionsRunner
with anExtensionRestPathRegistry
.PathTrie
so that the matching behavior matches that of the OpenSearchRestController
ExtensionRestResponse
. This is a simple wrapper for aBytesRestResponse
with added handling for a list of consumed parametersRestResponse
class already provides a facility for custom headers, presently only used with theOpenSearchException
class. Adding a new key for consumed parameters doesn't conflict with this usage.HelloWorldExtension
to add another Route:PUT
and a{name}
parameter allows changing the name of the world for future greetings.ExtensionRestPathRegistry
,ExtensionRestResponse
, and sample extension behavior, as well as updating other tests as required.Other changes (mostly in second commit):
./gradlew run
to the test settings onExtensionsRunner
and added a newtask
for the Hello World extension: it can be executed with./gradlew helloWorld
.HelloWorld
extension into a subpackage of thesample
package in anticipation of more samples (such as the CRUD sample the security team is working on).Issues Resolved
Fixes #122
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.