/// <summary> /// Gets the document client. /// </summary> /// <returns>The document client.</returns> /// <remarks> /// <para>This operation ensures that the database configuration is current before returning the client. This is /// an expensive operation if the configuration has changed by another process because the database must be /// updated to reflect the changes. In practice, configuration should not be changing if this class is reused /// for the life time of an application. /// </para> /// <para>The config update process is run synchronously.</para> /// </remarks> internal IDocumentClient GetClient() { if (!_started) { throw new NebulaServiceException("Document DB services have not been started"); } _configManager.EnsureConfigCurrent(_client, _dbConfig); return(_client); }
public async void EnsureConfigCurrentWithUnchangedSignature() { var dbConfig = CreateDbConfig(); string signature = "sig"; var configDoc = CreateConfigDoc("Test", signature); _signatureGenerator.CreateSignature(Arg.Any <IList <DocumentStoreConfig> >()).Returns(signature); _documentClient.ReadDocumentAsync(Arg.Any <Uri>(), Arg.Is <RequestOptions>(x => x.PartitionKey != null)).Returns(WrapResource(configDoc)); // Existing index that should remain. var includeIdx1 = new IncludedPath(); includeIdx1.Path = "/content_Test_StoreA_DocA/*"; includeIdx1.Indexes.Add(new HashIndex(DataType.String, -1)); // Existing index that should be removed. It is no longer present. var includeIdx2 = new IncludedPath(); includeIdx2.Path = "/content_Test_StoreB_DocA/PropA/*"; includeIdx2.Indexes.Add(new RangeIndex(DataType.String)); var manager = new ServiceDbConfigManager("Test", _signatureGenerator); _documentClient.UpsertDocumentAsync(Arg.Any <Uri>(), Arg.Is <Document>(x => x.GetPropertyValue <string>("Signature") == signature)) .Returns(WrapResource(CreateConfigDoc(configDoc.Id, signature))); manager.RegisterStoreConfigSource(CreateConfigSource("A")); manager.RegisterStoreConfigSource(CreateConfigSource("B")); manager.EnsureConfigCurrent(_documentClient, dbConfig); await AssertNoUpdateTriggered(); }
private async Task EnsureStoreConfigCurrentAsync(IEnumerable <IDocumentStoreConfigSource> storeConfigSources) { foreach (var source in storeConfigSources) { _configManager.RegisterStoreConfigSource(source); } await _configManager.EnsureConfigCurrent(_client, _dbConfig); }
public void EnsureConfigCurrentThrowsForSignatureFailure() { var dbConfig = CreateDbConfig(); var configDoc = CreateConfigDoc("Test", "sig"); _signatureGenerator.CreateSignature(Arg.Any <IList <DocumentStoreConfig> >()).Throws(new Exception()); _documentClient.ReadDocumentAsync(Arg.Any <Uri>()).Returns(WrapResource(configDoc)); var manager = new ServiceDbConfigManager("Test", _signatureGenerator); manager.RegisterStoreConfigSource(_configSourceA); var ex = Assert.Throws <NebulaConfigException>(() => manager.EnsureConfigCurrent(_documentClient, dbConfig)); Assert.Contains("signature generation failed", ex.Message); }
public async void EnsureConfigCurrentWithDuplicateStoreConfigRegistrationsAndNoSignatureChange() { var dbConfig = CreateDbConfig(); var configDoc = CreateConfigDoc("Test", "sig"); _signatureGenerator.CreateSignature(Arg.Any <IList <DocumentStoreConfig> >()).Returns("sig"); _documentClient.ReadDocumentAsync(Arg.Any <Uri>(), Arg.Is <RequestOptions>(x => x.PartitionKey != null)).Returns(WrapResource(configDoc)); var manager = new ServiceDbConfigManager("Test", _signatureGenerator); manager.RegisterStoreConfigSource(CreateConfigSource("A")); manager.RegisterStoreConfigSource(CreateConfigSource("A")); manager.EnsureConfigCurrent(_documentClient, dbConfig); await AssertNoUpdateTriggered(); }
public async void EnsureConfigCurrentWithChangedSignature() { var dbConfig = CreateDbConfig(); string oldSig = "old_sig"; string newSig = "new_sig"; var configDoc = CreateConfigDoc("Test", oldSig); DocumentStoreConfigBuilder storeABuilder = new DocumentStoreConfigBuilder("StoreA"); storeABuilder.AddDocument("DocA"); DocumentStoreConfigBuilder storeBBuilder = new DocumentStoreConfigBuilder("StoreB"); storeBBuilder.AddDocument("DocA"); storeBBuilder.AddDocument("DocB"); var configSourceA = CreateConfigSource(storeABuilder); var configSourceB = CreateConfigSource(storeBBuilder); _signatureGenerator.CreateSignature(Arg.Any <IList <DocumentStoreConfig> >()).Returns(newSig); _documentClient.ReadDocumentAsync(Arg.Any <Uri>(), Arg.Is <RequestOptions>(x => x.PartitionKey != null)).Returns(WrapResource(configDoc)); // Existing index that should remain. var includeIdx1 = new IncludedPath(); includeIdx1.Path = "/content_Test_StoreA_DocA/*"; includeIdx1.Indexes.Add(new HashIndex(DataType.String, -1)); // Existing index that should be removed. It is no longer present. var includeIdx2 = new IncludedPath(); includeIdx2.Path = "/content_Test_StoreB_DocA/PropA/*"; includeIdx2.Indexes.Add(new RangeIndex(DataType.String)); var col1 = new DocumentCollection(); col1.IndexingPolicy.IncludedPaths.Add(includeIdx1); col1.IndexingPolicy.IncludedPaths.Add(includeIdx2); _documentClient.ReadDocumentCollectionAsync(Arg.Any <Uri>()).Returns(WrapResource(col1)); var manager = new ServiceDbConfigManager("Test", _signatureGenerator); var foo = WrapResource(col1); _documentClient.ReplaceDocumentCollectionAsync(Arg.Any <DocumentCollection>(), Arg.Any <RequestOptions>()).Returns(foo); _documentClient.UpsertDocumentAsync( Arg.Any <Uri>(), Arg.Is <object>(r => ((ServiceDbConfigManager.ServiceConfigRecord)r).Signature == newSig), Arg.Any <RequestOptions>()) .Returns(WrapResource(CreateConfigDoc(configDoc.Id, newSig))); manager.RegisterStoreConfigSource(configSourceA); manager.RegisterStoreConfigSource(configSourceB); manager.EnsureConfigCurrent(_documentClient, dbConfig); await _documentClient.Received(1).UpsertDocumentAsync(Arg.Any <Uri>(), Arg.Any <object>(), Arg.Any <RequestOptions>()); await _documentClient.Received().ReplaceDocumentCollectionAsync( Arg.Is <DocumentCollection>(c => IncludedPathCheck( c.IndexingPolicy.IncludedPaths, "/content_Test_StoreA_DocA/*", "/content_Test_StoreB_DocA/*", "/content_Test_StoreB_DocB/*")), Arg.Any <RequestOptions>()); }