Skip to content

Commit

Permalink
Delivery rules correction for proper rollout key (#351)
Browse files Browse the repository at this point in the history
* Fix delivery rules to use experiment as key instead of experiments_map, which was invalid.
* Use featureId for building variables map
* Update sdkKey and environmentKey to default to blank string
  • Loading branch information
The-inside-man committed Aug 9, 2021
1 parent 637129a commit 0cb19ce
Show file tree
Hide file tree
Showing 2 changed files with 357 additions and 29 deletions.
48 changes: 27 additions & 21 deletions optimizely/optimizely_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ def __init__(self, revision, experiments_map, features_map, datafile=None,
self.experiments_map = experiments_map
self.features_map = features_map
self._datafile = datafile
self.sdk_key = sdk_key
self.environment_key = environment_key
self.sdk_key = sdk_key or ''
self.environment_key = environment_key or ''
self.attributes = attributes or []
self.events = events or []
self.audiences = audiences or []
Expand Down Expand Up @@ -125,11 +125,9 @@ def __init__(self, project_config):
Merging typed_audiences with audiences from project_config.
The typed_audiences has higher precedence.
'''

typed_audiences = project_config.typed_audiences[:]
optly_typed_audiences = []
id_lookup_dict = {}
for typed_audience in typed_audiences:
for typed_audience in project_config.typed_audiences:
optly_audience = OptimizelyAudience(
typed_audience.get('id'),
typed_audience.get('name'),
Expand Down Expand Up @@ -269,6 +267,8 @@ def _create_lookup_maps(self):
self.exp_id_to_feature_map = {}
self.feature_key_variable_key_to_variable_map = {}
self.feature_key_variable_id_to_variable_map = {}
self.feature_id_variable_id_to_feature_variables_map = {}
self.feature_id_variable_key_to_feature_variables_map = {}

for feature in self.feature_flags:
for experiment_id in feature['experimentIds']:
Expand All @@ -283,10 +283,12 @@ def _create_lookup_maps(self):
variables_key_map[variable['key']] = opt_variable
variables_id_map[variable['id']] = opt_variable

self.feature_id_variable_id_to_feature_variables_map[feature['id']] = variables_id_map
self.feature_id_variable_key_to_feature_variables_map[feature['id']] = variables_key_map
self.feature_key_variable_key_to_variable_map[feature['key']] = variables_key_map
self.feature_key_variable_id_to_variable_map[feature['key']] = variables_id_map

def _get_variables_map(self, experiment, variation):
def _get_variables_map(self, experiment, variation, feature_id=None):
""" Gets variables map for given experiment and variation.
Args:
Expand All @@ -296,23 +298,27 @@ def _get_variables_map(self, experiment, variation):
Returns:
dict - Map of variable key to OptimizelyVariable for the given variation.
"""
variables_map = {}

feature_flag = self.exp_id_to_feature_map.get(experiment['id'], None)
if feature_flag is None:
if feature_flag is None and feature_id is None:
return {}

# set default variables for each variation
variables_map = {}
variables_map = copy.deepcopy(self.feature_key_variable_key_to_variable_map[feature_flag['key']])
if feature_id:
variables_map = copy.deepcopy(self.feature_id_variable_key_to_feature_variables_map[feature_id])
else:
variables_map = copy.deepcopy(self.feature_key_variable_key_to_variable_map[feature_flag['key']])

# set variation specific variable value if any
if variation.get('featureEnabled'):
for variable in variation.get('variables', []):
feature_variable = self.feature_key_variable_id_to_variable_map[feature_flag['key']][variable['id']]
variables_map[feature_variable.key].value = variable['value']
# set variation specific variable value if any
if variation.get('featureEnabled'):
for variable in variation.get('variables', []):
feature_variable = self.feature_key_variable_id_to_variable_map[feature_flag['key']][variable['id']]
variables_map[feature_variable.key].value = variable['value']

return variables_map

def _get_variations_map(self, experiment):
def _get_variations_map(self, experiment, feature_id=None):
""" Gets variation map for the given experiment.
Args:
Expand All @@ -324,7 +330,7 @@ def _get_variations_map(self, experiment):
variations_map = {}

for variation in experiment.get('variations', []):
variables_map = self._get_variables_map(experiment, variation)
variables_map = self._get_variables_map(experiment, variation, feature_id)
feature_enabled = variation.get('featureEnabled', None)

optly_variation = OptimizelyVariation(
Expand Down Expand Up @@ -394,7 +400,7 @@ def _get_features_map(self, experiments_id_map):

for feature in self.feature_flags:

delivery_rules = self._get_delivery_rules(self.rollouts, feature.get('rolloutId'))
delivery_rules = self._get_delivery_rules(self.rollouts, feature.get('rolloutId'), feature['id'])
experiment_rules = []

exp_map = {}
Expand All @@ -415,7 +421,7 @@ def _get_features_map(self, experiments_id_map):

return features_map

def _get_delivery_rules(self, rollouts, rollout_id):
def _get_delivery_rules(self, rollouts, rollout_id, feature_id):
""" Gets an array of rollouts for the project config
returns:
Expand All @@ -435,12 +441,12 @@ def _get_delivery_rules(self, rollouts, rollout_id):
for optly_audience in self.audiences:
audiences_map[optly_audience.id] = optly_audience.name

# Get the experiments_map for that rollout
experiments = rollout.get('experiments_map')
# Get the experiments for that rollout
experiments = rollout.get('experiments')
if experiments:
for experiment in experiments:
optly_exp = OptimizelyExperiment(
experiment['id'], experiment['key'], self._get_variations_map(experiment)
experiment['id'], experiment['key'], self._get_variations_map(experiment, feature_id)
)
audiences = self.replace_ids_with_names(experiment.get('audienceConditions', []), audiences_map)
optly_exp.audiences = audiences
Expand Down

0 comments on commit 0cb19ce

Please sign in to comment.