Esempio n. 1
0
        /// <see cref="ILdClient.AllFlags(User)"/>
        public IDictionary <string, JToken> AllFlags(User user)
        {
            if (IsOffline())
            {
                Log.Warn("AllFlags() was called when client is in offline mode. Returning null.");
                return(null);
            }
            if (!Initialized())
            {
                Log.Warn("AllFlags() was called before client has finished initializing. Returning null.");
                return(null);
            }
            if (user == null || user.Key == null)
            {
                Log.Warn("AllFlags() called with null user or null user key. Returning null");
                return(null);
            }

            IDictionary <string, FeatureFlag> flags   = _featureStore.All(VersionedDataKind.Features);
            IDictionary <string, JToken>      results = new Dictionary <string, JToken>();

            foreach (KeyValuePair <string, FeatureFlag> pair in flags)
            {
                try
                {
                    FeatureFlag.EvalResult evalResult = pair.Value.Evaluate(user, _featureStore, _configuration);
                    results.Add(pair.Key, evalResult.Result);
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Exception caught when evaluating all flags: {0}", e, Util.ExceptionMessage(e));
                }
            }
            return(results);
        }
Esempio n. 2
0
        private JToken Evaluate(string featureKey, User user, JToken defaultValue, JTokenType?expectedType)
        {
            if (!Initialized())
            {
                Logger.LogWarning("LaunchDarkly client has not yet been initialized. Returning default");
                return(defaultValue);
            }
            if (user == null || user.Key == null)
            {
                Logger.LogWarning("Feature flag evaluation called with null user or null user key. Returning default");
                sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
                return(defaultValue);
            }

            try
            {
                var featureFlag = _featureStore.Get(featureKey);
                if (featureFlag == null)
                {
                    Logger.LogWarning("Unknown feature flag " + featureKey + "; returning default value: ");
                    sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
                    return(defaultValue);
                }

                FeatureFlag.EvalResult evalResult = featureFlag.Evaluate(user, _featureStore);
                if (!IsOffline())
                {
                    foreach (var prereqEvent in evalResult.PrerequisiteEvents)
                    {
                        _eventStore.Add(prereqEvent);
                    }
                }
                if (evalResult.Result != null)
                {
                    if (expectedType != null && !evalResult.Result.Type.Equals(expectedType))
                    {
                        Logger.LogError("Expected type: " + expectedType + " but got " + evalResult.GetType() +
                                        " when evaluating FeatureFlag: " + featureKey + ". Returning default");
                        sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, featureFlag.Version);
                        return(defaultValue);
                    }
                    sendFlagRequestEvent(featureKey, user, evalResult.Result, defaultValue, featureFlag.Version);
                    return(evalResult.Result);
                }
            }
            catch (Exception e)
            {
                Logger.LogError(
                    String.Format(
                        "Encountered exception in LaunchDarkly client: {0} when evaluating feature key: {1} for user key: {2}",
                        e.Message, featureKey, user.Key));
                Logger.LogDebug(e.ToString());
            }
            sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
            return(defaultValue);
        }
Esempio n. 3
0
        /// <inheritdoc/>
        public FeatureFlagsState AllFlagsState(User user, params FlagsStateOption[] options)
        {
            if (IsOffline())
            {
                Log.Warn("AllFlagsState() was called when client is in offline mode. Returning empty state.");
                return(new FeatureFlagsState(false));
            }
            if (!Initialized())
            {
                if (_featureStore.Initialized())
                {
                    Log.Warn("AllFlagsState() called before client initialized; using last known values from feature store");
                }
                else
                {
                    Log.Warn("AllFlagsState() called before client initialized; feature store unavailable, returning empty state");
                    return(new FeatureFlagsState(false));
                }
            }
            if (user == null || user.Key == null)
            {
                Log.Warn("AllFlagsState() called with null user or null user key. Returning empty state");
                return(new FeatureFlagsState(false));
            }

            var state                = new FeatureFlagsState(true);
            var clientSideOnly       = FlagsStateOption.HasOption(options, FlagsStateOption.ClientSideOnly);
            var withReasons          = FlagsStateOption.HasOption(options, FlagsStateOption.WithReasons);
            var detailsOnlyIfTracked = FlagsStateOption.HasOption(options, FlagsStateOption.DetailsOnlyForTrackedFlags);
            IDictionary <string, FeatureFlag> flags = _featureStore.All(VersionedDataKind.Features);

            foreach (KeyValuePair <string, FeatureFlag> pair in flags)
            {
                var flag = pair.Value;
                if (clientSideOnly && !flag.ClientSide)
                {
                    continue;
                }
                try
                {
                    FeatureFlag.EvalResult result = flag.Evaluate(user, _featureStore, EventFactory.Default);
                    state.AddFlag(flag, result.Result.Value.InnerValue, result.Result.VariationIndex,
                                  withReasons ? result.Result.Reason : null, detailsOnlyIfTracked);
                }
                catch (Exception e)
                {
                    Log.ErrorFormat("Exception caught for feature flag \"{0}\" when evaluating all flags: {1}", flag.Key, Util.ExceptionMessage(e));
                    Log.Debug(e.ToString(), e);
                    EvaluationReason reason = new EvaluationReason.Error(EvaluationErrorKind.EXCEPTION);
                    state.AddFlag(flag, null, null, withReasons ? reason : null, detailsOnlyIfTracked);
                }
            }
            return(state);
        }
