/* * 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.Collections.Generic; using System.Globalization; using System.IO; using System.Net; using Amazon.Runtime.Internal.Util; using Amazon.Util.Internal.PlatformServices; namespace Amazon.Util.Internal { public static partial class InternalSDKUtils { #region UserAgent static string _versionNumber; static string _customSdkUserAgent; static string _customData; public static void SetUserAgent(string productName, string versionNumber) { SetUserAgent(productName, versionNumber, null); } public static void SetUserAgent(string productName, string versionNumber, string customData) { _userAgentBaseName = productName; _versionNumber = versionNumber; _customData = customData; BuildCustomUserAgentString(); } static void BuildCustomUserAgentString() { if (_versionNumber == null) { _versionNumber = CoreVersionNumber; } var environmentInfo = ServiceFactory.Instance.GetService(); string executionEnvironmentString = ""; executionEnvironmentString = GetExecutionEnvironmentUserAgentString(); if (string.IsNullOrEmpty(executionEnvironmentString)) { _customSdkUserAgent = string.Format(CultureInfo.InvariantCulture, "{0}/{1} {2} OS/{3} {4}", _userAgentBaseName, _versionNumber, environmentInfo.FrameworkUserAgent, environmentInfo.PlatformUserAgent, _customData).Trim(); } else { _customSdkUserAgent = string.Format(CultureInfo.InvariantCulture, "{0}/{1} {2} OS/{3} {4} {5}", _userAgentBaseName, _versionNumber, environmentInfo.FrameworkUserAgent, environmentInfo.PlatformUserAgent, executionEnvironmentString, _customData).Trim(); } } public static string BuildUserAgentString(string serviceSdkVersion) { if (!string.IsNullOrEmpty(_customSdkUserAgent)) { return _customSdkUserAgent; } var environmentInfo = ServiceFactory.Instance.GetService(); #if BCL return string.Format(CultureInfo.InvariantCulture, "{0}/{1} aws-sdk-dotnet-core/{2} {3} OS/{4} {5} {6}", _userAgentBaseName, serviceSdkVersion, CoreVersionNumber, environmentInfo.FrameworkUserAgent, environmentInfo.PlatformUserAgent, GetExecutionEnvironmentUserAgentString(), _customData).Trim(); #elif NETSTANDARD return string.Format(CultureInfo.InvariantCulture, "{0}/{1} aws-sdk-dotnet-core/{2} {3} OS/{4} {5} {6}", _userAgentBaseName, serviceSdkVersion, CoreVersionNumber, environmentInfo.FrameworkUserAgent, environmentInfo.PlatformUserAgent, GetExecutionEnvironmentUserAgentString(), _customData).Trim(); #endif } #endregion public static void ApplyValues(object target, IDictionary propertyValues) { if (propertyValues == null || propertyValues.Count == 0) return; var targetTypeInfo = TypeFactory.GetTypeInfo(target.GetType()); foreach(var kvp in propertyValues) { var property = targetTypeInfo.GetProperty(kvp.Key); if (property == null) throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unable to find property {0} on type {1}.", kvp.Key, targetTypeInfo.FullName)); try { var propertyTypeInfo = TypeFactory.GetTypeInfo(property.PropertyType); if (propertyTypeInfo.IsEnum) { var enumValue = Enum.Parse(property.PropertyType, kvp.Value.ToString(), true); property.SetValue(target, enumValue, null); } else { property.SetValue(target, kvp.Value, null); } } catch(Exception e) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Unable to set property {0} on type {1}: {2}", kvp.Key, targetTypeInfo.FullName, e.Message)); } } } public static void AddToDictionary(Dictionary dictionary, TKey key, TValue value) { if (dictionary.ContainsKey(key)) throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Dictionary already contains item with key {0}", key)); dictionary[key] = value; } public static void FillDictionary(IEnumerable items, Func keyGenerator, Func valueGenerator, Dictionary targetDictionary) { foreach (var item in items) { var key = keyGenerator(item); var value = valueGenerator(item); AddToDictionary(targetDictionary, key, value); } } public static Dictionary ToDictionary(IEnumerable items, Func keyGenerator, Func valueGenerator) { return ToDictionary(items, keyGenerator, valueGenerator, comparer: null); } public static Dictionary ToDictionary(IEnumerable items, Func keyGenerator, Func valueGenerator, IEqualityComparer comparer) { Dictionary dictionary; if (comparer == null) dictionary = new Dictionary(); else dictionary = new Dictionary(comparer); FillDictionary(items, keyGenerator, valueGenerator, dictionary); return dictionary; } public static bool TryFindByValue( IDictionary dictionary, TValue value, IEqualityComparer valueComparer, out TKey key) { foreach (var kvp in dictionary) { var candidateValue = kvp.Value; if (valueComparer.Equals(value, candidateValue)) { key = kvp.Key; return true; } } key = default(TKey); return false; } internal static string EXECUTION_ENVIRONMENT_ENVVAR = "AWS_EXECUTION_ENV"; internal static string GetExecutionEnvironment() { return Environment.GetEnvironmentVariable(EXECUTION_ENVIRONMENT_ENVVAR); } private static string GetExecutionEnvironmentUserAgentString() { string userAgentString = ""; string executionEnvValue = GetExecutionEnvironment(); if (!string.IsNullOrEmpty(executionEnvValue)) { userAgentString = string.Format(CultureInfo.InvariantCulture, "exec-env/{0}", executionEnvValue); } return userAgentString; } /// /// Tests if the filePath is rooted with the directoryPath when resolved. The filePath and /// directoryPath do not need to exist to call this method. /// /// The filePath to test against the directoryPath. /// The directoryPath to use as root in the test. /// true if directoryPath is root of filePath else false public static bool IsFilePathRootedWithDirectoryPath(string filePath, string directoryPath) { //Construct a local directory path that always ends with the directory separator char. This //ensures our directory starts with test doesn't allow files that start with the directory //to be popped off the path to fake out the test: //LocalDirectory = a\b\c //FilePath = a\b\c\..\ctest.txt var dirTestPath = directoryPath; if (!dirTestPath.EndsWith(Path.DirectorySeparatorChar.ToString())) { dirTestPath += Path.DirectorySeparatorChar; } var dirInfo = new DirectoryInfo(dirTestPath); var fileInfo = new FileInfo(filePath); //Test if the target file is a child of directoryPath return fileInfo.FullName.StartsWith(dirInfo.FullName); } //Since .net 35 doesn't have Zip functionality, this is a custom implementation that does the same thing as LINQ's zip method. internal static IEnumerable Zip(IEnumerable first, IEnumerable second, Func resultSelector) { using (var enumerator1 = first.GetEnumerator()) using (var enumerator2 = second.GetEnumerator()) { while (enumerator1.MoveNext() && enumerator2.MoveNext()) { yield return resultSelector(enumerator1.Current, enumerator2.Current); } } } #region IsSet methods /* Set Collection True -> set to empty AlwaysSend* False -> set to empty collection type Value type True -> set to default(T) False -> set to null Get Collection Field is AlwaysSend* OR has items -> True Otherwise -> False Value type Field is any value -> True Null -> False */ public static void SetIsSet(bool isSet, ref Nullable field) where T : struct { if (isSet) field = default(T); else field = null; } public static void SetIsSet(bool isSet, ref List field) { if (isSet) field = new AlwaysSendList(field); else field = new List(); } public static void SetIsSet(bool isSet, ref Dictionary field) { if (isSet) field = new AlwaysSendDictionary(field); else field = new Dictionary(); } public static bool GetIsSet(Nullable field) where T : struct { return (field.HasValue); } public static bool GetIsSet(List field) { if (field == null) return false; if (field.Count > 0) return true; var sl = field as AlwaysSendList; if (sl != null) return true; return false; } public static bool GetIsSet(Dictionary field) { if (field == null) return false; if (field.Count > 0) return true; var sd = field as AlwaysSendDictionary; if (sd != null) return true; return false; } #endregion } }