absmartly-sdk 0.1.2

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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/.rubocop.yml +180 -0
  4. data/.ruby-version +1 -0
  5. data/CHANGELOG.md +5 -0
  6. data/CODE_OF_CONDUCT.md +84 -0
  7. data/Gemfile +21 -0
  8. data/Gemfile.lock +92 -0
  9. data/LICENSE.txt +21 -0
  10. data/README +180 -0
  11. data/Rakefile +12 -0
  12. data/example/example.rb +48 -0
  13. data/lib/a_b_smartly.rb +92 -0
  14. data/lib/a_b_smartly_config.rb +49 -0
  15. data/lib/absmartly/md5.rb +178 -0
  16. data/lib/absmartly/variant_assigner.rb +36 -0
  17. data/lib/absmartly/version.rb +5 -0
  18. data/lib/absmartly.rb +57 -0
  19. data/lib/audience_deserializer.rb +8 -0
  20. data/lib/audience_matcher.rb +38 -0
  21. data/lib/client.rb +80 -0
  22. data/lib/client_config.rb +43 -0
  23. data/lib/context.rb +528 -0
  24. data/lib/context_config.rb +70 -0
  25. data/lib/context_data_deserializer.rb +8 -0
  26. data/lib/context_data_provider.rb +8 -0
  27. data/lib/context_event_handler.rb +8 -0
  28. data/lib/context_event_logger.rb +9 -0
  29. data/lib/context_event_serializer.rb +8 -0
  30. data/lib/default_audience_deserializer.rb +13 -0
  31. data/lib/default_context_data_deserializer.rb +16 -0
  32. data/lib/default_context_data_provider.rb +15 -0
  33. data/lib/default_context_event_handler.rb +15 -0
  34. data/lib/default_context_event_serializer.rb +58 -0
  35. data/lib/default_http_client.rb +61 -0
  36. data/lib/default_http_client_config.rb +19 -0
  37. data/lib/default_variable_parser.rb +13 -0
  38. data/lib/hashing.rb +9 -0
  39. data/lib/http_client.rb +20 -0
  40. data/lib/json/attribute.rb +30 -0
  41. data/lib/json/context_data.rb +31 -0
  42. data/lib/json/experiment.rb +83 -0
  43. data/lib/json/experiment_application.rb +27 -0
  44. data/lib/json/experiment_variant.rb +29 -0
  45. data/lib/json/exposure.rb +60 -0
  46. data/lib/json/goal_achievement.rb +32 -0
  47. data/lib/json/publish_event.rb +42 -0
  48. data/lib/json/unit.rb +30 -0
  49. data/lib/json_expr/evaluator.rb +27 -0
  50. data/lib/json_expr/expr_evaluator.rb +122 -0
  51. data/lib/json_expr/json_expr.rb +37 -0
  52. data/lib/json_expr/operator.rb +8 -0
  53. data/lib/json_expr/operators/and_combinator.rb +14 -0
  54. data/lib/json_expr/operators/binary_operator.rb +22 -0
  55. data/lib/json_expr/operators/boolean_combinator.rb +15 -0
  56. data/lib/json_expr/operators/equals_operator.rb +12 -0
  57. data/lib/json_expr/operators/greater_than_operator.rb +12 -0
  58. data/lib/json_expr/operators/greater_than_or_equal_operator.rb +12 -0
  59. data/lib/json_expr/operators/in_operator.rb +23 -0
  60. data/lib/json_expr/operators/less_than_operator.rb +12 -0
  61. data/lib/json_expr/operators/less_than_or_equal_operator.rb +12 -0
  62. data/lib/json_expr/operators/match_operator.rb +17 -0
  63. data/lib/json_expr/operators/nil_operator.rb +11 -0
  64. data/lib/json_expr/operators/not_operator.rb +11 -0
  65. data/lib/json_expr/operators/or_combinator.rb +14 -0
  66. data/lib/json_expr/operators/unary_operator.rb +13 -0
  67. data/lib/json_expr/operators/value_operator.rb +11 -0
  68. data/lib/json_expr/operators/var_operator.rb +21 -0
  69. data/lib/scheduled_executor_service.rb +8 -0
  70. data/lib/scheduled_thread_pool_executor.rb +14 -0
  71. data/lib/string.rb +30 -0
  72. data/lib/variable_parser.rb +8 -0
  73. data/lib/variant_assigner.rb +47 -0
  74. data/sig/absmartly.rbs +4 -0
  75. metadata +120 -0
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+ require_relative "context"
5
+ require_relative "audience_matcher"
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"
11
+
12
+ class ABSmartly
13
+ attr_accessor :context_data_provider, :context_event_handler,
14
+ :variable_parser, :scheduler, :context_event_logger,
15
+ :audience_deserializer, :client
16
+
17
+ def self.configure_client(&block)
18
+ @@init_http = block
19
+ end
20
+
21
+ def self.create(config)
22
+ ABSmartly.new(config)
23
+ end
24
+
25
+ def initialize(config)
26
+ @@init_http = nil
27
+ @context_data_provider = config.context_data_provider
28
+ @context_event_handler = config.context_event_handler
29
+ @context_event_logger = config.context_event_logger
30
+ @variable_parser = config.variable_parser
31
+ @audience_deserializer = config.audience_deserializer
32
+ @scheduler = config.scheduler
33
+
34
+ if @context_data_provider.nil? || @context_event_handler.nil?
35
+ @client = config.client
36
+ raise ArgumentError.new("Missing Client instance configuration") if @client.nil?
37
+
38
+ if @context_data_provider.nil?
39
+ @context_data_provider = DefaultContextDataProvider.new(@client)
40
+ end
41
+
42
+ if @context_event_handler.nil?
43
+ @context_event_handler = DefaultContextEventHandler.new(@client)
44
+ end
45
+ end
46
+
47
+ if @variable_parser.nil?
48
+ @variable_parser = DefaultVariableParser.new
49
+ end
50
+
51
+ if @audience_deserializer.nil?
52
+ @audience_deserializer = DefaultAudienceDeserializer.new
53
+ end
54
+ if @scheduler.nil?
55
+ @scheduler = ScheduledThreadPoolExecutor.new(1)
56
+ end
57
+ end
58
+
59
+ def create_context(config)
60
+ validate_params(config)
61
+ Context.create(get_utc_format, config, @scheduler, @context_data_provider.context_data,
62
+ @context_data_provider, @context_event_handler, @context_event_logger, @variable_parser,
63
+ AudienceMatcher.new(@audience_deserializer))
64
+ end
65
+
66
+ def create_context_with(config, data)
67
+ Context.create(get_utc_format, config, scheduler, data,
68
+ @context_data_provider, @context_event_handler, @context_event_logger, @variable_parser,
69
+ AudienceMatcher.new(@audience_deserializer))
70
+ end
71
+
72
+ def context_data
73
+ @context_data_provider.context_data
74
+ end
75
+
76
+ private
77
+ def get_utc_format
78
+ Time.now.utc.iso8601(3)
79
+ end
80
+
81
+ def validate_params(params)
82
+ params.units.each do |key, value|
83
+ unless value.is_a?(String) || value.is_a?(Numeric)
84
+ raise ArgumentError.new("Unit '#{key}' UID is of unsupported type '#{value.class}'. UID must be one of ['string', 'number']")
85
+ end
86
+
87
+ if value.to_s.size.zero?
88
+ raise ArgumentError.new("Unit '#{key}' UID length must be >= 1")
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ABSmartlyConfig
4
+ attr_accessor :context_data_provider, :context_event_handler,
5
+ :variable_parser, :scheduler, :context_event_logger,
6
+ :client, :audience_deserializer
7
+ def self.create
8
+ ABSmartlyConfig.new
9
+ end
10
+
11
+ def context_data_provider=(context_data_provider)
12
+ @context_data_provider = context_data_provider
13
+ self
14
+ end
15
+
16
+ def context_event_handler=(context_event_handler)
17
+ @context_event_handler = context_event_handler
18
+ self
19
+ end
20
+
21
+ def context_data_provide
22
+ @context_event_handler
23
+ end
24
+
25
+ def variable_parser=(variable_parser)
26
+ @variable_parser = variable_parser
27
+ self
28
+ end
29
+
30
+ def scheduler=(scheduler)
31
+ @scheduler = scheduler
32
+ self
33
+ end
34
+
35
+ def context_event_logger=(context_event_logger)
36
+ @context_event_logger = context_event_logger
37
+ self
38
+ end
39
+
40
+ def audience_deserializer=(audience_deserializer)
41
+ @audience_deserializer = audience_deserializer
42
+ self
43
+ end
44
+
45
+ def client=(client)
46
+ @client = client
47
+ self
48
+ end
49
+ end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "arraybuffer"
4
+
5
+ module Absmartly
6
+ class Md5
7
+ def self.cmn (q, a, b, x, s, t)
8
+ a = a + q + (x >> 0) + t # TODO >>>
9
+ ((a << s) | (a >> (32 - s))) + b # TODO >>>
10
+ end
11
+
12
+ def self.ff(a, b, c, d, x, s, t)
13
+ cmn((b & c) | (~b & d), a, b, x, s, t)
14
+ end
15
+
16
+ def self.gg(a, b, c, d, x, s, t)
17
+ cmn((b & d) | (c & ~d), a, b, x, s, t)
18
+ end
19
+
20
+ def self.hh(a, b, c, d, x, s, t)
21
+ cmn(b ^ c ^ d, a, b, x, s, t)
22
+ end
23
+
24
+ def self.ii(a, b, c, d, x, s, t)
25
+ cmn(c ^ (b | ~d), a, b, x, s, t)
26
+ end
27
+
28
+ def self.md5_cycle(x, k)
29
+ a = x[0]
30
+ b = x[1]
31
+ c = x[2]
32
+ d = x[3]
33
+
34
+ a = ff(a, b, c, d, k[0], 7, -680876936)
35
+ d = ff(d, a, b, c, k[1], 12, -389564586)
36
+ c = ff(c, d, a, b, k[2], 17, 606105819)
37
+ b = ff(b, c, d, a, k[3], 22, -1044525330)
38
+ a = ff(a, b, c, d, k[4], 7, -176418897)
39
+ d = ff(d, a, b, c, k[5], 12, 1200080426)
40
+ c = ff(c, d, a, b, k[6], 17, -1473231341)
41
+ b = ff(b, c, d, a, k[7], 22, -45705983)
42
+ a = ff(a, b, c, d, k[8], 7, 1770035416)
43
+ d = ff(d, a, b, c, k[9], 12, -1958414417)
44
+ c = ff(c, d, a, b, k[10], 17, -42063)
45
+ b = ff(b, c, d, a, k[11], 22, -1990404162)
46
+ a = ff(a, b, c, d, k[12], 7, 1804603682)
47
+ d = ff(d, a, b, c, k[13], 12, -40341101)
48
+ c = ff(c, d, a, b, k[14], 17, -1502002290)
49
+ b = ff(b, c, d, a, k[15], 22, 1236535329)
50
+
51
+ a = gg(a, b, c, d, k[1], 5, -165796510)
52
+ d = gg(d, a, b, c, k[6], 9, -1069501632)
53
+ c = gg(c, d, a, b, k[11], 14, 643717713)
54
+ b = gg(b, c, d, a, k[0], 20, -373897302)
55
+ a = gg(a, b, c, d, k[5], 5, -701558691)
56
+ d = gg(d, a, b, c, k[10], 9, 38016083)
57
+ c = gg(c, d, a, b, k[15], 14, -660478335)
58
+ b = gg(b, c, d, a, k[4], 20, -405537848)
59
+ a = gg(a, b, c, d, k[9], 5, 568446438)
60
+ d = gg(d, a, b, c, k[14], 9, -1019803690)
61
+ c = gg(c, d, a, b, k[3], 14, -187363961)
62
+ b = gg(b, c, d, a, k[8], 20, 1163531501)
63
+ a = gg(a, b, c, d, k[13], 5, -1444681467)
64
+ d = gg(d, a, b, c, k[2], 9, -51403784)
65
+ c = gg(c, d, a, b, k[7], 14, 1735328473)
66
+ b = gg(b, c, d, a, k[12], 20, -1926607734)
67
+
68
+ a = hh(a, b, c, d, k[5], 4, -378558)
69
+ d = hh(d, a, b, c, k[8], 11, -2022574463)
70
+ c = hh(c, d, a, b, k[11], 16, 1839030562)
71
+ b = hh(b, c, d, a, k[14], 23, -35309556)
72
+ a = hh(a, b, c, d, k[1], 4, -1530992060)
73
+ d = hh(d, a, b, c, k[4], 11, 1272893353)
74
+ c = hh(c, d, a, b, k[7], 16, -155497632)
75
+ b = hh(b, c, d, a, k[10], 23, -1094730640)
76
+ a = hh(a, b, c, d, k[13], 4, 681279174)
77
+ d = hh(d, a, b, c, k[0], 11, -358537222)
78
+ c = hh(c, d, a, b, k[3], 16, -722521979)
79
+ b = hh(b, c, d, a, k[6], 23, 76029189)
80
+ a = hh(a, b, c, d, k[9], 4, -640364487)
81
+ d = hh(d, a, b, c, k[12], 11, -421815835)
82
+ c = hh(c, d, a, b, k[15], 16, 530742520)
83
+ b = hh(b, c, d, a, k[2], 23, -995338651)
84
+
85
+ a = ii(a, b, c, d, k[0], 6, -198630844)
86
+ d = ii(d, a, b, c, k[7], 10, 1126891415)
87
+ c = ii(c, d, a, b, k[14], 15, -1416354905)
88
+ b = ii(b, c, d, a, k[5], 21, -57434055)
89
+ a = ii(a, b, c, d, k[12], 6, 1700485571)
90
+ d = ii(d, a, b, c, k[3], 10, -1894986606)
91
+ c = ii(c, d, a, b, k[10], 15, -1051523)
92
+ b = ii(b, c, d, a, k[1], 21, -2054922799)
93
+ a = ii(a, b, c, d, k[8], 6, 1873313359)
94
+ d = ii(d, a, b, c, k[15], 10, -30611744)
95
+ c = ii(c, d, a, b, k[6], 15, -1560198380)
96
+ b = ii(b, c, d, a, k[13], 21, 1309151649)
97
+ a = ii(a, b, c, d, k[4], 6, -145523070)
98
+ d = ii(d, a, b, c, k[11], 10, -1120210379)
99
+ c = ii(c, d, a, b, k[2], 15, 718787259)
100
+ b = ii(b, c, d, a, k[9], 21, -343485551)
101
+
102
+ x[0] = (a + x[0]) >> 0 # TODO >>>
103
+ x[1] = (b + x[1]) >> 0 # TODO >>>
104
+ x[2] = (c + x[2]) >> 0 # TODO >>>
105
+ x[3] = (d + x[3]) >> 0 # TODO >>>
106
+ end
107
+
108
+ def self.process(new_bytes_buffer)
109
+ key = DataView.new new_bytes_buffer, 0, new_bytes_buffer.length
110
+
111
+ l = new_bytes_buffer.length
112
+ n = l & ~63
113
+ i = 0
114
+ block = ArrayBuffer.new(16)
115
+ state = ArrayBuffer.new(4)
116
+
117
+ [1732584193, -271733879, -1732584194, 271733878].each_with_index do |el, index|
118
+ state[index] = el
119
+ end
120
+
121
+ (0...n).step(64).each do |val|
122
+ (0...16).each do |w|
123
+ block[w] = key.getU32(val + (w << 2))
124
+ end
125
+
126
+ md5_cycle(state, block)
127
+
128
+ i += 64
129
+ end
130
+
131
+ w = 0
132
+ m = l & ~3
133
+
134
+ (i...m).step(4).each do |val|
135
+ block[w] = key.getU32(val)
136
+ w += 1
137
+ end
138
+
139
+ p = l & 3
140
+
141
+ case p
142
+ when 3
143
+ block[w] = 0x80000000 | key.getU8(i) | (key.getU8(i + 1) << 8) | (key.getU8(i + 2) << 16)
144
+ w += 1
145
+ when 2
146
+ block[w] = 0x800000 | key.getUint8(i) | (key.getUint8(i + 1) << 8)
147
+ w += 1
148
+
149
+ when 1
150
+ block[w] = 0x8000 | key.getUint8(i)
151
+ w += 1
152
+
153
+ else
154
+ block[w] = 0x80
155
+ w += 1
156
+
157
+ end
158
+
159
+ if w > 14
160
+ (w...16).each do |v|
161
+ block[v] = 0
162
+ end
163
+
164
+ md5_cycle(state, block)
165
+ w = 0
166
+ end
167
+
168
+ (w...16).each do |v|
169
+ block[v] = 0
170
+ end
171
+
172
+ block[14] = l << 3
173
+ md5_cycle(state, block)
174
+
175
+ state
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "arraybuffer"
4
+ require "murmurhash3"
5
+
6
+ module Absmartly
7
+ # VariantAssigner
8
+ class VariantAssigner
9
+ def initialize(_unit)
10
+ # this._unitHash = murmur3_32(stringToUint8Array(unit).buffer);
11
+ end
12
+
13
+ def assign(split, seed_hi, seed_lo)
14
+ prob = probability(seed_hi, seed_lo)
15
+ chooseVariant(split, prob)
16
+ end
17
+
18
+ # private
19
+
20
+ # def chooseVariant(split, prob)
21
+ #
22
+ # end
23
+ #
24
+ # def probability(seedHi, seedLo)
25
+ # const key = this._unitHash;
26
+ # const buffer = new ArrayBuffer(12)
27
+ # const view = new DataView(buffer)
28
+ # view.setUint32(0, seedLo, true)
29
+ # view.setUint32(4, seedHi, true)
30
+ # view.setUint32(8, key, true)
31
+ #
32
+ # murmur3_32(buffer) * (1.0 / 0xffffffff)
33
+ # end
34
+ end
35
+ end
36
+ # DataView.new(new_bytes_buffer, src_offset, new_bytes.length)
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Absmartly
4
+ VERSION = "0.1.2"
5
+ end
data/lib/absmartly.rb ADDED
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "absmartly/version"
4
+ require_relative "absmartly/variant_assigner"
5
+ require_relative "absmartly/md5"
6
+ require_relative "a_b_smartly"
7
+ require_relative "a_b_smartly_config"
8
+ require_relative "client"
9
+ require_relative "client_config"
10
+ require_relative "context_config"
11
+
12
+ module Absmartly
13
+ @@init_config = nil
14
+
15
+ class Error < StandardError
16
+ end
17
+
18
+ class << self
19
+ attr_accessor :endpoint, :api_key, :application, :environment
20
+
21
+ def configure_client
22
+ yield self
23
+ end
24
+
25
+ def create
26
+ ABSmartly.create(sdk_config)
27
+ end
28
+
29
+ def create_context_config
30
+ ContextConfig.create
31
+ end
32
+
33
+ def create_context(context_config)
34
+ sdk.create_context(context_config)
35
+ end
36
+
37
+ private
38
+ def client_config
39
+ @client_config = ClientConfig.create
40
+ @client_config.endpoint = @endpoint
41
+ @client_config.api_key = @api_key
42
+ @client_config.application = @application
43
+ @client_config.environment = @environment
44
+ @client_config
45
+ end
46
+
47
+ def sdk_config
48
+ @sdk_config = ABSmartlyConfig.create
49
+ @sdk_config.client = Client.create(client_config)
50
+ @sdk_config
51
+ end
52
+
53
+ def sdk
54
+ @sdk ||= create
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AudienceDeserializer
4
+ # @interface method
5
+ def deserialize(bytes, offset, length)
6
+ raise NotImplementedError.new("You must implement deserialize method.")
7
+ end
8
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require_relative "json_expr/json_expr"
5
+
6
+ class AudienceMatcher
7
+ attr_accessor :deserializer, :json_expr
8
+
9
+ def initialize(deserializer)
10
+ @deserializer = deserializer
11
+ @json_expr = JsonExpr.new
12
+ end
13
+
14
+ class Result
15
+ attr_accessor :result
16
+
17
+ def initialize(result)
18
+ @result = result
19
+ end
20
+
21
+ def get
22
+ @result
23
+ end
24
+ end
25
+
26
+ def evaluate(audience, attributes)
27
+ audience_map = JSON.parse(audience, symbolize_names: true)
28
+
29
+ unless audience_map.nil?
30
+ filter = audience_map[:filter]
31
+ if filter.is_a?(Hash) || filter.is_a?(Array)
32
+ Result.new(@json_expr.evaluate_boolean_expr(filter, attributes))
33
+ end
34
+ end
35
+ rescue
36
+ nil
37
+ end
38
+ end
data/lib/client.rb ADDED
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "default_http_client"
4
+ require_relative "default_http_client_config"
5
+ require_relative "default_context_data_deserializer"
6
+ require_relative "default_context_event_serializer"
7
+
8
+ class Client
9
+ attr_accessor :url, :query, :headers, :http_client, :executor, :deserializer, :serializer
10
+ attr_reader :data_future, :promise, :exception
11
+
12
+ def self.create(config, http_client = nil)
13
+ Client.new(config, http_client || DefaultHttpClient.create(DefaultHttpClientConfig.create))
14
+ end
15
+
16
+ def initialize(config = nil, http_client = nil)
17
+ endpoint = config.endpoint
18
+ raise ArgumentError.new("Missing Endpoint configuration") if endpoint.nil? || endpoint.empty?
19
+
20
+ api_key = config.api_key
21
+ raise ArgumentError.new("Missing APIKey configuration") if api_key.nil? || api_key.empty?
22
+
23
+ application = config.application
24
+ raise ArgumentError.new("Missing Application configuration") if application.nil? || application.empty?
25
+
26
+ environment = config.environment
27
+ raise ArgumentError.new("Missing Environment configuration") if environment.nil? || environment.empty?
28
+
29
+ @url = "#{endpoint}/context"
30
+ @http_client = http_client
31
+ @deserializer = config.context_data_deserializer
32
+ @serializer = config.context_event_serializer
33
+ @executor = config.executor
34
+
35
+ @deserializer = DefaultContextDataDeserializer.new if @deserializer.nil?
36
+ @serializer = DefaultContextEventSerializer.new if @serializer.nil?
37
+
38
+ @headers = {
39
+ "Content-Type": "application/json",
40
+ "X-API-Key": api_key,
41
+ "X-Application": application,
42
+ "X-Environment": environment,
43
+ "X-Application-Version": "0",
44
+ "X-Agent": "absmartly-ruby-sdk"
45
+ }
46
+
47
+ @query = {
48
+ "application": application,
49
+ "environment": environment
50
+ }
51
+ end
52
+
53
+ def context_data
54
+ @promise = @http_client.get(@url, @query, @headers)
55
+ unless @promise.success?
56
+ @exception = Exception.new(@promise.body)
57
+ return self
58
+ end
59
+
60
+ content = (@promise.body || {}).to_s
61
+ @data_future = @deserializer.deserialize(content, 0, content.size)
62
+ self
63
+ end
64
+
65
+ def publish(event)
66
+ content = @serializer.serialize(event)
67
+ response = @http_client.put(@url, nil, @headers, content)
68
+ return Exception.new(response.body) unless response.success?
69
+
70
+ response
71
+ end
72
+
73
+ def close
74
+ @http_client.close
75
+ end
76
+
77
+ def success?
78
+ @promise.success?
79
+ end
80
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ClientConfig
4
+ attr_accessor :endpoint, :api_key, :environment, :application, :deserializer,
5
+ :serializer, :executor
6
+
7
+ def self.create
8
+ ClientConfig.new
9
+ end
10
+
11
+ def self.create_from_properties(properties, prefix)
12
+ properties = properties.transform_keys(&:to_sym)
13
+ client_config = create
14
+ client_config.endpoint = properties["#{prefix}endpoint".to_sym]
15
+ client_config.environment = properties["#{prefix}environment".to_sym]
16
+ client_config.application = properties["#{prefix}application".to_sym]
17
+ client_config.api_key = properties["#{prefix}apikey".to_sym]
18
+ client_config
19
+ end
20
+
21
+ def initialize(endpoint: nil, environment: nil, application: nil, api_key: nil)
22
+ @endpoint = endpoint
23
+ @environment = environment
24
+ @application = application
25
+ @api_key = api_key
26
+ end
27
+
28
+ def context_data_deserializer
29
+ @deserializer
30
+ end
31
+
32
+ def context_data_deserializer=(deserializer)
33
+ @deserializer = deserializer
34
+ end
35
+
36
+ def context_event_serializer
37
+ @serializer
38
+ end
39
+
40
+ def context_event_serializer=(serializer)
41
+ @serializer = serializer
42
+ end
43
+ end