Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
commit odp_manager updates and cleanup
  • Loading branch information
Mat001 committed Sep 16, 2022
commit ec96869d72c4f8980cedff37b3edb4ae6004be51
56 changes: 27 additions & 29 deletions optimizely/odp/odp_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
from optimizely import logger as optimizely_logger
from optimizely.helpers.enums import Errors, OdpManagerConfig
from optimizely.helpers.validator import are_odp_data_types_valid
from optimizely.odp.lru_cache import LRUCache
from optimizely.odp.odp_config import OdpConfig
from optimizely.odp.lru_cache import OptimizelySegmentsCache
from optimizely.odp.odp_config import OdpConfig, OdpConfigState
from optimizely.odp.odp_event_manager import OdpEventManager
from optimizely.odp.odp_segment_manager import OdpSegmentManager
from optimizely.odp.zaius_graphql_api_manager import ZaiusGraphQLApiManager
Expand All @@ -29,55 +29,59 @@
class OdpManager:
"""Orchestrates segment manager, event manager and odp config."""

def __init__(self,
def __init__(
self,
disable: bool,
cache_size: int,
cache_timeout_in_sec: int,
segments_cache: OptimizelySegmentsCache,
segment_manager: Optional[OdpSegmentManager] = None,
event_manager: Optional[OdpEventManager] = None,
logger: Optional[optimizely_logger.Logger] = None) -> None:
logger: Optional[optimizely_logger.Logger] = None
) -> None:

self.enabled = not disable
self.cache_size = cache_size
self.cache_timeout_in_sec = cache_timeout_in_sec
self.odp_config = OdpConfig()
self.logger = logger or optimizely_logger.NoOpLogger()

self.segment_manager = None
self.event_manager = None

if not self.enabled:
self.logger.info('ODP is disabled.')
return

if segment_manager:
segment_manager.odp_config = self.odp_config
self.segment_manager = segment_manager
else:
self.segment_manager = OdpSegmentManager(self.odp_config,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we consider removing odp_config from the constructor params? It should be overriden for custom segment-manager anyway? Let's talk about it when integrating at the top level.

LRUCache(cache_size, cache_timeout_in_sec),
segments_cache,
ZaiusGraphQLApiManager(logger), logger)
if event_manager:
event_manager.odp_config = self.odp_config
self.event_manager = event_manager
else:
self.event_manager = OdpEventManager(self.odp_config, logger)

def fetch_qualified_segments(self, user_id: str, options: list[str]) -> None:
if not self.enabled:
self.event_manager.start()

def fetch_qualified_segments(self, user_id: str, options: list[str]) -> Optional[list[str]]:
if not self.enabled or not self.segment_manager:
raise optimizely_exception.OdpNotEnabled(Errors.ODP_NOT_ENABLED)

user_key = OdpManagerConfig.KEY_FOR_USER_ID
user_value = user_id

if self.segment_manager:
self.segment_manager.fetch_qualified_segments(user_key, user_value, options)
return self.segment_manager.fetch_qualified_segments(user_key, user_value, options)

def identify_user(self, user_id: str) -> None:
if not self.enabled:
if not self.enabled or not self.event_manager:
self.logger.debug('ODP identify event is not dispatched (ODP disabled).')
return
if self.odp_config.odp_state() == OdpConfigState.NOT_INTEGRATED:
self.logger.debug('ODP Identify event is not dispatched (ODP not integrated).')
return

if self.event_manager:
self.event_manager.identify_user(user_id)
self.event_manager.identify_user(user_id)

def send_event(self, type: str, action: str, identifiers: dict[str, str], data: dict[str, Any]) -> None:
"""
Expand All @@ -92,36 +96,30 @@ def send_event(self, type: str, action: str, identifiers: dict[str, str], data:

Raises custom exception if error is detected.
"""
if not self.enabled:
if not self.enabled or not self.event_manager:
raise optimizely_exception.OdpNotEnabled(Errors.ODP_NOT_ENABLED)

if self.odp_config.odp_state() == OdpConfigState.NOT_INTEGRATED:
raise optimizely_exception.OdpNotIntegrated(Errors.ODP_NOT_INTEGRATED)

if not are_odp_data_types_valid(data):
raise optimizely_exception.OdpInvalidData(Errors.ODP_INVALID_DATA)

if self.event_manager:
self.event_manager.send_event(type, action, identifiers, data)
self.event_manager.send_event(type, action, identifiers, data)

def update_odp_config(self, api_key: Optional[str], api_host: Optional[str],
segments_to_check: list[str]) -> None:
if not self.enabled:
return

# flush old events using old odp publicKey (if exists) before updating odp key.
if self.event_manager:
self.event_manager.flush()
# wait until done flushing to avoid flushing in the middle of the batch
self.event_manager.event_queue.join()

config_changed = self.odp_config.update(api_key, api_host, segments_to_check)
if not config_changed:
self.logger.debug('Odp config was not changed.')
return

# reset segments cache when odp integration or segmentsToCheck are changed
# reset segments cache when odp integration or segments to check are changed
if self.segment_manager:
self.segment_manager.reset()

# flush events with the new integration key if events still remain in the queue
# (when we get the first datafile ready)
if self.event_manager:
self.event_manager.flush()
self.event_manager.update_config()
2 changes: 1 addition & 1 deletion tests/test_odp_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ class OdpManagerTest(base.BaseTest):

def test_configurations_disable_odp(self):
mock_logger = mock.MagicMock()

manager = OdpManager(True, OptimizelySegmentsCache, None, None, mock_logger)

self.assertRaisesRegex(optimizely_exception.OdpNotEnabled, Errors.ODP_NOT_ENABLED,
manager.fetch_qualified_segments, 'user1', [])

mock_logger.info.assert_called_once_with('ODP is disabled.')
manager.update_odp_config('valid', 'host', [])
self.assertIsNone(manager.odp_config.get_api_key())
self.assertIsNone(manager.odp_config.get_api_host())
Expand Down
1 change: 0 additions & 1 deletion tests/test_odp_zaius_rest_api_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ class ZaiusRestApiManagerTest(base.BaseTest):
api_key = "test-api-key"
api_host = "test-host"

# TODO - UPDATE THESE EVENTS TO BE OdpEvent class not dict (see Andy's comment and change)
events = [
{"type": "t1", "action": "a1", "identifiers": {"id-key-1": "id-value-1"}, "data": {"key-1": "value1"}},
{"type": "t2", "action": "a2", "identifiers": {"id-key-2": "id-value-2"}, "data": {"key-2": "value2"}},
Expand Down