// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using AWS.Deploy.Common.Recipes.Validation; using Newtonsoft.Json; namespace AWS.Deploy.Common.Recipes { /// , and methods public partial class OptionSettingItem { public T? GetValue(IDictionary replacementTokens, IDictionary? displayableOptionSettings = null) { var value = GetValue(replacementTokens, displayableOptionSettings); return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value)); } public object GetValue(IDictionary replacementTokens, IDictionary? displayableOptionSettings = null) { if (_value != null) { return _value; } if (Type == OptionSettingValueType.Object) { var objectValue = new Dictionary(); foreach (var childOptionSetting in ChildOptionSettings) { var childValue = childOptionSetting.GetValue(replacementTokens); if ( displayableOptionSettings != null && displayableOptionSettings.TryGetValue(childOptionSetting.Id, out bool isDisplayable)) { if (!isDisplayable) continue; } objectValue[childOptionSetting.Id] = childValue; } return objectValue; } if (DefaultValue == null) { return string.Empty; } if (DefaultValue is string defaultValueString) { return ApplyReplacementTokens(replacementTokens, defaultValueString); } return DefaultValue; } public T? GetDefaultValue(IDictionary replacementTokens) { var value = GetDefaultValue(replacementTokens); if (value == null) { return default; } return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(value)); } public object? GetDefaultValue(IDictionary replacementTokens) { if (DefaultValue == null) { return null; } if (DefaultValue is string defaultValueString) { return ApplyReplacementTokens(replacementTokens, defaultValueString); } return DefaultValue; } /// /// Assigns a value to the OptionSettingItem. /// /// Value to assign /// Current deployment recommendation, may be used if the validator needs to consider properties other than itself /// /// Thrown if one or more determine /// is not valid. /// public async Task SetValue(IOptionSettingHandler optionSettingHandler, object valueOverride, IOptionSettingItemValidator[] validators, Recommendation recommendation, bool skipValidation) { if (!skipValidation) { foreach (var validator in validators) { var result = await validator.Validate(valueOverride, recommendation, this); if (!result.IsValid) { Validation.ValidationStatus = ValidationStatus.Invalid; Validation.ValidationMessage = result.ValidationFailedMessage?.Trim() ?? $"The value '{valueOverride}' is invalid for option setting '{Name}'."; Validation.InvalidValue = valueOverride; throw new ValidationFailedException(DeployToolErrorCode.OptionSettingItemValueValidationFailed, Validation.ValidationMessage); } } } if (AllowedValues != null && AllowedValues.Count > 0 && valueOverride != null && !AllowedValues.Contains(valueOverride.ToString() ?? "")) { Validation.ValidationStatus = ValidationStatus.Invalid; Validation.ValidationMessage = $"Invalid value for option setting item '{Name}'"; Validation.InvalidValue = valueOverride; throw new InvalidOverrideValueException(DeployToolErrorCode.InvalidValueForOptionSettingItem, Validation.ValidationMessage); } Validation.ValidationStatus = ValidationStatus.Valid; Validation.ValidationMessage = string.Empty; Validation.InvalidValue = null; try { if (valueOverride is bool || valueOverride is int || valueOverride is long || valueOverride is double || valueOverride is Dictionary || valueOverride is SortedSet) { _value = valueOverride; } else if (Type.Equals(OptionSettingValueType.KeyValue)) { var deserialized = JsonConvert.DeserializeObject>(valueOverride?.ToString() ?? ""); _value = deserialized; } else if (Type.Equals(OptionSettingValueType.List)) { var deserialized = JsonConvert.DeserializeObject>(valueOverride?.ToString() ?? ""); _value = deserialized; } else if (valueOverride is string valueOverrideString) { if (bool.TryParse(valueOverrideString, out var valueOverrideBool)) { _value = valueOverrideBool; } else if (int.TryParse(valueOverrideString, out var valueOverrideInt)) { _value = valueOverrideInt; } else { _value = valueOverrideString; } } else { var deserialized = JsonConvert.DeserializeObject>(JsonConvert.SerializeObject(valueOverride)); foreach (var childOptionSetting in ChildOptionSettings) { if (deserialized?.TryGetValue(childOptionSetting.Id, out var childValueOverride) ?? false) { await optionSettingHandler.SetOptionSettingValue(recommendation, childOptionSetting, childValueOverride, skipValidation: skipValidation); } } } } catch (JsonReaderException ex) { Validation.ValidationStatus = ValidationStatus.Invalid; Validation.ValidationMessage = $"The value you are trying to set is invalid."; Validation.InvalidValue = valueOverride; throw new UnsupportedOptionSettingType(DeployToolErrorCode.UnsupportedOptionSettingType, $"The value you are trying to set for the option setting '{Name}' is invalid.", ex); } } private object ApplyReplacementTokens(IDictionary replacementTokens, object defaultValue) { var defaultValueString = defaultValue?.ToString(); if (!string.IsNullOrEmpty(defaultValueString)) { if (Type != OptionSettingValueType.String) { foreach (var token in replacementTokens) { if (defaultValueString.Equals(token.Key)) defaultValue = token.Value; } } else { foreach (var token in replacementTokens) { defaultValueString = defaultValueString.Replace(token.Key, token.Value.ToString()); } defaultValue = defaultValueString; } } return defaultValue ?? string.Empty; } } }