3838require_relative 'optimizely/notification_center'
3939require_relative 'optimizely/optimizely_config'
4040require_relative 'optimizely/optimizely_user_context'
41+ require_relative 'optimizely/odp/lru_cache'
42+ require_relative 'optimizely/odp/odp_manager'
43+ require_relative 'optimizely/helpers/sdk_settings'
4144
4245module Optimizely
4346 class Project
@@ -46,7 +49,7 @@ class Project
4649 attr_reader :notification_center
4750 # @api no-doc
4851 attr_reader :config_manager , :decision_service , :error_handler , :event_dispatcher ,
49- :event_processor , :logger , :stopped
52+ :event_processor , :logger , :odp_manager , : stopped
5053
5154 # Constructor for Projects.
5255 #
@@ -62,6 +65,8 @@ class Project
6265 # @param config_manager - Optional Responds to 'config' method.
6366 # @param notification_center - Optional Instance of NotificationCenter.
6467 # @param event_processor - Optional Responds to process.
68+ # @param default_decide_options: Optional default decision options.
69+ # @param settings: Optional instance of OptimizelySdkSettings for sdk configuration.
6570
6671 def initialize ( # rubocop:disable Metrics/ParameterLists
6772 datafile = nil ,
@@ -74,13 +79,15 @@ def initialize( # rubocop:disable Metrics/ParameterLists
7479 config_manager = nil ,
7580 notification_center = nil ,
7681 event_processor = nil ,
77- default_decide_options = [ ]
82+ default_decide_options = [ ] ,
83+ settings = nil
7884 )
7985 @logger = logger || NoOpLogger . new
8086 @error_handler = error_handler || NoOpErrorHandler . new
8187 @event_dispatcher = event_dispatcher || EventDispatcher . new ( logger : @logger , error_handler : @error_handler )
8288 @user_profile_service = user_profile_service
8389 @default_decide_options = [ ]
90+ @sdk_settings = settings
8491
8592 if default_decide_options . is_a? Array
8693 @default_decide_options = default_decide_options . clone
@@ -98,6 +105,16 @@ def initialize( # rubocop:disable Metrics/ParameterLists
98105
99106 @notification_center = notification_center . is_a? ( Optimizely ::NotificationCenter ) ? notification_center : NotificationCenter . new ( @logger , @error_handler )
100107
108+ setup_odp!
109+
110+ @odp_manager = OdpManager . new (
111+ disable : @sdk_settings . odp_disabled ,
112+ segment_manager : @sdk_settings . odp_segment_manager ,
113+ event_manager : @sdk_settings . odp_event_manager ,
114+ segments_cache : @sdk_settings . odp_segments_cache ,
115+ logger : @logger
116+ )
117+
101118 @config_manager = if config_manager . respond_to? ( :config )
102119 config_manager
103120 elsif sdk_key
@@ -113,6 +130,10 @@ def initialize( # rubocop:disable Metrics/ParameterLists
113130 StaticProjectConfigManager . new ( datafile , @logger , @error_handler , skip_json_validation )
114131 end
115132
133+ # must call this even if it's scheduled as a listener
134+ # in case the config manager was initialized before the listener was added
135+ update_odp_config_on_datafile_update unless @sdk_settings . odp_disabled
136+
116137 @decision_service = DecisionService . new ( @logger , @user_profile_service )
117138
118139 @event_processor = if event_processor . respond_to? ( :process )
@@ -816,6 +837,7 @@ def close
816837 @stopped = true
817838 @config_manager . stop! if @config_manager . respond_to? ( :stop! )
818839 @event_processor . stop! if @event_processor . respond_to? ( :stop! )
840+ @odp_manager . stop!
819841 end
820842
821843 def get_optimizely_config
@@ -869,6 +891,25 @@ def get_optimizely_config
869891 end
870892 end
871893
894+ # Send an event to the ODP server.
895+ #
896+ # @param action - the event action name.
897+ # @param type - the event type (default = "fullstack").
898+ # @param identifiers - a hash for identifiers.
899+ # @param data - a hash for associated data. The default event data will be added to this data before sending to the ODP server.
900+
901+ def send_odp_event ( action :, type : Helpers ::Constants ::ODP_MANAGER_CONFIG [ :EVENT_TYPE ] , identifiers : { } , data : { } )
902+ @odp_manager . send_event ( type : type , action : action , identifiers : identifiers , data : data )
903+ end
904+
905+ def identify_user ( user_id :)
906+ @odp_manager . identify_user ( user_id : user_id )
907+ end
908+
909+ def fetch_qualified_segments ( user_id :, options : [ ] )
910+ @odp_manager . fetch_qualified_segments ( user_id : user_id , options : options )
911+ end
912+
872913 private
873914
874915 def get_variation_with_config ( experiment_key , user_id , attributes , config )
@@ -1126,5 +1167,51 @@ def send_impression(config, experiment, variation_key, flag_key, rule_key, enabl
11261167 def project_config
11271168 @config_manager . config
11281169 end
1170+
1171+ def update_odp_config_on_datafile_update
1172+ # if datafile isn't ready, expects to be called again by the notification_center
1173+ return if @config_manager . respond_to? ( :ready? ) && !@config_manager . ready?
1174+
1175+ config = @config_manager &.config
1176+ return unless config
1177+
1178+ @odp_manager . update_odp_config ( config . public_key_for_odp , config . host_for_odp , config . all_segments )
1179+ end
1180+
1181+ def setup_odp!
1182+ unless @sdk_settings . is_a? Optimizely ::Helpers ::OptimizelySdkSettings
1183+ @logger . log ( Logger ::DEBUG , 'Provided sdk_settings is not an OptimizelySdkSettings instance.' ) unless @sdk_settings . nil?
1184+ @sdk_settings = Optimizely ::Helpers ::OptimizelySdkSettings . new
1185+ end
1186+
1187+ return if @sdk_settings . odp_disabled
1188+
1189+ @notification_center . add_notification_listener (
1190+ NotificationCenter ::NOTIFICATION_TYPES [ :OPTIMIZELY_CONFIG_UPDATE ] ,
1191+ -> { update_odp_config_on_datafile_update }
1192+ )
1193+
1194+ if !@sdk_settings . odp_segment_manager . nil? && !Helpers ::Validator . segment_manager_valid? ( @sdk_settings . odp_segment_manager )
1195+ @logger . log ( Logger ::ERROR , 'Invalid ODP segment manager, reverting to default.' )
1196+ @sdk_settings . odp_segment_manager = nil
1197+ end
1198+
1199+ if !@sdk_settings . odp_event_manager . nil? && !Helpers ::Validator . event_manager_valid? ( @sdk_settings . odp_event_manager )
1200+ @logger . log ( Logger ::ERROR , 'Invalid ODP event manager, reverting to default.' )
1201+ @sdk_settings . odp_event_manager = nil
1202+ end
1203+
1204+ return if @sdk_settings . odp_segment_manager
1205+
1206+ if !@sdk_settings . odp_segments_cache . nil? && !Helpers ::Validator . segments_cache_valid? ( @sdk_settings . odp_segments_cache )
1207+ @logger . log ( Logger ::ERROR , 'Invalid ODP segments cache, reverting to default.' )
1208+ @sdk_settings . odp_segments_cache = nil
1209+ end
1210+
1211+ @sdk_settings . odp_segments_cache ||= LRUCache . new (
1212+ @sdk_settings . segments_cache_size ,
1213+ @sdk_settings . segments_cache_timeout_in_secs
1214+ )
1215+ end
11291216 end
11301217end
0 commit comments