11/****************************************************************************
2- * Copyright 2019, Optimizely, Inc. and contributors *
2+ * Copyright 2019-2020 , Optimizely, Inc. and contributors *
33 * *
44 * Licensed under the Apache License, Version 2.0 (the "License"); *
55 * you may not use this file except in compliance with the License. *
@@ -430,29 +430,9 @@ func (o *OptimizelyClient) GetAllFeatureVariablesWithDecision(featureKey string,
430430 }
431431 }
432432
433- var out interface {}
434- out = val
435- switch varType := v .Type ; varType {
436- case entities .Boolean :
437- out , err = strconv .ParseBool (val )
438- errs = multierror .Append (errs , err )
439- case entities .Double :
440- out , err = strconv .ParseFloat (val , 64 )
441- errs = multierror .Append (errs , err )
442- case entities .Integer :
443- out , err = strconv .Atoi (val )
444- errs = multierror .Append (errs , err )
445- case entities .JSON :
446- var optlyJSON * optimizelyjson.OptimizelyJSON
447- optlyJSON , err = optimizelyjson .NewOptimizelyJSONfromString (val )
448- out = optlyJSON .ToMap ()
449- errs = multierror .Append (errs , err )
450- case entities .String :
451- default :
452- o .logger .Warning (fmt .Sprintf (`type "%s" is unknown, returning string` , varType ))
453- }
454-
455- variableMap [v .Key ] = out
433+ typedValue , typedError := o .getTypedValue (val , v .Type )
434+ errs = multierror .Append (errs , typedError )
435+ variableMap [v .Key ] = typedValue
456436 }
457437
458438 if o .notificationCenter != nil {
@@ -467,6 +447,70 @@ func (o *OptimizelyClient) GetAllFeatureVariablesWithDecision(featureKey string,
467447 return enabled , variableMap , errs .ErrorOrNil ()
468448}
469449
450+ // GetDetailedFeatureDecisionUnsafe triggers an impression event and returns all the variables
451+ // for a given feature along with the experiment key, variation key and the enabled state.
452+ // Usage of this method is unsafe and not recommended since it can be removed in any of the next releases.
453+ func (o * OptimizelyClient ) GetDetailedFeatureDecisionUnsafe (featureKey string , userContext entities.UserContext , disableTracking bool ) (decisionInfo decision.UnsafeFeatureDecisionInfo , err error ) {
454+
455+ decisionInfo = decision.UnsafeFeatureDecisionInfo {}
456+ decisionInfo .VariableMap = make (map [string ]interface {})
457+ decisionContext , featureDecision , err := o .getFeatureDecision (featureKey , "" , userContext )
458+ if err != nil {
459+ o .logger .Error ("Optimizely SDK tracking error" , err )
460+ return decisionInfo , err
461+ }
462+
463+ if featureDecision .Variation != nil {
464+ decisionInfo .Enabled = featureDecision .Variation .FeatureEnabled
465+
466+ if featureDecision .Source == decision .FeatureTest {
467+ decisionInfo .VariationKey = featureDecision .Variation .Key
468+ decisionInfo .ExperimentKey = featureDecision .Experiment .Key
469+ // Triggers impression events when applicable
470+ if ! disableTracking {
471+ // send impression event for feature tests
472+ impressionEvent := event .CreateImpressionUserEvent (decisionContext .ProjectConfig , featureDecision .Experiment , * featureDecision .Variation , userContext )
473+ o .EventProcessor .ProcessEvent (impressionEvent )
474+ }
475+ }
476+ }
477+
478+ feature := decisionContext .Feature
479+ if feature == nil {
480+ o .logger .Warning (fmt .Sprintf (`feature "%s" does not exist` , featureKey ))
481+ return decisionInfo , nil
482+ }
483+
484+ errs := new (multierror.Error )
485+
486+ for _ , v := range feature .VariableMap {
487+ val := v .DefaultValue
488+
489+ if decisionInfo .Enabled {
490+ if variable , ok := featureDecision .Variation .Variables [v .ID ]; ok {
491+ val = variable .Value
492+ } else {
493+ o .logger .Warning (fmt .Sprintf (`variable with id "%s" does not exist` , v .ID ))
494+ }
495+ }
496+
497+ typedValue , typedError := o .getTypedValue (val , v .Type )
498+ errs = multierror .Append (errs , typedError )
499+ decisionInfo .VariableMap [v .Key ] = typedValue
500+ }
501+
502+ if o .notificationCenter != nil {
503+ decisionNotification := decision .FeatureNotificationWithVariables (featureKey , & featureDecision , & userContext ,
504+ map [string ]interface {}{"variableValues" : decisionInfo .VariableMap })
505+ decisionNotification .Type = notification .AllFeatureVariables
506+
507+ if err = o .notificationCenter .Send (notification .Decision , * decisionNotification ); err != nil {
508+ o .logger .Warning (fmt .Sprintf ("Problem with sending notification: %v" , err ))
509+ }
510+ }
511+ return decisionInfo , errs .ErrorOrNil ()
512+ }
513+
470514// GetAllFeatureVariables returns all the variables as OptimizelyJSON object for a given feature.
471515func (o * OptimizelyClient ) GetAllFeatureVariables (featureKey string , userContext entities.UserContext ) (optlyJSON * optimizelyjson.OptimizelyJSON , err error ) {
472516 _ , variableMap , err := o .GetAllFeatureVariablesWithDecision (featureKey , userContext )
@@ -685,6 +729,26 @@ func (o *OptimizelyClient) RemoveOnTrack(id int) error {
685729 return nil
686730}
687731
732+ func (o * OptimizelyClient ) getTypedValue (value string , variableType entities.VariableType ) (convertedValue interface {}, err error ) {
733+ convertedValue = value
734+ switch variableType {
735+ case entities .Boolean :
736+ convertedValue , err = strconv .ParseBool (value )
737+ case entities .Double :
738+ convertedValue , err = strconv .ParseFloat (value , 64 )
739+ case entities .Integer :
740+ convertedValue , err = strconv .Atoi (value )
741+ case entities .JSON :
742+ var optlyJSON * optimizelyjson.OptimizelyJSON
743+ optlyJSON , err = optimizelyjson .NewOptimizelyJSONfromString (value )
744+ convertedValue = optlyJSON .ToMap ()
745+ case entities .String :
746+ default :
747+ o .logger .Warning (fmt .Sprintf (`type "%s" is unknown, returning string` , variableType ))
748+ }
749+ return convertedValue , err
750+ }
751+
688752func (o * OptimizelyClient ) getProjectConfig () (projectConfig config.ProjectConfig , err error ) {
689753
690754 if isNil (o .ConfigManager ) {
0 commit comments