kameleoon-client-ruby 3.2.0 → 3.4.0

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 +4 -4
  2. data/lib/kameleoon/configuration/custom_data_info.rb +16 -8
  3. data/lib/kameleoon/configuration/data_file.rb +40 -17
  4. data/lib/kameleoon/configuration/feature_flag.rb +10 -0
  5. data/lib/kameleoon/configuration/rule.rb +4 -0
  6. data/lib/kameleoon/configuration/settings.rb +13 -8
  7. data/lib/kameleoon/configuration/variation_exposition.rb +4 -0
  8. data/lib/kameleoon/data/browser.rb +4 -0
  9. data/lib/kameleoon/data/conversion.rb +4 -0
  10. data/lib/kameleoon/data/cookie.rb +4 -0
  11. data/lib/kameleoon/data/custom_data.rb +11 -3
  12. data/lib/kameleoon/data/data.rb +30 -4
  13. data/lib/kameleoon/data/device.rb +4 -0
  14. data/lib/kameleoon/data/geolocation.rb +5 -0
  15. data/lib/kameleoon/data/kcs_heat.rb +16 -0
  16. data/lib/kameleoon/data/manager/assigned_variation.rb +5 -0
  17. data/lib/kameleoon/data/manager/data_array_storage.rb +7 -0
  18. data/lib/kameleoon/data/manager/data_map_storage.rb +7 -0
  19. data/lib/kameleoon/data/manager/page_view_visit.rb +4 -0
  20. data/lib/kameleoon/data/manager/visitor.rb +198 -67
  21. data/lib/kameleoon/data/manager/visitor_manager.rb +54 -17
  22. data/lib/kameleoon/data/mapping_identifier.rb +33 -0
  23. data/lib/kameleoon/data/operating_system.rb +4 -0
  24. data/lib/kameleoon/data/page_view.rb +6 -1
  25. data/lib/kameleoon/data/unique_identifier.rb +11 -0
  26. data/lib/kameleoon/data/user_agent.rb +4 -0
  27. data/lib/kameleoon/data/visitor_visits.rb +12 -1
  28. data/lib/kameleoon/hybrid/manager.rb +13 -4
  29. data/lib/kameleoon/kameleoon_client.rb +348 -146
  30. data/lib/kameleoon/kameleoon_client_config.rb +64 -17
  31. data/lib/kameleoon/kameleoon_client_factory.rb +15 -2
  32. data/lib/kameleoon/logging/default_logger.rb +20 -0
  33. data/lib/kameleoon/logging/kameleoon_logger.rb +77 -0
  34. data/lib/kameleoon/logging/logger.rb +12 -0
  35. data/lib/kameleoon/managers/data/data_manager.rb +36 -0
  36. data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +33 -18
  37. data/lib/kameleoon/managers/remote_data/remote_visitor_data.rb +42 -16
  38. data/lib/kameleoon/managers/tracking/tracking_builder.rb +149 -0
  39. data/lib/kameleoon/managers/tracking/tracking_manager.rb +97 -0
  40. data/lib/kameleoon/managers/tracking/visitor_tracking_registry.rb +94 -0
  41. data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +22 -5
  42. data/lib/kameleoon/network/access_token_source.rb +46 -14
  43. data/lib/kameleoon/network/cookie/cookie_manager.rb +45 -7
  44. data/lib/kameleoon/network/net_provider.rb +2 -3
  45. data/lib/kameleoon/network/network_manager.rb +16 -21
  46. data/lib/kameleoon/network/request.rb +14 -3
  47. data/lib/kameleoon/network/response.rb +4 -0
  48. data/lib/kameleoon/network/url_provider.rb +11 -10
  49. data/lib/kameleoon/real_time/real_time_configuration_service.rb +10 -11
  50. data/lib/kameleoon/sdk_version.rb +31 -0
  51. data/lib/kameleoon/targeting/condition.rb +6 -2
  52. data/lib/kameleoon/targeting/condition_factory.rb +3 -0
  53. data/lib/kameleoon/targeting/conditions/browser_condition.rb +3 -3
  54. data/lib/kameleoon/targeting/conditions/cookie_condition.rb +10 -10
  55. data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +0 -1
  56. data/lib/kameleoon/targeting/conditions/kcs_heat_range_condition.rb +37 -0
  57. data/lib/kameleoon/targeting/conditions/number_condition.rb +4 -4
  58. data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +1 -2
  59. data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +2 -1
  60. data/lib/kameleoon/targeting/conditions/segment_condition.rb +3 -3
  61. data/lib/kameleoon/targeting/conditions/string_value_condition.rb +2 -1
  62. data/lib/kameleoon/targeting/conditions/target_feature_flag_condition.rb +7 -11
  63. data/lib/kameleoon/targeting/conditions/time_elapsed_since_visit_condition.rb +1 -2
  64. data/lib/kameleoon/targeting/conditions/visit_number_today_condition.rb +4 -4
  65. data/lib/kameleoon/targeting/conditions/visit_number_total_condition.rb +5 -3
  66. data/lib/kameleoon/targeting/conditions/visitor_new_return_condition.rb +7 -6
  67. data/lib/kameleoon/targeting/models.rb +0 -14
  68. data/lib/kameleoon/targeting/targeting_manager.rb +37 -7
  69. data/lib/kameleoon/targeting/tree_builder.rb +10 -5
  70. data/lib/kameleoon/types/remote_visitor_data_filter.rb +21 -3
  71. data/lib/kameleoon/types/variable.rb +21 -0
  72. data/lib/kameleoon/types/variation.rb +22 -0
  73. data/lib/kameleoon/utils.rb +18 -0
  74. data/lib/kameleoon/version.rb +1 -27
  75. metadata +16 -2
