public async void ShouldThrowInvalidOpEx_WhenConfigAlreadyExists() { var dict = await _service.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(CoreService.KvpDictionaryName); KvpConfig config = null; using (var tx = new MockTransaction()) { config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; var key = new ConfigKey(config); await dict.TryAddAsync(tx, key, config); await tx.CommitAsync(); } KvpConfig newconfig = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; await Assert.ThrowsAnyAsync <InvalidOperationException>(() => _service.AddConfigSetting(newconfig)); }
public async void ShouldNotGetNonExistantKvpConfig() { var dict = await _service.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(CoreService.KvpDictionaryName); KvpConfig config = null; using (var tx = new MockTransaction()) { config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; var key = new ConfigKey(config); await dict.TryAddAsync(tx, key, config); await tx.CommitAsync(); } if (await dict.GetCountAsync(new MockTransaction()) != 1) { Assert.False(true, "The config key was not saved. The test will not proceed"); } var val = await _service.GetConfigSetting(new ConfigKey("NotAKey", "1.0.0")); Assert.True(val == null, "The service returned a response.... That ain't right"); }
public async Task <KvpConfig> GetLatestConfigSetting(string name) { var kvpDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(KvpDictionaryName); KvpConfig config = null; using (var tx = this.StateManager.CreateTransaction()) { var asyncEnumerable = await kvpDictionary.CreateEnumerableAsync(tx); var kvps = asyncEnumerable.GetAsyncEnumerator(); SemVer greatestRelease = null; while (await kvps.MoveNextAsync(new CancellationToken())) { var kvp = kvps.Current; if (kvp.Key.Name != name) { continue; } if (greatestRelease == null) { greatestRelease = new SemVer(kvp.Key.Version); } var version = new SemVer(kvp.Key.Version); if (greatestRelease < version) { greatestRelease = version; config = (KvpConfig)kvp.Value; } } } return(config); }
///<summary> ///Backs up config settings to mongodb store. Currently abandons all hope of saving if an exception is thrown. that's what ///stateful services are for anyways right? lol ///</summary> //TODO add some way to add failures to a queue of shit that needs to be backed up private async Task BackupConfigSetting(KvpConfig config) { var db = DbClient.GetDatabase(_backupDbName); var collection = db.GetCollection <BsonDocument>(_backupKvpCollection); var toInsert = new BsonDocument { { "Type", config.Type }, { "Value", config.Value }, { "Name", config.Name }, { "Version", config.Version }, }; try { var exists = await collection.FindAsync(toInsert); if (exists.Any()) { _logger.Log(LogLevel.Warning, 0, $"Attempted to backup a config which already exists {config.Name}: {config.Value}. Aborting", null, (msg, exx) => msg); return; } await collection.InsertOneAsync(toInsert); } catch (Exception ex) { _logger.Log(LogLevel.Error, 0, "Exception of type {0} occured while saving config to backup: {1} | {2}", ex, (msg, exx) => String.Format(msg, exx.Message, exx.Source, exx.StackTrace)); } }
public void BasicUpdater_ShouldRetrieveNewerConfig() { KvpConfig older_config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; KvpConfig config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.1.0" }; var providerMock = new Mock <IKvpConfigService>(); providerMock.Setup(svc => svc.GetLatestConfigSetting(It.Is <string>(x => x == "Test"))).Returns(Task <KvpConfig> .FromResult(config)); var logger = new Mock <ILogger>().Object; var updateTarget = new Dictionary <string, KvpConfig>() { ["Test"] = older_config }; var basicUpdater = new BasicConfigUpdateStrategy(providerMock.Object, logger, TimeSpan.FromHours(6), new List <string>() { "Test" }, updateTarget); basicUpdater.TriggerUpdates(); Assert.True(updateTarget.Keys.Count == 1); Assert.True(updateTarget["Test"].Version == "1.1.0"); }
public async Task AddConfigSetting(KvpConfig config) { var kvpDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(KvpDictionaryName); bool saved = false; using (var tx = this.StateManager.CreateTransaction()) { var configValue = await kvpDictionary.TryGetValueAsync(tx, new ConfigKey(config)); if (configValue.HasValue) { string msg = $"You are trying to add a config for which the SemVer you specified already exists: {config.Name}, {config.Version}. That is not allowed"; _logger.Log(LogLevel.Error, 0, msg, null, (ms, ex) => ms); tx.Abort(); throw new InvalidOperationException(msg); } else { await kvpDictionary.AddAsync(tx, new ConfigKey(config), new KvpConfig(config)); await tx.CommitAsync(); saved = true; } } if (saved) { Task.Run(async() => await this.BackupConfigSetting(config)); } }
public async void ShouldAdd_IncrementedVersion() { if (!_fixture.RunTheseTests) { return; } KvpConfig config = new KvpConfig() { Value = "new test", Name = "Test", Type = "String", Version = "1.1.0" }; await Client.AddConfigSetting(config); var val = await Client.GetConfigSetting(new ConfigKey(config)); Assert.True(val != null, "The client didnt get the new config...."); var old_val = await Client.GetConfigSetting(new ConfigKey("Test", "1.0.0")); Assert.True(old_val != null, "The old configuration key doesn't exist..."); Assert.True(old_val.Value != val.Value, "We added a new config but didn't update the value...."); Assert.True(val.Value == "new test", "We added a new config but didn't update the value...."); //Cleanup -- reset all internal and external state await Client.DeleteConfigSetting(new ConfigKey(config)); }
public async void ShouldNot_RetrieveConfigWhichDoesntExist() { if (!_fixture.RunTheseTests) { return; } KvpConfig config = new KvpConfig() { Value = "Test2", Name = "sfajslkfjds", Type = "String", Version = "1.0.0" }; var val = await Client.GetConfigSetting(new ConfigKey(config)); Assert.True(val == null, "The client retrieved something...."); }
protected override async Task RunAsync(CancellationToken cancellationToken) { var kvpDictionary = await this.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(KvpDictionaryName); long result = 0; using (var tx = this.StateManager.CreateTransaction()) { //do we have any values? Should we get from backup? result = await kvpDictionary.GetCountAsync(tx); } //get from backup nosql store if (result == 0) { ServiceEventSource.Current.ServiceMessage(this.Context, "No config values found, updating from backup: {0}", DateTime.UtcNow); var db = DbClient.GetDatabase(_backupDbName); var kvpCollection = db.GetCollection <BsonDocument>(_backupKvpCollection); var kvps = await kvpCollection.Find(new BsonDocument()).ToListAsync(); //var temp = await kvpCollection.CountAsync(new BsonDocument()); foreach (var config in kvps) { using (var tx = this.StateManager.CreateTransaction()) { var name = config.GetValue("Name").AsString; var version = config.GetValue("Version").AsString; var type = config.GetValue("Type").AsString; var value = config.GetValue("Value").AsString; var x = new KvpConfig() { Name = name, Version = version, Type = type, Value = value }; var key = new ConfigKey(name, version); await kvpDictionary.AddAsync(tx, key, x); await tx.CommitAsync(); } } } }
public async void ShouldRetrieveConfig() { if (!_fixture.RunTheseTests) { return; } KvpConfig config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; var val = await Client.GetConfigSetting(new ConfigKey(config)); Assert.True(val != null, "The test config was not retrieved..."); Assert.True(val.Version == config.Version, "The retrieved value did not match expected"); Assert.True(val.Name == config.Name, "The retrieved value did not match expected"); Assert.True(val.Type == config.Type, "The retrieved value did not match expected"); Assert.True(val.Value == config.Value, "The retrieved value did not match expected"); }
public async void ShouldGetLatestKvpConfigByName() { var dict = await _service.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(CoreService.KvpDictionaryName); KvpConfig config = null; using (var tx = new MockTransaction()) { config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.1.0" }; var key = new ConfigKey(config); await dict.TryAddAsync(tx, key, config); var config2 = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; var key2 = new ConfigKey(config2); await dict.TryAddAsync(tx, key2, config2); await tx.CommitAsync(); } if (await dict.GetCountAsync(new MockTransaction()) != 2) { Assert.False(true, "The config key was not saved. The test will not proceed"); } var val = await _service.GetLatestConfigSetting("Test"); Assert.True(val != null, "The srevice returned a null response. That ain't right"); Assert.True(val.Equals(config), "The service returned a value but it did not equal the stored config"); }
public async void ShouldDeleteConfig() { if (!_fixture.RunTheseTests) { return; } KvpConfig config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; await Client.DeleteConfigSetting(new ConfigKey("Test", "1.0.0")); var val = await Client.GetConfigSetting(new ConfigKey("Test", "1.0.0")); Assert.True(val == null, "The client didnt delete the config...."); //Cleanup -- reset all internal and external state await Client.AddConfigSetting(config); }
public async void ShouldSaveConfig() { var dict = new MockReliableDictionary <ConfigKey, KvpConfig>(); using (var tx = new MockTransaction()) { var config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; var key = new ConfigKey(config); await dict.TryAddAsync(tx, key, config); await tx.CommitAsync(); } using (var tx = new MockTransaction()) { var config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; var key = new ConfigKey(config); var val = await dict.TryGetValueAsync(tx, key); Assert.True(val.HasValue); Assert.Equal(val.Value.Name, config.Name); Assert.Equal(val.Value.Type, config.Type); Assert.Equal(val.Value.Version, config.Version); Assert.Equal(val.Value.Value, config.Value); } }
public async void ShouldAddNewConfig() { KvpConfig config = new KvpConfig() { Value = "Test", Name = "Test", Type = "String", Version = "1.0.0" }; await _service.AddConfigSetting(config); var dict = await _service.StateManager.GetOrAddAsync <IReliableDictionary <ConfigKey, KvpConfig> >(CoreService.KvpDictionaryName); if (await dict.GetCountAsync(new MockTransaction()) != 1) { Assert.False(true, "The config key was not saved. The test will not proceed"); } var val = await _service.GetConfigSetting(new ConfigKey("Test", "1.0.0")); Assert.True(val.Name == config.Name, "The config value saved was not equal to that passed into the service"); Assert.True(val.Version == config.Version, "The config value saved was not equal to that passed into the service"); Assert.True(val.Type == config.Type, "The config value saved was not equal to that passed into the service"); Assert.True(val.Value == config.Value, "The config value saved was not equal to that passed into the service"); }
public async Task AddConfigSetting(KvpConfig config) { await _fabricProvider.AddConfigSetting(config); }