/// <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);
        }
Exemplo n.º 3
0
        /// <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);
        }