@@ -5,12 +5,15 @@ require 'kameleoon/data/browser'
5
5
  require 'kameleoon/data/conversion'
6
6
  require 'kameleoon/data/custom_data'
7
7
  require 'kameleoon/data/device'
8
+ require 'kameleoon/data/kcs_heat'
8
9
  require 'kameleoon/data/page_view'
10
+ require 'kameleoon/data/unique_identifier'
9
11
  require 'kameleoon/data/user_agent'
10
12
  require 'kameleoon/data/manager/assigned_variation'
11
13
  require 'kameleoon/data/manager/page_view_visit'
12
14
  require 'kameleoon/data/manager/data_map_storage'
13
15
  require 'kameleoon/data/manager/data_array_storage'
16
+ require 'kameleoon/logging/kameleoon_logger'
14
17
 
15
18
  module Kameleoon
16
19
  module DataManager
@@ -18,129 +21,265 @@ module Kameleoon
18
21
  # Visitor is a container of all data assigned to a visitor.
19
22
  # It is thread-safe
20
23
  class Visitor
21
- attr_reader :last_activity_time, :user_agent, :device, :browser, :geolocation, :operating_system, :cookie, :visitor_visits
22
- attr_accessor :legal_consent, :mapping_identifier
24
+ attr_reader :data, :is_unique_identifier
23
25
 
24
- def initialize
25
- @mutex = Concurrent::ReadWriteLock.new
26
- @legal_consent = false
26
+ def to_s
27
+ "Visitor{}"
28
+ end
29
+
30
+ def initialize(source = nil)
31
+ if source.nil?
32
+ @data = VisitorData.new
33
+ @is_unique_identifier = false
34
+ else
35
+ @data = source.data
36
+ @is_unique_identifier = source.is_unique_identifier
37
+ end
27
38
  update_last_activity_time
28
39
  end
29
40
 
41
+ def last_activity_time
42
+ @data.last_activity_time
43
+ end
44
+
30
45
  def update_last_activity_time
31
- @last_activity_time = Time.new.to_i
46
+ @data.last_activity_time = Time.new.to_i
32
47
  end
33
48
 
34
49
  def enumerate_sendable_data(&blk)
35
- blk.call(@device) unless @device.nil?
36
- blk.call(@browser) unless @browser.nil?
37
- blk.call(@operating_system) unless @operating_system.nil?
38
- blk.call(@geolocation) unless @geolocation.nil?
39
- @mutex.with_read_lock do
40
- @custom_data_map&.each { |_, cd| blk.call(cd) }
41
- @page_view_visits&.each { |_, pvv| blk.call(pvv.page_view) }
42
- @conversions&.each { |c| blk.call(c) }
43
- @variations&.each { |_, av| blk.call(av) }
44
- end
50
+ @data.enumerate_sendable_data(&blk)
45
51
  end
