kameleoon-client-ruby 3.3.0 → 3.5.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.
- checksums.yaml +4 -4
 - data/lib/kameleoon/configuration/custom_data_info.rb +16 -8
 - data/lib/kameleoon/configuration/data_file.rb +52 -16
 - data/lib/kameleoon/configuration/feature_flag.rb +11 -1
 - data/lib/kameleoon/configuration/rule.rb +4 -0
 - data/lib/kameleoon/configuration/settings.rb +13 -8
 - data/lib/kameleoon/configuration/variation_exposition.rb +4 -0
 - data/lib/kameleoon/data/browser.rb +4 -0
 - data/lib/kameleoon/data/conversion.rb +4 -0
 - data/lib/kameleoon/data/cookie.rb +4 -0
 - data/lib/kameleoon/data/custom_data.rb +11 -3
 - data/lib/kameleoon/data/data.rb +30 -4
 - data/lib/kameleoon/data/device.rb +4 -0
 - data/lib/kameleoon/data/geolocation.rb +5 -0
 - data/lib/kameleoon/data/kcs_heat.rb +4 -0
 - data/lib/kameleoon/data/manager/assigned_variation.rb +8 -1
 - data/lib/kameleoon/data/manager/data_array_storage.rb +7 -0
 - data/lib/kameleoon/data/manager/data_map_storage.rb +7 -0
 - data/lib/kameleoon/data/manager/page_view_visit.rb +4 -0
 - data/lib/kameleoon/data/manager/visitor.rb +197 -73
 - data/lib/kameleoon/data/manager/visitor_manager.rb +54 -17
 - data/lib/kameleoon/data/mapping_identifier.rb +33 -0
 - data/lib/kameleoon/data/operating_system.rb +4 -0
 - data/lib/kameleoon/data/page_view.rb +6 -1
 - data/lib/kameleoon/data/unique_identifier.rb +11 -0
 - data/lib/kameleoon/data/user_agent.rb +4 -0
 - data/lib/kameleoon/data/visitor_visits.rb +4 -0
 - data/lib/kameleoon/hybrid/manager.rb +19 -7
 - data/lib/kameleoon/kameleoon_client.rb +477 -178
 - data/lib/kameleoon/kameleoon_client_config.rb +65 -18
 - data/lib/kameleoon/kameleoon_client_factory.rb +15 -2
 - data/lib/kameleoon/logging/default_logger.rb +20 -0
 - data/lib/kameleoon/logging/kameleoon_logger.rb +77 -0
 - data/lib/kameleoon/logging/logger.rb +12 -0
 - data/lib/kameleoon/managers/data/data_manager.rb +36 -0
 - data/lib/kameleoon/managers/remote_data/remote_data_manager.rb +32 -15
 - data/lib/kameleoon/managers/tracking/tracking_builder.rb +149 -0
 - data/lib/kameleoon/managers/tracking/tracking_manager.rb +98 -0
 - data/lib/kameleoon/managers/tracking/visitor_tracking_registry.rb +94 -0
 - data/lib/kameleoon/managers/warehouse/warehouse_manager.rb +22 -5
 - data/lib/kameleoon/network/access_token_source.rb +46 -14
 - data/lib/kameleoon/network/cookie/cookie_manager.rb +46 -7
 - data/lib/kameleoon/network/net_provider.rb +2 -3
 - data/lib/kameleoon/network/network_manager.rb +17 -21
 - data/lib/kameleoon/network/request.rb +14 -3
 - data/lib/kameleoon/network/response.rb +4 -0
 - data/lib/kameleoon/network/url_provider.rb +3 -3
 - data/lib/kameleoon/real_time/real_time_configuration_service.rb +10 -11
 - data/lib/kameleoon/sdk_version.rb +31 -0
 - data/lib/kameleoon/targeting/condition.rb +4 -2
 - data/lib/kameleoon/targeting/conditions/browser_condition.rb +3 -3
 - data/lib/kameleoon/targeting/conditions/cookie_condition.rb +10 -10
 - data/lib/kameleoon/targeting/conditions/geolocation_condition.rb +0 -1
 - data/lib/kameleoon/targeting/conditions/number_condition.rb +4 -4
 - data/lib/kameleoon/targeting/conditions/operating_system_condition.rb +1 -2
 - data/lib/kameleoon/targeting/conditions/sdk_language_condition.rb +2 -1
 - data/lib/kameleoon/targeting/conditions/segment_condition.rb +3 -3
 - data/lib/kameleoon/targeting/conditions/string_value_condition.rb +2 -1
 - data/lib/kameleoon/targeting/models.rb +0 -14
 - data/lib/kameleoon/targeting/targeting_manager.rb +35 -7
 - data/lib/kameleoon/targeting/tree_builder.rb +10 -5
 - data/lib/kameleoon/types/remote_visitor_data_filter.rb +13 -0
 - data/lib/kameleoon/types/variable.rb +4 -0
 - data/lib/kameleoon/types/variation.rb +8 -0
 - data/lib/kameleoon/utils.rb +49 -0
 - data/lib/kameleoon/version.rb +1 -27
 - metadata +12 -2
 
| 
         @@ -37,13 +37,13 @@ module Kameleoon 
     | 
|
| 
       37 
37 
     | 
    
         
             
                    @data_api_domain = domain if domain.is_a?(String)
         
     | 
| 
       38 
38 
     | 
    
         
             
                  end
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  def make_tracking_url 
     | 
| 
      
 40 
     | 
    
         
            +
                  def make_tracking_url
         
     | 
| 
       41 
41 
     | 
    
         
             
                    params = {
         
     | 
| 
       42 
42 
     | 
    
         
             
                      sdkName: SDK_NAME,
         
     | 
| 
       43 
43 
     | 
    
         
             
                      sdkVersion: SDK_VERSION,
         
     | 
| 
       44 
     | 
    
         
            -
                      siteCode: @site_code
         
     | 
| 
      
 44 
     | 
    
         
            +
                      siteCode: @site_code,
         
     | 
| 
      
 45 
     | 
    
         
            +
                      bodyUa: true
         
     | 
| 
       45 
46 
     | 
    
         
             
                    }
         
     | 
| 
       46 
     | 
    
         
            -
                    params[is_unique_identifier ? :mappingValue : :visitorCode] = visitor_code
         
     | 
