/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
using System;
using System.Reflection;
using Amazon;
using Amazon.Runtime;
using Amazon.Util;
using Amazon.Extensions.NETCore.Setup;
using System.Linq;
namespace Microsoft.Extensions.Configuration
{
///
/// This class adds extension methods to IConfiguration making it easier to pull out
/// AWS configuration options.
///
public static class ConfigurationExtensions
{
///
/// The default section where settings are read from the IConfiguration object. This is set to "AWS".
///
public const string DEFAULT_CONFIG_SECTION = "AWS";
///
/// Constructs an AWSOptions class with the options specified in the "AWS" section in the IConfiguration object.
///
///
/// The AWSOptions containing the values set in configuration system.
public static AWSOptions GetAWSOptions(this IConfiguration config)
{
return GetAWSOptions(config, DEFAULT_CONFIG_SECTION);
}
///
/// Constructs an AWSOptions class with the options specified in the "AWS" section in the IConfiguration object.
///
///
/// The config section to extract AWS options from.
/// The AWSOptions containing the values set in configuration system.
public static AWSOptions GetAWSOptions(this IConfiguration config, string configSection)
{
return GetAWSOptions(config, configSection);
}
///
/// Constructs an AWSOptions class with the options specified in the "AWS" section in the IConfiguration object.
///
/// The AWS client config to be used in creating clients, like AmazonS3Config.
///
/// The AWSOptions containing the values set in configuration system.
public static AWSOptions GetAWSOptions(this IConfiguration config) where TConfig : ClientConfig, new()
{
return GetAWSOptions(config, DEFAULT_CONFIG_SECTION);
}
///
/// Constructs an AWSOptions class with the options specified in the "AWS" section in the IConfiguration object.
///
/// The AWS client config to be used in creating clients, like AmazonS3Config.
///
/// The config section to extract AWS options from.
/// The AWSOptions containing the values set in configuration system.
public static AWSOptions GetAWSOptions(this IConfiguration config, string configSection) where TConfig : ClientConfig, new()
{
var options = new AWSOptions
{
DefaultClientConfig = new TConfig(),
};
IConfiguration section;
if (string.IsNullOrEmpty(configSection))
section = config;
else
section = config.GetSection(configSection);
if (section == null)
return options;
var clientConfigType = typeof(TConfig);
var properties = clientConfigType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var element in section.GetChildren())
{
try
{
var property = properties.SingleOrDefault(p => p.Name.Equals(element.Key, StringComparison.OrdinalIgnoreCase));
if (property == null || property.SetMethod == null)
continue;
if (property.PropertyType == typeof(string) || property.PropertyType.GetTypeInfo().IsPrimitive)
{
var value = Convert.ChangeType(element.Value, property.PropertyType);
property.SetMethod.Invoke(options.DefaultClientConfig, new object[] { value });
}
else if (property.PropertyType == typeof(TimeSpan) || property.PropertyType == typeof(Nullable))
{
var milliSeconds = Convert.ToInt64(element.Value);
var timespan = TimeSpan.FromMilliseconds(milliSeconds);
property.SetMethod.Invoke(options.DefaultClientConfig, new object[] { timespan });
}
else if (property.PropertyType.IsEnum)
{
var value = Enum.Parse(property.PropertyType, element.Value);
if ( value != null )
{
property.SetMethod.Invoke(options.DefaultClientConfig, new object[] { value });
}
}
}
catch(Exception e)
{
throw new ConfigurationException($"Error reading value for property {element.Key}.", e)
{
PropertyName = element.Key,
PropertyValue = element.Value
};
}
}
if (!string.IsNullOrEmpty(section["Profile"]))
{
options.Profile = section["Profile"];
}
// Check legacy name if the new name isn't set
else if (!string.IsNullOrEmpty(section["AWSProfileName"]))
{
options.Profile = section["AWSProfileName"];
}
if (!string.IsNullOrEmpty(section["ProfilesLocation"]))
{
options.ProfilesLocation = section["ProfilesLocation"];
}
// Check legacy name if the new name isn't set
else if (!string.IsNullOrEmpty(section["AWSProfilesLocation"]))
{
options.ProfilesLocation = section["AWSProfilesLocation"];
}
if (!string.IsNullOrEmpty(section["Region"]))
{
options.Region = RegionEndpoint.GetBySystemName(section["Region"]);
}
// Check legacy name if the new name isn't set
else if (!string.IsNullOrEmpty(section["AWSRegion"]))
{
options.Region = RegionEndpoint.GetBySystemName(section["AWSRegion"]);
}
if (!string.IsNullOrEmpty(section["DefaultsMode"]))
{
if(!Enum.TryParse(section["DefaultsMode"], out var mode))
{
throw new ArgumentException($"Invalid value for DefaultConfiguration. Valid values are: {string.Join(", ", Enum.GetNames(typeof(DefaultConfigurationMode)))} ");
}
options.DefaultConfigurationMode = mode;
}
if (!string.IsNullOrEmpty(section["SessionRoleArn"]))
{
options.SessionRoleArn = section["SessionRoleArn"];
}
if (!string.IsNullOrEmpty(section["SessionName"]))
{
options.SessionName = section["SessionName"];
}
var loggingSection = section.GetSection("Logging");
if(loggingSection != null)
{
options.Logging = new AWSOptions.LoggingSetting();
if (!string.IsNullOrEmpty(loggingSection[nameof(AWSOptions.LoggingSetting.LogTo)]))
{
if (!Enum.TryParse(loggingSection[nameof(AWSOptions.LoggingSetting.LogTo)], out var logTo))
{
throw new ArgumentException($"Invalid value for {nameof(AWSOptions.LoggingSetting.LogTo)}. Valid values are: {string.Join(", ", Enum.GetNames(typeof(LoggingOptions)))} ");
}
options.Logging.LogTo = logTo;
}
if (!string.IsNullOrEmpty(loggingSection[nameof(AWSOptions.LoggingSetting.LogResponses)]))
{
if (!Enum.TryParse(loggingSection[nameof(AWSOptions.LoggingSetting.LogResponses)], out var logResponses))
{
throw new ArgumentException($"Invalid value for {nameof(AWSOptions.LoggingSetting.LogResponses)}. Valid values are: {string.Join(", ", Enum.GetNames(typeof(ResponseLoggingOption)))} ");
}
options.Logging.LogResponses = logResponses;
}
if (!string.IsNullOrEmpty(loggingSection[nameof(AWSOptions.LoggingSetting.LogResponsesSizeLimit)]))
{
if (!int.TryParse(loggingSection[nameof(AWSOptions.LoggingSetting.LogResponsesSizeLimit)], out var logResponsesSizeLimit))
{
throw new ArgumentException($"Invalid integer value for {nameof(AWSOptions.LoggingSetting.LogResponsesSizeLimit)}.");
}
options.Logging.LogResponsesSizeLimit = logResponsesSizeLimit;
}
if (!string.IsNullOrEmpty(loggingSection[nameof(AWSOptions.LoggingSetting.LogMetrics)]))
{
if (!bool.TryParse(loggingSection[nameof(AWSOptions.LoggingSetting.LogMetrics)], out var logMetrics))
{
throw new ArgumentException($"Invalid boolean value for {nameof(AWSOptions.LoggingSetting.LogMetrics)}.");
}
options.Logging.LogMetrics = logMetrics;
}
}
return options;
}
}
}