46
52
 
47
53
  def count_sendable_data
48
- count = 0
49
- @mutex.with_read_lock do
50
- count += 1 unless @device.nil?
51
- count += 1 unless @browser.nil?
52
- count += 1 unless @geolocation.nil?
53
- count += 1 unless @operating_system.nil?
54
- count += @custom_data_map.size unless @custom_data_map.nil?
55
- count += @page_view_visits.size unless @page_view_visits.nil?
56
- count += @conversions.size unless @conversions.nil?
57
- count += @variations.size unless @variations.nil?
58
- end
59
- count
54
+ count_sendable_data = @data.count_sendable_data
55
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.count_sendable_data -> (count_sendable_data: %s)', count_sendable_data)
56
+ count_sendable_data
57
+ end
58
+
59
+ def user_agent
60
+ user_agent = @data.user_agent
61
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.user_agent -> (user_agent: %s)', user_agent)
62
+ user_agent
63
+ end
64
+
65
+ def device
66
+ device = @data.device
67
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.device -> (device: %s)', device)
68
+ device
69
+ end
70
+
71
+ def browser
72
+ browser = @data.browser
73
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.browser -> (browser: %s)', browser)
74
+ browser
75
+ end
76
+
77
+ def geolocation
78
+ geolocation = @data.geolocation
79
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.geolocation -> (geolocation: %s)', geolocation)
80
+ geolocation
81
+ end
82
+
83
+ def operating_system
84
+ operating_system = @data.operating_system
85
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.operating_system -> (operating_system: %s)', operating_system)
86
+ operating_system
87
+ end
88
+
89
+ def cookie
90
+ cookie = @data.cookie
91
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.cookie -> (cookie: %s)', cookie)
92
+ cookie
93
+ end
94
+
95
+ def kcs_heat
96
+ kcs_heat = @data.kcs_heat
97
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.kcs_heat -> (kcs_heat: %s)', kcs_heat)
98
+ kcs_heat
99
+ end
100
+
101
+ def visitor_visits
102
+ visitor_visits = @data.visitor_visits
103
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.visitor_visits -> (visitor_visits: %s)', visitor_visits)
104
+ visitor_visits
105
+ end
106
+
107
+ def legal_consent
108
+ legal_consent = @data.legal_consent
109
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.legal_consent -> (legal_consent: %s)', legal_consent)
110
+ legal_consent
111
+ end
112
+
113
+ def legal_consent=(value)
114
+ @data.legal_consent = value
115
+ end
116
+
117
+ def mapping_identifier
118
+ mapping_identifier = @data.mapping_identifier
119
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.mapping_identifier -> (mapping_identifier: %s)',
120
+ mapping_identifier)
121
+ mapping_identifier
122
+ end
123
+
124
+ def mapping_identifier=(value)
125
+ @data.mapping_identifier = value
60
126
  end
61
127
 
62
128
  def custom_data
63
- DataMapStorage.new(@mutex, @custom_data_map)
129
+ custom_data = @data.custom_data
130
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.custom_data -> (custom_data: %s)', custom_data)
131
+ custom_data
64
132
  end
65
133
 
66
134
  def page_view_visits
67
- DataMapStorage.new(@mutex, @page_view_visits)
135
+ page_view_visits = @data.page_view_visits
136
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.page_view_visits -> (page_view_visits: %s)',
137
+ page_view_visits)
138
+ page_view_visits
68
139
  end
69
140
 
70
141
  def conversions
71
- DataArrayStorage.new(@mutex, @conversions)
142
+ conversions = @data.conversions
143
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.conversions -> (conversions: %s)', conversions)
144
+ conversions
72
145
  end
73
146
 
74
147
  def variations
75
- DataMapStorage.new(@mutex, @variations)
148
+ variations = @data.variations
149
+ Logging::KameleoonLogger.debug('CALL/RETURN: Visitor.variations -> (variations: %s)', variations)
150
+ variations
76
151
  end
