kameleoon-client-ruby 1.0.10 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b70d1fc8cd47248dd68ba217e9a860577008e008cac7e6f562ab1856b3dc24c3
4
- data.tar.gz: 03ddd4ce4f1ea480bc5adfc347c9f2168af952cc9036ce5cff494af9699a4dfe
3
+ metadata.gz: a985a05999f2b8caeba131919f70ae77a1e6df7d125b82bf040a1056b300c1e5
4
+ data.tar.gz: d603f64d8801a3945236de7891ccde5c9a2c6747f18cb704954591a43abc5a99
5
5
  SHA512:
6
- metadata.gz: d3d39ad2e27a0312ff090f58a93cba6aa69450fd7763fbdc1375bd146bf1af909dde84815073fc7cf7d60b8aa123cb4cc139e8dee19c30aba3a88ae021475633
7
- data.tar.gz: bfb92b7c42f02fde8d90484efef51abe294eaece630e97e7d0168e7974dd89d06b9069e9226c23bc2cf25755a2c1d4e41c87d114a1093b6e391a04d440f60de7
6
+ metadata.gz: 89a04fd8440e3d2f3c17a6878df42088f6258979d1ec384ea8e2eaf7a3bd60c8e99624bb424bf925f86177ea9d58a98df2ddbf5adcc60871833140df600fc3d1
7
+ data.tar.gz: a61ec90742b861ce596e8526d32bef2186f722e0d2524250c470fcb5bc8de3a90711c391edbf9e8f64d4bad6b5fccb00cc3f8dd4d874cfd6f45268775defecf8
@@ -9,6 +9,8 @@ require 'rufus/scheduler'
9
9
  require 'yaml'
10
10
  require 'json'
11
11
  require 'em-synchrony'
12
+ require 'em-synchrony/em-http'
13
+ require 'em-synchrony/fiber_iterator'
12
14
  require 'objspace'
13
15
  require 'time'
14
16
 
@@ -29,8 +31,10 @@ module Kameleoon
29
31
  @site_code = site_code
30
32
  @blocking = blocking
31
33
  @default_timeout = config['default_timeout'] || default_timeout # in ms
32
- @interval = config['actions_configuration_refresh_interval'].to_s + 'm' || interval
34
+ refresh_interval = config['actions_configuration_refresh_interval']
35
+ @interval = refresh_interval.nil? ? interval : "#{refresh_interval}m"
33
36
  @tracking_url = config['tracking_url'] || "https://api-ssx.kameleoon.com"
37
+ @api_data_url = "https://api-data.kameleoon.com"
34
38
  @client_id = client_id || config['client_id']
35
39
  @client_secret = client_secret || config['client_secret']
36
40
  @data_maximum_size = config['visitor_data_maximum_size'] || 500 # mb
@@ -100,8 +104,7 @@ module Kameleoon
100
104
  variation_id = nil
101
105
  EM.synchrony do
102
106
  connexion_options = { :connect_timeout => (timeout.to_f / 1000.0) }
