public UnleashServices(UnleashSettings settings, IRandom random, IUnleashApiClientFactory unleashApiClientFactory, IUnleashScheduledTaskManager scheduledTaskManager, IToggleCollectionCache toggleCollectionCache, IEnumerable <IStrategy> strategies) { this.Random = random ?? throw new ArgumentNullException(nameof(random)); this.scheduledTaskManager = scheduledTaskManager ?? throw new ArgumentNullException(nameof(scheduledTaskManager)); var settingsValidator = new UnleashSettingsValidator(); settingsValidator.Validate(settings); StrategyMap = BuildStrategyMap(strategies?.ToArray() ?? new IStrategy[0]); CancellationToken = cancellationTokenSource.Token; var cachedFilesResult = toggleCollectionCache.Load(cancellationTokenSource.Token).GetAwaiter().GetResult(); cacheMiss = cachedFilesResult.IsCacheMiss; ToggleCollection = new ThreadSafeToggleCollection { Instance = cachedFilesResult.InitialToggleCollection ?? new ToggleCollection() }; MetricsBucket = new ThreadSafeMetricsBucket(); var scheduledTasks = CreateScheduledTasks(settings, unleashApiClientFactory, toggleCollectionCache, cachedFilesResult); scheduledTaskManager.Configure(scheduledTasks, CancellationToken); }
public UnleashServiceFixture() { Settings = new UnleashSettings { UnleashApi = new Uri("http://localhost:4242/"), AppName = "IntegrationTest", InstanceTag = "Test" }; UnleashServices = new DefaultUnleashServices(Settings); ContextProvider = new DefaultUnleashContextProvider(); Unleash = new Unleash(Settings, UnleashServices, ContextProvider); UnleashServices?.FeatureToggleLoadComplete(false, CancellationToken.None).Wait(); var httpClient = new HttpClient { BaseAddress = new Uri("http://localhost:4242/admin/") }; httpClient.DefaultRequestHeaders.ConnectionClose = false; httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Accept", "application/json"); httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json"); httpClient.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue { NoCache = true }; var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); JsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); AdminApiClient = new UnleashAdminApiClient(httpClient, JsonSerializer); }
internal async Task ExecuteAsync_WhenApiReturns200Ok_CompletesSuccessfully( [Frozen] UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, [Frozen] MetricsBucket metricsBucket) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket); var backgroundTask = new ClientMetricsBackgroundTask(apiClientFactoryMock.Object, settings, threadSafeMetricsBucket); httpMessageHandler.SetupPostSendMetricsRequestForSuccess(requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); }
internal async Task FetchToggles_WhenServerReturns304NotModified_ReturnsCacheHitResult( UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, string etagMinusQuotes ) { var etag = $"\"{etagMinusQuotes}\""; var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupGetFeaturesRequestForCacheHit(requestHeaders, etag); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None); Assert.Null(actualFetchTogglesResult.ToggleCollection); Assert.False(actualFetchTogglesResult.HasChanged); Assert.Equal(etag, actualFetchTogglesResult.Etag); httpMessageHandler.VerifyAll(); }
internal async Task ExecuteAsync_WhenHttpExceptionOccurs_CompletesSuccessfully( HttpStatusCode statusCode, string responseBody, string responseContentType, [Frozen] UnleashSettings settings, [Frozen] ThreadSafeToggleCollection toggleCollection, [Frozen] Mock <IToggleCollectionCache> toggleCollectionCache, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, TaskCompletionSource <object> taskCompletionSource) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var backgroundTask = new FetchFeatureTogglesTask(apiClientFactoryMock.Object, toggleCollection, toggleCollectionCache.Object, taskCompletionSource); httpMessageHandler.SetupGetFeaturesRequestForException(requestHeaders, statusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); Assert.True(taskCompletionSource.Task.IsCompletedSuccessfully); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); toggleCollectionCache.VerifyNoOtherCalls(); }
internal async Task FetchToggles_WhenHttpExceptionOccurs_ReturnsEmptyResult( HttpStatusCode responseStatusCode, string responseBody, string responseContentType, UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, string etag ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupGetFeaturesRequestForException(requestHeaders, responseStatusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None); Assert.Null(actualFetchTogglesResult.ToggleCollection); Assert.Null(actualFetchTogglesResult.Etag); Assert.False(actualFetchTogglesResult.HasChanged); httpMessageHandler.VerifyAll(); }
internal async Task FetchToggles_WhenServerReturnsExpectedToggles_ReturnsValidResult( UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, string etag ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var expectedToggles = new ToggleCollection(); httpMessageHandler.SetupGetFeaturesRequestForSuccess(jsonSerializer, expectedToggles, requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var actualFetchTogglesResult = await apiClient.FetchToggles(etag, CancellationToken.None); var actualToggles = actualFetchTogglesResult.ToggleCollection; Assert.Equal(expectedToggles.Features, actualToggles.Features); Assert.True(actualFetchTogglesResult.HasChanged); Assert.NotEqual(etag, actualFetchTogglesResult.Etag); httpMessageHandler.VerifyAll(); }
internal async Task RegisterMetrics_WhenHttpExceptionOccurs_ReturnsFalse( HttpStatusCode responseStatusCode, string responseBody, string responseContentType, UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, MetricsBucket metricsBucket ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupPostSendMetricsRequestForException(requestHeaders, responseStatusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket); var successResult = await apiClient.SendMetrics(threadSafeMetricsBucket, CancellationToken.None); Assert.False(successResult); httpMessageHandler.VerifyAll(); }
public async Task Load_WhenTogglesOrEtagFileDoesNotExists_ReturnsEmptyResult( bool toggleFileExists, bool etagFileExists, [Frozen] UnleashSettings settings, [Frozen] Mock <IFileSystem> fileSystem, FileSystemToggleCollectionCache cache ) { var etagFilePath = settings.GetFeatureToggleETagFilePath(); var toggleFilePath = settings.GetFeatureToggleFilePath(); fileSystem.Setup(fs => fs.FileExists(etagFilePath)).Returns(etagFileExists); if (etagFileExists) { fileSystem.Setup(fs => fs.FileExists(toggleFilePath)).Returns(toggleFileExists); } var result = await cache.Load(CancellationToken.None); Assert.Equal(string.Empty, result.InitialETag); Assert.Null(result.InitialToggleCollection); fileSystem.VerifyAll(); }
internal async Task RegisterMetrics_WhenServerReturns200Ok_ReturnsTrue( UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] UnleashApiClientRequestHeaders requestHeaders, MetricsBucket metricsBucket ) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); httpMessageHandler.SetupPostSendMetricsRequestForSuccess(requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); var threadSafeMetricsBucket = new ThreadSafeMetricsBucket(metricsBucket); var successResult = await apiClient.SendMetrics(threadSafeMetricsBucket, CancellationToken.None); Assert.True(successResult); httpMessageHandler.VerifyAll(); }
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); var form = new UnleashForm(); JsonSerializerTester.Assert(new NewtonsoftJson7Serializer()); settings = new UnleashSettings { UnleashApi = new Uri("http://unleash.herokuapp.com/"), //UnleashApi = new Uri("http://localhost:4242/"), AppName = "dotnet-forms-test", InstanceTag = "instance 1", SendMetricsInterval = TimeSpan.FromSeconds(5), FetchTogglesInterval = TimeSpan.FromSeconds(10), UnleashContextProvider = new WinFormsContextProvider(form), JsonSerializer = new NewtonsoftJson7Serializer() }; unleash = new DefaultUnleash(settings); form.Unleash = unleash; form.Settings = settings; Application.ApplicationExit += (sender, args) => { unleash?.Dispose(); }; Application.Run(form); }
public async Task Load_WhenValidToggleAndEtagFilesExist_ReturnsExpectedResult( [Frozen] UnleashSettings settings, [Frozen] Mock <IFileSystem> fileSystem, [Frozen] Mock <IJsonSerializer> jsonSerializer, FileSystemToggleCollectionCache cache, ToggleCollection toggleCollection, string etag ) { var toggleFilePath = settings.GetFeatureToggleFilePath(); var etagFilePath = settings.GetFeatureToggleETagFilePath(); fileSystem.Setup(fs => fs.FileExists(toggleFilePath)).Returns(true); fileSystem.Setup(fs => fs.FileExists(etagFilePath)).Returns(true); var ms = new MemoryStream(); fileSystem.Setup(fs => fs.FileOpenRead(toggleFilePath)).Returns(ms); fileSystem.Setup(fs => fs.ReadAllText(etagFilePath)).Returns(etag); jsonSerializer.Setup(js => js.Deserialize <ToggleCollection>(ms)).Returns(toggleCollection); var result = await cache.Load(CancellationToken.None); Assert.Equal(etag, result.InitialETag); Assert.Same(toggleCollection, result.InitialToggleCollection); fileSystem.VerifyAll(); jsonSerializer.VerifyAll(); }
internal async Task ExecuteAsync_WhenHttpExceptionOccurs_CompletesSuccessfully( HttpStatusCode statusCode, string responseBody, string responseContentType, [Frozen] UnleashSettings settings, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, List <string> strategies) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var backgroundTask = new ClientRegistrationBackgroundTask(apiClientFactoryMock.Object, settings, strategies); httpMessageHandler.SetupPostRegisterClientRequestForException(requestHeaders, statusCode, responseBody, responseContentType); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); }
public FileSystemToggleCollectionCache(UnleashSettings settings, IJsonSerializer jsonSerializer, IFileSystem fileSystem) { this.jsonSerializer = jsonSerializer; this.fileSystem = fileSystem; this.toggleFile = settings.GetFeatureToggleFilePath(); this.etagFile = settings.GetFeatureToggleETagFilePath(); }
public DefaultUnleashApiClientFactory(UnleashSettings settings, IHttpClientFactory httpClientFactory, IJsonSerializer jsonSerializer, UnleashApiClientRequestHeaders unleashApiClientRequestHeaders) { this.settings = settings; this.httpClientFactory = httpClientFactory; this.jsonSerializer = jsonSerializer; this.unleashApiClientRequestHeaders = unleashApiClientRequestHeaders; }
public void Should_set_environment_to_default() { // Act var settings = new UnleashSettings(); // Assert settings.Environment.Should().Be("default"); }
public ClientMetricsBackgroundTask( IUnleashApiClient apiClient, UnleashSettings settings, ThreadSafeMetricsBucket metricsBucket) { this.apiClient = apiClient; this.settings = settings; this.metricsBucket = metricsBucket; }
public ClientRegistrationBackgroundTask( IUnleashApiClientFactory apiClientFactory, UnleashSettings settings, List <string> strategies) { this.apiClientFactory = apiClientFactory; this.settings = settings; this.strategies = strategies; }
public static IUnleash CreateUnleash(TestDefinition testDefinition, UnleashContextDefinition contextDefinition) { var fakeHttpClientFactory = A.Fake <IHttpClientFactory>(); var fakeHttpMessageHandler = new TestHttpMessageHandler(); var httpClient = new HttpClient(fakeHttpMessageHandler) { BaseAddress = new Uri("http://localhost") }; var fakeScheduler = A.Fake <IUnleashScheduledTaskManager>(); var fakeFileSystem = new MockFileSystem(); A.CallTo(() => fakeHttpClientFactory.Create(A <Uri> ._)).Returns(httpClient); A.CallTo(() => fakeScheduler.Configure(A <IEnumerable <IUnleashScheduledTask> > ._, A <CancellationToken> ._)).Invokes(action => { var task = ((IEnumerable <IUnleashScheduledTask>)action.Arguments[0]).First(); task.ExecuteAsync((CancellationToken)action.Arguments[1]).Wait(); }); fakeHttpMessageHandler.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(testDefinition.State.ToString(), Encoding.UTF8, "application/json"), Headers = { ETag = new EntityTagHeaderValue("\"123\"") } }; var contextBuilder = new UnleashContext.Builder() .UserId(contextDefinition.UserId) .SessionId(contextDefinition.SessionId) .RemoteAddress(contextDefinition.RemoteAddress) .Environment(contextDefinition.Environment) .AppName(contextDefinition.AppName); if (contextDefinition.Properties != null) { foreach (var property in contextDefinition.Properties) { contextBuilder.AddProperty(property.Key, property.Value); } } var settings = new UnleashSettings { AppName = testDefinition.Name, UnleashContextProvider = new DefaultUnleashContextProvider(contextBuilder.Build()), HttpClientFactory = fakeHttpClientFactory, ScheduledTaskManager = fakeScheduler, FileSystem = fakeFileSystem }; var unleash = new DefaultUnleash(settings); return(unleash); }
///// <summary> ///// Initializes a new instance of Unleash client. ///// </summary> ///// <param name="SynchronousInitialization">If true, fetch and cache toggles before returning. If false, allow the unleash client schedule an initial poll of features in the background</param> public async Task <IUnleash> Generate(UnleashSettings settings, bool SynchronousInitialization = false) { if (SynchronousInitialization) { settings.ScheduleFeatureToggleFetchImmediatly = false; var unleash = new DefaultUnleash(settings); await unleash.services.FetchFeatureTogglesTask.ExecuteAsync(CancellationToken.None); return(unleash); } return(new DefaultUnleash(settings)); }
public static IServiceCollection AddUnleash(this IServiceCollection serviceCollection, Action <UnleashSettings> configurator) { // This is to support the anonymous serviceCollection.AddSingleton<IUnleash, DefaultUnleash>() below. If // DefaultUnleash's constructor asked for an IEnumerable<IStrategy> instead of an IStrategy[] this wouldn't // be necessary. It shouldn't be a breaking change given that T[] : IEnumerable<T>. serviceCollection.AddSingleton(sp => sp.GetRequiredService <IEnumerable <IStrategy> >().ToArray()); // ASP.NET Core will create a scope per HTTP request, message queue consumer code will typically create a // scope per message, timer-based services will create a scope per interval. Disposing the scope disposes // the IDisposable scopes resolved. We'd like to rely on DI's scope to provide isolation across // requests/messages/intervals, basically just new-ing up a Dictionary<string,string>() per request // In your docs, you say "If you are using Asp.Net the UnleashContextProvider will typically be a 'request // scoped' instance.". I agree that makes sense here, and am trying to use DI to enforce it/handle the one // state per scope problem. Also, my goal is for this extension method to work in anything that uses the // DI Scope pattern w/o any changes. serviceCollection.AddScoped <IUnleashContextProvider, ScopedDictionaryContextProvider>(); // Since IUnleash should be a singleton, UnleashSettings must be as well. However, the // UnleashContextProvider property is scoped. serviceCollection.AddSingleton <UnleashSettings>(sp => { // In order to configure this, we are basically capturing a scoped dependency as a singleton. This // instance will never exist within a scope and so it won't have anything to capture. var contextProvider = sp.GetRequiredService <IUnleashContextProvider>(); // Crash happens here var settings = new UnleashSettings { UnleashContextProvider = contextProvider }; configurator?.Invoke(settings); return(settings); }); serviceCollection.AddSingleton <IUnleash, DefaultUnleash>(); /* * Should be equivalent to: * * serviceCollection.AddSingleton<IUnleash>(sp => * { * var unleashSettings = sp.GetRequiredService<UnleashSettings>(); * var strategies = sp.GetRequiredService<IEnumerable<IStrategy>>().ToArray(); * * return new DefaultUnleash(unleashSettings, strategies); * }); */ return(serviceCollection); }
/// <summary> /// Initializes a new instance of Unleash client. /// </summary> /// <param name="synchronousInitialization">If true, fetch and cache toggles before returning. If false, allow the unleash client schedule an initial poll of features in the background</param> /// <param name="strategies">Custom strategies, added in addtion to builtIn strategies.</param> public async Task <IUnleash> CreateClientAsync(UnleashSettings settings, bool synchronousInitialization = false, params IStrategy[] strategies) { if (synchronousInitialization) { settings.ScheduleFeatureToggleFetchImmediatly = false; var unleash = new DefaultUnleash(settings, strategies); await unleash.services.FetchFeatureTogglesTask.ExecuteAsync(CancellationToken.None).ConfigureAwait(false); return(unleash); } return(new DefaultUnleash(settings, strategies)); }
internal async Task ExecuteAsync_WhenApiReturns200Ok_CompletesSuccessfully( [Frozen] UnleashSettings settings, [Frozen] ThreadSafeToggleCollection toggleCollection, [Frozen] Mock <IToggleCollectionCache> toggleCollectionCache, [Frozen] Mock <FakeHttpMessageHandler> httpMessageHandler, [Frozen] Mock <IUnleashApiClientFactory> apiClientFactoryMock, [Frozen] UnleashApiClientRequestHeaders requestHeaders, TaskCompletionSource <object> taskCompletionSource) { var jsonSerializerSettings = new NewtonsoftJsonSerializerSettings(); var jsonSerializer = new NewtonsoftJsonSerializer(jsonSerializerSettings); var toggleCollectionInstance = toggleCollection.Instance; toggleCollectionCache .Setup( x => x.Save( It.Is <ToggleCollection>( y => y.Version.Equals(toggleCollectionInstance.Version) && y.Features.All( z => toggleCollectionInstance.Features.Any(zz => zz.Name.Equals(z.Name)) ) ), It.IsAny <string>(), CancellationToken.None ) ) .Returns(Task.CompletedTask); var backgroundTask = new FetchFeatureTogglesTask(apiClientFactoryMock.Object, toggleCollection, toggleCollectionCache.Object, taskCompletionSource); httpMessageHandler.SetupGetFeaturesRequestForSuccess(jsonSerializer, toggleCollectionInstance, requestHeaders); var httpClient = new HttpClient(httpMessageHandler.Object) { BaseAddress = settings.UnleashApi }; var apiClient = new UnleashApiClient(httpClient, jsonSerializer, requestHeaders); apiClientFactoryMock.Setup(cf => cf.CreateClient()).Returns(apiClient); await backgroundTask.ExecuteAsync(CancellationToken.None); Assert.True(taskCompletionSource.Task.IsCompletedSuccessfully); httpMessageHandler.VerifyAll(); apiClientFactoryMock.VerifyAll(); toggleCollectionCache.VerifyAll(); }
/// <summary> /// Initializes a new instance of Unleash client. /// </summary> /// <param name="synchronousInitialization">If true, fetch and cache toggles before returning. If false, allow the unleash client schedule an initial poll of features in the background</param> /// <param name="strategies">Custom strategies, added in addtion to builtIn strategies.</param> public IUnleash CreateClient(UnleashSettings settings, bool synchronousInitialization = false, params IStrategy[] strategies) { if (synchronousInitialization) { settings.ScheduleFeatureToggleFetchImmediatly = false; var unleash = new DefaultUnleash(settings, strategies); TaskFactory .StartNew(() => unleash.services.FetchFeatureTogglesTask.ExecuteAsync(CancellationToken.None)) .Unwrap() .GetAwaiter() .GetResult(); return(unleash); } return(new DefaultUnleash(settings, strategies)); }
public void Validate(UnleashSettings settings) { if (settings.UnleashApi == null) { throw new UnleashException("You are required to specify an uri to an unleash service"); } if (settings.AppName == null) { throw new UnleashException("You are required to specify an appName"); } if (settings.InstanceTag == null) { throw new UnleashException("You are required to specify an instance id"); } }
public DefaultUnleashServices(UnleashSettings settings) { _services = new UnleashServices( settings, DefaultRandom, new DefaultUnleashApiClientFactory( settings, DefaultHttpClientFactory, DefaultJsonSerializer, new UnleashApiClientRequestHeaders { AppName = settings.AppName, CustomHttpHeaders = settings.CustomHttpHeaders, InstanceTag = settings.InstanceTag }), ScheduledTaskManager, new FileSystemToggleCollectionCache( settings, DefaultJsonSerializer, new FileSystem()), DefaultStrategies); }
private IEnumerable <IUnleashScheduledTask> CreateScheduledTasks(UnleashSettings settings, IUnleashApiClientFactory unleashApiClientFactory, IToggleCollectionCache toggleCollectionCache, ToggleCollectionCacheResult toggleCollectionCacheResult) { yield return(new FetchFeatureTogglesTask( unleashApiClientFactory, ToggleCollection, toggleCollectionCache, flagsFetchedFromUnleashTaskCompletionSource) { ExecuteDuringStartup = true, Interval = settings.FetchTogglesInterval, Etag = toggleCollectionCacheResult.InitialETag }); if (settings.RegisterClient) { yield return(new ClientRegistrationBackgroundTask( unleashApiClientFactory, settings, StrategyMap.Keys.ToList()) { Interval = TimeSpan.Zero, ExecuteDuringStartup = true }); } if (settings.SendMetricsInterval != null) { yield return(new ClientMetricsBackgroundTask( unleashApiClientFactory, settings, MetricsBucket) { ExecuteDuringStartup = false, Interval = settings.SendMetricsInterval.Value }); } }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); UnleashSettings = new UnleashSettings() { UnleashApi = new Uri("http://unleash.herokuapp.com/api/"), //UnleashApi = new Uri("http://localhost:4242/api/"), AppName = "dotnet-api-test", InstanceTag = "instance 1", SendMetricsInterval = TimeSpan.FromSeconds(20), UnleashContextProvider = new AspNetContextProvider(), //JsonSerializer = new JsonNetSerializer() }; UnleashInfo = UnleashSettings.ToString(); Unleash = new DefaultUnleash(UnleashSettings); }
public void Validate(UnleashSettings settings) { if (settings.UnleashApi == null) { throw new UnleashException("You are required to specify an uri to an unleash service"); } if (settings.AppName == null) { throw new UnleashException("You are required to specify an appName"); } if (settings.InstanceTag == null) { throw new UnleashException("You are required to specify an instance id"); } if (settings.JsonSerializer == null) { throw new UnleashException("You are required to specify an json serializer"); } settings.JsonSerializer = DynamicJsonLibraryChooser.CheckIfJsonSerializerCanBeInitialized(settings.JsonSerializer); }
/// <summary> /// This pattern is not recommended. You will miss out on the Unleash.Extensions.* capabilities. You should /// consider using the Generic Host if possible or minimally introducing dependency injection. See the other /// sample projects for examples. This shows the bare functionality most closely resembling the original /// Unleash .NET client (pre-.NET Core) /// </summary> /// <param name="args"></param> static async Task Main(string[] args) { System.Console.WriteLine("Optional Arguments: [userId] [sessionId] [featureToggleName] [extraParamName extraParamValue]"); var settings = new UnleashSettings { UnleashApi = new Uri("http://localhost:4242/"), AppName = "Sample.Console", InstanceTag = "Test", FetchTogglesInterval = TimeSpan.FromSeconds(30), SendMetricsInterval = TimeSpan.FromSeconds(1) }; var unleashContext = new UnleashContext(); using (var unleashServices = new DefaultUnleashServices(settings)) { var unleashContextProvider = new DefaultUnleashContextProvider(unleashContext); var unleash = new Unleash.Unleash(settings, unleashServices, unleashContextProvider); System.Console.WriteLine("Waiting for initial feature toggle load to complete..."); await unleashServices.FeatureToggleLoadComplete(false, CancellationToken.None); System.Console.WriteLine("Feature toggles loaded."); // Configure settings from args/defaults var userId = args.Length > 0 ? args[0] : "1"; var sessionId = args.Length > 1 ? args[1] : "1"; var featureToggleName = args.Length > 2 ? args[2] : "unleash.sample.test.flag"; var extraParamName = args.Length > 4 ? args[3] : null; var extraParamValue = args.Length > 4 ? args[4] : null; // Initialize context unleashContextProvider.Context.RemoteAddress = GetIpAddress() ?? "127.0.0.1"; unleashContextProvider.Context.UserId = userId; unleashContextProvider.Context.SessionId = sessionId; if (extraParamName != null && extraParamValue != null) { unleashContextProvider.Context.Properties[extraParamName] = extraParamValue; } // Check flag var isEnabled = unleash.IsEnabled(featureToggleName); // Output results var messageBuilder = new StringBuilder(); messageBuilder.Append($"{featureToggleName}={isEnabled} for "); messageBuilder.Append($"(UserId={userId},SessionId={sessionId}"); if (extraParamName != null && extraParamValue != null) { messageBuilder.Append($",{extraParamName}={extraParamValue})"); } else { messageBuilder.Append(")"); } System.Console.WriteLine(messageBuilder.ToString()); // Allow metrics to get sent. System.Console.WriteLine("Waiting for metrics job to execute..."); await Task.Delay(TimeSpan.FromSeconds(2)); System.Console.WriteLine("Metrics job complete (presumably)."); System.Console.WriteLine("Stopping scheduler..."); } System.Console.WriteLine("Stopped."); }