8000 feat(OptimizelyConfig): Add new fields to OptimizelyConfig by mnoman09 · Pull Request #266 · optimizely/csharp-sdk · GitHub
[go: up one dir, main page]

Skip to content

feat(OptimizelyConfig): Add new fields to OptimizelyConfig #266

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 26 commits into from
Aug 2, 2021
Merged
Changes from 1 commit
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
98dcba5
Added new Optimizely config fields
mnoman09 Jun 30, 2021
41e684b
Added delivery rules
mnoman09 Jul 2, 2021
c6ad489
Added optimizelyAudience and rollout featureVariables fix
mnoman09 Jul 6, 2021
9973794
Added new line at end
mnoman09 Jul 6, 2021
665c553
Added audiences and fixed tests
mnoman09 Jul 8, 2021
3c04342
Net 3.5 deserializing fix
mnoman09 Jul 9, 2021
1c0bf1a
Used string builder instead of string
mnoman09 Jul 13, 2021
ef6218b
Added OptimizelyProjectConfigTest file in tests
mnoman09 Jul 13, 2021
9fc9d54
Moved getEvent After GetFeaturesMap
mnoman09 Jul 13, 2021
53fbc69
Resolved comments and refactored logic
mnoman09 Jul 15, 2021
c8ccfca
Fixed space was added before NOT condition in audiences
mnoman09 Jul 26, 2021
b85ae86
Resolved comments
mnoman09 Jul 26, 2021
22a2039
Resolved unitTest issue
mnoman09 Jul 26, 2021
9ace97f
removed two additional tests for testing
mnoman09 Jul 27, 2021
621e62c
Merge branch 'master' into mnoman/optimizelyConfigNewFields
mnoman09 Jul 27, 2021
ce2505b
Audience array merge fix Unit test fix
mnoman09 Jul 27, 2021
b362593
Condition simplified
mnoman09 Jul 27, 2021
cb47e3c
Added OptimizelyEvent and OptimizelyAttribute Class
mnoman09 Jul 27, 2021
8ba7fe5
Added $opt_dummy_audience in datafile to verify that it is getting ig…
mnoman09 Jul 28, 2021
62ed97f
Added serializedAudiences Tests cases
mnoman09 Jul 28, 2021
c685c61
refactored little bit.
msohailhussain Jul 29, 2021
7351048
Refactored comments
mnoman09 Jul 29, 2021
f1e684f
ad 8000 ded unit tests for multiple experiment and removed sdk and env key.
msohailhussain Jul 29, 2021
b5d3383
Setting sdkKey and environment key default value as empty string
mnoman09 Jul 30, 2021
1e9d40f
fixed sorting issue
msohailhussain Jul 30, 2021
6a8dafa
corrected sequence of audiences
msohailhussain Aug 2, 2021
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
refactored little bit.
  • Loading branch information
msohailhussain committed Jul 29, 2021
commit c685c618841730cce84a368ea8a44d349ad19c9a
98 changes: 59 additions & 39 deletions OptimizelySDK/OptlyConfig/OptimizelyConfigService.cs
< 10000 tr data-hunk="c24063e817dfbc45248be5591a9650565e029546f4a3f3ffb84b164639f1f91a" class="show-top-border">
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,22 @@ public class OptimizelyConfigService
{
private OptimizelyConfig OptimizelyConfig;

private IDictionary<string, List<FeatureVariable>> featureIdVariablesMap;


public OptimizelyConfigService(ProjectConfig projectConfig)
{
if (projectConfig == null)
{
return;
}
featureIdVariablesMap = GetFeatureVariablesByIdMap(projectConfig);
var attributes = GetAttributes(projectConfig);
var audiences = GetAudiences(projectConfig);
var experimentMap = GetExperimentsMap(projectConfig);
var featureMap = GetFeaturesMap(projectConfig, experimentMap);
var experimentsMapById = GetExperimentsMapById(projectConfig);
var experimentsKeyMap = GetExperimentsKeyMap(experimentsMapById);

var featureMap = GetFeaturesMap(projectConfig, experimentsMapById);
var events = GetEvents(projectConfig);

OptimizelyConfig = new OptimizelyConfig(projectConfig.Revision,
Expand All @@ -46,7 +52,7 @@ public OptimizelyConfigService(ProjectConfig projectConfig)
attributes,
Copy link
Contributor

Choose a reason for hiding this comment

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

won't this break existing constructor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No actually attributes sdkKey and env key are all in the new constructor.

audiences,
events,
experimentMap,
experimentsKeyMap,
featureMap,
projectConfig.ToDatafile());
}
Expand Down Expand Up @@ -85,12 +91,23 @@ private OptimizelyAttribute[] GetAttributes(ProjectConfig projectConfig)
return attributes.ToArray();
}

/// <summary>
/// Converts Experiment Id map to Experiment Key map.
/// </summary>
/// <param name="experimentsMapById"></param>
/// <returns>Map of experiment key.</returns>