77
152
 
78
- def add_data(log_func, *args, overwrite: true)
79
- @mutex.with_write_lock do
153
+ def add_data(*args, overwrite: true)
154
+ Logging::KameleoonLogger.debug('CALL: Visitor.add_data(args: %s, overwrite: %s)', args, overwrite)
155
+ @data.mutex.with_write_lock do
80
156
  args.each do |data|
81
157
  case data
82
158
  when Kameleoon::UserAgent
83
- set_user_agent(data)
159
+ @data.user_agent = data.value
84
160
  when Kameleoon::DataManager::AssignedVariation
85
- add_variation(data, overwrite)
161
+ @data.add_variation(data, overwrite)
86
162
  when Kameleoon::Device
87
- set_device(data, overwrite)
163
+ @data.set_device(data, overwrite)
88
164
  when Kameleoon::Browser
89
- set_browser(data, overwrite)
165
+ @data.set_browser(data, overwrite)
90
166
  when Kameleoon::CustomData
91
- add_custom_data(data, overwrite)
167
+ @data.add_custom_data(data, overwrite)
92
168
  when Kameleoon::PageView
93
- add_page_view(data)
169
+ @data.add_page_view(data)
94
170
  when Kameleoon::DataManager::PageViewVisit
95
- add_page_view_visit(data)
171
+ @data.add_page_view_visit(data)
96
172
  when Kameleoon::Conversion
97
- add_conversion(data)
173
+ @data.add_conversion(data)
98
174
  when Kameleoon::Cookie
99
- set_cookie(data)
175
+ @data.cookie = data
100
176
  when Kameleoon::OperatingSystem
101
- set_operating_system(data, overwrite)
177
+ @data.set_operating_system(data, overwrite)
102
178
  when Kameleoon::Geolocation
103
- set_geolocation(data, overwrite)
179
+ @data.set_geolocation(data, overwrite)
180
+ when Kameleoon::KcsHeat
181
+ @data.kcs_heat = data
104
182
  when Kameleoon::VisitorVisits
105
- set_visitor_visits(data)
183
+ @data.visitor_visits = data
184
+ when Kameleoon::UniqueIdentifier
185
+ @is_unique_identifier = data.value
106
186
  else
107
- log_func&.call("Data has unsupported type '#{data.class}'")
187
+ Logging::KameleoonLogger.warning("Data has unsupported type '%s'", data.class)
108
188
  end
109
189
  end
110
190
  end
191
+ Logging::KameleoonLogger.debug('RETURN: Visitor.add_data(args: %s, overwrite: %s)', args, overwrite)
111
192
  end
112
193
 
113
194
  def assign_variation(variation)
114
- @mutex.with_write_lock do
115
- @variations = {} if @variations.nil?
116
- @variations[variation.experiment_id] = variation
195
+ @data.mutex.with_write_lock do
196
+ @data.add_variation(variation, true)
117
197
  end
118
198
  end
119
199
 
120
- private
200
+ def clone
201
+ Visitor.new(self)
202
+ end
203
+ end
204
+
205
+ class VisitorData
206
+ attr_reader :mutex, :device, :browser, :geolocation, :operating_system
207
+ attr_accessor :last_activity_time, :legal_consent, :user_agent, :cookie, :kcs_heat, :visitor_visits,
208
+ :mapping_identifier
121
209
 
