|
| 1 | +/**************************************************************************** |
| 2 | + * Copyright 2019, Optimizely, Inc. and contributors * |
| 3 | + * * |
| 4 | + * Licensed under the Apache License, Version 2.0 (the "License"); * |
| 5 | + * you may not use this file except in compliance with the License. * |
| 6 | + * You may obtain a copy of the License at * |
| 7 | + * * |
| 8 | + * http://www.apache.org/licenses/LICENSE-2.0 * |
| 9 | + * * |
| 10 | + * Unless required by applicable law or agreed to in writing, software * |
| 11 | + * distributed under the License is distributed on an "AS IS" BASIS, * |
| 12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * |
| 13 | + * See the License for the specific language governing permissions and * |
| 14 | + * limitations under the License. * |
| 15 | + ***************************************************************************/ |
| 16 | + |
| 17 | +// Package config // |
| 18 | +package config |
| 19 | + |
| 20 | +import "github.com/optimizely/go-sdk/pkg/entities" |
| 21 | + |
| 22 | +// OptimizelyConfig is a snapshot of the experiments and features in the project config |
| 23 | +type OptimizelyConfig struct { |
| 24 | + Revision string |
| 25 | + ExperimentsMap map[string]OptimizelyExperiment |
| 26 | + FeaturesMap map[string]OptimizelyFeature |
| 27 | +} |
| 28 | + |
| 29 | +// OptimizelyExperiment has experiment info |
| 30 | +type OptimizelyExperiment struct { |
| 31 | + ID string |
| 32 | + Key string |
| 33 | + VariationsMap map[string]OptimizelyVariation |
| 34 | +} |
| 35 | + |
| 36 | +// OptimizelyFeature has feature info |
| 37 | +type OptimizelyFeature struct { |
| 38 | + ID string |
| 39 | + Key string |
| 40 | + ExperimentsMap map[string]OptimizelyExperiment |
| 41 | + VariablesMap map[string]OptimizelyVariable |
| 42 | +} |
| 43 | + |
| 44 | +// OptimizelyVariation has variation info |
| 45 | +type OptimizelyVariation struct { |
| 46 | + ID string |
| 47 | + Key string |
| 48 | + FeatureEnabled bool |
| 49 | + VariablesMap map[string]OptimizelyVariable |
| 50 | +} |
| 51 | + |
| 52 | +// OptimizelyVariable has variable info |
| 53 | +type OptimizelyVariable struct { |
| 54 | + ID string |
| 55 | + Key string |
| 56 | + Type string |
| 57 | + Value string |
| 58 | +} |
| 59 | + |
| 60 | +func getVariableByIDMap(features []entities.Feature) (variableByIDMap map[string]entities.Variable) { |
| 61 | + variableByIDMap = map[string]entities.Variable{} |
| 62 | + for _, feature := range features { |
| 63 | + for _, variable := range feature.VariableMap { |
| 64 | + variableByIDMap[variable.ID] = variable |
| 65 | + } |
| 66 | + } |
| 67 | + return variableByIDMap |
| 68 | +} |
| 69 | + |
| 70 | +func getExperimentVariablesMap(features []entities.Feature) (experimentVariableMap map[string]map[string]OptimizelyVariable) { |
| 71 | + experimentVariableMap = map[string]map[string]OptimizelyVariable{} |
| 72 | + for _, feature := range features { |
| 73 | + |
| 74 | + var optimizelyVariableMap = map[string]OptimizelyVariable{} |
| 75 | + for _, variable := range feature.VariableMap { |
| 76 | + optimizelyVariableMap[variable.Key] = OptimizelyVariable{Key: variable.Key, ID: variable.ID, Value: variable.DefaultValue, Type: string(variable.Type)} |
| 77 | + |
| 78 | + } |
| 79 | + for _, experiment := range feature.FeatureExperiments { |
| 80 | + experimentVariableMap[experiment.Key] = optimizelyVariableMap |
| 81 | + } |
| 82 | + } |
| 83 | + return experimentVariableMap |
| 84 | +} |
| 85 | + |
| 86 | +func getExperimentMap(features []entities.Feature, experiments []entities.Experiment, variableByIDMap map[string]entities.Variable) (optlyExperimentMap map[string]OptimizelyExperiment) { |
| 87 | + |
| 88 | + optlyExperimentMap = map[string]OptimizelyExperiment{} |
| 89 | + experimentVariablesMap := getExperimentVariablesMap(features) |
| 90 | + |
| 91 | + for _, experiment := range experiments { |
| 92 | + var optlyVariationsMap = map[string]OptimizelyVariation{} |
| 93 | + for _, variation := range experiment.Variations { |
| 94 | + var optlyVariablesMap = map[string]OptimizelyVariable{} |
| 95 | + |
| 96 | + if variableMap, ok := experimentVariablesMap[experiment.Key]; ok { |
| 97 | + for index, element := range variableMap { // copy by value |
| 98 | + optlyVariablesMap[index] = element |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + for _, variable := range variation.Variables { |
| 103 | + if experiment.IsFeatureExperiment && variation.FeatureEnabled { |
| 104 | + if convertedVariable, ok := variableByIDMap[variable.ID]; ok { |
| 105 | + optlyVariable := OptimizelyVariable{Key: convertedVariable.Key, ID: convertedVariable.ID, |
| 106 | + Type: string(convertedVariable.Type), Value: variable.Value} |
| 107 | + optlyVariablesMap[convertedVariable.Key] = optlyVariable |
| 108 | + } |
| 109 | + } |
| 110 | + } |
| 111 | + optVariation := OptimizelyVariation{ID: variation.ID, Key: variation.Key, VariablesMap: optlyVariablesMap, FeatureEnabled: variation.FeatureEnabled} |
| 112 | + optlyVariationsMap[variation.Key] = optVariation |
| 113 | + } |
| 114 | + optlyExperiment := OptimizelyExperiment{ID: experiment.ID, Key: experiment.Key, VariationsMap: optlyVariationsMap} |
| 115 | + optlyExperimentMap[experiment.Key] = optlyExperiment |
| 116 | + } |
| 117 | + return optlyExperimentMap |
| 118 | +} |
| 119 | + |
| 120 | +func getFeatureMap(features []entities.Feature, experimentsMap map[string]OptimizelyExperiment) (optlyFeatureMap map[string]OptimizelyFeature) { |
| 121 | + |
| 122 | + optlyFeatureMap = map[string]OptimizelyFeature{} |
| 123 | + |
| 124 | + for _, feature := range features { |
| 125 | + |
| 126 | + var optlyFeatureVariablesMap = map[string]OptimizelyVariable{} |
| 127 | + for _, featureVarible := range feature.VariableMap { |
| 128 | + optlyVariable := OptimizelyVariable{Key: featureVarible.Key, ID: featureVarible.ID, |
| 129 | + Type: string(featureVarible.Type), Value: featureVarible.DefaultValue} |
| 130 | + optlyFeatureVariablesMap[featureVarible.Key] = optlyVariable |
| 131 | + } |
| 132 | + |
| 133 | + var optlyExperimentMap = map[string]OptimizelyExperiment{} |
| 134 | + for _, experiment := range feature.FeatureExperiments { |
| 135 | + optlyExperimentMap[experiment.Key] = experimentsMap[experiment.Key] |
| 136 | + } |
| 137 | + |
| 138 | + optlyFeature := OptimizelyFeature{ID: feature.ID, Key: feature.Key, ExperimentsMap: optlyExperimentMap, VariablesMap: optlyFeatureVariablesMap} |
| 139 | + optlyFeatureMap[feature.Key] = optlyFeature |
| 140 | + |
| 141 | + } |
| 142 | + return optlyFeatureMap |
| 143 | +} |
| 144 | + |
| 145 | +// NewOptimizelyConfig constructs OptimizelyConfig object |
| 146 | +func NewOptimizelyConfig(projConfig ProjectConfig) *OptimizelyConfig { |
| 147 | + |
| 148 | + if projConfig == nil { |
| 149 | + return nil |
| 150 | + } |
| 151 | + featuresList := projConfig.GetFeatureList() |
| 152 | + experimentsList := projConfig.GetExperimentList() |
| 153 | + revision := projConfig.GetRevision() |
| 154 | + |
| 155 | + optimizelyConfig := &OptimizelyConfig{} |
| 156 | + |
| 157 | + variableByIDMap := getVariableByIDMap(featuresList) |
| 158 | + |
| 159 | + optimizelyConfig.ExperimentsMap = getExperimentMap(featuresList, experimentsList, variableByIDMap) |
| 160 | + optimizelyConfig.FeaturesMap = getFeatureMap(featuresList, optimizelyConfig.ExperimentsMap) |
| 161 | + optimizelyConfig.Revision = revision |
| 162 | + |
| 163 | + return optimizelyConfig |
| 164 | +} |
0 commit comments