103
- body = @data.values.flatten.select { |data| !data.sent }.map { |data| data.obtain_full_post_text_line }
104
- .join("\n") || ""
107
+ body = (data_not_sent(visitor_code).map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8")
105
108
  path = get_experiment_register_url(visitor_code, experiment_id)
106
109
  request_options = { :path => path, :body => body }
107
110
  log "Trigger experiment request: " + request_options.inspect
@@ -199,7 +202,11 @@ module Kameleoon
199
202
  #
200
203
  def flush(visitor_code = nil)
201
204
  check_visitor_code(visitor_code) unless visitor_code.nil?
202
- track_data(visitor_code)
205
+ if !visitor_code.nil?
206
+ track_data(visitor_code)
207
+ else
208
+ @data.select { |_, values| values.any? { |data| !data.sent } }.each_key { |key| flush(key) }
209
+ end
203
210
  end
204
211
 
205
212
  ##
@@ -250,7 +257,7 @@ module Kameleoon
250
257
  connexion_options = { :connect_timeout => (timeout.to_f / 1000.0) }
251
258
  request_options = {
252
259
  :path => get_experiment_register_url(visitor_code, id),
253
- :body => (data_not_sent(visitor_code).values.map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8")
260
+ :body => (data_not_sent(visitor_code).map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8")
254
261
  }
255
262
  log "Activate feature request: " + request_options.inspect
256
263
  log "Activate feature connexion:" + connexion_options.inspect
@@ -293,7 +300,7 @@ module Kameleoon
293
300
  # A feature variable can be changed easily via our web application.
294
301
  #
295
302
  # @param [String | Integer] feature_key
296
- # @param [String ] variable_key
303
+ # @param [String] variable_key
297
304
  #
298
305
  # @raise [Kameleoon::Exception::FeatureConfigurationNotFound]
299
306
  # @raise [Kameleoon::Exception::FeatureVariableNotFound]
@@ -318,6 +325,30 @@ module Kameleoon
318
325
  end
319
326
  end
320
327
 
328
+ ##
329
+ # The retrieved_data_from_remote_source method allows you to retrieve data (according to a key passed as argument)
330
+ # stored on a remote Kameleoon server. Usually data will be stored on our remote servers via the use of our Data API.
331
+ # This method, along with the availability of our highly scalable servers for this purpose, provides a convenient way
332
+ # to quickly store massive amounts of data that can be later retrieved for each of your visitors / users.
333
+ #
334
+ # @param [String] key Key you want to retrieve data. This field is mandatory.
335
+ # @param [Int] timeout Timeout for request. Equals default_timeout in a config file. This field is optional.
336
+ #
337
+ # @return [Hash] Hash object of the json object.
338
+ #
339
+ #
340
+ def retrieve_data_from_remote_source(key, timeout = @default_timeout)
341
+ connexion_options = { connect_timeout: (timeout.to_f / 1000.0) }
342
+ path = get_api_data_request_url(key)
343
+ log "Retrieve API Data connexion: #{connexion_options.inspect}"
344
+ response = get_sync(@api_data_url + path, connexion_options)
345
+ if is_successful_sync(response)
346
+ JSON.parse(response.body) unless response.nil?
347
+ else
348
+ return nil
349
+ end
350
+ end
351
+
321
352
  private
322
353
 
323
354
  API_SSX_URL = 'https://api-ssx.kameleoon.com'
@@ -582,6 +613,14 @@ module Kameleoon
582
613
  "/dataTracking?" + URI.encode_www_form(get_common_ssx_parameters(visitor_code))
583
614
  end
584
615
 
616
+ def get_api_data_request_url(key)
617
+ mapKey = {
618
+ siteCode: site_code,
619
+ key: key
620
+ }
621
+ "/data?#{URI.encode_www_form(mapKey)}"
622
+ end
623
+
585
624
  def get_feature_flag(feature_key)
586
625
  if feature_key.is_a?(String)
587
626
  feature_flag = @feature_flags.select { |ff| ff['identificationKey'] == feature_key}.first
@@ -616,67 +655,58 @@ module Kameleoon
616
655
  data_not_sent = data_not_sent(visitor_code)
617
656
  options = {
618
657
  :path => get_experiment_register_url(visitor_code, experiment_id, variation_id, none_variation),
619
- :body => ((data_not_sent.values[0] || []).map{ |it| it.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8"),
658
+ :body => (data_not_sent.map{ |it| it.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8"),
620
659
  :head => { "Content-Type" => "text/plain"}
621
660
  }
622
661
  trial = 0
623
662
  success = false
624
663
  log "Start post tracking experiment: " + data_not_sent.inspect
625
664
  Thread.new do
626
- EM.synchrony do
627
- while trial < 10
628
- request = EM::Synchrony.sync post(options, @tracking_url)
629
- log "Request " + request.inspect
630
- if is_successful(request)
631
- (data_not_sent.values[0] || []).each { |it| it.sent = true }
632
- EM.stop
633
- success = true
634
- break
635
- end
636
- trial += 1
665
+ while trial < 10
666
+ log "Send Experiment Tracking " + options.inspect
667
+ response = post_sync(options, @tracking_url)
668
+ log "Response " + response.inspect
669
+ if is_successful_sync(response)
670
+ data_not_sent.each { |it| it.sent = true }
671
+ success = true
672
+ break
637
673
  end
638
- EM.stop
674
+ trial += 1
639
675
  end
640
676
  if success
641
677
  log "Post to experiment tracking is done after " + (trial + 1).to_s + " trials"
642
- elsif
678
+ else
643
679
  log "Post to experiment tracking is failed after " + trial.to_s + " trials"
644
680
  end
645
- Thread.exit
646
681
  end
647
682
  end
648
683
 
649
- def track_data(visitor_code = nil)
684
+ def track_data(visitor_code)
650
685
  Thread.new do
651
- EM.synchrony do
652
- trials = 10
653
- concurrency = 1
654
- data_not_sent = data_not_sent(visitor_code)
655
- log "Start post tracking data: " + data_not_sent.inspect
656
- while trials > 0 && !data_not_sent.empty?
657
- EM::Synchrony::Iterator.new(data_not_sent, concurrency).map do |entry, iter|
658
- options = {
659
- :path => get_data_register_url(entry.first),
660
- :body => (entry.last.map { |data| data.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8"),
661
- :head => { "Content-Type" => "text/plain" }
662
- }
663
- log "Post tracking data for visitor_code: " + entry.first + " with options: " + options.inspect
664
- request = post(options, @tracking_url)
665
- request.callback {
666
- if is_successful(request)
667
- entry.last.each { |data| data.sent = true }
668
- end
669
- iter.return(request)
670
- }
671
- request.errback { iter.return(request) }
672
- end
673
- data_not_sent = data_not_sent(visitor_code)
674
- trials -= 1
686
+ trials = 0
687
+ data_not_sent = data_not_sent(visitor_code)
688
+ log "Start post tracking data: " + data_not_sent.inspect
689
+ while trials < 10 && !data_not_sent.empty?
690
+ options = {
691
+ :path => get_data_register_url(visitor_code),
692
+ :body => (data_not_sent.map{ |it| it.obtain_full_post_text_line }.join("\n") || "").encode("UTF-8"),
693
+ :head => { "Content-Type" => "text/plain" }
694
+ }
695
+ log "Post tracking data for visitor_code: " + visitor_code + " with options: " + options.inspect
696
+ response = post_sync(options, @tracking_url)
697
+ log "Response " + response.inspect
698
+ if is_successful_sync(response)
699
+ data_not_sent.each { |it| it.sent = true }
700
+ success = true
701
+ break
675
702
  end
676
- log "Post to data tracking is done."
677
- EM.stop
703
+ trials += 1
704
+ end
705
+ if success
706
+ log "Post to data tracking is done after " + (trials + 1).to_s + " trials"
707
+ else
708
+ log "Post to data tracking is failed after " + trials.to_s + " trials"
678
709
  end
679
- Thread.exit
680
710
  end
681
711
  end
682
712
 
@@ -686,12 +716,8 @@ module Kameleoon
686
716
  end
687
717
  end
688
718
 
689
- def data_not_sent(visitor_code = nil)
690
- if visitor_code.nil?
691
- @data.select {|key, values| values.any? {|data| !data.sent}}
692
- else
693
- @data.select { |key, values| key == visitor_code && values.any? {|data| !data.sent} }
694
- end
719
+ def data_not_sent(visitor_code)
720
+ @data.key?(visitor_code) ? @data[visitor_code].reject(&:sent) : []
695
721
  end
696
722
 
697
723
  def log(text)
@@ -1,5 +1,6 @@
1
1
  require "em-synchrony/em-http"
2
2
  require "kameleoon/version"
3
+ require 'net/http'
3
4
 
4
5
  module Kameleoon
5
6
  # @api private
@@ -20,6 +21,14 @@ module Kameleoon
20
21
  request(Method::POST, request_options, url, connexion_options)
21
22
  end
22
23
 
24
+ def get_sync(url = API_URL, connexion_options = {})
25
+ request_sync(Method::GET, url, connexion_options, {})
26
+ end
27
+
28
+ def post_sync(request_options, url = API_URL, connexion_options = {})
29
+ request_sync(Method::POST, url, connexion_options, request_options)
30
+ end
31
+
23
32
  private
24
33
 
25
34
  def request(method, request_options, url, connexion_options)
@@ -29,7 +38,30 @@ module Kameleoon
29
38
  when Method::POST then
30
39
  return EventMachine::HttpRequest.new(url, connexion_options).apost request_options
31
40
  when Method::GET then
32
- return EventMachine::HttpRequest.new(url, connexion_options).aget request_options
41
+ return EventMachine::HttpRequest.new(url, connexion_options).get request_options
42
+ else
43
+ print "Unknown request type"
44
+ return false
45
+ end
46
+ end
47
+
48
+ def request_sync(method, url, connexion_options, request_options)
49
+ request_options = {} if request_options.nil?
50
+ add_user_agent(request_options)
51
+ case method
52
+ when Method::GET then
53
+ uri = URI(url)
54
+ request = Net::HTTP.new(url)
55
+ response = Net::HTTP.get_response(uri)
56
+ response
57
+ when Method::POST then
58
+ uri = URI.parse(url)
59
+ http = Net::HTTP.new(uri.host, uri.port)
60
+ http.use_ssl = true
61
+ request = Net::HTTP::Post.new(request_options[:path], initheader = request_options[:head])
62
+ request.body = request_options[:body]
63
+ response = http.request(request)
64
+ response
33
65
  else
34
66
  print "Unknown request type"
35
67
  return false
@@ -40,6 +72,10 @@ module Kameleoon
40
72
  !request.nil? && request != false && /20\d/.match(request.response_header.status.to_s)
41
73
  end
42
74
 
75
+ def is_successful_sync(response)
76
+ !response.nil? && response != false && response.is_a?(Net::HTTPSuccess)
77
+ end
78
+
43
79
  def add_user_agent(request_options)
44
80
  if request_options[:head].nil?
45
81
  request_options[:head] = {'Kameleoon-Client' => 'sdk/ruby/' + Kameleoon::VERSION}
@@ -1,3 +1,3 @@
1
1
  module Kameleoon
2
- VERSION = '1.0.10'
2
+ VERSION = '1.1.2'
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.10
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kameleoon
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-28 00:00:00.000000000 Z
11
+ date: 2022-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-http-request