private IDictionary<string, OptimizelyExperiment> GetExperimentsKeyMap(IDictionary<string, OptimizelyExperiment> experimentsMapById)
{
return experimentsMapById?.Values.ToDictionary(k => k.Key);
}

/// <summary>
/// Gets Map of all experiments except rollouts
/// </summary>
/// <param name="projectConfig">The project config</param>
/// <returns>Dictionary | Dictionary of experiment key and value as experiment object</returns>
private IDictionary<string, OptimizelyExperiment> GetExperimentsMap(ProjectConfig projectConfig)
private IDictionary<string, OptimizelyExperiment> GetExperimentsMapById(ProjectConfig projectConfig)
{
var experimentsMap = new Dictionary<string, OptimizelyExperiment>();
var featureVariableIdMap = GetVariableIdMap(projectConfig);
Expand All @@ -99,14 +116,15 @@ private IDictionary<string, OptimizelyExperiment> GetExperimentsMap(ProjectConfi

foreach (Experiment experiment in experiments)
{
var variationsMap = GetVariationsMap(experiment, featureVariableIdMap, projectConfig);
var featureId = projectConfig.GetExperimentFeatureList(experiment.Id)?.FirstOrDefault();
var variationsMap = GetVariationsMap(experiment.Variations, featureVariableIdMap, featureId);
var experimentAudience = GetExperimentAudiences(experiment, projectConfig);
var optimizelyExperiment = new OptimizelyExperiment(experiment.Id,
experiment.Key,
experimentAudience,
variationsMap);

experimentsMap.Add(experiment.Key, optimizelyExperiment);
experimentsMap.Add(experiment.Id, optimizelyExperiment);
}

return experimentsMap;
Expand All @@ -120,19 +138,18 @@ private IDictionary<string, OptimizelyExperiment> GetExperimentsMap(ProjectConfi
/// <param name="projectConfig">The project config</param>
/// <param name="rolloutId">Rollout Id if the feature Id is null then use rollout id to get feature Id</param>
/// <returns>Dictionary | Dictionary of experiment key and value as experiment object</returns>
private IDictionary<string, OptimizelyVariation> GetVariationsMap(Experiment experiment,
private IDictionary<string, OptimizelyVariation> GetVariationsMap(IEnumerable<Variation> variations,
IDictionary<string, FeatureVariable> featureVariableIdMap,
ProjectConfig projectConfig,
string rolloutId = null)
string featureId)
{
var variationsMap = new Dictionary<string, OptimizelyVariation>();
foreach (Variation variation in experiment.Variations)
foreach (Variation variation in variations)
{
var variablesMap = MergeFeatureVariables(projectConfig,
var variablesMap = MergeFeatureVariables(
featureVariableIdMap,
experiment.Id,
variation,
rolloutId);
featureId,
variation.FeatureVariableUsageInstances,
variation.IsFeatureEnabled);

var optimizelyVariation = new OptimizelyVariation(variation.Id,
variation.Key,
Expand All @@ -154,38 +171,37 @@ private IDictionary<string, OptimizelyVariation> GetVariationsMap(Experiment exp
/// <param name="rolloutId">rollout id to get feature id</param>
/// <returns>Dictionary | Dictionary of FeatureVariable key and value as FeatureVariable object</returns>
private IDictionary<string, OptimizelyVariable> MergeFeatureVariables(
ProjectConfig projectConfig,
IDictionary<string, FeatureVariable> variableIdMap,
string experimentId,
Variation variation,
string rolloutId = null)
string featureId,
IEnumerable<FeatureVariableUsage> featureVariableUsages,
bool isFeatureEnabled)
{
var featureId = projectConfig.GetExperimentFeatureList(experimentId)?.FirstOrDefault();
var featureIdVariablesMap = GetFeatureIdVariablesMap(projectConfig);
//var featureId = projectConfig.GetExperimentFeatureList(experimentId)?.FirstOrDefault();

var variablesMap = new Dictionary<string, OptimizelyVariable>();
string featureIdRollout = null;
if (rolloutId != null)
{
featureIdRollout = projectConfig.FeatureFlags.Where(feat => feat.RolloutId == rolloutId).FirstOrDefault()?.Id;
}
//string featureIdRollout = null;
//if (rolloutId != null)
//{
// featureIdRollout = projectConfig.FeatureFlags.Where(feat => feat.RolloutId == rolloutId).FirstOrDefault()?.Id;
//}

featureId = featureId ?? featureIdRollout;
//featureId = featureId ?? featureIdRollout;

if (featureId?.Any() ?? false)
if (!string.IsNullOrEmpty(featureId))
{
variablesMap = featureIdVariablesMap[featureId]?.Select(f => new OptimizelyVariable(f.Id,
f.Key,
f.Type.ToString().ToLower(),
f.DefaultValue)
).ToDictionary(k => k.Key, v => v);

foreach (var featureVariableUsage in variation.FeatureVariableUsageInstances)
foreach (var featureVariableUsage in featureVariableUsages)
{
var defaultVariable = variableIdMap[featureVariableUsage.Id];
var optimizelyVariable = new OptimizelyVariable(featureVariableUsage.Id,
defaultVariable.Key,
defaultVariable.Type.ToString().ToLower(),
variation.IsFeatureEnabled ? featureVariableUsage.Value : defaultVariable.DefaultValue);
isFeatureEnabled ? featureVariableUsage.Value : defaultVariable.DefaultValue);

variablesMap[defaultVariable.Key] = optimizelyVariable;
}
Expand All @@ -200,22 +216,26 @@ private IDictionary<string, OptimizelyVariable> MergeFeatureVariables(
/// <param name="projectConfig">The project config</param>
/// <param name="experimentsMap">Dictionary of experiment key and value as experiment object</param>
/// <returns>Dictionary | Dictionary of FeatureFlag key and value as OptimizelyFeature object</returns>
private IDictionary<string, OptimizelyFeature> GetFeaturesMap(ProjectConfig projectConfig, IDictionary<string, OptimizelyExperiment> experimentsMap)
private IDictionary<string, OptimizelyFeature> GetFeaturesMap(ProjectConfig projectConfig, IDictionary<string, OptimizelyExperiment> experimentsMapById)
{
var FeaturesMap = new Dictionary<string, OptimizelyFeature>();

foreach (var featureFlag in projectConfig.FeatureFlags)
foreach (var featureFlag in projectConfig.FeatureFlags)
{
var featureExperimentMap = experimentsMap.Where(expMap => featureFlag.ExperimentIds.Contains(expMap.Value.Id)).ToDictionary(k => k.Key, v => v.Value);

var featureExperimentMap = experimentsMapById.Where(expMap => featureFlag.ExperimentIds.Contains(expMap.Key))
.ToDictionary(k => k.Value.Key, v => v.Value);

var featureVariableMap = featureFlag.Variables.Select(v => (OptimizelyVariable)v).ToDictionary(k => k.Key, v => v) ?? new Dictionary<string, OptimizelyVariable>();

var experimentRules = featureExperimentMap.Select(exMap => exMap.Value).ToList();
var rollout = projectConfig.GetRolloutFromId(featureFlag.RolloutId);
var deliveryRules = GetDeliveryRules(featureFlag.Id, rollout.Experiments, projectConfig);

var optimizelyFeature = new OptimizelyFeature(featureFlag.Id,
featureFlag.Key,
experimentRules,
GetDeliveryRules(featureFlag.RolloutId, projectConfig),
deliveryRules,
featureExperimentMap,
featureVariableMap);

Expand All @@ -233,7 +253,7 @@ private IDictionary<string, OptimizelyFeature> GetFeaturesMap(ProjectConfig proj
/// </summary>
/// <param name="projectConfig">The project config</param>
/// <returns>Dictionary | Dictionary of FeatureFlag key and value as list of all FeatureVariable inside it</returns>
private IDictionary<string, List<FeatureVariable>> GetFeatureIdVariablesMap(ProjectConfig projectConfig)
private IDictionary<string, List<FeatureVariable>> GetFeatureVariablesByIdMap(ProjectConfig projectConfig)
{
var featureIdVariablesMap = projectConfig?.FeatureFlags?.ToDictionary(k => k.Id, v => v.Variables);

Expand Down Expand Up @@ -333,10 +353,10 @@ private string GetSerializedAudiences(List<object> audienceConditions, Dictionar
/// <param name="rolloutID">Rollout ID</param>
/// <param name="projectConfig">Project Config</param>
/// <returns>List | List of Optimizely rollout experiments.</returns>
private List<OptimizelyExperiment> GetDeliveryRules(string rolloutID, ProjectConfig projectConfig)
private List<OptimizelyExperiment> GetDeliveryRules(string featureId, IEnumerable<Experiment> experiments,
ProjectConfig projectConfig)
{
var rollout = projectConfig.GetRolloutFromId(rolloutID);
if (rollout?.Experiments == null)
if (experiments == null)
{
return new List<OptimizelyExperiment>();
}
Expand All @@ -345,13 +365,13 @@ private List<OptimizelyExperiment> GetDeliveryRules(string rolloutID, ProjectCon

var deliveryRules = new List<OptimizelyExperiment>();

foreach (var experiment in rollout?.Experiments)
foreach (var experiment in experiments)
{
var optimizelyExperiment = new OptimizelyExperiment(
id: experiment.Id,
key: experiment.Key,
audiences: GetExperimentAudiences(experiment, projectConfig),
variationsMap: GetVariationsMap(experiment, featureVariableIdMap, projectConfig, rolloutId: rollout.Id)
variationsMap: GetVariationsMap(experiment.Variations, featureVariableIdMap, featureId)
);
deliveryRules.Add(optimizelyExperiment);
}
Expand Down
0