So you want to contribute code to the OpenSearch Ruby client? Excellent! We're glad you're here. Here's what you need to do.
Fork opensearch-project/opensearch-ruby and clone locally, e.g. git clone https://github.com/[your username]/opensearch-ruby.git
.
- Install ruby to continue with the development.
- Install bundler to manage dependencies.
- Install all dependencies using
bundle install
. - Install Docker, required for running integration tests for the repo.
Tests configurations are grouped into rake tasks in test
namespace. Integration tests require a running OpenSearch cluster:
export CLUSTER_VERSION=latest
export PORT=9200
export DISABLE_SECURITY=true
./.github/actions/opensearch/run.sh
To run all tests:
rake test:all
Run all unit tests:
rake test:unit
Run unit tests of a specific module:
rake test:api:unit
rake test:transport:unit
rake test:dsl:unit
rake test:client:unit
To run integration tests for the ruby client, start an OpenSearch cluster using docker:
Run all integration tests:
rake test:integration:all
run integration tests of a specific module:
rake test:api:integration
rake test:transport:integration
rake test:dsl:integration
rake test:client:integration
Use Rubocop to auto-lint Ruby code.
rubocop -a
rubocop --auto-gen-config
the generate_api workflow runs every Sunday at 00:00 UTC to generate API actions from the latest OpenSearch REST API, and creates a PR with the changes. You can also run the workflow locally to generate API actions:
bundle exec rake download_spec
bundle exec rake generate_api
The OpenSearch ruby client supports request signing as an authentication mechanism. When instantiating a client, you can pass a request signer object to sign requests. The request signer object implements the sign_request
method that returns a hash representing the signed headers. This method must accept the following parameters:
method
(String): The HTTP method of the request. (e.g.GET
,POST
,PUT
,DELETE
)host
(String): The host of the request. (e.g.localhost
)path
(String): The path of the request. (e.g._search
,_cluster/health
)port
(Integer): The port of the request. (e.g.9200
)url
(String): The full URL of the request. (e.g.'https://localhost:9200/_search?q=example'
)params
(Hash): The query parameters of the request. (e.g.{ 'q' => 'example' }
)headers
(Hash): The headers of the request. (e.g.{ 'Content-Type' => 'application/json' }
)body
(String | Hash | NilClass): The body of the request. (e.g.{ query: { match_all: {}}
)logger
(Logger | NilClass): The logger object to log messages. (e.g.Logger.new(STDOUT)
)
Note that you can ignore any of the parameters if they are not needed for the signing process. The following is a simple example of a request signer implementation:
class MyRequestSigner
def initialize(public_key, private_key)
@public_key = public_key
@private_key = private_key
end
def sign_request(method:, host:, path:, port:, url:, params:, headers:, body:, logger:)
logger&.info("Signing request: #{method} #{url}")
signed_headers = headers.merge({
'X-Date' => Time.now.utc.strftime('%Y%m%dT%H%M%SZ'),
'X-public_key' => @public_key,
'X-Hash' => OpenSSL::HMAC.hexdigest('sha256', @private_key, body.to_s)
})
logger&.debug("Signed headers: #{signed_headers}")
signed_headers
end
end
See CONTRIBUTING.
-
{OpenSearch::Transport::Client} is composed of {OpenSearch::Transport::Transport}
-
{OpenSearch::Transport::Transport} is composed of {OpenSearch::Transport::Transport::Connections}, and an instance of logger, tracer, serializer and sniffer.
-
Logger and tracer can be any object conforming to Ruby logging interface, i.e. an instance of
Logger
, log4r, logging, etc. -
The {OpenSearch::Transport::Transport::Serializer::Base} implementations handle converting data for OpenSearch (e.g. to JSON). You can implement your own serializer.
-
{OpenSearch::Transport::Transport::Sniffer} allows to discover nodes in the cluster and use them as connections.
-
{OpenSearch::Transport::Transport::Connections::Collection} is composed of {OpenSearch::Transport::Transport::Connections::Connection} instances and a selector instance.
-
{OpenSearch::Transport::Transport::Connections::Connection} contains the connection attributes such as hostname and port, as well as the concrete persistent "session" connected to a specific node.
-
The {OpenSearch::Transport::Transport::Connections::Selector::Base} implementations allow to choose connections from the pool, e.g. in a round-robin or random fashion. You can implement your own selector strategy.