/// <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); }
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); }
/// <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); }
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); }
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); } }