Class: Shipeasy::OpenFeature::Provider

Inherits:
Object
  • Object
show all
Defined in:
lib/shipeasy/sdk/openfeature.rb

Overview

Shipeasy OpenFeature provider (server paradigm). Wraps a ‘Shipeasy::SDK::FlagsClient`; evaluation is local against the cached blob, so resolution is effectively synchronous.

Constant Summary collapse

OF =
::OpenFeature::SDK::Provider
REASON_MAP =

Shipeasy ‘FlagDetail#reason` → [OpenFeature reason, optional error_code]. Per the cross-SDK contract (doc 20):

RULE_MATCH        TARGETING_MATCH
DEFAULT           DEFAULT
OFF               DISABLED
OVERRIDE          STATIC
FLAG_NOT_FOUND    ERROR (error_code FLAG_NOT_FOUND)
CLIENT_NOT_READY  ERROR (error_code PROVIDER_NOT_READY)
{
  Shipeasy::SDK::FlagsClient::REASON_RULE_MATCH       => [OF::Reason::TARGETING_MATCH, nil],
  Shipeasy::SDK::FlagsClient::REASON_DEFAULT          => [OF::Reason::DEFAULT, nil],
  Shipeasy::SDK::FlagsClient::REASON_OFF              => [OF::Reason::DISABLED, nil],
  Shipeasy::SDK::FlagsClient::REASON_OVERRIDE         => [OF::Reason::STATIC, nil],
  Shipeasy::SDK::FlagsClient::REASON_FLAG_NOT_FOUND   => [OF::Reason::ERROR, OF::ErrorCode::FLAG_NOT_FOUND],
  Shipeasy::SDK::FlagsClient::REASON_CLIENT_NOT_READY => [OF::Reason::ERROR, OF::ErrorCode::PROVIDER_NOT_READY],
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ Provider

Returns a new instance of Provider.



69
70
71
72
# File 'lib/shipeasy/sdk/openfeature.rb', line 69

def initialize(client)
  @client = client
  @metadata = OF::ProviderMetadata.new(name: "shipeasy").freeze
end

Instance Attribute Details

#metadataObject (readonly)

Returns the value of attribute metadata.



67
68
69
# File 'lib/shipeasy/sdk/openfeature.rb', line 67

def 
  @metadata
end

Instance Method Details

#fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil) ⇒ Object

— Boolean → gate ——————————————————



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/shipeasy/sdk/openfeature.rb', line 86

def fetch_boolean_value(flag_key:, default_value:, evaluation_context: nil)
  user = to_user(evaluation_context)
  detail = @client.get_flag_detail(flag_key, user)
  of_reason, error_code = REASON_MAP.fetch(detail.reason, [OF::Reason::UNKNOWN, nil])

  if error_code
    OF::ResolutionDetails.new(value: default_value, reason: of_reason, error_code: error_code)
  else
    OF::ResolutionDetails.new(value: detail.value, reason: of_reason)
  end
rescue => e
  OF::ResolutionDetails.new(
    value: default_value, reason: OF::Reason::ERROR,
    error_code: OF::ErrorCode::GENERAL, error_message: e.message,
  )
end

#fetch_float_value(flag_key:, default_value:, evaluation_context: nil) ⇒ Object



117
118
119
# File 'lib/shipeasy/sdk/openfeature.rb', line 117

def fetch_float_value(flag_key:, default_value:, evaluation_context: nil)
  resolve_config(flag_key, default_value) { |v| numeric?(v) }
end

#fetch_integer_value(flag_key:, default_value:, evaluation_context: nil) ⇒ Object



113
114
115
# File 'lib/shipeasy/sdk/openfeature.rb', line 113

def fetch_integer_value(flag_key:, default_value:, evaluation_context: nil)
  resolve_config(flag_key, default_value) { |v| v.is_a?(Integer) }
end

#fetch_number_value(flag_key:, default_value:, evaluation_context: nil) ⇒ Object



109
110
111
# File 'lib/shipeasy/sdk/openfeature.rb', line 109

def fetch_number_value(flag_key:, default_value:, evaluation_context: nil)
  resolve_config(flag_key, default_value) { |v| numeric?(v) }
end

#fetch_object_value(flag_key:, default_value:, evaluation_context: nil) ⇒ Object



121
122
123
# File 'lib/shipeasy/sdk/openfeature.rb', line 121

def fetch_object_value(flag_key:, default_value:, evaluation_context: nil)
  resolve_config(flag_key, default_value) { |v| v.is_a?(Hash) || v.is_a?(Array) }
end

#fetch_string_value(flag_key:, default_value:, evaluation_context: nil) ⇒ Object

— String / number / integer / float / object → dynamic config ——–



105
106
107
# File 'lib/shipeasy/sdk/openfeature.rb', line 105

def fetch_string_value(flag_key:, default_value:, evaluation_context: nil)
  resolve_config(flag_key, default_value) { |v| v.is_a?(String) }
end

#init(_evaluation_context = nil) ⇒ Object

OpenFeature lifecycle (optional but supported): fetch the blob once and tear down the poll thread on shutdown.



76
77
78
# File 'lib/shipeasy/sdk/openfeature.rb', line 76

def init(_evaluation_context = nil)
  @client.init_once
end

#shutdownObject



80
81
82
# File 'lib/shipeasy/sdk/openfeature.rb', line 80

def shutdown
  @client.destroy
end

#track(tracking_event_name, evaluation_context: nil, details: {}) ⇒ Object

OpenFeature ‘track()` → Shipeasy `track()`. No-ops without a targeting key.



126
127
128
129
130
131
132
133
# File 'lib/shipeasy/sdk/openfeature.rb', line 126

def track(tracking_event_name, evaluation_context: nil, details: {})
  ctx = normalize_context(evaluation_context)
  user_id = ctx["targeting_key"] || ctx["user_id"]
  return if user_id.nil? || user_id.to_s.empty?

  props = details.is_a?(Hash) ? details : {}
  @client.track(user_id, tracking_event_name, props)
end