122
- def set_user_agent(user_agent)
123
- @user_agent = user_agent.value
210
+ def initialize
211
+ Logging::KameleoonLogger.debug('CALL: VisitorData.new')
212
+ @mutex = Concurrent::ReadWriteLock.new
213
+ @legal_consent = false
214
+ Logging::KameleoonLogger.debug('RETURN: VisitorData.new')
215
+ end
216
+
217
+ def enumerate_sendable_data(&blk)
218
+ blk.call(@device) unless @device.nil?
219
+ blk.call(@browser) unless @browser.nil?
220
+ blk.call(@operating_system) unless @operating_system.nil?
221
+ blk.call(@geolocation) unless @geolocation.nil?
222
+ @mutex.with_read_lock do
223
+ @custom_data_map&.each { |_, cd| blk.call(cd) }
224
+ @page_view_visits&.each { |_, pvv| blk.call(pvv.page_view) }
225
+ @conversions&.each { |c| blk.call(c) }
226
+ @variations&.each { |_, av| blk.call(av) }
227
+ end
228
+ end
229
+
230
+ def count_sendable_data
231
+ Logging::KameleoonLogger.debug('CALL: Visitor.count_sendable_data')
232
+ count = 0
233
+ @mutex.with_read_lock do
234
+ count += 1 unless @device.nil?
235
+ count += 1 unless @browser.nil?
236
+ count += 1 unless @geolocation.nil?
237
+ count += 1 unless @operating_system.nil?
238
+ count += @custom_data_map.size unless @custom_data_map.nil?
239
+ count += @page_view_visits.size unless @page_view_visits.nil?
240
+ count += @conversions.size unless @conversions.nil?
241
+ count += @variations.size unless @variations.nil?
242
+ end
243
+ Logging::KameleoonLogger.debug('RETURN: VisitorData.count_sendable_data -> (count: %s)', count)
244
+ count
245
+ end
246
+
247
+ def custom_data
248
+ DataMapStorage.new(@mutex, @custom_data_map)
249
+ end
250
+
251
+ def page_view_visits
252
+ DataMapStorage.new(@mutex, @page_view_visits)
253
+ end
254
+
255
+ def conversions
256
+ DataArrayStorage.new(@mutex, @conversions)
257
+ end
258
+
259
+ def variations
260
+ DataMapStorage.new(@mutex, @variations)
124
261
  end
125
262
 
126
263
  def set_device(device, overwrite)
127
- @device = device if overwrite || @device == nil
264
+ @device = device if overwrite || @device.nil?
128
265
  end
129
266
 
130
267
  def add_variation(variation, overwrite)
131
- @variations = {} if @variations == nil
268
+ @variations = {} if @variations.nil?
132
269
  if overwrite || !@variations.include?(variation.experiment_id)
133
270
  @variations[variation.experiment_id] = variation
134
271
  end
135
272
  end
136
273
 
137
274
  def set_browser(browser, overwrite)
138
- @browser = browser if overwrite || @browser == nil
275
+ @browser = browser if overwrite || @browser.nil?
139
276
  end
140
277
 
141
278
  def add_custom_data(custom_data, overwrite)
142
279
  @custom_data_map = {} if @custom_data_map.nil?
143
- @custom_data_map[custom_data.id] = custom_data if overwrite || !@custom_data_map.include?(custom_data.id)
280
+ if overwrite || !@custom_data_map.include?(custom_data.id)
281
+ @custom_data_map[custom_data.id] = custom_data
282
+ end
144
283
  end
145
284
 
146
285
  def add_page_view(page_view)
@@ -173,19 +312,11 @@ module Kameleoon
173
312
  end
174
313
 
175
314
  def set_geolocation(geolocation, overwrite)
176
- @geolocation = geolocation if overwrite || @geolocation == nil
177
- end
178
-
179
- def set_cookie(cookie)
180
- @cookie = cookie
315
+ @geolocation = geolocation if overwrite || @geolocation.nil?
181
316
  end
182
317
 
183
318
  def set_operating_system(operating_system, overwrite)
184
- @operating_system = operating_system if overwrite || @operating_system == nil
185
- end
186
-
187
- def set_visitor_visits(visitor_visits)
188
- @visitor_visits = visitor_visits
319
+ @operating_system = operating_system if overwrite || @operating_system.nil?
189
320
  end
190
321
  end
191
322
  end
@@ -2,7 +2,10 @@
2
2
 
3
3
  require 'concurrent'
4
4
  require 'rufus/scheduler'
5
+ require 'kameleoon/configuration/custom_data_info'
6
+ require 'kameleoon/data/mapping_identifier'
5
7
  require 'kameleoon/data/manager/visitor'
8
+ require 'kameleoon/logging/kameleoon_logger'
6
9
 
7
10
  module Kameleoon
8
11
  module DataManager
