kameleoon-client-ruby 1.0.1 → 1.0.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1acddc80101273c13cdf39b6cf2fb497716e947981dbffcf4d31540ea1f62edc
4
- data.tar.gz: c00f33ed4eb494f7b1f2b4009005e84492ccad9cc366ac8fd34888c6aa63e2eb
3
+ metadata.gz: dbb0fcb2b7bd0c35767c990d39eb0b5d06d996b4bbe1b3c43ec04ec03541a671
4
+ data.tar.gz: bcdf01f341003189b8a41d9184e792091603b1369b47bc5838786fa2f382c65d
5
5
  SHA512:
6
- metadata.gz: 6b4a67c7e0f8315aaeb2e46c15c2961840099a40a874d56c821bfc5407aa4f506ea732cf90cad13abb406e1c2f6d98bea62fb07a9b7bf427798ad27a15ef11e3
7
- data.tar.gz: a62a96d1a772835c9e4db7ad8c968c302339dae2b9937204c37bbd2d8f22f23d6c76dae15b8f8577a0e692e1a181d27177635e64fba0f1b090290c870c0f9034
6
+ metadata.gz: b81e0518ca8b69e837daa26fe467d2ab5b306ed0dd4770e83d7bd8d022fc7fe485a9c95cf89a44b8bdf5d4ea2af6b335842c19b354c9db30ff37134dd29d7cb3
7
+ data.tar.gz: 420d763b0a306809a0d784c44d7058a214e76b2e9ddf88727fe14bfe71d327a18172c621eb7d48cf18874f34d20f1e7c1b87b594c639f9dc769dee41aba1e1f1
@@ -30,6 +30,7 @@ module Kameleoon
30
30
  @client_id = client_id || config['client_id']
31
31
  @client_secret = client_secret || config['client_secret']
32
32
  @data_maximum_size = config['visitor_data_maximum_size'] || 500 # mb
33
+ @verbose_mode = config['verbose_mode'] || false
33
34
  @experiments = []
34
35
  @feature_flags = []
35
36
  @data = {}
@@ -96,10 +97,13 @@ module Kameleoon
96
97
  .join("\n") || ""
97
98
  path = get_experiment_register_url(visitor_code, experiment_id)
98
99
  request_options = { :path => path, :body => body }
100
+ log "Trigger experiment request: " + request_options.inspect
101
+ log "Trigger experiment connexion:" + connexion_options.inspect
99
102
  request = EM::Synchrony.sync post(request_options, @tracking_url, connexion_options)
100
103
  if is_successful(request)
101
104
  variation_id = request.response
102
105
  else
106
+ log "Failed to trigger experiment: " + request.inspect
103
107
  raise Exception::ExperimentConfigurationNotFound.new(experiment_id) if variation_id.nil?
104
108
  end
105
109
  EM.stop
@@ -112,16 +116,16 @@ module Kameleoon
112
116
  variation_id.to_i
113
117
  else
114
118
  visitor_data = @data.select { |key, value| key.to_s == visitor_code }.values.flatten! || []
115
- if experiment['targetingSegment'].check_tree(visitor_data)
119
+ if experiment['targetingSegment'].nil? || experiment['targetingSegment'].check_tree(visitor_data)
116
120
  threshold = obtain_hash_double(visitor_code, experiment['respoolTime'], experiment['id'])
117
121
  experiment['deviations'].each do |key, value|
118
122
  threshold -= value
119
123
  if threshold < 0
120
- post_beacon("experimentTracking", visitor_code, experiment_id, key)
124
+ track_experiment(visitor_code, experiment_id, key)
121
125
  return key.to_s.to_i
122
126
  end
123
127
  end
124
- post_beacon("experimentTracking", visitor_code, experiment_id, REFERENCE, true)
128
+ track_experiment(visitor_code, experiment_id, REFERENCE, true)
125
129
  raise Exception::NotActivated.new(visitor_code)
126
130
  end
127
131
  raise Exception::NotTargeted.new(visitor_code)
@@ -178,7 +182,7 @@ module Kameleoon
178
182
  # @param [String] visitor_code Optional field - Visitor code, without visitor code it flush all of the data
179
183
  #
180
184
  def flush(visitor_code = nil)