| 
       47 
47 
     | 
    
         
             
                    "https://#{@data_api_domain}#{TRACKING_PATH}?#{UriHelper.encode_query(params)}"
         
     | 
| 
       48 
48 
     | 
    
         
             
                  end
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
         @@ -3,6 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            # Kameleoon Real Time Configuration Service
         
     | 
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            require 'json'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       6 
7 
     | 
    
         
             
            require 'kameleoon/real_time/real_time_event'
         
     | 
| 
       7 
8 
     | 
    
         
             
            require 'kameleoon/real_time/sse_request'
         
     | 
| 
       8 
9 
     | 
    
         
             
            require 'kameleoon/real_time/sse_client'
         
     | 
| 
         @@ -21,8 +22,7 @@ module Kameleoon 
     | 
|
| 
       21 
22 
     | 
    
         
             
                  # @param url [String]
         
     | 
| 
       22 
23 
     | 
    
         
             
                  # @param update_handler [Callable[Kameleoon::RealTime::RealTimeEvent] | NilClass] Handler which
         
     | 
| 
       23 
24 
     | 
    
         
             
                  # is synchronously called for gotten RealTimeEvent objects.
         
     | 
| 
       24 
     | 
    
         
            -
                   
     | 
| 
       25 
     | 
    
         
            -
                  def initialize(url, update_handler, log_func, sse_request_source = nil)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def initialize(url, update_handler, sse_request_source = nil)
         
     | 
| 
       26 
26 
     | 
    
         
             
                    @url = url
         
     | 
| 
       27 
27 
     | 
    
         
             
                    @update_handler = update_handler
         
     | 
| 
       28 
28 
     | 
    
         
             
                    @need_close = false
         
     | 
| 
         @@ -31,7 +31,6 @@ module Kameleoon 
     | 
|
| 
       31 
31 
     | 
    
         
             
                      'Cache-Control': 'no-cache',
         
     | 
| 
       32 
32 
     | 
    
         
             
                      'Connection': 'Keep-Alive'
         
     | 
| 
       33 
33 
     | 
    
         
             
                    }
         
     | 
| 
       34 
     | 
    
         
            -
                    @log_func = log_func
         
     | 
| 
       35 
34 
     | 
    
         
             
                    @sse_request_source = sse_request_source
         
     | 
| 
       36 
35 
     | 
    
         
             
                    @sse_thread = nil
         
     | 
| 
       37 
36 
     | 
    
         
             
                    @sse_client = nil
         
     | 
| 
         @@ -43,13 +42,13 @@ module Kameleoon 
     | 
|
| 
       43 
42 
     | 
    
         
             
                  def close
         
     | 
| 
       44 
43 
     | 
    
         
             
                    return if @need_close
         
     | 
| 
       45 
44 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
      
 45 
     | 
    
         
            +
                    Logging::KameleoonLogger.info('Real-time configuration service is shutting down')
         
     | 
| 
       47 
46 
     | 
    
         
             
                    @need_close = true
         
     | 
| 
       48 
47 
     | 
    
         
             
                    return if @sse_thread.nil?
         
     | 
| 
       49 
48 
     | 
    
         | 
| 
       50 
49 
     | 
    
         
             
                    @sse_thread.kill
         
     | 
| 
       51 
50 
     | 
    
         
             
                    @sse_thread = nil
         
     | 
| 
       52 
     | 
    
         
            -
                    @sse_client 
     | 
| 
      
 51 
     | 
    
         
            +
                    @sse_client&.call_close_handler
         
     | 
| 
       53 
52 
     | 
    
         
             
                  end
         
     | 
| 
       54 
53 
     | 
    
         | 
| 
       55 
54 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -60,7 +59,7 @@ module Kameleoon 
     | 
|
| 
       60 
59 
     | 
    
         | 
| 
       61 
60 
     | 
    
         
             
                  def init_sse_client
         
     | 
| 
       62 
61 
     | 
    
         
             
                    message_handler = proc do |message|
         
     | 
| 
       63 
     | 
    
         
            -
                       
     | 
| 
      
 62 
     | 
    
         
            +
                      Logging::KameleoonLogger.debug("Got SSE event: #{message.event}")
         
     | 
| 
       64 
63 
     | 
    
         
             
                      if message.event == CONFIGURATION_UPDATE_EVENT
         
     | 
| 
       65 
64 
     | 
    
         
             
                        event_dict = JSON.parse(message.data)
         
     | 
| 
       66 
65 
     | 
    
         
             
                        @update_handler&.call(RealTimeEvent.new(event_dict))
         
     | 
| 
         @@ -68,14 +67,14 @@ module Kameleoon 
     | 
|
| 
       68 
67 
     | 
    
         
             
                    end
         
     | 
| 
       69 
68 
     | 
    
         
             
                    sse_request = make_sse_request
         
     | 
| 
       70 
69 
     | 
    
         
             
                    @sse_client = SseClient.new(sse_request, message_handler)
         
     | 
| 
       71 
     | 
    
         
            -
                     
     | 
| 
      
 70 
     | 
    
         
            +
                    Logging::KameleoonLogger.info('Created SSE client')
         
     | 
| 
       72 
71 
     | 
    
         
             
                  end
         
     | 
| 
       73 
72 
     | 
    
         | 
| 
       74 
73 
     | 
    
         
             
                  def make_sse_request
         
     | 