@@ -11,36 +14,52 @@ module Kameleoon
11
14
  # It is thread-safe except `stop` method
12
15
  class VisitorManager
13
16
  attr_reader :expiration_period
14
- attr_accessor :custom_data_info
15
17
 
16
- def initialize(expiration_period, log_func = nil)
18
+ def initialize(data_manager, expiration_period, scheduler)
19
+ Logging::KameleoonLogger.debug(
20
+ 'CALL: VisitorManager.new(data_manager, expiration_period: %s, scheduler)', expiration_period
21
+ )
22
+ @data_manager = data_manager
17
23
  @expiration_period = expiration_period
24
+ @scheduler = scheduler
18
25
  @visitors = Concurrent::Map.new
19
- @log_func = log_func
20
26
  start
27
+ Logging::KameleoonLogger.debug(
28
+ 'RETURN: VisitorManager.new(data_manager, expiration_period: %s, scheduler)', expiration_period
29
+ )
21
30
  end
22
31
 
23
32
  def stop
24
- return if @purge_job.nil?
25
-
26
- @purge_job.unschedule
33
+ Logging::KameleoonLogger.debug('CALL: VisitorManager.stop')
34
+ @purge_job&.unschedule
27
35
  @purge_job = nil
36
+ Logging::KameleoonLogger.debug('RETURN: VisitorManager.stop')
28
37
  end
29
38
 
30
39
  def get_visitor(visitor_code)
31
- @visitors.compute_if_present(visitor_code) do |visitor|
40
+ Logging::KameleoonLogger.debug("CALL: VisitorManager.get_visitor(visitor_code: '%s')", visitor_code)
41
+ visitor = @visitors.compute_if_present(visitor_code) do |visitor|
32
42
  visitor.update_last_activity_time
33
43
  visitor
34
44
  end
45
+ Logging::KameleoonLogger.debug("RETURN: VisitorManager.get_visitor(visitor_code: '%s') -> (visitor: %s)",
46
+ visitor_code, visitor)
47
+ visitor
35
48
  end
36
49
 
37
50
  def get_or_create_visitor(visitor_code)
38
- @visitors.compute(visitor_code) do |former_v|
51
+ Logging::KameleoonLogger.debug("CALL: VisitorManager.get_or_create_visitor(visitor_code: '%s')",
52
+ visitor_code)
53
+ visitor = @visitors.compute(visitor_code) do |former_v|
39
54
  next DataManager::Visitor.new if former_v.nil?
40
55
 
41
56
  former_v.update_last_activity_time
42
57
  former_v
43
58
  end
59
+ Logging::KameleoonLogger.debug(
60
+ "RETURN: VisitorManager.get_or_create_visitor(visitor_code: '%s') -> (visitor)", visitor_code
61
+ )
62
+ visitor
44
63
  end
45
64
 
46
65
  def enumerate(&blk)
@@ -51,42 +70,60 @@ module Kameleoon
51
70
  @visitors.size
52
71
  end
53
72
 
54
- def add_data(visitor_code, *args)
73
+ def add_data(visitor_code, *args, overwrite: true)
74
+ Logging::KameleoonLogger.debug("CALL: VisitorManager.add_data(visitor_code: '%s', args: %s, overwrite: %s)",
75
+ visitor_code, args, overwrite)
55
76
  visitor = get_or_create_visitor(visitor_code)
56
- for custom_data in args
77
+ cdi = @data_manager.data_file.custom_data_info
78
+ args.size.times do |i|
79
+ custom_data = args[i]
57
80
  next unless custom_data.is_a?(Kameleoon::CustomData)
81
+
58
82
  # We shouldn't send custom data with local only type
59
- custom_data.mark_as_sent if @custom_data_info.local_only?(custom_data.id)
83
+ custom_data.mark_as_sent if cdi.local_only?(custom_data.id)
60
84
  # If mappingIdentifier is passed, we should link anonymous visitor with real unique userId.
61
85
  # After authorization, customer must be able to continue work with userId, but hash for variation
62
86
  # should be calculated based on anonymous visitor code, that's why set MappingIdentifier to visitor.
