/// <summary> /// Helper method to handle all responses from Habitat Server (including errors) in a consistent manner /// </summary> /// <param name="task">The response task from the HttpClient</param> private ConfigServiceResponse HandleConfigServiceResponse(Task <HttpResponseMessage> task) { var configResults = new ConfigServiceResponse { Config = new ConfigRoot { ComponentName = _componentName } }; try { HttpResponseMessage response = task.Result; configResults.StatusCode = response.StatusCode; if (response.IsSuccessStatusCode) { if (response.StatusCode != HttpStatusCode.NoContent) { var dataReadTask = response.Content.ReadAsStringAsync().ContinueWith(x => ReadConfigServiceJson(x)); dataReadTask.Wait(); configResults.Config = dataReadTask.Result.Config; } } else { configResults.Exception = new UnableToAccessConfigurationException(string.Format("Could not retrieve config. Service returned status code {0}", response.StatusCode)); } } catch (Exception exception) { configResults.Exception = new UnableToAccessConfigurationException(string.Format("Could not retrieve config. Error in web request."), exception); } return(configResults); }
/// <summary> /// Helper method to parse server responses as the appropriate JSON type and format for readability. /// </summary> /// <typeparam name="T">The expected type of JSON being returned (e.g. array)</typeparam> /// <param name="readTask">The Habitat Server response task that provides the JSON values</param> private ConfigServiceResponse ReadConfigServiceJson <T>(Task <T> readTask) where T : class { ConfigServiceResponse configResults = new ConfigServiceResponse(); configResults.Config = JsonConvert.DeserializeObject <ConfigRoot>(readTask.Result.ToString()); return(configResults); }
/// <summary> /// Obtains a copy of the current configuration settings, and ensures they are valid. /// </summary> /// <returns>The config settings, as a tree</returns> /// <exception cref="ConfigValidationException">if one or more expected configuration settings are invalid or missing</exception> public ConfigRoot GetAndValidateConfiguration() { ConfigRoot configRoot; try { ConfigServiceResponse responseFromService = _serviceProvider.GetConfig(); bool hasValidConfigFromServer = false; string[] errors = new string[0]; if (responseFromService.Config != null && responseFromService.Config.Data != null) { Dictionary <string, bool> serverConfigValidationResults = Validate(responseFromService.Config.Data.ToDictionary()); hasValidConfigFromServer = (serverConfigValidationResults.Count(x => x.Value == false) == 0); if (hasValidConfigFromServer) { SaveConfigToCache(responseFromService.Config); } else { errors = (from r in serverConfigValidationResults where r.Value == false select r.Key).ToArray(); } } bool hasValidConfigFromCache = false; configRoot = LoadConfigFromCache(); if (configRoot != null) { Dictionary <string, bool> cachedConfigValidationResults = Validate(configRoot.Data.ToDictionary()); hasValidConfigFromCache = (cachedConfigValidationResults.Count(x => x.Value == false) == 0); // Only report the cache errors if the server data was missing or valid if (!hasValidConfigFromCache && errors.Length == 0) { errors = (from r in cachedConfigValidationResults where r.Value == false select r.Key).ToArray(); } } if (!hasValidConfigFromCache && !hasValidConfigFromServer) { if (responseFromService.Exception != null) { throw responseFromService.Exception; } throw new ConfigValidationException(string.Format("One or more config settings invalid or missing ({0}).", string.Join(", ", errors)), errors.ToList()); } } catch (Exception e) { throw new UnableToAccessConfigurationException(string.Format("Config can not be retrieved for application '{0}'.", _componentName), e); } return(configRoot); }
/// <summary> /// Makes a call to retrieve config data from the Habitat Server. /// This call blocks the executing thread until a response is given. /// </summary> /// <returns>The response from the Habitat Server</returns> public ConfigServiceResponse GetConfig() { var serviceResponse = new ConfigServiceResponse { Config = new ConfigRoot { ComponentName = _componentName } }; var serviceCallTask = _client.GetAsync(string.Format("Config/{0}", _componentName)); var handleResponseTask = serviceCallTask.ContinueWith <ConfigServiceResponse>(HandleConfigServiceResponse); handleResponseTask.Wait(); if (!handleResponseTask.IsFaulted) { serviceResponse = handleResponseTask.Result; } return(serviceResponse); }