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 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(); }
public UnleashServices(UnleashSettings settings, Dictionary <string, IStrategy> strategyMap) { var fileSystem = settings.FileSystem ?? new FileSystem(settings.Encoding); var backupFile = settings.GetFeatureToggleFilePath(); var etagBackupFile = settings.GetFeatureToggleETagFilePath(); // Cancellation CancellationToken = cancellationTokenSource.Token; ContextProvider = settings.UnleashContextProvider; var loader = new CachedFilesLoader(settings.JsonSerializer, fileSystem, backupFile, etagBackupFile); var cachedFilesResult = loader.EnsureExistsAndLoad(); ToggleCollection = new ThreadSafeToggleCollection { Instance = cachedFilesResult.InitialToggleCollection ?? new ToggleCollection() }; MetricsBucket = new ThreadSafeMetricsBucket(); IUnleashApiClient apiClient; if (settings.UnleashApiClient == null) { var httpClient = settings.HttpClientFactory.Create(settings.UnleashApi); apiClient = new UnleashApiClient(httpClient, settings.JsonSerializer, new UnleashApiClientRequestHeaders() { AppName = settings.AppName, InstanceTag = settings.InstanceTag, CustomHttpHeaders = settings.CustomHttpHeaders }); if (settings.LoadTogglesImmediately) { var toggles = apiClient.FetchToggles("", CancellationToken.None); ToggleCollection.Instance = toggles.Result.ToggleCollection; } } else { // Mocked backend: fill instance collection apiClient = settings.UnleashApiClient; var toggles = apiClient.FetchToggles("", CancellationToken.None); ToggleCollection.Instance = toggles.Result.ToggleCollection; } scheduledTaskManager = settings.ScheduledTaskManager; IsMetricsDisabled = settings.SendMetricsInterval == null; var fetchFeatureTogglesTask = new FetchFeatureTogglesTask( apiClient, ToggleCollection, settings.JsonSerializer, fileSystem, backupFile, etagBackupFile) { ExecuteDuringStartup = true, Interval = settings.FetchTogglesInterval, Etag = cachedFilesResult.InitialETag }; var scheduledTasks = new List <IUnleashScheduledTask>() { fetchFeatureTogglesTask }; if (settings.SendMetricsInterval != null) { var clientRegistrationBackgroundTask = new ClientRegistrationBackgroundTask( apiClient, settings, strategyMap.Select(pair => pair.Key).ToList()) { Interval = TimeSpan.Zero, ExecuteDuringStartup = true }; scheduledTasks.Add(clientRegistrationBackgroundTask); var clientMetricsBackgroundTask = new ClientMetricsBackgroundTask( apiClient, settings, MetricsBucket) { ExecuteDuringStartup = false, Interval = settings.SendMetricsInterval.Value }; scheduledTasks.Add(clientMetricsBackgroundTask); } scheduledTaskManager.Configure(scheduledTasks, CancellationToken); }