Esempio n. 4
0
        private JToken Evaluate(string featureKey, User user, JToken defaultValue, JTokenType?expectedType)
        {
            if (!Initialized())
            {
                Log.Warn("LaunchDarkly client has not yet been initialized. Returning default");
                return(defaultValue);
            }
            if (user == null || user.Key == null)
            {
                Log.Warn("Feature flag evaluation called with null user or null user key. Returning default");
                sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
                return(defaultValue);
            }

            try
            {
                var featureFlag = _featureStore.Get(VersionedDataKind.Features, featureKey);
                if (featureFlag == null)
                {
                    Log.InfoFormat("Unknown feature flag {0}; returning default value",
                                   featureKey);

                    sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
                    return(defaultValue);
                }

                FeatureFlag.EvalResult evalResult = featureFlag.Evaluate(user, _featureStore, _configuration);
                if (!IsOffline())
                {
                    foreach (var prereqEvent in evalResult.PrerequisiteEvents)
                    {
                        _eventStore.Add(prereqEvent);
                    }
                }
                if (evalResult.Result != null)
                {
                    if (expectedType != null && !evalResult.Result.Type.Equals(expectedType))
                    {
                        Log.ErrorFormat("Expected type: {0} but got {1} when evaluating FeatureFlag: {2}. Returning default",
                                        expectedType,
                                        evalResult.GetType(),
                                        featureKey);

                        sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, featureFlag.Version);
                        return(defaultValue);
                    }
                    sendFlagRequestEvent(featureKey, user, evalResult.Result, defaultValue, featureFlag.Version);
                    return(evalResult.Result);
                }
            }
            catch (Exception e)
            {
                Log.ErrorFormat("Encountered exception in LaunchDarkly client: {0} when evaluating feature key: {1} for user key: {2}",
                                e,
                                Util.ExceptionMessage(e),
                                featureKey,
                                user.Key);

                Log.Debug("{0}", e);
            }
            sendFlagRequestEvent(featureKey, user, defaultValue, defaultValue, null);
            return(defaultValue);
        }
Esempio n. 5
0
        private EvaluationDetail <JToken> Evaluate(string featureKey, User user, JToken defaultValue, JTokenType?expectedType,
                                                   EventFactory eventFactory)
        {
            if (!Initialized())
            {
                if (_featureStore.Initialized())
                {
                    Log.Warn("Flag evaluation before client initialized; using last known values from feature store");
                }
                else
                {
                    Log.Warn("Flag evaluation before client initialized; feature store unavailable, returning default value");
                    return(new EvaluationDetail <JToken>(defaultValue, null,
                                                         new EvaluationReason.Error(EvaluationErrorKind.CLIENT_NOT_READY)));
                }
            }

            FeatureFlag featureFlag = null;

            try
            {
                featureFlag = _featureStore.Get(VersionedDataKind.Features, featureKey);
                if (featureFlag == null)
                {
                    Log.InfoFormat("Unknown feature flag {0}; returning default value",
                                   featureKey);

                    _eventProcessor.SendEvent(eventFactory.NewUnknownFeatureRequestEvent(featureKey, user, defaultValue,
                                                                                         EvaluationErrorKind.FLAG_NOT_FOUND));
                    return(new EvaluationDetail <JToken>(defaultValue, null,
                                                         new EvaluationReason.Error(EvaluationErrorKind.FLAG_NOT_FOUND)));
                }

                if (user == null || user.Key == null)
                {
                    Log.Warn("Feature flag evaluation called with null user or null user key. Returning default");
                    _eventProcessor.SendEvent(eventFactory.NewDefaultFeatureRequestEvent(featureFlag, user, defaultValue,
                                                                                         EvaluationErrorKind.USER_NOT_SPECIFIED));
                    return(new EvaluationDetail <JToken>(defaultValue, null,
                                                         new EvaluationReason.Error(EvaluationErrorKind.USER_NOT_SPECIFIED)));
                }

                FeatureFlag.EvalResult evalResult = featureFlag.Evaluate(user, _featureStore, eventFactory);
                if (!IsOffline())
                {
                    foreach (var prereqEvent in evalResult.PrerequisiteEvents)
                    {
                        _eventProcessor.SendEvent(prereqEvent);
                    }
                }
                var detail = evalResult.Result;
                if (detail.VariationIndex == null)
                {
                    detail = new EvaluationDetail <JToken>(defaultValue, null, detail.Reason);
                }
                if (detail.Value != null && !CheckResultType(expectedType, detail.Value))
                {
                    Log.ErrorFormat("Expected type: {0} but got {1} when evaluating FeatureFlag: {2}. Returning default",
                                    expectedType,
                                    detail.Value.GetType(),
                                    featureKey);

                    _eventProcessor.SendEvent(eventFactory.NewDefaultFeatureRequestEvent(featureFlag, user, defaultValue,
                                                                                         EvaluationErrorKind.WRONG_TYPE));
                    return(new EvaluationDetail <JToken>(defaultValue, null,
                                                         new EvaluationReason.Error(EvaluationErrorKind.WRONG_TYPE)));
                }
                _eventProcessor.SendEvent(eventFactory.NewFeatureRequestEvent(featureFlag, user, detail, defaultValue));
                return(detail);
            }
            catch (Exception e)
            {
                Log.ErrorFormat("Encountered exception in LaunchDarkly client: {0} when evaluating feature key: {1} for user key: {2}",
                                Util.ExceptionMessage(e),
                                featureKey,
                                user.Key);
                Log.Debug(e.ToString(), e);
                var detail = new EvaluationDetail <JToken>(defaultValue, null,
                                                           new EvaluationReason.Error(EvaluationErrorKind.EXCEPTION));
                if (featureFlag == null)
                {
                    _eventProcessor.SendEvent(eventFactory.NewUnknownFeatureRequestEvent(featureKey, user, defaultValue,
                                                                                         EvaluationErrorKind.EXCEPTION));
                }
                else
                {
                    _eventProcessor.SendEvent(eventFactory.NewFeatureRequestEvent(featureFlag, user,
                                                                                  detail, defaultValue));
                }
                return(detail);
            }
        }