63
- if @custom_data_info.mapping_identifier?(custom_data.id) && custom_data.values.size > 0 && custom_data.values[0].size > 0
64
- custom_data.is_mapping_identifier = true
87
+ if Configuration::CustomDataInfo.mapping_identifier?(cdi, custom_data)
65
88
  visitor.mapping_identifier = visitor_code
66
- target_visitor_code = custom_data.values[0]
67
- @visitors[target_visitor_code] = visitor if visitor_code != target_visitor_code
89
+ user_id = custom_data.values[0]
90
+ args[i] = MappingIdentifier.new(custom_data)
91
+ if visitor_code != user_id
92
+ @visitors[user_id] = visitor.clone
93
+ Logging::KameleoonLogger.info(-> { "Linked anonymous visitor '#{visitor_code}' with user '#{user_id}'" })
94
+ end
68
95
  end
69
96
  end
70
- visitor.add_data(@log_func, *args)
97
+ visitor.add_data(*args, overwrite: overwrite)
98
+ Logging::KameleoonLogger.debug(
99
+ "RETURN: VisitorManager.add_data(visitor_code: '%s', args: %s, overwrite: %s) -> (visitor)",
100
+ visitor_code, args, overwrite
101
+ )
71
102
  visitor
72
103
  end
73
104
 
74
105
  private
75
106
 
76
107
  def purge
108
+ Logging::KameleoonLogger.debug('CALL: VisitorManager.purge')
77
109
  expired_time = Time.new.to_i - @expiration_period
78
110
  @visitors.each_pair do |vc, v|
79
111
  next if v.last_activity_time >= expired_time
80
112
 
81
113
  @visitors.compute_if_present(vc) { |visitor| v.last_activity_time < expired_time ? nil : visitor }
82
114
  end
115
+ Logging::KameleoonLogger.debug('RETURN: VisitorManager.purge')
116
+ @visitors
83
117
  end
84
118
 
85
119
  def start
120
+ Logging::KameleoonLogger.debug('CALL: VisitorManager.start')
86
121
  stop unless @purge_job.nil?
87
- @purge_job = Rufus::Scheduler.singleton.schedule_every @expiration_period do
122
+ @purge_job = @scheduler.schedule_every @expiration_period do
88
123
  purge
89
124
  end
125
+ Logging::KameleoonLogger.debug('RETURN: VisitorManager.start')
126
+ @purge_job
90
127
  end
91
128
  end
92
129
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kameleoon/data/custom_data'
4
+ require 'kameleoon/network/uri_helper'
5
+
6
+ module Kameleoon
7
+ class MappingIdentifier < CustomData
8
+ def initialize(custom_data)
9
+ super(custom_data.id, *custom_data.values)
10
+ end
11
+
12
+ def unsent
13
+ true
14
+ end
15
+
16
+ def transmitting
17
+ false
18
+ end
19
+
20
+ def sent
21
+ false
22
+ end
23
+
24
+ def obtain_full_post_text_line
25
+ mip = Kameleoon::Network::UriHelper.encode_query({ mappingIdentifier: true })
26
+ "#{super}&#{mip}"
27
+ end
28
+
29
+ def to_s
30
+ "MappingIdentifier{id:#{@id},values:#{@values}}"
31
+ end
32
+ end
33
+ end
@@ -52,6 +52,10 @@ module Kameleoon
52
52
  class OperatingSystem < DuplicationUnsafeData
53
53
  attr_reader :os_type
54
54
 
55
+ def to_s
56
+ "OperatingSystem{os_type:#{@os_type}}"
57
+ end
58
+
55
59
  # @param [OperatingSystemType] os_type Operating system type, can be: WINDOWS, MAC, IOS, LINUX, ANDROID, WINDOWS_PHONE
56
60
  def initialize(os_type)
57
61
  super(DataType::OPERATING_SYSTEM)
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
+ require 'kameleoon/logging/kameleoon_logger'
4
5
  require 'kameleoon/network/uri_helper'
5
6
  require_relative 'data'
6
7
 
@@ -9,13 +10,17 @@ module Kameleoon
9
10
  class PageView < DuplicationSafeData