| 
       75 
     | 
    
         
            -
                    open_handler = proc {  
     | 
| 
       76 
     | 
    
         
            -
                    close_handler = proc {  
     | 
| 
      
 74 
     | 
    
         
            +
                    open_handler = proc { Logging::KameleoonLogger.info('SSE connection open') }
         
     | 
| 
      
 75 
     | 
    
         
            +
                    close_handler = proc { Logging::KameleoonLogger.info('SSE connection closed') }
         
     | 
| 
       77 
76 
     | 
    
         
             
                    unexpected_status_code_handler =
         
     | 
| 
       78 
     | 
    
         
            -
                      proc { |resp|  
     | 
| 
      
 77 
     | 
    
         
            +
                      proc { |resp| Logging::KameleoonLogger.error("Unexpected status code of SSE response: #{resp.code}") }
         
     | 
| 
       79 
78 
     | 
    
         
             
                    if @sse_request_source.nil?
         
     | 
| 
       80 
79 
     | 
    
         
             
                      return SseRequest.new(@url, @headers, open_handler, close_handler, unexpected_status_code_handler)
         
     | 
| 
       81 
80 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -89,7 +88,7 @@ module Kameleoon 
     | 
|
| 
       89 
88 
     | 
    
         
             
                      begin
         
     | 
| 
       90 
89 
     | 
    
         
             
                        @sse_client.start
         
     | 
| 
       91 
90 
     | 
    
         
             
                      rescue StandardError => e
         
     | 
| 
       92 
     | 
    
         
            -
                         
     | 
| 
      
 91 
     | 
    
         
            +
                        Logging::KameleoonLogger.error("Error occurred within SSE client: #{e}")
         
     | 
| 
       93 
92 
     | 
    
         
             
                      end
         
     | 
| 
       94 
93 
     | 
    
         
             
                    end
         
     | 
| 
       95 
94 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Kameleoon
         
     | 
| 
      
 6 
     | 
    
         
            +
              # SdkManager is a helper method for fetching / obtaining version of SDK from string
         
     | 
| 
      
 7 
     | 
    
         
            +
              class SdkVersion
         
     | 
| 
      
 8 
     | 
    
         
            +
                def self.get_version_components(version_string)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  versions = [0, 0, 0]
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  version_parts = version_string.split('.')
         
     | 
| 
      
 12 
     | 
    
         
            +
                  version_parts.each_with_index do |part, i|
         
     | 
| 
      
 13 
     | 
    
         
            +
                    versions[i] = Integer(part)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  rescue ArgumentError
         
     | 
| 
      
 15 
     | 
    
         
            +
                    Logging::KameleoonLogger.error('Invalid version component, index: %s, value: %s', i, part)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    return nil
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                  versions
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def self.get_float_version(version_string)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  version_components = get_version_components(version_string)
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                  return Float::NAN if version_components.nil?
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  major = version_components[0]
         
     | 
| 
      
 27 
     | 
    
         
            +
                  minor = version_components[1]
         
     | 
| 
      
 28 
     | 
    
         
            +
                  "#{major}.#{minor}".to_f
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'kameleoon/exceptions'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       6 
7 
     | 
    
         
             
              # @api private
         
     | 
| 
         @@ -47,12 +48,13 @@ module Kameleoon 
     | 
|
| 
       47 
48 
     | 
    
         | 
| 
       48 
49 
     | 
    
         
             
                # Base class for all targeting conditions
         
     | 
| 
       49 
50 
     | 
    
         
             
                class Condition
         
     | 
| 
       50 
     | 
    
         
            -
                  attr_reader :type, :include
         
     | 
| 
      
 51 
     | 
    
         
            +
                  attr_reader :type, :include, :id
         
     | 
| 
       51 
52 
     | 
    
         | 
| 
       52 
53 
     | 
    
         
             
                  def initialize(json_condition)
         
     | 
| 
       53 
54 
     | 
    
         
             
                    raise Exception::NotFound.new('targetingType'), 'targetingType missed' if json_condition['targetingType'].nil?
         
     | 
| 
       54 
55 
     | 
    
         | 
| 
       55 
56 
     | 
    
         
             
                    @type = json_condition['targetingType']
         
     | 
| 
      
 57 
     | 
    
         
            +
                    @id = json_condition['id']
         
     | 
| 
       56 
58 
     | 
    
         
             
                    @include = json_condition['isInclude'].nil? ? true : json_condition['isInclude']
         
     | 
| 
       57 
59 
     | 
    
         
             
                  end
         
     | 
| 
       58 
60 
     | 
    
         | 
| 
         @@ -70,7 +72,7 @@ module Kameleoon 
     | 
|
| 
       70 
72 
     | 
    
         
             
                    begin
         
     | 
| 
       71 
73 
     | 
    
         
             
                      return pattern.match? value
         
     | 
| 
       72 
74 
     | 
    
         
             
                    rescue StandardError => e
         
     | 
| 
       73 
     | 
    
         
            -
                       
     | 
| 
      
 75 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Failed to match with regex (targeting): #{e}")
         
     | 
| 
       74 
76 
     | 
    
         
             
                    end
         
     | 
| 
       75 
77 
     | 
    
         
             
                    false
         
     | 
| 
       76 
78 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'kameleoon/data/browser'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'kameleoon/ 
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'kameleoon/sdk_version'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       7 
8 
     | 
    
         
             
              # @api private
         
     | 
| 
       8 
9 
     | 
    
         
             
              module Targeting
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
10 
     | 
    
         
             
                CHROME = 'CHROME'
         
     | 
| 
       11 
11 
     | 
    
         
             
                INTERNET_EXPLORER = 'IE'
         
     | 
| 
       12 
12 
     | 
    
         
             
                FIREFOX = 'FIREFOX'
         
     | 
| 
         @@ -44,7 +44,7 @@ module Kameleoon 
     | 
|
| 
       44 
44 
     | 
    
         
             
                    when Operator::LOWER
         
     | 
| 
       45 
45 
     | 
    
         
             
                      browser.version < version_number
         
     | 
| 
       46 
46 
     | 
    
         
             
                    else
         
     | 
| 
       47 
     | 
    
         
            -
                       
     | 
| 
      
 47 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Unexpected comparing operation for 'Browser' condition: '#{@version_match_type}'")
         
     | 
| 
       48 
48 
     | 
    
         
             
                      false
         
     | 
| 
       49 
49 
     | 
    
         
             
                    end
         
     | 
| 
       50 
50 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'kameleoon/data/cookie'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'kameleoon/version'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       7 
8 
     | 
    
         
             
              # @api private
         
     | 
| 
       8 
9 
     | 
    
         
             
              module Targeting
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
10 
     | 
    
         
             
                class CookieCondition < Condition
         
     | 
| 
       11 
11 
     | 
    
         
             
                  def initialize(json_condition)
         
     | 
| 
       12 
12 
     | 
    
         
             
                    super(json_condition)
         
     | 
| 
         @@ -26,13 +26,13 @@ module Kameleoon 
     | 
|
| 
       26 
26 
     | 
    
         
             
                    case @name_match_type
         
     | 
| 
       27 
27 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::EXACT
         
     | 
| 
       28 
28 
     | 
    
         
             
                      value = cookie.cookies[@condition_name]
         
     | 
| 
       29 
     | 
    
         
            -
                      return value 
     | 
| 
      
 29 
     | 
    
         
            +
                      return !value.nil? ? [value] : []
         
     | 
| 
       30 
30 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::CONTAINS
         
     | 
| 
       31 
     | 
    
         
            -
                      return cookie.cookies.select{|key| key.include? @condition_name}.values 
     | 
| 
      
 31 
     | 
    
         
            +
                      return cookie.cookies.select { |key| key.include? @condition_name }.values
         
     | 
| 
       32 
32 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::REGULAR_EXPRESSION
         
     | 
| 
       33 
     | 
    
         
            -
                      return cookie.cookies.select{|key| is_regex_match(@condition_name, key)}.values 
     | 
| 
      
 33 
     | 
    
         
            +
                      return cookie.cookies.select { |key| is_regex_match(@condition_name, key) }.values
         
     | 
| 
       34 
34 
     | 
    
         
             
                    else
         
     | 
| 
       35 
     | 
    
         
            -
                       
     | 
| 
      
 35 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Unexpected comparing operation for 'Cookie' condition (name): '#{@name_match_type}'")
         
     | 
| 
       36 
36 
     | 
    
         
             
                    end
         
     | 
| 
       37 
37 
     | 
    
         
             
                    []
         
     | 
| 
       38 
38 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -40,14 +40,14 @@ module Kameleoon 
     | 
|
| 
       40 
40 
     | 
    
         
             
                  def check_values(values)
         
     | 
| 
       41 
41 
     | 
    
         
             
                    case @value_match_type
         
     | 
| 
       42 
42 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::EXACT
         
     | 
| 
       43 
     | 
    
         
            -
                       
     | 
| 
      
 43 
     | 
    
         
            +
                      values.any? { |value| value == @condition_value }
         
     | 
| 
       44 
44 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::CONTAINS
         
     | 
| 
       45 
     | 
    
         
            -
                       
     | 
| 
      
 45 
     | 
    
         
            +
                      values.any? { |value| value.include? @condition_value }
         
     | 
| 
       46 
46 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::REGULAR_EXPRESSION
         
     | 
| 
       47 
     | 
    
         
            -
                       
     | 
| 
      
 47 
     | 
    
         
            +
                      values.any? { |value| is_regex_match(@condition_value, value) }
         
     | 
| 
       48 
48 
     | 
    
         
             
                    else
         
     | 
| 
       49 
     | 
    
         
            -
                       
     | 
| 
       50 
     | 
    
         
            -
                       
     | 
| 
      
 49 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Unexpected comparing operation for 'Cookie' condition (name): '#{@name_match_type}'")
         
     | 
| 
      
 50 
     | 
    
         
            +
                      false
         
     | 
| 
       51 
51 
     | 
    
         
             
                    end
         
     | 
| 
       52 
52 
     | 
    
         
             
                  end
         
     | 
| 
       53 
53 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'kameleoon/data/cookie'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'kameleoon/version'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       7 
8 
     | 
    
         
             
              # @api private
         
     | 
| 
       8 
9 
     | 
    
         
             
              module Targeting
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
10 
     | 
    
         
             
                class NumberCondition < Condition
         
     | 
| 
       11 
11 
     | 
    
         
             
                  def initialize(json_condition, value)
         
     | 
| 
       12 
12 
     | 
    
         
             
                    super(json_condition)
         
     | 
| 
         @@ -25,11 +25,11 @@ module Kameleoon 
     | 
|
| 
       25 
25 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::EQUAL
         
     | 
| 
       26 
26 
     | 
    
         
             
                      return value == @condition_value
         
     | 
| 
       27 
27 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::GREATER
         
     | 
| 
       28 
     | 
    
         
            -
                      return  
     | 
| 
      
 28 
     | 
    
         
            +
                      return !@condition_value.nil? && value > @condition_value
         
     | 
| 
       29 
29 
     | 
    
         
             
                    when Kameleoon::Targeting::Operator::LOWER
         
     | 
| 
       30 
     | 
    
         
            -
                      return  
     | 
| 
      
 30 
     | 
    
         
            +
                      return !@condition_value.nil? && value < @condition_value
         
     | 
| 
       31 
31 
     | 
    
         
             
                    else
         
     | 
| 
       32 
     | 
    
         
            -
                       
     | 
| 
      
 32 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Unexpected comparing operation for '#{@type}' condition: '#{@match_type}'")
         
     | 
| 
       33 
33 
     | 
    
         
             
                    end
         
     | 
| 
       34 
34 
     | 
    
         
             
                    false
         
     | 
| 
       35 
35 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -6,7 +6,6 @@ require 'kameleoon/version' 
     | 
|
| 
       6 
6 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       7 
7 
     | 
    
         
             
              # @api private
         
     | 
| 
       8 
8 
     | 
    
         
             
              module Targeting
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
9 
     | 
    
         
             
                class OperatingSystemCondition < Condition
         
     | 
| 
       11 
10 
     | 
    
         
             
                  def initialize(json_condition)
         
     | 
| 
       12 
11 
     | 
    
         
             
                    super(json_condition)
         
     | 
| 
         @@ -20,7 +19,7 @@ module Kameleoon 
     | 
|
| 
       20 
19 
     | 
    
         
             
                  private
         
     | 
| 
       21 
20 
     | 
    
         | 
| 
       22 
21 
     | 
    
         
             
                  def check_targeting(operating_system)
         
     | 
| 
       23 
     | 
    
         
            -
                     
     | 
| 
      
 22 
     | 
    
         
            +
                    !@os_type.nil? && operating_system.os_type == @os_type
         
     | 
| 
       24 
23 
     | 
    
         
             
                  end
         
     | 
| 
       25 
24 
     | 
    
         
             
                end
         
     | 
| 
       26 
25 
     | 
    
         
             
              end
         
     | 
| 
         @@ -1,6 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'kameleoon/data/data'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       4 
5 
     | 
    
         
             
            require 'kameleoon/version'
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
         @@ -56,7 +57,7 @@ module Kameleoon 
     | 
|
| 
       56 
57 
     | 
    
         
             
                        (major_sdk == major_condition && minor_sdk < minor_condition) ||
         
     | 
| 
       57 
58 
     | 
    
         
             
                        (major_sdk == major_condition && minor_sdk == minor_condition && patch_sdk < patch_condition)
         
     | 
| 
       58 
59 
     | 
    
         
             
                    else
         
     | 
| 
       59 
     | 
    
         
            -
                       
     | 
| 
      
 60 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Unexpected comparing operation for 'SdkLanguage' condition: '#{@operator}'")
         
     | 
| 
       60 
61 
     | 
    
         
             
                      false
         
     | 
| 
       61 
62 
     | 
    
         
             
                    end
         
     | 
| 
       62 
63 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -6,11 +6,10 @@ require 'kameleoon/version' 
     | 
|
| 
       6 
6 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       7 
7 
     | 
    
         
             
              # @api private
         
     | 
| 
       8 
8 
     | 
    
         
             
              module Targeting
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
9 
     | 
    
         
             
                class SegmentCondition < Condition
         
     | 
| 
       11 
10 
     | 
    
         
             
                  def initialize(json_condition)
         
     | 
| 
       12 
11 
     | 
    
         
             
                    super(json_condition)
         
     | 
| 
       13 
     | 
    
         
            -
                    @segment_id = json_condition[ 
     | 
| 
      
 12 
     | 
    
         
            +
                    @segment_id = json_condition['segmentId']
         
     | 
| 
       14 
13 
     | 
    
         
             
                  end
         
     | 
| 
       15 
14 
     | 
    
         | 
| 
       16 
15 
     | 
    
         
             
                  def check(data)
         
     | 
| 
         @@ -22,7 +21,8 @@ module Kameleoon 
     | 
|
| 
       22 
21 
     | 
    
         
             
                  def check_targeting(segment_info)
         
     | 
| 
       23 
22 
     | 
    
         
             
                    rule = segment_info.data_file.rule_by_segment_id[@segment_id]
         
     | 
| 
       24 
23 
     | 
    
         
             
                    return false unless rule.is_a?(Kameleoon::Configuration::Rule)
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    rule.targeting_segment.check_tree(->(type) { segment_info.condition_data(type) })
         
     | 
| 
       26 
26 
     | 
    
         
             
                  end
         
     | 
| 
       27 
27 
     | 
    
         
             
                end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
         @@ -1,5 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'kameleoon/targeting/condition'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
         @@ -33,7 +34,7 @@ module Kameleoon 
     | 
|
| 
       33 
34 
     | 
    
         
             
                      pattern = Regexp.new(@condition_value)
         
     | 
| 
       34 
35 
     | 
    
         
             
                      pattern.match?(value)
         
     | 
| 
       35 
36 
     | 
    
         
             
                    else
         
     | 
| 
       36 
     | 
    
         
            -
                       
     | 
| 
      
 37 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("Unexpected comparing operation for '#{@type}' condition: '#{@operator}'")
         
     | 
| 
       37 
38 
     | 
    
         
             
                      false
         
     | 
| 
       38 
39 
     | 
    
         
             
                    end
         
     | 
| 
       39 
40 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -10,7 +10,6 @@ module Kameleoon 
     | 
|
| 
       10 
10 
     | 
    
         
             
                  include TreeBuilder
         
     | 
| 
       11 
11 
     | 
    
         
             
                  attr_accessor :id, :tree
         
     | 
| 
       12 
12 
     | 
    
         
             
                  def to_s
         
     | 
| 
       13 
     | 
    
         
            -
                    print("\nSegment id: #{@id}\n")
         
     | 
| 
       14 
13 
     | 
    
         
             
                    @tree.to_s
         
     | 
| 
       15 
14 
     | 
    
         
             
                  end
         
     | 
| 
       16 
15 
     | 
    
         | 
| 
         @@ -49,19 +48,6 @@ module Kameleoon 
     | 
|
| 
       49 
48 
     | 
    
         
             
                class Tree
         
     | 
| 
       50 
49 
     | 
    
         
             
                  attr_accessor :or_operator, :left_child, :right_child, :condition
         
     | 
| 
       51 
50 
     | 
    
         | 
| 
       52 
     | 
    
         
            -
                  def to_s
         
     | 
| 
       53 
     | 
    
         
            -
                    print("or_operator: #{@or_operator}\n")
         
     | 
| 
       54 
     | 
    
         
            -
                    print("condition: #{@condition}")
         
     | 
| 
       55 
     | 
    
         
            -
                    unless @left_child.nil?
         
     | 
| 
       56 
     | 
    
         
            -
                      print('\nLeft child:\n    ')
         
     | 
| 
       57 
     | 
    
         
            -
                      @left_child.to_s
         
     | 
| 
       58 
     | 
    
         
            -
                    end
         
     | 
| 
       59 
     | 
    
         
            -
                    unless @right_child.nil?
         
     | 
| 
       60 
     | 
    
         
            -
                      print('\nright child:\n    ')
         
     | 
| 
       61 
     | 
    
         
            -
                      @right_child.to_s
         
     | 
| 
       62 
     | 
    
         
            -
                    end
         
     | 
| 
       63 
     | 
    
         
            -
                  end
         
     | 
| 
       64 
     | 
    
         
            -
             
     | 
| 
       65 
51 
     | 
    
         
             
                  def initialize(or_operator = nil, left_child = nil, right_child = nil, condition = nil)
         
     | 
| 
       66 
52 
     | 
    
         
             
                    @or_operator = Marshal.load(Marshal.dump(or_operator))
         
     | 
| 
       67 
53 
     | 
    
         
             
                    @left_child = left_child
         
     | 
| 
         @@ -1,25 +1,45 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       3 
4 
     | 
    
         
             
            require 'kameleoon/targeting/conditions/segment_condition'
         
     | 
| 
       4 
5 
     | 
    
         | 
| 
       5 
6 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       6 
7 
     | 
    
         
             
              # @api private
         
     | 
| 
       7 
8 
     | 
    
         
             
              module Targeting
         
     | 
| 
       8 
9 
     | 
    
         
             
                class TargetingManager
         
     | 
| 
       9 
     | 
    
         
            -
                  def initialize( 
     | 
| 
      
 10 
     | 
    
         
            +
                  def initialize(data_manager, visitor_manager)
         
     | 
| 
      
 11 
     | 
    
         
            +
                    @data_manager = data_manager
         
     | 
| 
       10 
12 
     | 
    
         
             
                    @visitor_manager = visitor_manager
         
     | 
| 
       11 
     | 
    
         
            -
                    @data_file = data_file
         
     | 
| 
       12 
13 
     | 
    
         
             
                  end
         
     | 
| 
       13 
14 
     | 
    
         | 
| 
       14 
15 
     | 
    
         
             
                  def check_targeting(visitor_code, campaign_id, exp_ff_rule)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    Logging::KameleoonLogger.debug(
         
     | 
| 
      
 17 
     | 
    
         
            +
                      "CALL: TargetingManager.check_targeting(visitorCode: '%s', campaignId: %s, exp_ff_rule: %s)",
         
     | 
| 
      
 18 
     | 
    
         
            +
                      visitor_code, campaign_id, exp_ff_rule
         
     | 
| 
      
 19 
     | 
    
         
            +
                    )
         
     | 
| 
       15 
20 
     | 
    
         
             
                    segment = exp_ff_rule.targeting_segment
         
     | 
| 
       16 
     | 
    
         
            -
                     
     | 
| 
      
 21 
     | 
    
         
            +
                    if segment.nil?
         
     | 
| 
      
 22 
     | 
    
         
            +
                      Logging::KameleoonLogger.debug(
         
     | 
| 
      
 23 
     | 
    
         
            +
                        "RETURN: TargetingManager.check_targeting(visitorCode: '%s', campaignId: %s, exp_ff_rule: %s) -> " \
         
     | 
| 
      
 24 
     | 
    
         
            +
                          '(targeting: true)', visitor_code, campaign_id, exp_ff_rule
         
     | 
| 
      
 25 
     | 
    
         
            +
                      )
         
     | 
| 
      
 26 
     | 
    
         
            +
                      return true
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
       17 
28 
     | 
    
         | 
| 
       18 
29 
     | 
    
         
             
                    visitor = @visitor_manager.get_visitor(visitor_code)
         
     | 
| 
       19 
     | 
    
         
            -
                    segment.check_tree(->(type) { get_condition_data(type, visitor, visitor_code, campaign_id) })
         
     | 
| 
      
 30 
     | 
    
         
            +
                    targeting = segment.check_tree(->(type) { get_condition_data(type, visitor, visitor_code, campaign_id) })
         
     | 
| 
      
 31 
     | 
    
         
            +
                    Logging::KameleoonLogger.debug(
         
     | 
| 
      
 32 
     | 
    
         
            +
                      "RETURN: TargetingManager.check_targeting(visitorCode: '%s', campaignId: %s, exp_ff_rule: %s) -> " \
         
     | 
| 
      
 33 
     | 
    
         
            +
                        '(targeting: %s)', visitor_code, campaign_id, exp_ff_rule, targeting
         
     | 
| 
      
 34 
     | 
    
         
            +
                    )
         
     | 
| 
      
 35 
     | 
    
         
            +
                    targeting
         
     | 
| 
       20 
36 
     | 
    
         
             
                  end
         
     | 
| 
       21 
37 
     | 
    
         | 
| 
       22 
38 
     | 
    
         
             
                  def get_condition_data(type, visitor, visitor_code, campaign_id)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    Logging::KameleoonLogger.debug(
         
     | 
| 
      
 40 
     | 
    
         
            +
                      "CALL: TargetingManager.get_condition_data(type: %s, visitor, visitorCode: '%s', campaignId: %s)",
         
     | 
| 
      
 41 
     | 
    
         
            +
                      type, visitor_code, campaign_id
         
     | 
| 
      
 42 
     | 
    
         
            +
                    )
         
     | 
| 
       23 
43 
     | 
    
         
             
                    condition_data = nil
         
     | 
| 
       24 
44 
     | 
    
         
             
                    case type
         
     | 
| 
       25 
45 
     | 
    
         
             
                    when Kameleoon::Targeting::ConditionType::CUSTOM_DATUM
         
     | 
| 
         @@ -41,7 +61,7 @@ module Kameleoon 
     | 
|
| 
       41 
61 
     | 
    
         
             
                      condition_data = visitor.operating_system unless visitor.nil?
         
     | 
| 
       42 
62 
     | 
    
         
             
                    when Kameleoon::Targeting::ConditionType::SEGMENT
         
     | 
| 
       43 
63 
     | 
    
         
             
                      condition_data = SegmentInfo.new(
         
     | 
| 
       44 
     | 
    
         
            -
                        @data_file,
         
     | 
| 
      
 64 
     | 
    
         
            +
                        @data_manager.data_file,
         
     | 
| 
       45 
65 
     | 
    
         
             
                        lambda { |type|
         
     | 
| 
       46 
66 
     | 
    
         
             
                          get_condition_data(type, visitor, visitor_code, campaign_id)
         
     | 
| 
       47 
67 
     | 
    
         
             
                        }
         
     | 
| 
         @@ -53,14 +73,22 @@ module Kameleoon 
     | 
|
| 
       53 
73 
     | 
    
         
             
                    when Kameleoon::Targeting::ConditionType::VISITOR_CODE
         
     | 
| 
       54 
74 
     | 
    
         
             
                      condition_data = visitor_code
         
     | 
| 
       55 
75 
     | 
    
         
             
                    when Kameleoon::Targeting::ConditionType::TARGET_FEATURE_FLAG
         
     | 
| 
       56 
     | 
    
         
            -
                      condition_data = TargetFeatureFlagInfo.new(@data_file, visitor.variations) unless visitor.nil?
         
     | 
| 
      
 76 
     | 
    
         
            +
                      condition_data = TargetFeatureFlagInfo.new(@data_manager.data_file, visitor.variations) unless visitor.nil?
         
     | 
| 
       57 
77 
     | 
    
         
             
                    when Kameleoon::Targeting::ConditionType::EXCLUSIVE_FEATURE_FLAG
         
     | 
| 
       58 
78 
     | 
    
         
             
                      condition_data = ExclusiveFeatureFlagInfo.new(campaign_id, visitor&.variations)
         
     | 
| 
       59 
     | 
    
         
            -
                    when ConditionType::FIRST_VISIT, 
     | 
| 
      
 79 
     | 
    
         
            +
                    when ConditionType::FIRST_VISIT,
         
     | 
| 
      
 80 
     | 
    
         
            +
                      ConditionType::LAST_VISIT,
         
     | 
| 
      
 81 
     | 
    
         
            +
                      ConditionType::VISITS,
         
     | 
| 
      
 82 
     | 
    
         
            +
                      ConditionType::SAME_DAY_VISITS,
         
     | 
| 
      
 83 
     | 
    
         
            +
                      ConditionType::NEW_VISITORS
         
     | 
| 
       60 
84 
     | 
    
         
             
                      condition_data = visitor.visitor_visits unless visitor.nil?
         
     | 
| 
       61 
85 
     | 
    
         
             
                    when Kameleoon::Targeting::ConditionType::HEAT_SLICE
         
     | 
| 
       62 
86 
     | 
    
         
             
                      condition_data = visitor&.kcs_heat
         
     | 
| 
       63 
87 
     | 
    
         
             
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
                    Logging::KameleoonLogger.debug(
         
     | 
| 
      
 89 
     | 
    
         
            +
                      "RETURN: TargetingManager.get_condition_data(type: %s, visitor, visitor_code: '%s', campaign_id: %s) -> " \
         
     | 
| 
      
 90 
     | 
    
         
            +
                        '(condition_data: %s)', type, visitor_code, campaign_id, condition_data
         
     | 
| 
      
 91 
     | 
    
         
            +
                    )
         
     | 
| 
       64 
92 
     | 
    
         
             
                    condition_data
         
     | 
| 
       65 
93 
     | 
    
         
             
                  end
         
     | 
| 
       66 
94 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            require 'kameleoon/targeting/condition_factory'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       2 
3 
     | 
    
         | 
| 
       3 
4 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       4 
5 
     | 
    
         
             
              #@api private
         
     | 
| 
         @@ -6,13 +7,17 @@ module Kameleoon 
     | 
|
| 
       6 
7 
     | 
    
         
             
                module TreeBuilder
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
                  def create_tree(conditions_data_json)
         
     | 
| 
       9 
     | 
    
         
            -
                    if conditions_data_json.nil?
         
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                     
     | 
| 
      
 10 
     | 
    
         
            +
                    return nil if conditions_data_json.nil?
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    Logging::KameleoonLogger.debug('CALL: TreeBuilder.create_tree(conditions_data_json: %s)',
         
     | 
| 
      
 13 
     | 
    
         
            +
                                                   conditions_data_json)
         
     | 
| 
       12 
14 
     | 
    
         
             
                    if conditions_data_json['firstLevel'].empty?
         
     | 
| 
       13 
15 
     | 
    
         
             
                      conditions_data_json['firstLevelOrOperators'] = []
         
     | 
| 
       14 
16 
     | 
    
         
             
                    end
         
     | 
| 
       15 
     | 
    
         
            -
                    create_first_level(conditions_data_json)
         
     | 
| 
      
 17 
     | 
    
         
            +
                    tree = create_first_level(conditions_data_json)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    Logging::KameleoonLogger.debug('RETURN: TreeBuilder.create_tree(conditions_data_json: %s) -> (tree)',
         
     | 
| 
      
 19 
     | 
    
         
            +
                                                   conditions_data_json)
         
     | 
| 
      
 20 
     | 
    
         
            +
                    tree
         
     | 
| 
       16 
21 
     | 
    
         
             
                  end
         
     | 
| 
       17 
22 
     | 
    
         | 
| 
       18 
23 
     | 
    
         
             
                  private
         
     | 
| 
         @@ -69,4 +74,4 @@ module Kameleoon 
     | 
|
| 
       69 
74 
     | 
    
         
             
                  end
         
     | 
| 
       70 
75 
     | 
    
         
             
                end
         
     | 
| 
       71 
76 
     | 
    
         
             
              end
         
     | 
| 
       72 
     | 
    
         
            -
            end
         
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -7,6 +7,19 @@ module Kameleoon 
     | 
|
| 
       7 
7 
     | 
    
         
             
                  attr_reader :previous_visit_amount, :current_visit, :custom_data, :page_views, :geolocation, :device, :browser,
         
     | 
| 
       8 
8 
     | 
    
         
             
                              :operating_system, :conversions, :experiments, :kcs
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "RemoteVisitorDataFilter{previous_visit_amount:#{@previous_visit_amount}," \
         
     | 
| 
      
 12 
     | 
    
         
            +
                      "current_visit:#{@current_visit}," \
         
     | 
| 
      
 13 
     | 
    
         
            +
                      "custom_data:#{@custom_data}," \
         
     | 
| 
      
 14 
     | 
    
         
            +
                      "page_views:#{@page_views}," \
         
     | 
| 
      
 15 
     | 
    
         
            +
                      "geolocation:#{@geolocation}," \
         
     | 
| 
      
 16 
     | 
    
         
            +
                      "device:#{@device}," \
         
     | 
| 
      
 17 
     | 
    
         
            +
                      "browser:#{@browser}," \
         
     | 
| 
      
 18 
     | 
    
         
            +
                      "operating_system:#{@operating_system}," \
         
     | 
| 
      
 19 
     | 
    
         
            +
                      "conversions:#{@conversions}," \
         
     | 
| 
      
 20 
     | 
    
         
            +
                      "experiments:#{@experiments},kcs:#{@kcs}}"
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
       10 
23 
     | 
    
         
             
                  def initialize(
         
     | 
| 
       11 
24 
     | 
    
         
             
                    previous_visit_amount: 1, current_visit: true, custom_data: true, page_views: false,
         
     | 
| 
       12 
25 
     | 
    
         
             
                    geolocation: false, device: false, browser: false, operating_system: false, conversions: false,
         
     | 
| 
         @@ -7,12 +7,20 @@ module Kameleoon 
     | 
|
| 
       7 
7 
     | 
    
         
             
                class Variation
         
     | 
| 
       8 
8 
     | 
    
         
             
                  attr_reader :key, :id, :experiment_id, :variables
         
     | 
| 
       9 
9 
     | 
    
         | 
| 
      
 10 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 11 
     | 
    
         
            +
                    "Variation{key:'#{@key}',id:#{@id},experiment_id:#{@experiment_id},variables:#{@variables}}"
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       10 
14 
     | 
    
         
             
                  def initialize(key, id, experiment_id, variables)
         
     | 
| 
       11 
15 
     | 
    
         
             
                    @key = key
         
     | 
| 
       12 
16 
     | 
    
         
             
                    @id = id
         
     | 
| 
       13 
17 
     | 
    
         
             
                    @experiment_id = experiment_id
         
     | 
| 
       14 
18 
     | 
    
         
             
                    @variables = variables
         
     | 
| 
       15 
19 
     | 
    
         
             
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def active?
         
     | 
| 
      
 22 
     | 
    
         
            +
                    variation_key != Configuration::VariationType::VARIATION_OFF
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
       16 
24 
     | 
    
         
             
                end
         
     | 
| 
       17 
25 
     | 
    
         
             
              end
         
     | 
| 
       18 
26 
     | 
    
         
             
            end
         
     | 
    
        data/lib/kameleoon/utils.rb
    CHANGED
    
    | 
         @@ -4,6 +4,7 @@ require 'fiber' 
     | 
|
| 
       4 
4 
     | 
    
         
             
            require 'bigdecimal'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'kameleoon/utils'
         
     | 
| 
       6 
6 
     | 
    
         
             
            require 'kameleoon/exceptions'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'kameleoon/logging/kameleoon_logger'
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
       9 
10 
     | 
    
         
             
              # Utils is a helper module for project
         
     | 
| 
         @@ -50,5 +51,53 @@ module Kameleoon 
     | 
|
| 
       50 
51 
     | 
    
         
             
                    (Digest::SHA256.hexdigest(identifier.encode('UTF-8')).to_i(16) / (BigDecimal('2')**BigDecimal('256'))).round(16)
         
     | 
| 
       51 
52 
     | 
    
         
             
                  end
         
     | 
| 
       52 
53 
     | 
    
         
             
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                module Strval
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                  def self.secret(secret)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    hid_ch = '*'
         
     | 
| 
      
 59 
     | 
    
         
            +
                    vis_count = 4
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                    return 'nil' if secret.nil?
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                    length = secret.length
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    return hid_ch * length if length <= vis_count
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                    hidden_length = [length - vis_count, vis_count].max
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    secret[0, length - hidden_length] + hid_ch * hidden_length
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                module Domain
         
     | 
| 
      
 74 
     | 
    
         
            +
                  HTTP = 'http://'
         
     | 
| 
      
 75 
     | 
    
         
            +
                  HTTPS = 'https://'
         
     | 
| 
      
 76 
     | 
    
         
            +
                  REGEX_DOMAIN = /^(\.?(([a-zA-Z\d][a-zA-Z\d-]*[a-zA-Z\d])|[a-zA-Z\d]))
         
     | 
| 
      
 77 
     | 
    
         
            +
            (\.(([a-zA-Z\d][a-zA-Z\d-]*[a-zA-Z\d])|[a-zA-Z\d])){1,126}$/x.freeze
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def self.validate_top_level_domain(top_level_domain)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    return nil if top_level_domain.nil? || top_level_domain.empty?
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    top_level_domain = top_level_domain.downcase
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    [HTTP, HTTPS].each do |protocol|
         
     | 
| 
      
 85 
     | 
    
         
            +
                      next unless top_level_domain.start_with?(protocol)
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                      top_level_domain = top_level_domain[protocol.length..]
         
     | 
| 
      
 88 
     | 
    
         
            +
                      Logging::KameleoonLogger.warning(
         
     | 
| 
      
 89 
     | 
    
         
            +
                        "The top-level domain contains '%s'. Domain after protocol trimming: '%s'", protocol, top_level_domain
         
     | 
| 
      
 90 
     | 
    
         
            +
                      )
         
     | 
| 
      
 91 
     | 
    
         
            +
                      break
         
     | 
| 
      
 92 
     | 
    
         
            +
                    end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                    unless REGEX_DOMAIN.match?(top_level_domain)
         
     | 
| 
      
 95 
     | 
    
         
            +
                      Logging::KameleoonLogger.error("The top-level domain '%s' is invalid.", top_level_domain)
         
     | 
| 
      
 96 
     | 
    
         
            +
                      return nil
         
     | 
| 
      
 97 
     | 
    
         
            +
                    end
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                    top_level_domain
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
       53 
102 
     | 
    
         
             
              end
         
     | 
| 
       54 
103 
     | 
    
         
             
            end
         
     | 
    
        data/lib/kameleoon/version.rb
    CHANGED
    
    | 
         @@ -1,32 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module Kameleoon
         
     | 
| 
      
 4 
     | 
    
         
            +
              SDK_VERSION = '3.5.0'
         
     | 
| 
       4 
5 
     | 
    
         
             
              SDK_NAME = 'RUBY'
         
     | 
| 
       5 
     | 
    
         
            -
              SDK_VERSION = '3.3.0'
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
              # SdkManager is a helper method for fetching / obtaining version of SDK from string
         
     | 
| 
       8 
     | 
    
         
            -
              class SdkVersion
         
     | 
| 
       9 
     | 
    
         
            -
                def self.get_version_components(version_string)
         
     | 
| 
       10 
     | 
    
         
            -
                  versions = [0, 0, 0]
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  version_parts = version_string.split('.')
         
     | 
| 
       13 
     | 
    
         
            -
                  version_parts.each_with_index do |part, i|
         
     | 
| 
       14 
     | 
    
         
            -
                    versions[i] = Integer(part)
         
     | 
| 
       15 
     | 
    
         
            -
                  rescue ArgumentError
         
     | 
| 
       16 
     | 
    
         
            -
                    puts "Invalid version component, index: #{i}, value: #{part}"
         
     | 
| 
       17 
     | 
    
         
            -
                    return nil
         
     | 
| 
       18 
     | 
    
         
            -
                  end
         
     | 
| 
       19 
     | 
    
         
            -
                  versions
         
     | 
| 
       20 
     | 
    
         
            -
                end
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                def self.get_float_version(version_string)
         
     | 
| 
       23 
     | 
    
         
            -
                  version_components = get_version_components(version_string)
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                  return Float::NAN if version_components.nil?
         
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                  major = version_components[0]
         
     | 
| 
       28 
     | 
    
         
            -
                  minor = version_components[1]
         
     | 
| 
       29 
     | 
    
         
            -
                  "#{major}.#{minor}".to_f
         
     | 
| 
       30 
     | 
    
         
            -
                end
         
     | 
| 
       31 
     | 
    
         
            -
              end
         
     | 
| 
       32 
6 
     | 
    
         
             
            end
         
     |