Skip to content

Commit

Permalink
chore: upgrade grpc client (#16)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexandre Chakroun <[email protected]>
  • Loading branch information
alxckn authored Apr 8, 2024
1 parent f59b3b4 commit 23ed78a
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 138 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,8 @@ jobs:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
working-directory: ./providers/openfeature-flagd-provider
- name: Launch flagd instance
run: docker-compose up -d flagd
working-directory: ./providers/openfeature-flagd-provider/docker
- name: Run tests
run: bundle exec rspec
46 changes: 26 additions & 20 deletions providers/openfeature-flagd-provider/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,40 @@ GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
diff-lcs (1.5.0)
google-protobuf (3.21.12)
googleapis-common-protos-types (1.4.0)
google-protobuf (~> 3.14)
grpc (1.50.0)
google-protobuf (~> 3.21)
diff-lcs (1.5.1)
google-protobuf (3.25.3-arm64-darwin)
google-protobuf (3.25.3-x86_64-linux)
googleapis-common-protos-types (1.14.0)
google-protobuf (~> 3.18)
grpc (1.62.0-arm64-darwin)
google-protobuf (~> 3.25)
googleapis-common-protos-types (~> 1.0)
json (2.6.2)
parallel (1.22.1)
parser (3.1.3.0)
grpc (1.62.0-x86_64-linux)
google-protobuf (~> 3.25)
googleapis-common-protos-types (~> 1.0)
json (2.7.2)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
racc
racc (1.7.3)
rainbow (3.1.1)
rake (13.0.6)
regexp_parser (2.6.1)
rexml (3.2.5)
rake (13.2.1)
regexp_parser (2.9.0)
rexml (3.2.6)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.0)
rspec-core (3.12.3)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.0)
rspec-expectations (3.12.4)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.0)
rspec-mocks (3.12.7)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.0)
rspec-support (3.12.2)
rubocop (1.37.1)
json (~> 2.3)
parallel (~> 1.10)
Expand All @@ -46,10 +52,10 @@ GEM
rubocop-ast (>= 1.23.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.23.0)
parser (>= 3.1.1.0)
ruby-progressbar (1.11.0)
unicode-display_width (2.3.0)
rubocop-ast (1.31.2)
parser (>= 3.3.0.4)
ruby-progressbar (1.13.0)
unicode-display_width (2.5.0)

PLATFORMS
arm64-darwin-21
Expand Down
10 changes: 10 additions & 0 deletions providers/openfeature-flagd-provider/docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: '3.7'

services:
flagd:
image: ghcr.io/open-feature/flagd:v0.9.2
ports:
- '127.0.0.1:8013:8013'
volumes:
- ./:/etc/flagd
command: start -x --uri file:./etc/flagd/flags.json
41 changes: 41 additions & 0 deletions providers/openfeature-flagd-provider/docker/flags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "https://flagd.dev/schema/v0/flags.json",
"flags": {
"boolean-flag": {
"state": "ENABLED",
"variants": {
"on": true,
"off": false
},
"defaultVariant": "off"
},
"integer-flag": {
"state": "ENABLED",
"variants": {
"fourty-two": 42
},
"defaultVariant": "fourty-two"
},
"float-flag": {
"state": "ENABLED",
"variants": {
"four-point-two": 4.2
},
"defaultVariant": "four-point-two"
},
"string-flag": {
"state": "ENABLED",
"variants": {
"lilili": "lalala"
},
"defaultVariant": "lilili"
},
"object-flag": {
"state": "ENABLED",
"variants": {
"real-object": { "real": "value" }
},
"defaultVariant": "real-object"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,49 +30,63 @@ module Provider
# * <tt>resolve_object_value(flag_key:, default_value:, context: nil)</tt>
# manner; <tt>client.resolve_object_value(flag_key: 'flag', default_value: { default_value: 'value'})</tt>
class Client
PROVIDER_NAME = "flagd Provider"

attr_reader :metadata

def initialize(configuration: nil)
@metadata = Metadata.new(PROVIDER_NAME).freeze
@metadata = Metadata.new(PROVIDER_NAME)
@grpc_client = grpc_client(configuration)
end

PROVIDER_NAME = "flagd Provider"
TYPE_RESOLVER_MAPPER = {
boolean: Grpc::ResolveBooleanRequest,
integer: Grpc::ResolveIntRequest,
float: Grpc::ResolveFloatRequest,
string: Grpc::ResolveStringRequest,
object: Grpc::ResolveObjectRequest
}.freeze

TYPE_RESOLVER_MAPPER.each_pair do |type, resolver|
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def resolve_#{type}_value(flag_key:, default_value:, context: nil)
request = #{resolver}.new(flag_key: flag_key)
response = @grpc_client.resolve_#{type}(request)
ResolutionDetails.new(nil, nil, response.reason, response.value, response.variant).to_h.freeze
rescue GRPC::NotFound => e
error_response("FLAG_NOT_FOUND", e.message)
rescue GRPC::InvalidArgument => e
error_response("TYPE_MISMATCH", e.message)
rescue GRPC::Unavailable => e
error_response("FLAG_NOT_FOUND", e.message)
rescue GRPC::DataLoss => e
error_response("PARSE_ERROR", e.message)
rescue StandardError => e
error_response("GENERAL", e.message)
end
RUBY

def resolve_boolean_value(flag_key:, default_value:, context: nil)
request = Grpc::ResolveBooleanRequest.new(flag_key: flag_key)
process_request { @grpc_client.resolve_boolean(request) }
end

def resolve_integer_value(flag_key:, default_value:, context: nil)
request = Grpc::ResolveIntRequest.new(flag_key: flag_key)
process_request { @grpc_client.resolve_int(request) }
end

def resolve_float_value(flag_key:, default_value:, context: nil)
request = Grpc::ResolveFloatRequest.new(flag_key: flag_key)
process_request { @grpc_client.resolve_float(request) }
end

def resolve_string_value(flag_key:, default_value:, context: nil)
request = Grpc::ResolveStringRequest.new(flag_key: flag_key)
process_request { @grpc_client.resolve_string(request) }
end

def resolve_object_value(flag_key:, default_value:, context: nil)
request = Grpc::ResolveObjectRequest.new(flag_key: flag_key)
process_request { @grpc_client.resolve_object(request) }
end

private

Metadata = Struct.new("Metadata", :name)
ResolutionDetails = Struct.new("ResolutionDetails", :error_code, :error_message, :reason, :value, :variant)

def process_request(&block)
response = block.call
ResolutionDetails.new(nil, nil, response.reason, response.value, response.variant).to_h
rescue GRPC::NotFound => e
error_response("FLAG_NOT_FOUND", e.message)
rescue GRPC::InvalidArgument => e
error_response("TYPE_MISMATCH", e.message)
rescue GRPC::Unavailable => e
error_response("FLAG_NOT_FOUND", e.message)
rescue GRPC::DataLoss => e
error_response("PARSE_ERROR", e.message)
rescue StandardError => e
error_response("GENERAL", e.message)
end

def error_response(error_code, error_message)
ResolutionDetails.new(error_code, error_message, "ERROR", nil, nil).to_h.freeze
ResolutionDetails.new(error_code, error_message, "ERROR", nil, nil).to_h
end

def grpc_client(configuration)
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion providers/openfeature-flagd-provider/schemas
Loading

0 comments on commit 23ed78a

Please sign in to comment.