absmartly-sdk 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +40 -7
- data/absmartly.gemspec +44 -0
- data/lib/a_b_smartly.rb +61 -24
- data/lib/a_b_smartly_config.rb +25 -45
- data/lib/absmartly/version.rb +1 -1
- data/lib/absmartly.rb +22 -8
- data/lib/client.rb +49 -19
- data/lib/client_config.rb +25 -64
- data/lib/context.rb +2 -5
- data/lib/context_config.rb +3 -0
- data/lib/default_http_client.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dd9b4360f94a88304191f94a53fbab8ea76d70824d9ab5b3e593d69978989565
|
|
4
|
+
data.tar.gz: d3539a3334fe8c08e8c198fe9fece965f538eb4800ce2f4d52b06b94bb0c37cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8101361bf9fae3a18c04d4276a53a184fef7ab1c2bb0224e0018fe3ba1f84d04822968974fb749b0d902007040fa8b060fd83051c16c741d4a48e19ff3551204
|
|
7
|
+
data.tar.gz: 979f1e2e9b6e0f929cca1826441edda2e5385b11bcb6f068140dd45770aadcf8487d3cfe4f224c5bfbb3074a18ca9bb5fd4d4fee2cf12493f83ff2a95d6e14a0
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -29,6 +29,10 @@ Absmartly.configure_client do |config|
|
|
|
29
29
|
config.api_key = "YOUR-API-KEY"
|
|
30
30
|
config.application = "website"
|
|
31
31
|
config.environment = "development"
|
|
32
|
+
config.connect_timeout = 3.0
|
|
33
|
+
config.connection_request_timeout = 3.0
|
|
34
|
+
config.retry_interval = 0.5
|
|
35
|
+
config.max_retries = 5
|
|
32
36
|
end
|
|
33
37
|
```
|
|
34
38
|
|
|
@@ -37,21 +41,50 @@ end
|
|
|
37
41
|
| Config | Type | Required? | Default | Description |
|
|
38
42
|
| :---------- | :----------------------------------- | :-------: | :-------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
43
|
| endpoint | `string` | ✅ | `undefined` | The URL to your API endpoint. Most commonly `"your-company.absmartly.io"` |
|
|
40
|
-
|
|
|
44
|
+
| api_key | `string` | ✅ | `undefined` | Your API key which can be found on the Web Console. |
|
|
41
45
|
| environment | `"production"` or `"development"` | ✅ | `undefined` | The environment of the platform where the SDK is installed. Environments are created on the Web Console and should match the available environments in your infrastructure. |
|
|
42
46
|
| application | `string` | ✅ | `undefined` | The name of the application where the SDK is installed. Applications are created on the Web Console and should match the applications where your experiments will be running. |
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
47
|
+
| connect_timeout | `number` | ❌ | `3.0` | The socket connection timeout in seconds. |
|
|
48
|
+
| connection_request_timeout | `number` | ❌ | `3.0` | The request timeout in seconds. |
|
|
49
|
+
| retry_interval | `number` | ❌ | `0.5` | The initial retry interval in seconds (uses exponential backoff). |
|
|
50
|
+
| max_retries | `number` | ❌ | `5` | The maximum number of retries before giving up. |
|
|
51
|
+
| event_logger | `ContextEventLogger` | ❌ | See "Using a Custom Event Logger" below | A `ContextEventLogger` instance implementing `handle_event(event, data)` to receive SDK events. |
|
|
46
52
|
|
|
47
53
|
### Using a Custom Event Logger
|
|
48
54
|
|
|
49
55
|
The A/B Smartly SDK can be instantiated with an event logger used for all
|
|
50
56
|
contexts. In addition, an event logger can be specified when creating a
|
|
51
|
-
particular context
|
|
57
|
+
particular context in the context config.
|
|
52
58
|
|
|
53
|
-
```
|
|
54
|
-
|
|
59
|
+
```ruby
|
|
60
|
+
class MyEventLogger < ContextEventLogger
|
|
61
|
+
def handle_event(event, data)
|
|
62
|
+
case event
|
|
63
|
+
when EVENT_TYPE::EXPOSURE
|
|
64
|
+
puts "Exposure: #{data}"
|
|
65
|
+
when EVENT_TYPE::GOAL
|
|
66
|
+
puts "Goal: #{data}"
|
|
67
|
+
when EVENT_TYPE::ERROR
|
|
68
|
+
puts "Error: #{data}"
|
|
69
|
+
when EVENT_TYPE::PUBLISH
|
|
70
|
+
puts "Publish: #{data}"
|
|
71
|
+
when EVENT_TYPE::READY
|
|
72
|
+
puts "Ready: #{data}"
|
|
73
|
+
when EVENT_TYPE::REFRESH
|
|
74
|
+
puts "Refresh: #{data}"
|
|
75
|
+
when EVENT_TYPE::CLOSE
|
|
76
|
+
puts "Close"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
Absmartly.configure_client do |config|
|
|
82
|
+
config.endpoint = "https://your-company.absmartly.io/v1"
|
|
83
|
+
config.api_key = "YOUR-API-KEY"
|
|
84
|
+
config.application = "website"
|
|
85
|
+
config.environment = "development"
|
|
86
|
+
config.event_logger = MyEventLogger.new
|
|
87
|
+
end
|
|
55
88
|
```
|
|
56
89
|
|
|
57
90
|
The data parameter depends on the type of event. Currently, the SDK logs the
|
data/absmartly.gemspec
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# $:.push File.expand_path("../lib", __FILE__)
|
|
4
|
+
require File.expand_path("lib/absmartly/version", __dir__)
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "absmartly-sdk"
|
|
7
|
+
spec.version = Absmartly::VERSION
|
|
8
|
+
spec.authors = ["absmartly"]
|
|
9
|
+
spec.email = ["sdks@absmartly.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "Absmartly gem"
|
|
12
|
+
spec.description = "Absmartly gem"
|
|
13
|
+
|
|
14
|
+
spec.homepage = "https://github.com/absmartly/ruby-sdk"
|
|
15
|
+
|
|
16
|
+
spec.license = "MIT"
|
|
17
|
+
spec.required_ruby_version = ">= 2.7.0"
|
|
18
|
+
spec.extra_rdoc_files = ["README.md"]
|
|
19
|
+
|
|
20
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
21
|
+
spec.metadata["source_code_uri"] = "https://github.com/absmartly/ruby-sdk"
|
|
22
|
+
spec.metadata["changelog_uri"] = "https://github.com/absmartly/ruby-sdk"
|
|
23
|
+
|
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
|
25
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
26
|
+
spec.files = Dir.chdir(__dir__) do
|
|
27
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
28
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
spec.bindir = "exe"
|
|
32
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
33
|
+
spec.require_paths = ["lib"]
|
|
34
|
+
|
|
35
|
+
# Required for Ruby 3.4+ where base64 is no longer a default gem.
|
|
36
|
+
# Faraday 2.7.x uses base64 but doesn't declare it as a dependency.
|
|
37
|
+
spec.add_dependency "base64", "~> 0.2"
|
|
38
|
+
spec.add_dependency "faraday", "~> 2.0"
|
|
39
|
+
spec.add_dependency "faraday-retry", "~> 2.0"
|
|
40
|
+
spec.add_dependency "murmurhash3", "~> 0.1.7"
|
|
41
|
+
|
|
42
|
+
# For more information and examples about making a new gem, check out our
|
|
43
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
|
44
|
+
end
|
data/lib/a_b_smartly.rb
CHANGED
|
@@ -1,51 +1,88 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "time"
|
|
4
|
-
require "singleton"
|
|
5
|
-
require "forwardable"
|
|
6
4
|
require_relative "context"
|
|
7
5
|
require_relative "audience_matcher"
|
|
8
|
-
require_relative "
|
|
9
|
-
require_relative "
|
|
6
|
+
require_relative "default_context_data_provider"
|
|
7
|
+
require_relative "default_context_event_handler"
|
|
8
|
+
require_relative "default_variable_parser"
|
|
9
|
+
require_relative "default_audience_deserializer"
|
|
10
|
+
require_relative "scheduled_thread_pool_executor"
|
|
10
11
|
|
|
11
12
|
class ABSmartly
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def_delegators :@config, :context_data_provider, :context_event_handler, :variable_parser, :context_event_logger,
|
|
17
|
-
:audience_deserializer, :client
|
|
18
|
-
|
|
19
|
-
def_delegators :@config, :endpoint, :api_key, :application, :environment
|
|
13
|
+
attr_accessor :context_data_provider, :context_event_handler,
|
|
14
|
+
:variable_parser, :scheduler, :context_event_logger,
|
|
15
|
+
:audience_deserializer, :client
|
|
20
16
|
|
|
21
17
|
def self.create(config)
|
|
22
|
-
new(config)
|
|
18
|
+
ABSmartly.new(config)
|
|
23
19
|
end
|
|
24
20
|
|
|
25
21
|
def initialize(config)
|
|
26
|
-
config.
|
|
22
|
+
@context_data_provider = config.context_data_provider
|
|
23
|
+
@context_event_handler = config.context_event_handler
|
|
24
|
+
@context_event_logger = config.context_event_logger
|
|
25
|
+
@variable_parser = config.variable_parser
|
|
26
|
+
@audience_deserializer = config.audience_deserializer
|
|
27
|
+
@scheduler = config.scheduler
|
|
28
|
+
|
|
29
|
+
if @context_data_provider.nil? || @context_event_handler.nil?
|
|
30
|
+
@client = config.client
|
|
31
|
+
raise ArgumentError.new("Missing Client instance configuration") if @client.nil?
|
|
32
|
+
|
|
33
|
+
if @context_data_provider.nil?
|
|
34
|
+
@context_data_provider = DefaultContextDataProvider.new(@client)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if @context_event_handler.nil?
|
|
38
|
+
@context_event_handler = DefaultContextEventHandler.new(@client)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
27
41
|
|
|
28
|
-
@
|
|
42
|
+
if @variable_parser.nil?
|
|
43
|
+
@variable_parser = DefaultVariableParser.new
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
if @audience_deserializer.nil?
|
|
47
|
+
@audience_deserializer = DefaultAudienceDeserializer.new
|
|
48
|
+
end
|
|
49
|
+
if @scheduler.nil?
|
|
50
|
+
@scheduler = ScheduledThreadPoolExecutor.new(1)
|
|
51
|
+
end
|
|
29
52
|
end
|
|
30
53
|
|
|
31
|
-
def create_context(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
def create_context(config)
|
|
55
|
+
validate_params(config)
|
|
56
|
+
Context.create(get_utc_format, config, @context_data_provider.context_data,
|
|
57
|
+
@context_data_provider, @context_event_handler, @context_event_logger, @variable_parser,
|
|
58
|
+
AudienceMatcher.new(@audience_deserializer))
|
|
35
59
|
end
|
|
36
60
|
|
|
37
|
-
def create_context_with(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
61
|
+
def create_context_with(config, data)
|
|
62
|
+
validate_params(config)
|
|
63
|
+
Context.create(get_utc_format, config, data,
|
|
64
|
+
@context_data_provider, @context_event_handler, @context_event_logger, @variable_parser,
|
|
65
|
+
AudienceMatcher.new(@audience_deserializer))
|
|
41
66
|
end
|
|
42
67
|
|
|
43
68
|
def context_data
|
|
44
|
-
context_data_provider.context_data
|
|
69
|
+
@context_data_provider.context_data
|
|
45
70
|
end
|
|
46
71
|
|
|
47
72
|
private
|
|
48
73
|
def get_utc_format
|
|
49
74
|
Time.now.utc.iso8601(3)
|
|
50
75
|
end
|
|
76
|
+
|
|
77
|
+
def validate_params(params)
|
|
78
|
+
params.units.each do |key, value|
|
|
79
|
+
unless value.is_a?(String) || value.is_a?(Numeric)
|
|
80
|
+
raise ArgumentError.new("Unit '#{key}' UID is of unsupported type '#{value.class}'. UID must be one of ['string', 'number']")
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if value.to_s.size.zero?
|
|
84
|
+
raise ArgumentError.new("Unit '#{key}' UID length must be >= 1")
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
51
88
|
end
|
data/lib/a_b_smartly_config.rb
CHANGED
|
@@ -1,65 +1,45 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "forwardable"
|
|
4
|
-
|
|
5
|
-
require_relative "client"
|
|
6
|
-
require_relative "client_config"
|
|
7
|
-
require_relative "default_context_data_provider"
|
|
8
|
-
require_relative "default_context_event_handler"
|
|
9
|
-
require_relative "default_variable_parser"
|
|
10
|
-
require_relative "default_audience_deserializer"
|
|
11
|
-
|
|
12
3
|
class ABSmartlyConfig
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
attr_writer :context_data_provider, :context_event_handler, :audience_deserializer, :variable_parser, :client
|
|
18
|
-
|
|
19
|
-
attr_reader :client_config, :context_event_logger
|
|
20
|
-
|
|
21
|
-
def_delegators :@client_config, :endpoint, :api_key, :application, :environment
|
|
22
|
-
def_delegators :@client_config, :connect_timeout, :connection_request_timeout, :retry_interval, :max_retries
|
|
23
|
-
|
|
4
|
+
attr_accessor :context_data_provider, :context_event_handler,
|
|
5
|
+
:variable_parser, :scheduler, :context_event_logger,
|
|
6
|
+
:client, :audience_deserializer
|
|
24
7
|
def self.create
|
|
25
|
-
new
|
|
8
|
+
ABSmartlyConfig.new
|
|
26
9
|
end
|
|
27
10
|
|
|
28
|
-
def
|
|
29
|
-
@
|
|
11
|
+
def context_data_provider=(context_data_provider)
|
|
12
|
+
@context_data_provider = context_data_provider
|
|
13
|
+
self
|
|
30
14
|
end
|
|
31
15
|
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
raise ArgumentError.new("failed to initialize context_data_provider") if context_data_provider.nil?
|
|
16
|
+
def context_event_handler=(context_event_handler)
|
|
17
|
+
@context_event_handler = context_event_handler
|
|
18
|
+
self
|
|
36
19
|
end
|
|
37
20
|
|
|
38
|
-
def
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
else
|
|
42
|
-
@context_event_logger = context_event_logger
|
|
43
|
-
end
|
|
21
|
+
def variable_parser=(variable_parser)
|
|
22
|
+
@variable_parser = variable_parser
|
|
23
|
+
self
|
|
44
24
|
end
|
|
45
25
|
|
|
46
|
-
def
|
|
47
|
-
@
|
|
26
|
+
def scheduler=(scheduler)
|
|
27
|
+
@scheduler = scheduler
|
|
28
|
+
self
|
|
48
29
|
end
|
|
49
30
|
|
|
50
|
-
def
|
|
51
|
-
@
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def context_data_provider
|
|
55
|
-
@context_data_provider ||= DefaultContextDataProvider.new(client)
|
|
31
|
+
def context_event_logger=(context_event_logger)
|
|
32
|
+
@context_event_logger = context_event_logger
|
|
33
|
+
self
|
|
56
34
|
end
|
|
57
35
|
|
|
58
|
-
def
|
|
59
|
-
@
|
|
36
|
+
def audience_deserializer=(audience_deserializer)
|
|
37
|
+
@audience_deserializer = audience_deserializer
|
|
38
|
+
self
|
|
60
39
|
end
|
|
61
40
|
|
|
62
|
-
def client
|
|
63
|
-
@client
|
|
41
|
+
def client=(client)
|
|
42
|
+
@client = client
|
|
43
|
+
self
|
|
64
44
|
end
|
|
65
45
|
end
|
data/lib/absmartly/version.rb
CHANGED
data/lib/absmartly.rb
CHANGED
|
@@ -12,12 +12,12 @@ module Absmartly
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
class << self
|
|
15
|
-
|
|
15
|
+
attr_accessor :endpoint, :api_key, :application, :environment,
|
|
16
|
+
:connect_timeout, :connection_request_timeout, :retry_interval, :max_retries,
|
|
17
|
+
:event_logger
|
|
16
18
|
|
|
17
19
|
def configure_client
|
|
18
|
-
yield
|
|
19
|
-
|
|
20
|
-
sdk_config.validate!
|
|
20
|
+
yield self
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def create
|
|
@@ -40,15 +40,29 @@ module Absmartly
|
|
|
40
40
|
sdk.context_data
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
private_constant :MUTEX
|
|
44
|
-
|
|
45
43
|
private
|
|
44
|
+
def client_config
|
|
45
|
+
@client_config = ClientConfig.create
|
|
46
|
+
@client_config.endpoint = @endpoint
|
|
47
|
+
@client_config.api_key = @api_key
|
|
48
|
+
@client_config.application = @application
|
|
49
|
+
@client_config.environment = @environment
|
|
50
|
+
@client_config.connect_timeout = @connect_timeout
|
|
51
|
+
@client_config.connection_request_timeout = @connection_request_timeout
|
|
52
|
+
@client_config.retry_interval = @retry_interval
|
|
53
|
+
@client_config.max_retries = @max_retries
|
|
54
|
+
@client_config
|
|
55
|
+
end
|
|
56
|
+
|
|
46
57
|
def sdk_config
|
|
47
|
-
|
|
58
|
+
@sdk_config = ABSmartlyConfig.create
|
|
59
|
+
@sdk_config.client = Client.create(client_config)
|
|
60
|
+
@sdk_config.context_event_logger = @event_logger
|
|
61
|
+
@sdk_config
|
|
48
62
|
end
|
|
49
63
|
|
|
50
64
|
def sdk
|
|
51
|
-
|
|
65
|
+
@sdk ||= create
|
|
52
66
|
end
|
|
53
67
|
end
|
|
54
68
|
end
|
data/lib/client.rb
CHANGED
|
@@ -1,49 +1,79 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "forwardable"
|
|
4
3
|
require_relative "default_http_client"
|
|
5
|
-
require_relative "default_http_client_config"
|
|
6
4
|
require_relative "default_context_data_deserializer"
|
|
7
5
|
require_relative "default_context_event_serializer"
|
|
8
6
|
|
|
9
7
|
class Client
|
|
10
|
-
|
|
8
|
+
attr_accessor :url, :query, :headers, :http_client, :executor, :deserializer, :serializer
|
|
9
|
+
attr_reader :data_future, :promise, :exception
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
def self.create(config, http_client = nil)
|
|
12
|
+
Client.new(config, http_client || DefaultHttpClient.create(config.http_client_config))
|
|
13
|
+
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
def initialize(config, http_client = nil)
|
|
16
|
+
endpoint = config.endpoint
|
|
17
|
+
raise ArgumentError.new("Missing Endpoint configuration") if endpoint.nil? || endpoint.empty?
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
new(
|
|
21
|
-
|
|
19
|
+
api_key = config.api_key
|
|
20
|
+
raise ArgumentError.new("Missing APIKey configuration") if api_key.nil? || api_key.empty?
|
|
21
|
+
|
|
22
|
+
application = config.application
|
|
23
|
+
raise ArgumentError.new("Missing Application configuration") if application.nil? || application.empty?
|
|
24
|
+
|
|
25
|
+
environment = config.environment
|
|
26
|
+
raise ArgumentError.new("Missing Environment configuration") if environment.nil? || environment.empty?
|
|
27
|
+
|
|
28
|
+
@url = "#{endpoint}/context"
|
|
29
|
+
@http_client = http_client
|
|
30
|
+
@deserializer = config.context_data_deserializer
|
|
31
|
+
@serializer = config.context_event_serializer
|
|
32
|
+
@executor = config.executor
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
@
|
|
25
|
-
@config.validate!
|
|
34
|
+
@deserializer = DefaultContextDataDeserializer.new if @deserializer.nil?
|
|
35
|
+
@serializer = DefaultContextEventSerializer.new if @serializer.nil?
|
|
26
36
|
|
|
27
|
-
@
|
|
37
|
+
@headers = {
|
|
38
|
+
"Content-Type": "application/json",
|
|
39
|
+
"X-API-Key": api_key,
|
|
40
|
+
"X-Application": application,
|
|
41
|
+
"X-Environment": environment,
|
|
42
|
+
"X-Application-Version": "0",
|
|
43
|
+
"X-Agent": "absmartly-ruby-sdk"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
@query = {
|
|
47
|
+
"application": application,
|
|
48
|
+
"environment": environment
|
|
49
|
+
}
|
|
28
50
|
end
|
|
29
51
|
|
|
30
52
|
def context_data
|
|
31
|
-
@promise = http_client.get(
|
|
53
|
+
@promise = @http_client.get(@url, @query, @headers)
|
|
32
54
|
unless @promise.success?
|
|
33
55
|
@exception = Exception.new(@promise.body)
|
|
34
56
|
return self
|
|
35
57
|
end
|
|
36
58
|
|
|
37
59
|
content = (@promise.body || {}).to_s
|
|
38
|
-
@data_future = deserializer.deserialize(content, 0, content.size)
|
|
60
|
+
@data_future = @deserializer.deserialize(content, 0, content.size)
|
|
39
61
|
self
|
|
40
62
|
end
|
|
41
63
|
|
|
42
64
|
def publish(event)
|
|
43
|
-
content = serializer.serialize(event)
|
|
44
|
-
response = http_client.put(
|
|
65
|
+
content = @serializer.serialize(event)
|
|
66
|
+
response = @http_client.put(@url, nil, @headers, content)
|
|
45
67
|
return Exception.new(response.body) unless response.success?
|
|
46
68
|
|
|
47
69
|
response
|
|
48
70
|
end
|
|
71
|
+
|
|
72
|
+
def close
|
|
73
|
+
@http_client.close
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def success?
|
|
77
|
+
@promise&.success? || false
|
|
78
|
+
end
|
|
49
79
|
end
|
data/lib/client_config.rb
CHANGED
|
@@ -1,33 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "forwardable"
|
|
4
|
-
require_relative "default_context_data_deserializer"
|
|
5
|
-
require_relative "default_context_event_serializer"
|
|
6
3
|
require_relative "default_http_client_config"
|
|
7
4
|
|
|
8
5
|
class ClientConfig
|
|
9
|
-
|
|
6
|
+
attr_accessor :endpoint, :api_key, :environment, :application, :deserializer,
|
|
7
|
+
:serializer, :executor, :connect_timeout, :connection_request_timeout,
|
|
8
|
+
:retry_interval, :max_retries
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
attr_reader :http_client_config
|
|
14
|
-
|
|
15
|
-
attr_writer :context_data_deserializer, :context_event_serializer
|
|
16
|
-
|
|
17
|
-
def_delegators :@http_client_config, :connect_timeout, :connection_request_timeout, :retry_interval, :max_retries
|
|
18
|
-
|
|
19
|
-
def self.create(endpoint: nil, environment: nil, application: nil, api_key: nil)
|
|
20
|
-
new(endpoint: endpoint, environment: environment, application: application, api_key: api_key)
|
|
10
|
+
def self.create
|
|
11
|
+
ClientConfig.new
|
|
21
12
|
end
|
|
22
13
|
|
|
23
14
|
def self.create_from_properties(properties, prefix)
|
|
24
15
|
properties = properties.transform_keys(&:to_sym)
|
|
25
|
-
create
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
client_config = create
|
|
17
|
+
client_config.endpoint = properties["#{prefix}endpoint".to_sym]
|
|
18
|
+
client_config.environment = properties["#{prefix}environment".to_sym]
|
|
19
|
+
client_config.application = properties["#{prefix}application".to_sym]
|
|
20
|
+
client_config.api_key = properties["#{prefix}apikey".to_sym]
|
|
21
|
+
client_config
|
|
31
22
|
end
|
|
32
23
|
|
|
33
24
|
def initialize(endpoint: nil, environment: nil, application: nil, api_key: nil)
|
|
@@ -35,60 +26,30 @@ class ClientConfig
|
|
|
35
26
|
@environment = environment
|
|
36
27
|
@application = application
|
|
37
28
|
@api_key = api_key
|
|
38
|
-
|
|
39
|
-
@http_client_config = DefaultHttpClientConfig.new
|
|
40
29
|
end
|
|
41
30
|
|
|
42
31
|
def context_data_deserializer
|
|
43
|
-
@
|
|
32
|
+
@deserializer
|
|
44
33
|
end
|
|
45
34
|
|
|
46
|
-
def
|
|
47
|
-
@
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def deserializer=(deserializer)
|
|
51
|
-
@context_data_deserializer = deserializer
|
|
35
|
+
def context_data_deserializer=(deserializer)
|
|
36
|
+
@deserializer = deserializer
|
|
52
37
|
end
|
|
53
38
|
|
|
54
|
-
def
|
|
55
|
-
@
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def deserializer
|
|
59
|
-
context_data_deserializer
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def serializer
|
|
63
|
-
context_event_serializer
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def url
|
|
67
|
-
@url ||= "#{endpoint}/context"
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def headers
|
|
71
|
-
@headers ||= {
|
|
72
|
-
"Content-Type": "application/json",
|
|
73
|
-
"X-API-Key": api_key,
|
|
74
|
-
"X-Application": application,
|
|
75
|
-
"X-Environment": environment,
|
|
76
|
-
"X-Application-Version": "0",
|
|
77
|
-
"X-Agent": "absmartly-ruby-sdk"
|
|
78
|
-
}
|
|
39
|
+
def context_event_serializer
|
|
40
|
+
@serializer
|
|
79
41
|
end
|
|
80
42
|
|
|
81
|
-
def
|
|
82
|
-
@
|
|
83
|
-
"application": application,
|
|
84
|
-
"environment": environment
|
|
85
|
-
}
|
|
43
|
+
def context_event_serializer=(serializer)
|
|
44
|
+
@serializer = serializer
|
|
86
45
|
end
|
|
87
46
|
|
|
88
|
-
def
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
47
|
+
def http_client_config
|
|
48
|
+
http_config = DefaultHttpClientConfig.create
|
|
49
|
+
http_config.connect_timeout = @connect_timeout unless @connect_timeout.nil?
|
|
50
|
+
http_config.connection_request_timeout = @connection_request_timeout unless @connection_request_timeout.nil?
|
|
51
|
+
http_config.retry_interval = @retry_interval unless @retry_interval.nil?
|
|
52
|
+
http_config.max_retries = @max_retries unless @max_retries.nil?
|
|
53
|
+
http_config
|
|
93
54
|
end
|
|
94
55
|
end
|
data/lib/context.rb
CHANGED
|
@@ -10,7 +10,7 @@ require_relative "json/publish_event"
|
|
|
10
10
|
require_relative "json/goal_achievement"
|
|
11
11
|
|
|
12
12
|
class Context
|
|
13
|
-
attr_reader :pending_count
|
|
13
|
+
attr_reader :data, :pending_count
|
|
14
14
|
|
|
15
15
|
def self.create(clock, config, data_future, data_provider,
|
|
16
16
|
event_handler, event_logger, variable_parser, audience_matcher)
|
|
@@ -114,10 +114,6 @@ class Context
|
|
|
114
114
|
def set_unit(unit_type, uid)
|
|
115
115
|
check_not_closed?
|
|
116
116
|
|
|
117
|
-
unless uid.is_a?(String) || uid.is_a?(Numeric)
|
|
118
|
-
raise IllegalStateException.new("Unit '#{unit_type}' UID is of unsupported type '#{uid.class}'. UID must be one of ['string', 'number']")
|
|
119
|
-
end
|
|
120
|
-
|
|
121
117
|
previous = @units[unit_type.to_sym]
|
|
122
118
|
if !previous.nil? && previous != uid
|
|
123
119
|
raise IllegalStateException.new("Unit '#{unit_type}' already set.")
|
|
@@ -545,6 +541,7 @@ class Context
|
|
|
545
541
|
@experimentCustomFieldValues[custom_field_value.name] = value
|
|
546
542
|
|
|
547
543
|
end
|
|
544
|
+
|
|
548
545
|
end
|
|
549
546
|
end
|
|
550
547
|
|
data/lib/context_config.rb
CHANGED
data/lib/default_http_client.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: absmartly-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- absmartly
|
|
@@ -83,6 +83,7 @@ files:
|
|
|
83
83
|
- LICENSE.txt
|
|
84
84
|
- README.md
|
|
85
85
|
- Rakefile
|
|
86
|
+
- absmartly.gemspec
|
|
86
87
|
- example/example.rb
|
|
87
88
|
- lib/a_b_smartly.rb
|
|
88
89
|
- lib/a_b_smartly_config.rb
|