/// <summary> /// overwrite all existing keys with the ones in <paramref name="keysToImport" /> /// </summary> /// <param name="keysToImport"></param> /// <returns></returns> public IResult ImportKeys(ICollection <ConfigEnvironmentKey> keysToImport) { // copy dict as backup var oldKeys = Keys.ToDictionary(_ => _.Key, _ => _.Value); try { var newKeys = keysToImport.ToDictionary(k => k.Key, k => k, StringComparer.OrdinalIgnoreCase); Created = true; Keys = newKeys; CapturedDomainEvents.Add(new EnvironmentKeysImported( Identifier, newKeys.Values .OrderBy(k => k.Key) .Select(k => ConfigKeyAction.Set(k.Key, k.Value, k.Description, k.Type)) .ToArray())); _keyPaths = null; return(Result.Success()); } catch (Exception) { // restore backup Keys = oldKeys; return(Result.Error("could not import all keys into this environment", ErrorCode.Undefined)); } }
/// <summary> /// Add or Update existing Variables, and record all events necessary for this action /// </summary> /// <param name="updatedKeys"></param> /// <returns></returns> public IResult ModifyVariables(IDictionary <string, string> updatedKeys) { if (updatedKeys is null || !updatedKeys.Any()) { return(Result.Error("null or empty variables given", ErrorCode.InvalidData)); } // record all new keys to remove in case of exception var recordedAdditions = new List <string>(); // maps key to old value - to revert back in case of exception var recordedUpdates = new Dictionary <string, string>(); try { foreach (var(key, value) in updatedKeys) { if (Variables.ContainsKey(key)) { recordedUpdates[key] = Variables[key]; Variables[key] = value; } else { recordedAdditions.Add(key); Variables[key] = value; } } // all items that have actually been added to or changed in this structure are saved as event // skipping those that may not be there anymore and reducing the Event-Size or skipping the event entirely var recordedChanges = recordedAdditions.Concat(updatedKeys.Keys).ToList(); if (recordedChanges.Any()) { CapturedDomainEvents.Add( new StructureVariablesModified( Identifier, recordedChanges.Select(k => ConfigKeyAction.Set(k, Variables[k])) .ToArray())); } return(Result.Success()); } catch (Exception) { foreach (var addedKey in recordedAdditions) { Variables.Remove(addedKey); } foreach (var(key, value) in recordedUpdates) { Variables[key] = value; } return(Result.Error("could not update all variables for this Structure", ErrorCode.Undefined)); } }
/// <summary> /// flag this environment as deleted, and create the appropriate events for that /// </summary> /// <returns></returns> public IResult Delete() { if (Deleted) { return(Result.Success()); } Created = false; Deleted = true; CapturedDomainEvents.Add(new EnvironmentDeleted(Identifier)); return(Result.Success()); }
/// <summary> /// Mark this Object as Created, and record all events necessary for this action /// </summary> /// <param name="keys"></param> /// <param name="variables"></param> /// <returns></returns> public IResult Create(IDictionary <string, string> keys, IDictionary <string, string> variables) { if (Created) { return(Result.Success()); } Created = true; Keys = keys.ToDictionary(pair => pair.Key, pair => pair.Value); Variables = variables.ToDictionary(pair => pair.Key, pair => pair.Value); CapturedDomainEvents.Add(new StructureCreated(Identifier, keys, variables)); return(Result.Success()); }
/// <summary> /// build this Configuration with the given time-parameters /// </summary> /// <param name="validFrom"></param> /// <param name="validTo"></param> /// <returns></returns> public IResult Build(DateTime?validFrom, DateTime?validTo) { Created = true; ValidFrom = validFrom; ValidTo = validTo; Built = false; Keys = new Dictionary <string, string>(); Json = null; ConfigurationVersion = (long)DateTime.UtcNow .Subtract(_unixEpoch) .TotalSeconds; CapturedDomainEvents.Add(new ConfigurationBuilt(Identifier, validFrom, validTo)); return(Result.Success()); }
/// <summary> /// Delete existing Variables, and record all events necessary for this action /// </summary> /// <param name="keysToRemove"></param> /// <returns></returns> public IResult DeleteVariables(ICollection <string> keysToRemove) { if (keysToRemove is null || !keysToRemove.Any()) { return(Result.Error("null or empty list given", ErrorCode.InvalidData)); } if (keysToRemove.Any(k => !Variables.ContainsKey(k))) { return(Result.Error("not all variables could be found in target structure", ErrorCode.NotFound)); } var removedKeys = new Dictionary <string, string>(keysToRemove.Count); try { foreach (var deletedKey in keysToRemove) { if (Variables.Remove(deletedKey, out var removedKey)) { removedKeys.Add(deletedKey, removedKey); } } // all items that have actually been removed from this structure are saved as event // skipping those that may not be there anymore and reducing the Event-Size or skipping the event entirely if (removedKeys.Any()) { CapturedDomainEvents.Add(new StructureVariablesModified( Identifier, removedKeys.Keys .Select(ConfigKeyAction.Delete) .ToArray())); } return(Result.Success()); } catch (Exception) { // restore all keys that have been removed without the operation successfully completing foreach (var(key, entry) in removedKeys) { Keys[key] = entry; } return(Result.Error("could not remove all variables from the structure", ErrorCode.Undefined)); } }
/// <summary> /// flag this environment as existing, and create the appropriate events for that /// </summary> /// <returns></returns> public IResult Create(bool isDefault = false) { if (Created) { return(Result.Success()); } Created = true; IsDefault = isDefault; if (IsDefault) { CapturedDomainEvents.Add(new DefaultEnvironmentCreated(Identifier)); } else { CapturedDomainEvents.Add(new EnvironmentCreated(Identifier)); } return(Result.Success()); }
/// <summary> /// add new, or change some of the held keys, and create the appropriate events for that /// </summary> /// <param name="keysToAdd"></param> /// <returns></returns> public IResult UpdateKeys(ICollection <ConfigEnvironmentKey> keysToAdd) { if (keysToAdd is null || !keysToAdd.Any()) { return(Result.Error("null or empty list given", ErrorCode.InvalidData)); } var addedKeys = new List <ConfigEnvironmentKey>(); var updatedKeys = new Dictionary <string, ConfigEnvironmentKey>(); try { foreach (var newEntry in keysToAdd) { if (Keys.ContainsKey(newEntry.Key)) { var oldEntry = Keys[newEntry.Key]; if (oldEntry.Description == newEntry.Description && oldEntry.Type == newEntry.Type && oldEntry.Value == newEntry.Value) { // if the key and all metadata is same before and after the change, // we might as well skip this change altogether continue; } updatedKeys.Add(newEntry.Key, Keys[newEntry.Key]); Keys[newEntry.Key] = newEntry; } else { addedKeys.Add(newEntry); Keys.Add(newEntry.Key, newEntry); } } // all items that have actually been added to or changed in this environment are saved as event // skipping those that may not be there anymore and reducing the Event-Size or skipping the event entirely // --- // updatedKeys maps key => oldValue, so the old value can be restored if something goes wrong // this means we have to get the current/new/overwritten state based on the updatedKeys.Keys var recordedChanges = addedKeys.Concat(updatedKeys.Keys.Select(k => Keys[k])) .ToList(); if (recordedChanges.Any()) { CapturedDomainEvents.Add( new EnvironmentKeysModified( Identifier, recordedChanges.Select(k => ConfigKeyAction.Set(k.Key, k.Value, k.Description, k.Type)) .ToArray())); } _keyPaths = null; return(Result.Success()); } catch (Exception) { foreach (var addedKey in addedKeys) { Keys.Remove(addedKey.Key); } foreach (var(key, value) in updatedKeys) { Keys[key] = value; } return(Result.Error("could not update all keys in the environment", ErrorCode.Undefined)); } }
public void AddEvent(DomainEvent e) => CapturedDomainEvents.Add(e);