-
Notifications
You must be signed in to change notification settings - Fork 46
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
API Generator and Removing support of Ruby 2 #261
Conversation
Highly encourage you to do this instead of trying to address Rubocop complaining:
|
Consider splitting this into the generator and generated code PRs? |
@dblock There is a lot of refactoring that requires the existing API methods to also be updated (via running the generator) that it's impossible to do so without. I'll write up what's being change once I get all the tests to pass. |
5c49ab0
to
fc3f775
Compare
@dblock This is ready for review. There's a lot going on but basically:
OLD: def delete(arguments = {})
raise ArgumentError, "Required argument 'index' missing" unless arguments[:index]
raise ArgumentError, "Required argument 'id' missing" unless arguments[:id]
headers = arguments.delete(:headers) || {}
arguments = arguments.clone
_id = arguments.delete(:id)
_index = arguments.delete(:index)
method = OpenSearch::API::HTTP_DELETE
path = "#{Utils.__listify(_index)}/_doc/#{Utils.__listify(_id)}"
params = Utils.__validate_and_extract_params arguments, ParamsRegistry.get(__method__)
body = nil
if Array(arguments[:ignore]).include?(404)
Utils.__rescue_from_not_found { perform_request(method, path, params, body, headers).body }
else
perform_request(method, path, params, body, headers).body
end
end
ParamsRegistry.register(:delete, %i[
wait_for_active_shards
refresh
...
].freeze) NEW: def delete(args = {})
args = Utils.normalize_arguments(args)
raise ArgumentError, "Required argument 'id' missing" unless args['id']
raise ArgumentError, "Required argument 'index' missing" unless args['index']
_id = args.delete('id')
_index = args.delete('index')
ignore = args.delete('ignore') || []
headers = args.delete('headers') || {}
body = args.delete('body')
method = 'DELETE'
url = [_index, '_doc', _id].filter(&:present?).join('/').squeeze('/')
Utils.validate_query_params args, DELETE_QUERY_PARAMS
transport.perform_delete_request method, url, args, body, headers, ignore.include?(404)
end
DELETE_QUERY_PARAMS = Set.new(%w[
if_primary_term
if_seq_no
...
]).freeze |
This looks pretty cool. I haven't checked it out too closely but have two comments for now:
|
The main difference I want from
That's not what |
Right, in that case you can write it like this: [nil, "", "123", 456].reject { _1.nil? || (_1.is_a?(String) && _1.empty?) } It's a bit more code but not much so and I would say this is worth it to drop for that, especially since it's all generated anyways. As a rails-agnostic library I would never force
Apologies, I'm not sure how I missed that method. Carry on.
I think that will be marginally faster since it can avoid an allocation in case the key is already a symbol with |
@nhtruong I know I said that my personal opinion is not to worry about this, but if the only thing we're using is |
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 good with this with whatever revisions you want to make, I'd say my only must have is the need to have to duplicate args before .delete
.
One of a future improvements would be to use keyword arguments instead of args = {}
.
I see a bunch of deleted specs. Do you feel like we don't need to generate tests that call these generated methods?
@@ -1,6 +1,10 @@ | |||
# Upgrading | |||
Major versions of OpenSearch introduce breaking changes that require careful upgrades of the client. Check the [Compatibility](COMPATIBILITY.md) doc to see which version of the client should be used against your OpenSearch cluster. | |||
|
|||
### Upgrade to OpenSearch Ruby 4 |
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.
Any interface changes at all?
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 in in the API methods?
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, but looks like none?
Similar to #261 (comment)
It's actually already using keyword arguments. You can do
Those are legacy unit tests that weren't useful in the first place. This is the only client that has unit tests for every API method to make sure that an error is thrown when a required param is not provided or when an illegal query param is provided. And especially with generated API method, if we're also generating these specs, it's pretty much testing if |
Thanks for the feedback, everyone. Here are the changes I'm going to work on when I get back to this:
|
Signed-off-by: Theo Truong <[email protected]>
a3ec626
to
cecf316
Compare
This is ready for review again. |
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'm going to merge this, let's cut a beta so we can try it out.
@@ -1,6 +1,10 @@ | |||
# Upgrading | |||
Major versions of OpenSearch introduce breaking changes that require careful upgrades of the client. Check the [Compatibility](COMPATIBILITY.md) doc to see which version of the client should be used against your OpenSearch cluster. | |||
|
|||
### Upgrade to OpenSearch Ruby 4 |
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, but looks like none?
@@ -0,0 +1,16 @@ | |||
# SPDX-License-Identifier: Apache-2.0 |
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 should be capitalized Gemfile
that's the standard ;)
This PR contains an API generator for the OpenSearch Ruby client. This generator does not simply generate the API methods conforming to the how methods and namespaces are currently structured in this repo. Instead, the generated methods are in a new structure that is simpler, and move intuitive to use. There's also some refactoring of the existing API methods to streamline the code and fix some issues.
Module structure
Currently, each API method is added to the
OpenSearch::Client
class via a chain of includes. For example thehealth
method of thecat
namespace is added to theOpenSearch::Client
class via the following chain of includes:OpenSearch::Client
includesOpenSearch::API
OpenSearch::API
when included, triggers the inclusion ofOpenSearch::API::Cat
and other namespaces to the base class (i.e.OpenSearch::Client
)OpenSearch::API::Cat
contains thecat
method, which returns an instance of theOpenSearch::API::Cat::CatClient
class.OpenSearch::API::Cat::CatClient
includes theOpenSearch::API::Cat::Actions
module, which contains thehealth
method.The new structure is a a lot simpler: Within the definition of the
OpenSearch::Client
class itself, there's a method namedcat
that returns an instance of theOpenSearch::Namespace
that includes theOpenSearch::API::Cat::Actions
module where thehealth
method is defined. Note that we also do not need to define a class for each namespace anymore.How the perform_request method is invoked
Currently when you call
client.cat.health
:perform_request
method of the::CatClient
, which it gets from the::Common
module.perform_request
method of theOpenSearch::Client
class.OpenSearch::Client
class actually does not define aperform_request
method. So, method_missing is calledmethod_missing
verifies the OpenSearch version before passing the baton to theperform_request
method ofOpenSearch::Transport::Client
.The new path is a lot simpler: when
client.cat.health
is called, it directly calls theperform_request
method ofOpenSearch::Transport::Client
. Note that this also skips over the version check, which is not needed anymore.Storing valid query parameters
Currently, each namespace defines a
ParamsRegistry
module that registers an array of valid query parameters symbols per API action. These are iterated to validate the query parameters passed to the API method.With the new approach, the query parameter names are stored as a set of strings (instead of an array of symbols) in a CONSTANT named after the API action. This approach has the following benefits:
ParamsRegistry
module for each namespace.include?
method of theSet
class..
in the notifications namespace.Normalizing query parameters
Instead of simply cloning the arguments passed to the API method, the new approach creates a new hash where all keys are converted to strings. This is done to ensure that the query parameters are always in a consistent format, and add support for query parameters with special characters.
Validating query parameters
Currently, this validation is done through __validate_and_extract_params method, which iterates over the array of valid query params TWICE per param. The new validate_query_params method only needs to check if the query parameter is included in the set of valid query parameters.
This PR also removes the support of Ruby 2.x, which is a breaking change. Client version has also been bumped to 4.0.0
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.