Class: ConvertSdk::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/convert_sdk/config.rb

Overview

The SDK's configuration surface and wire-translation boundary #1.

+Config+ is the ONE place in the gem where the inbound public naming world (idiomatic snake_case keyword arguments) is translated into the internal / wire naming world (string-keyed camelCase). The only other naming-world conversion site in the entire gem is the outbound payload builder in ApiManager (Story 4.1); any other file converting option names is an architecture violation (the two-worlds rule).

== JS-parity defaults

DEFAULTS carries the frozen JS-parity values — batch 10, flush interval 1s, data-refresh 300s, bucketing seed 9999 / max-traffic 10000 / max-hash 2**32. These exact numbers are restated across the PRD, architecture, and research; they are NOT tuning knobs and must not drift. Endpoint URLs are copied verbatim from the reference SDKs' default config.

== Fail-fast validation (the SDK's only raising surface)

Construction delegates to ConfigValidator, which raises a stdlib +ArgumentError+ — naming the offending option and the expected type — for any presence/type violation. This is the SDK's ONLY raising surface (Decision 3): there is no custom exception hierarchy, because the SDK degrades gracefully (cached config / sentinels) for every runtime/infra failure, leaving nothing for a hierarchy to hold. Misconfiguration therefore surfaces immediately at boot rather than as silent misbehavior in production. Unknown option keys are rejected for the same reason — a typo fails fast instead of being ignored.

== Nil-able timer intervals (Lambda / CLI mode)

+flush_interval+ and +data_refresh_interval+ accept +nil+, meaning timer-off: the background flush / refresh threads are never started. This is the AWS Lambda and plain-CLI recipe (synchronous flush before exit; no background threads). +flush_interval+ is the canonical flush-timer key throughout the gem (the older +event_release_interval+ alias is retired).

== Secret registration (NFR5)

When an +sdk_key+ / +sdk_key_secret+ is present and a LogManager is injected, +Config+ registers those values with the manager's Redactor immediately at construction — so secrets are armed before any log line can carry them. +Config+ is constructible standalone (no +log_manager+) for unit tests; +ConvertSdk.create+ / Client (Story 2.5) injects the real manager.

Constant Summary collapse

MILLISECONDS_PER_SECOND =

Number of milliseconds per second — the +flush_interval+ second→ms wire translation factor.

1000
MAX_HASH =

The fixed bucketing hash space (2**32). A JS-parity constant, not a configurable option — exposed as a reader for the bucketing engine.

4_294_967_296
DEFAULTS =

The frozen JS-parity defaults for every public option. Verified against javascript-sdk +config/default.ts+ and php-sdk +DefaultConfig.php+.

{
  # Auth / data — at least one of sdk_key / data is required (validated).
  sdk_key: nil,
  sdk_key_secret: nil,
  data: nil,
  # Platform environment selector; nil leaves it to the platform default.
  environment: nil,
  # Live Convert endpoints (verbatim from the reference default config).
  config_endpoint: "https://cdn-4.convertexperiments.com/api/v1",
  track_endpoint: "https://[project_id].metrics.convertexperiments.com/v1",
  # Bucketing constants — frozen JS-parity numbers, do not tune.
  max_traffic: 10_000,
  hash_seed: 9999,
  # Config-refresh cadence in seconds (JS 300000 ms); nil = timer-off.
  data_refresh_interval: 300,
  # Event delivery — batch size and flush cadence (seconds); nil = timer-off.
  event_batch_size: 10,
  flush_interval: 1,
  # Rule evaluation options.
  keys_case_sensitive: true,
  negation: "!",
  # Logging verbosity (JS default.ts:29 logLevel: LogLevel.DEBUG).
  log_level: LogLevel::DEBUG,
  # Network tracking enable/disable.
  tracking: true,
  # HTTP client timeouts in seconds (consumed by HttpClient, Story 1.5).
  open_timeout: 5,
  read_timeout: 10
}.freeze
KNOWN_KEYS =

The canonical set of accepted option keys (the DEFAULTS keys).

DEFAULTS.keys.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(log_manager: nil, **options) ⇒ Config

Build a validated configuration from snake_case keyword options merged over DEFAULTS. Raises +ArgumentError+ (the SDK's only raising surface) on any presence/type violation or unknown option key.

Parameters:

  • log_manager (LogManager, nil) (defaults to: nil)

    when provided, present secrets (sdk_key / sdk_key_secret) are registered with its Redactor so they are armed before any log line. Optional for standalone construction.

  • options (Hash{Symbol=>Object})

    any subset of the DEFAULTS keys.

Raises:

  • (ArgumentError)

    on unknown keys, missing sdk_key+data, or bad types.



139
140
141
142
143
144
145
# File 'lib/convert_sdk/config.rb', line 139

def initialize(log_manager: nil, **options)
  reject_unknown_keys(options)
  merged = DEFAULTS.merge(options)
  assign(merged)
  ConfigValidator.new(merged).validate!
  register_secrets(log_manager)
end

Instance Attribute Details

#config_endpointString (readonly)

Returns config-fetch base URL (JS +api.endpoint.config+).

Returns:

  • (String)

    config-fetch base URL (JS +api.endpoint.config+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#dataHash? (readonly)

Returns inline config payload (JS +data+); skips fetch.

Returns:

  • (Hash, nil)

    inline config payload (JS +data+); skips fetch.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#data_refresh_intervalNumeric? (readonly)

Returns config-refresh seconds; nil = timer-off (JS +dataRefreshInterval+, ms).

Returns:

  • (Numeric, nil)

    config-refresh seconds; nil = timer-off (JS +dataRefreshInterval+, ms).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#environmentString? (readonly)

Returns platform environment (JS +environment+).

Returns:

  • (String, nil)

    platform environment (JS +environment+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#event_batch_sizeInteger (readonly)

Returns event flush batch size (JS +events.batch_size+).

Returns:

  • (Integer)

    event flush batch size (JS +events.batch_size+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#flush_intervalNumeric? (readonly)

Returns flush cadence seconds; nil = timer-off (JS +events.release_interval+, ms). Canonical flush-timer key.

Returns:

  • (Numeric, nil)

    flush cadence seconds; nil = timer-off (JS +events.release_interval+, ms). Canonical flush-timer key.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#hash_seedInteger (readonly)

Returns bucketing hash seed (JS +bucketing.hash_seed+).

Returns:

  • (Integer)

    bucketing hash seed (JS +bucketing.hash_seed+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#keys_case_sensitiveBoolean (readonly)

Returns rule key case sensitivity (JS +rules.keys_case_sensitive+).

Returns:

  • (Boolean)

    rule key case sensitivity (JS +rules.keys_case_sensitive+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#log_levelInteger (readonly)

Returns a LogLevel threshold (JS +logger.logLevel+).

Returns:

  • (Integer)

    a LogLevel threshold (JS +logger.logLevel+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#max_trafficInteger (readonly)

Returns bucketing max traffic (JS +bucketing.max_traffic+).

Returns:

  • (Integer)

    bucketing max traffic (JS +bucketing.max_traffic+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#negationString (readonly)

Returns rule negation token (JS +rules.negation+, default "!").

Returns:

  • (String)

    rule negation token (JS +rules.negation+, default "!").



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#open_timeoutNumeric (readonly)

Returns HTTP connect timeout seconds (HttpClient, NFR3).

Returns:

  • (Numeric)

    HTTP connect timeout seconds (HttpClient, NFR3).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#read_timeoutObject (readonly)

Returns the value of attribute read_timeout.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#sdk_keyString? (readonly)

Returns account/project SDK key (JS +sdkKey+). Path auth.

Returns:

  • (String, nil)

    account/project SDK key (JS +sdkKey+). Path auth.



124
125
126
# File 'lib/convert_sdk/config.rb', line 124

def sdk_key
  @sdk_key
end

#sdk_key_secretString? (readonly)

Returns bearer secret (JS +sdkKeySecret+). Redacted.

Returns:

  • (String, nil)

    bearer secret (JS +sdkKeySecret+). Redacted.



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#track_endpointString (readonly)

Returns tracking base URL (JS +api.endpoint.track+).

Returns:

  • (String)

    tracking base URL (JS +api.endpoint.track+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

#trackingBoolean (readonly)

Returns network tracking enabled (JS +network.tracking+).

Returns:

  • (Boolean)

    network tracking enabled (JS +network.tracking+).



124
125
126
127
128
# File 'lib/convert_sdk/config.rb', line 124

attr_reader :sdk_key, :sdk_key_secret, :data, :environment,
:config_endpoint, :track_endpoint, :max_traffic, :hash_seed,
:data_refresh_interval, :event_batch_size, :flush_interval,
:keys_case_sensitive, :negation, :log_level, :tracking,
:open_timeout, :read_timeout

Instance Method Details

#max_hashInteger

Returns the fixed bucketing hash space (2**32).

Returns:

  • (Integer)

    the fixed bucketing hash space (2**32).



148
149
150
# File 'lib/convert_sdk/config.rb', line 148

def max_hash
  MAX_HASH
end

#to_internalHash{String=>Object}

The wire-translation boundary: the internal, string-keyed camelCase representation downstream managers (DataManager / ApiManager) consume. This is the single inbound conversion site. +flush_interval+ seconds are translated to the millisecond wire value here; nil passes through (timer-off).

Returns:

  • (Hash{String=>Object})

    a frozen internal config snapshot.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/convert_sdk/config.rb', line 158

def to_internal
  {
    "sdkKey" => @sdk_key,
    "sdkKeySecret" => @sdk_key_secret,
    "data" => @data,
    "environment" => @environment,
    "configEndpoint" => @config_endpoint,
    "trackEndpoint" => @track_endpoint,
    "maxTraffic" => @max_traffic,
    "hashSeed" => @hash_seed,
    "maxHash" => MAX_HASH,
    "dataRefreshInterval" => @data_refresh_interval,
    "batchSize" => @event_batch_size,
    "releaseInterval" => to_milliseconds(@flush_interval),
    "keysCaseSensitive" => @keys_case_sensitive,
    "negation" => @negation,
    "logLevel" => @log_level,
    "tracking" => @tracking
  }.freeze
end