181
- post_beacon("dataTracking", visitor_code)
185
+ track_data(visitor_code)
182
186
  end
183
187
 
184
188
  ##
@@ -227,11 +231,15 @@ module Kameleoon
227
231
  connexion_options = { :connect_timeout => (timeout.to_f / 1000.0) }
228
232
  request_options = {
229
233
  :path => get_experiment_register_url(visitor_code, id),
230
- :body => (select_data_to_sent(visitor_code).values.map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8")
234
+ :body => (data_not_sent(visitor_code).values.map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8")
231
235
  }
236
+ log "Activate feature request: " + request_options.inspect
237
+ log "Activate feature connexion:" + connexion_options.inspect
232
238
  request = EM::Synchrony.sync post(request_options, @tracking_url, connexion_options)
233
239
  if is_successful(request)
234
240
  result = request.response
241
+ else
242
+ log "Failed to get activation:" + result.inspect
235
243
  end
236
244
  EM.stop
237
245
  end
@@ -243,10 +251,10 @@ module Kameleoon
243
251
  if feature_flag['targetingSegment'].nil? || feature_flag['targetingSegment'].check_tree(visitor_data)
244
252
  threshold = obtain_hash_double(visitor_code, {}, id)
245
253
  if threshold <= feature_flag['expositionRate']
246
- post_beacon("experimentTracking", visitor_code, id, feature_flag["variationsId"].first)
254
+ track_experiment(visitor_code, id, feature_flag["variationsId"].first)
247
255
  return true
248
256
  else
249
- post_beacon("experimentTracking", visitor_code, id, REFERENCE, true)
257
+ track_experiment(visitor_code, id, REFERENCE, true)
250
258
  return false
251
259
  end
252
260
  else
@@ -290,15 +298,16 @@ module Kameleoon
290
298
  API_SSX_URL = "https://api-ssx.kameleoon.com"
291
299
  REFERENCE = 0
292
300
  attr :site_code, :client_id, :client_secret, :access_token, :experiments, :feature_flags, :scheduler, :data,
293
- :blocking, :tracking_url, :default_timeout, :interval, :memory_limit
301
+ :blocking, :tracking_url, :default_timeout, :interval, :memory_limit, :verbose_mode
294
302
 
295
303
  def fetch_configuration
296
- print "=> Starting Scheduler"
297
304
  @scheduler = Rufus::Scheduler.singleton
298
305
  @scheduler.every @interval do
306
+ log("Scheduled job to fetch configuration is starting.")
299
307
  fetch_configuration_job
300
308
  end
301
309
  @scheduler.schedule '0s' do
310
+ log("Start-up, fetching is starting")
302
311
  fetch_configuration_job
303
312
  end
304
313
  end
@@ -334,15 +343,19 @@ module Kameleoon
334
343
  end
335
344
 
336
345
  def obtain_site
346
+ log "Fetching site"
337
347
  query_params = { 'perPage' => 1 }
338
348
  filters = [hash_filter('code', 'EQUAL', [@site_code])]
339
349
  request = fetch_one('sites', query_params, filters)
340
350
  if request != false
341
- JSON.parse(request.response)
351
+ sites = JSON.parse(request.response)
352
+ log "Sites are fetched: " + sites.inspect
353
+ sites
342
354
  end
343
355
  end
344
356
 
345
357
  def obtain_access_token
358
+ log "Fetching bearer token"
346
359
  body = {
347
360
  'grant_type' => 'client_credentials',
348
361
  'client_id' => @client_id,
@@ -353,6 +366,9 @@ module Kameleoon
353
366
  request = EM::Synchrony.sync post({ :path => '/oauth/token', :body => body, :head => header })
354
367
  if is_successful(request)
355
368
  @access_token = JSON.parse(request.response)['access_token']
369
+ log "Bearer Token is fetched: " + @access_token.to_s
370
+ else
371
+ log "Failed to fetch bearer token: " + request.inspect
356
372
  end
357
373
  end
358
374
 
@@ -381,26 +397,32 @@ module Kameleoon
381
397
  end
382
398
 
383
399
  def obtain_tests(site_id, per_page = -1)
400
+ log "Fetching experiments"
384
401
  query_values = { 'perPage' => per_page }
385
402
  filters = [
386
403
  hash_filter('siteId', 'EQUAL', [site_id]),
387
- hash_filter('status', 'EQUAL', ['ACTIVE']),
404
+ hash_filter('status', 'IN', ['ACTIVE', 'DEVIATED']),
388
405
  hash_filter('type', 'IN', ['SERVER_SIDE', 'HYBRID'])
389
406
  ]
390
- fetch_all('experiments', query_values, filters).map { |it| JSON.parse(it.response) }.flatten.map do |test|
407
+ experiments = fetch_all('experiments', query_values, filters).map { |it| JSON.parse(it.response) }.flatten.map do |test|
391
408
  complete_experiment(test)
392
409
  end
410
+ log "Experiment are fetched: " + experiments.inspect
411
+ experiments
393
412
  end
394
413
 
395
414
  def obtain_feature_flags(site_id, per_page = -1)
415
+ log "Fetching feature flags"
396
416
  query_values = { 'perPage' => per_page }
397
417
  filters = [
398
418
  hash_filter('siteId', 'EQUAL', [site_id]),
399
419
  hash_filter('status', 'EQUAL', ['ACTIVE'])
400
420
  ]
401
- fetch_all('feature-flags', query_values, filters).map { |it| JSON.parse(it.response) }.flatten.map do |ff|
421
+ feature_flags = fetch_all('feature-flags', query_values, filters).map { |it| JSON.parse(it.response) }.flatten.map do |ff|
402
422
  complete_experiment(ff)
403
423
  end
424
+ log "Feature flags are fetched: " + feature_flags.inspect
425
+ feature_flags
404
426
  end
405
427
 
406
428
  def fetch_all(path, query_values = {}, filters = [])
@@ -423,6 +445,7 @@ module Kameleoon
423
445
  end
424
446
  request = EM::Synchrony.sync get({ :path => path, :query => query_values, :head => hash_headers })
425
447
  unless is_successful(request)
448
+ log "Failed to fetch" + request.inspect
426
449
  return false
427
450
  end
428
451
  request
@@ -449,6 +472,10 @@ module Kameleoon
449
472
  url
450
473
  end
451
474
 
475
+ def get_data_register_url(visitor_code)
476
+ "/dataTracking?" + URI.encode_www_form(get_common_ssx_parameters(visitor_code))
477
+ end
478
+
452
479
  def get_feature_flag(feature_key)
453
480
  if feature_key.is_a?(String)
454
481
  feature_flag = @feature_flags.select { |ff| ff['identificationKey'] == feature_key}.first
@@ -463,19 +490,48 @@ module Kameleoon
463
490
  feature_flag
464
491
  end
465
492
 
466
- def post_beacon(type = "dataTracking", visitor_code = nil, experiment_id = nil, variation_id = nil, none_variation = false)
493
+ def track_experiment(visitor_code, experiment_id, variation_id = nil, none_variation = false)
494
+ data_not_sent = data_not_sent(visitor_code)
495
+ options = {
496
+ :path => get_experiment_register_url(visitor_code, experiment_id, variation_id, none_variation),
497
+ :body => ((data_not_sent.values[0] || []).map{ |it| it.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8"),
498
+ :head => { "Content-Type" => "text/plain"}
499
+ }
500
+ trial = 0
501
+ log "Start post tracking experiment: " + data_not_sent.inspect
502
+ Thread.new do
503
+ EM.synchrony do
504
+ while trial < 10
505
+ request = EM::Synchrony.sync post(options, @tracking_url)
506
+ log "Request " + request.inspect
507
+ if is_successful(request)
508
+ (data_not_sent.values[0] || []).each { |it| it.sent = true }
509
+ EM.stop
510
+ end
511
+ trial += 1
512
+ end
513
+ EM.stop
514
+ end
515
+ log "Post to experiment tracking is done after " + trial.to_s + " trials"
516
+ Thread.exit
517
+ end
518
+ end
519
+
520
+ def track_data(visitor_code = nil)
467
521
  Thread.new do
468
522
  EM.synchrony do
469
- entries = select_data_to_sent(visitor_code)
470
523
  trials = 10
471
524
  concurrency = 1
472
- while !entries.empty? && trials > 0
473
- EM::Synchrony::Iterator.new(entries, concurrency).map do |entry, iter|
525
+ data_not_sent = data_not_sent(visitor_code)
526
+ log "Start post tracking data: " + data_not_sent.inspect
527
+ while trials > 0 && !data_not_sent.empty?
528
+ EM::Synchrony::Iterator.new(data_not_sent, concurrency).map do |entry, iter|
474
529
  options = {
475
- :path => build_beacon_path(type, entry.first || visitor_code, experiment_id, variation_id, none_variation),
530
+ :path => get_data_register_url(entry.first),
476
531
  :body => (entry.last.map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8"),
477
532
  :head => { "Content-Type" => "text/plain" }
478
533
  }
534
+ log "Post tracking data for visitor_code: " + entry.first + " with options: " + options.inspect
479
535
  request = post(options, @tracking_url)
480
536
  request.callback {
481
537
  if is_successful(request)
@@ -485,16 +541,17 @@ module Kameleoon
485
541
  }
486
542
  request.errback { iter.return(request) }
487
543
  end
488
- entries = select_data_to_sent(visitor_code)
544
+ data_not_sent = data_not_sent(visitor_code)
489
545
  trials -= 1
490
546
  end
547
+ log "Post to data tracking is done."
491
548
  EM.stop
492
549
  end
493
550
  Thread.exit
494
551
  end
495
552
  end
496
553
 
497
- def select_data_to_sent(visitor_code)
554
+ def data_not_sent(visitor_code = nil)
498
555
  if visitor_code.nil?
499
556
  @data.select {|key, values| values.any? {|data| !data.sent}}
500
557
  else
@@ -502,13 +559,9 @@ module Kameleoon
502
559
  end
503
560
  end
504
561
 
505
- def build_beacon_path(type, visitor_code, experiment_id = nil, variation_id = nil, none_variation = nil)
506
- if type == "dataTracking"
507
- return "/dataTracking?" + URI.encode_www_form(get_common_ssx_parameters(visitor_code))
508
- elsif type == "experimentTracking"
509
- return get_experiment_register_url(visitor_code, experiment_id, variation_id, none_variation)
510
- else
511
- raise TypeError("Unknown type for post_beacon: " + type.to_s)
562
+ def log(text)
563
+ if @verbose_mode
564
+ print "Kameleoon Log: " + text.to_s + "\n"
512
565
  end
513
566
  end
514
567
  end
@@ -17,6 +17,8 @@ module Kameleoon
17
17
  #
18
18
  def self.create(site_code, blocking = false, config_path = CONFIG_PATH, client_id = nil, client_secret = nil)
19
19
  client = Client.new(site_code, config_path, blocking, CONFIGURATION_UPDATE_INTERVAL, DEFAULT_TIMEOUT, client_id, client_secret)
20
+ client.send(:log, "Warning: you are using the blocking mode") if blocking
21
+ client.send(:log, "Client created with site code: " + site_code.to_s)
20
22
  client.send(:fetch_configuration)
21
23
  client
22
24
  end
@@ -23,7 +23,7 @@ module Kameleoon
23
23
  private
24
24
 
25
25
  def request(method, request_options, url, connexion_options)
26
- #connexion_options[:tls] = {verify_peer: true}
26
+ connexion_options[:tls] = {verify_peer: false}
27
27
  add_user_agent(request_options)
28
28
  case method
29
29
  when Method::POST then
@@ -42,9 +42,9 @@ module Kameleoon
42
42
 
43
43
  def add_user_agent(request_options)
44
44
  if request_options[:head].nil?
45
- request_options[:head] = {'User-Agent' => 'kameleoon-client-ruby/' + Kameleoon::VERSION}
45
+ request_options[:head] = {'Kameleoon-Client' => 'sdk/ruby/' + Kameleoon::VERSION}
46
46
  else
47
- request_options[:head].store('User-Agent', 'kameleoon-client-ruby/' + Kameleoon::VERSION)
47
+ request_options[:head].store('Kameleoon-Client', 'sdk/ruby/' + Kameleoon::VERSION)
48
48
  end
49
49
  end
50
50
  end
@@ -1,3 +1,3 @@
1
1
  module Kameleoon
2
- VERSION = '1.0.1'
2
+ VERSION = '1.0.6'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kameleoon-client-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kameleoon - Guillaume Grandjean
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-16 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request