10
11
  attr_reader :url, :title, :referrer
11
12
 
13
+ def to_s
14
+ "PageView{url:'#{@url}',title:'#{@title}',referrers:#{@referrers}}"
15
+ end
16
+
12
17
  # @param [String] url Url of the page
13
18
  # @param [String] title Optional field - title of the page
14
19
  # @param [Array] referrers Optional field - Referrer ids
15
20
  def initialize(url, title = nil, referrers = nil)
16
21
  super(DataType::PAGE_VIEW)
17
22
  @url = url || ''
18
- print('Kameleoon SDK: Url for PageView is required parameter, the data will be ignored.') if url == ''
23
+ Logging::KameleoonLogger.error('Url for PageView is required parameter, the data will be ignored.') if @url == ''
19
24
  @title = title || ''
20
25
  @referrers = referrers.instance_of?(Integer) ? [referrers] : referrers
21
26
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kameleoon
4
+ class UniqueIdentifier
5
+ attr_reader :value
6
+
7
+ def initialize(value)
8
+ @value = value
9
+ end
10
+ end
11
+ end
@@ -7,6 +7,10 @@ module Kameleoon
7
7
  class UserAgent
8
8
  attr_reader :value
9
9
 
10
+ def to_s
11
+ "UserAgent{value:#{@value}}"
12
+ end
13
+
10
14
  def initialize(value)
11
15
  @value = value
12
16
  end
@@ -4,10 +4,21 @@ module Kameleoon
4
4
  class VisitorVisits
5
5
  attr_reader :previous_visit_timestamps
6
6
 
7
+ def to_s
8
+ "VisitorVisits{previous_visit_timestamps:#{@previous_visit_timestamps}}"
9
+ end
10
+
7
11
  def initialize(previous_visit_timestamps = [])
8
12
  @previous_visit_timestamps = previous_visit_timestamps
9
13
  @previous_visit_timestamps.freeze
10
14
  end
15
+
16
+ def self.get_previous_visit_timestamps(visitor_visits)
17
+ visitor_visits.is_a?(VisitorVisits) ? visitor_visits.previous_visit_timestamps : []
18
+ end
19
+
20
+ def self.visitor_visits?(obj)
21
+ obj.nil? || obj.is_a?(VisitorVisits)
22
+ end
11
23
  end
12
24
  end
13
-
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'kameleoon/logging/kameleoon_logger'
4
+
3
5
  module Kameleoon
4
6
  module Hybrid
5
7
  TC_INIT = 'window.kameleoonQueue=window.kameleoonQueue||[];'
@@ -17,14 +19,16 @@ module Kameleoon
17
19
 
18
20
  # Implementation of Cache with auto cleaning feature
19
21
  class ManagerImpl < Manager
20
- def initialize(expiration_time, log_func)
22
+ def initialize(expiration_time)
21
23
  super()
24
+ Logging::KameleoonLogger.debug('CALL: HybridManager.new(expiration_time: %s)', expiration_time)
22
25
  @expiration_time = expiration_time
23
- @log = log_func
24
- @log.call('Hybrid Manager was successfully initialized')
26
+ Logging::KameleoonLogger.debug('RETURN: HybridManager.new(expiration_time: %s)', expiration_time)
25
27
  end
26
28
 
27
29
  def get_engine_tracking_code(visitor_variations)
30
+ Logging::KameleoonLogger.debug('CALL: HybridManager.get_engine_tracking_code(visitor_variations: %s)',
31
+ visitor_variations)
28
32
  tracking_code = [TC_INIT]
29
33
  unless visitor_variations.nil?
30
34
  expired_time = (Time.now - @expiration_time).to_i
@@ -35,7 +39,12 @@ module Kameleoon
35
39
  end
36
40
  end
37
41
  end
38
- tracking_code.join
42
+ tracking_code = tracking_code.join
43
+ Logging::KameleoonLogger.debug(
44
+ "RETURN: HybridManager.get_engine_tracking_code(visitor_variations: %s) -> (tracking_code: '%s')",
45
+ visitor_variations, tracking_code
46
+ )
47
+ tracking_code
39
48
  end
40
49
  end
41
50
  end