public async Task BatchOperationDiagnostic(bool disableDiagnostics) { string pkValue = "DiagnosticTestPk"; TransactionalBatch batch = this.Container.CreateTransactionalBatch(new PartitionKey(pkValue)); BatchCore batchCore = (BatchCore)batch; List <PatchOperation> patch = new List <PatchOperation>() { PatchOperation.Remove("/cost") }; List <ToDoActivity> createItems = new List <ToDoActivity>(); for (int i = 0; i < 50; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkValue); createItems.Add(item); batch.CreateItem <ToDoActivity>(item); } for (int i = 0; i < 20; i++) { batch.ReadItem(createItems[i].id); batchCore.PatchItem(createItems[i].id, patch); } TransactionalBatchRequestOptions requestOptions = disableDiagnostics ? RequestOptionDisableDiagnostic : null; TransactionalBatchResponse response = await batch.ExecuteAsync(requestOptions); Assert.IsNotNull(response); CosmosDiagnosticsTests.VerifyPointDiagnostics( diagnostics: response.Diagnostics, disableDiagnostics: disableDiagnostics); }
public async Task ExecuteAsync(Container collection) { EnsureArg.IsNotNull(collection, nameof(collection)); // Detect if registry has been initialized var partitionKey = new PartitionKey(SearchParameterStatusWrapper.SearchParameterStatusPartitionKey); var query = _queryFactory.Create <dynamic>( collection, new CosmosQueryContext( new QueryDefinition($"SELECT TOP 1 * FROM c where c.{KnownDocumentProperties.PartitionKey} = '{SearchParameterStatusWrapper.SearchParameterStatusPartitionKey}'"), new QueryRequestOptions { PartitionKey = partitionKey })); var results = await query.ExecuteNextAsync(); if (!results.Any()) { var statuses = await _filebasedRegistry.GetSearchParameterStatuses(); foreach (var batch in statuses.TakeBatch(100)) { TransactionalBatch transaction = collection.CreateTransactionalBatch(partitionKey); foreach (SearchParameterStatusWrapper status in batch.Select(x => x.ToSearchParameterStatusWrapper())) { transaction.CreateItem(status); } await transaction.ExecuteAsync(); } } }
public async Task NoContentResponseTransactionBatchOverrideTest() { string pkId = "TestBatchId"; TransactionalBatch batch = this.containerWithFlag.CreateTransactionalBatch(new PartitionKey(pkId)); TransactionalBatchItemRequestOptions requestOptions = new TransactionalBatchItemRequestOptions() { EnableContentResponseOnWrite = false }; int noResponseItemCount = 100; for (int i = 0; i < noResponseItemCount; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId); batch.CreateItem <ToDoActivity>(item, requestOptions: requestOptions); } TransactionalBatchResponse response = await batch.ExecuteAsync(); Assert.AreEqual(response.Count, 100); foreach (TransactionalBatchOperationResult itemResponse in response) { Assert.IsTrue(itemResponse.StatusCode == HttpStatusCode.Created); Assert.IsNull(itemResponse.ResourceStream); } }
public override TransactionalBatch CreateItemStream( Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { if (requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions && encryptionItemRequestOptions.EncryptionOptions != null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { streamPayload = EncryptionProcessor.EncryptAsync( streamPayload, this.encryptor, encryptionItemRequestOptions.EncryptionOptions, diagnosticsContext, cancellationToken: default).Result; } } this.transactionalBatch = this.transactionalBatch.CreateItemStream( streamPayload, requestOptions); return(this); }
internal static async Task ExecuteOperationsAsync <TOperation>(this TransactionalBatch transactionalBatch, Dictionary <int, TOperation> operationMappings, PartitionKeyPath partitionKeyPath, CancellationToken cancellationToken = default) where TOperation : IOperation { foreach (var operation in operationMappings.Values) { operation.Apply(transactionalBatch, partitionKeyPath); } using (var batchOutcomeResponse = await transactionalBatch.ExecuteAsync(cancellationToken).ConfigureAwait(false)) { for (var i = 0; i < batchOutcomeResponse.Count; i++) { var result = batchOutcomeResponse[i]; operationMappings.TryGetValue(i, out var operation); IOperation operationToBeExecuted = operation ?? ThrowOnConflictOperation.Instance; if (result.IsSuccessStatusCode) { operationToBeExecuted.Success(result); continue; } // guaranteed to throw operationToBeExecuted.Conflict(result); } } }
/// <inheritdoc /> public async ValueTask UpdateAsBatchAsync( IEnumerable <TItem> items, CancellationToken cancellationToken = default) { List <TItem> list = items.ToList(); string partitionKey = GetPartitionKeyValue(list); Container container = await _containerProvider.GetContainerAsync(); TransactionalBatch batch = container.CreateTransactionalBatch(new PartitionKey(partitionKey)); foreach (TItem item in list) { TransactionalBatchItemRequestOptions options = new(); if (item is IItemWithEtag itemWithEtag) { options.IfMatchEtag = itemWithEtag.Etag; } batch.UpsertItem(item, options); } using TransactionalBatchResponse response = await batch.ExecuteAsync(cancellationToken); if (!response.IsSuccessStatusCode) { throw new BatchOperationException <TItem>(response); } }
private static async Task VerifyExceptionThrownOnExecuteAsync( TransactionalBatch batch, Type expectedTypeOfException, string expectedExceptionMessage = null, RequestOptions requestOptions = null) { bool wasExceptionThrown = false; try { if (requestOptions != null) { await((BatchCore)batch).ExecuteAsync(requestOptions); } else { await batch.ExecuteAsync(); } } catch (Exception ex) { Assert.AreEqual(expectedTypeOfException, ex.GetType()); if (expectedExceptionMessage != null) { Assert.IsTrue(ex.Message.Contains(expectedExceptionMessage)); } wasExceptionThrown = true; } if (!wasExceptionThrown) { Assert.Fail("Exception was expected to be thrown but was not."); } }
public async Task TestDispose() { CosmosClient cosmosClient = new CosmosClient(ConnectionString); Database database = cosmosClient.GetDatabase("asdf"); Container container = cosmosClient.GetContainer("asdf", "asdf"); TransactionalBatch batch = container.CreateTransactionalBatch(new PartitionKey("asdf")); batch.ReadItem("Test"); FeedIterator <dynamic> feedIterator1 = container.GetItemQueryIterator <dynamic>(); FeedIterator <dynamic> feedIterator2 = container.GetItemQueryIterator <dynamic>(queryText: "select * from T"); FeedIterator <dynamic> feedIterator3 = database.GetContainerQueryIterator <dynamic>(queryText: "select * from T"); string userAgent = cosmosClient.ClientContext.UserAgent; // Dispose should be idempotent cosmosClient.Dispose(); cosmosClient.Dispose(); List <Func <Task> > validateAsync = new List <Func <Task> >() { () => cosmosClient.ReadAccountAsync(), () => cosmosClient.CreateDatabaseAsync("asdf"), () => database.CreateContainerAsync("asdf", "/pkpathasdf", 200), () => container.ReadItemAsync <dynamic>("asdf", new PartitionKey("test")), () => container.Scripts.ReadStoredProcedureAsync("asdf"), () => container.Scripts.ReadTriggerAsync("asdf"), () => container.Scripts.ReadUserDefinedFunctionAsync("asdf"), () => batch.ExecuteAsync(), () => feedIterator1.ReadNextAsync(), () => feedIterator2.ReadNextAsync(), () => feedIterator3.ReadNextAsync(), }; foreach (Func <Task> asyncFunc in validateAsync) { try { await asyncFunc(); Assert.Fail("Should throw ObjectDisposedException"); } catch (CosmosObjectDisposedException e) { string expectedMessage = $"Cannot access a disposed 'CosmosClient'. Follow best practices and use the CosmosClient as a singleton." + $" CosmosClient was disposed at: {cosmosClient.DisposedDateTimeUtc.Value.ToString("o", CultureInfo.InvariantCulture)}; CosmosClient Endpoint: https://localtestcosmos.documents.azure.com/; Created at: {cosmosClient.ClientConfigurationTraceDatum.ClientCreatedDateTimeUtc.ToString("o", CultureInfo.InvariantCulture)}; UserAgent: {userAgent};"; Assert.IsTrue(e.Message.Contains(expectedMessage)); string diagnostics = e.Diagnostics.ToString(); Assert.IsNotNull(diagnostics); Assert.IsFalse(diagnostics.Contains("NoOp")); Assert.IsTrue(diagnostics.Contains("Client Configuration")); string exceptionString = e.ToString(); Assert.IsTrue(exceptionString.Contains(diagnostics)); Assert.IsTrue(exceptionString.Contains(e.Message)); Assert.IsTrue(exceptionString.Contains(e.StackTrace)); } } }
public EncryptionTransactionalBatch( TransactionalBatch transactionalBatch, Encryptor encryptor, CosmosSerializer cosmosSerializer) { this.transactionalBatch = transactionalBatch ?? throw new ArgumentNullException(nameof(transactionalBatch)); this.encryptor = encryptor ?? throw new ArgumentNullException(nameof(encryptor)); this.cosmosSerializer = cosmosSerializer ?? throw new ArgumentNullException(nameof(cosmosSerializer)); }
public override TransactionalBatch ReadItem( string id, TransactionalBatchItemRequestOptions requestOptions = null) { this.transactionalBatch = this.transactionalBatch.ReadItem( id, requestOptions); return(this); }
public async Task ItemBatchNoResponseTest() { TransactionalBatchItemRequestOptions requestOptions = new TransactionalBatchItemRequestOptions() { EnableContentResponseOnWrite = false }; string pkId = "TestBatchId"; TransactionalBatch batch = this.container.CreateTransactionalBatch(new PartitionKey(pkId)); int noResponseItemCount = 100; for (int i = 0; i < noResponseItemCount; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId); batch.CreateItem <ToDoActivity>(item, requestOptions: requestOptions); } TransactionalBatchResponse response = await batch.ExecuteAsync(); Assert.AreEqual(100, response.Count); this.ValidateResponse(response, noResponseItemCount); pkId = "TestBatchId2"; batch = this.container.CreateTransactionalBatch(new PartitionKey(pkId)); noResponseItemCount = 0; for (int i = 0; i < 10; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId); batch.CreateItem <ToDoActivity>(item, requestOptions: requestOptions); noResponseItemCount++; ToDoActivity item2 = ToDoActivity.CreateRandomToDoActivity(pk: pkId); item2.id = item.id; batch.ReplaceItem <ToDoActivity>(item2.id, item2, requestOptions); noResponseItemCount++; } int withBodyCount = 0; for (int i = 0; i < 5; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkId); batch.CreateItem <ToDoActivity>(item); withBodyCount++; batch.ReadItem(item.id); withBodyCount++; } response = await batch.ExecuteAsync(); Assert.AreEqual(noResponseItemCount + withBodyCount, response.Count); this.ValidateResponse(response, noResponseItemCount); }
public EncryptionTransactionalBatch( TransactionalBatch transactionalBatch, EncryptionContainer encryptionContainer, CosmosSerializer cosmosSerializer) { this.transactionalBatch = transactionalBatch ?? throw new ArgumentNullException(nameof(transactionalBatch)); this.encryptionContainer = encryptionContainer ?? throw new ArgumentNullException(nameof(encryptionContainer)); this.cosmosSerializer = cosmosSerializer ?? throw new ArgumentNullException(nameof(cosmosSerializer)); this.encryptionDiagnosticsContext = new EncryptionDiagnosticsContext(); this.encryptionDiagnosticsContext.Begin(Constants.DiagnosticsEncryptOperation); }
private TransactionalBatch InsertAllDocuments(TransactionalBatch batch) { TransactionalBatch result = batch; foreach (var shop in CreateShopList()) { result.CreateItem <Shop>(shop); Console.WriteLine($"Added shop to batch request: {shop.Name}"); } return(result); }
public override void Apply(TransactionalBatch transactionalBatch, PartitionKeyPath partitionKeyPath) { var jObject = ToEnrichedJObject(partitionKeyPath); // has to be kept open stream = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jObject))); var options = new TransactionalBatchItemRequestOptions { EnableContentResponseOnWrite = false }; transactionalBatch.CreateItemStream(stream, options); }
internal static async Task ExecuteAndDisposeOperationsAsync <TOperation>(this TransactionalBatch transactionalBatch, Dictionary <int, TOperation> operationMappings, PartitionKeyPath partitionKeyPath, CancellationToken cancellationToken = default) where TOperation : IOperation { try { await transactionalBatch.ExecuteOperationsAsync(operationMappings, partitionKeyPath, cancellationToken) .ConfigureAwait(false); } finally { foreach (var operation in operationMappings.Values) { operation.Dispose(); } } }
private TransactionalBatch CreateStaleBatch(TransactionalBatch batch, string location, string index) { if (batch == null) { batch = _transactionContainer.CreateTransactionalBatch(new PartitionKey(location)); } var transaction = Fetch(location, index); if (transaction == null) { return(batch); } transaction.Stale = true; return(null); // return batch.ReplaceItem(transaction.Id, transaction); }
public override TransactionalBatch CreateItem <T>( T item, TransactionalBatchItemRequestOptions requestOptions = null) { if (!(requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions) || encryptionItemRequestOptions.EncryptionOptions == null) { this.transactionalBatch = this.transactionalBatch.CreateItem( item, requestOptions); return(this); } Stream itemStream = this.cosmosSerializer.ToStream <T>(item); return(this.CreateItemStream( itemStream, requestOptions)); }
public override TransactionalBatch ReplaceItemStream( string id, Stream streamPayload, TransactionalBatchItemRequestOptions requestOptions = null) { CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions); using (diagnosticsContext.CreateScope("EncryptItemStream")) { streamPayload = this.encryptionProcessor.EncryptAsync( streamPayload, diagnosticsContext, default).Result; } this.transactionalBatch = this.transactionalBatch.ReplaceItemStream( id, streamPayload, requestOptions); return(this); }
public async Task ExecuteAsync(Container container, CancellationToken cancellationToken) { EnsureArg.IsNotNull(container, nameof(container)); // Detect if registry has been initialized var partitionKey = new PartitionKey(SearchParameterStatusWrapper.SearchParameterStatusPartitionKey); var query = _queryFactory.Create <dynamic>( container, new CosmosQueryContext( new QueryDefinition($"SELECT TOP 1 * FROM c where c.{KnownDocumentProperties.PartitionKey} = '{SearchParameterStatusWrapper.SearchParameterStatusPartitionKey}'"), new QueryRequestOptions { PartitionKey = partitionKey })); var results = await query.ExecuteNextAsync(cancellationToken); if (!results.Any()) { var statuses = await _filebasedSearchParameterStatusDataStore.GetSearchParameterStatuses(cancellationToken); foreach (var status in statuses.Where(x => _configuration.InitialSortParameterUris.Contains(x.Uri.OriginalString))) { status.SortStatus = SortParameterStatus.Enabled; } foreach (var batch in statuses.TakeBatch(100)) { TransactionalBatch transaction = container.CreateTransactionalBatch(partitionKey); foreach (SearchParameterStatusWrapper status in batch.Select(x => x.ToSearchParameterStatusWrapper())) { transaction.CreateItem(status); } await transaction.ExecuteAsync(cancellationToken); } } }
public async Task TestDispose() { CosmosClient cosmosClient = new CosmosClient(ConnectionString); Database database = cosmosClient.GetDatabase("asdf"); Container container = cosmosClient.GetContainer("asdf", "asdf"); TransactionalBatch batch = container.CreateTransactionalBatch(new PartitionKey("asdf")); batch.ReadItem("Test"); // Dispose should be idempotent cosmosClient.Dispose(); cosmosClient.Dispose(); List <Func <Task> > validateAsync = new List <Func <Task> >() { () => cosmosClient.ReadAccountAsync(), () => cosmosClient.CreateDatabaseAsync("asdf"), () => database.CreateContainerAsync("asdf", "/pkpathasdf", 200), () => container.ReadItemAsync <dynamic>("asdf", new PartitionKey("test")), () => container.Scripts.ReadStoredProcedureAsync("asdf"), () => container.Scripts.ReadTriggerAsync("asdf"), () => container.Scripts.ReadUserDefinedFunctionAsync("asdf"), () => batch.ExecuteAsync(), () => container.GetItemQueryIterator <dynamic>(queryText: "select * from T").ReadNextAsync(), () => container.GetItemQueryIterator <dynamic>().ReadNextAsync(), }; foreach (Func <Task> asyncFunc in validateAsync) { try { await asyncFunc(); Assert.Fail("Should throw ObjectDisposedException"); } catch (ObjectDisposedException) { } } }
internal static async Task ExecuteOperationAsync(this TransactionalBatch transactionalBatch, IOperation operation, PartitionKeyPath partitionKeyPath, CancellationToken cancellationToken = default) { operation.Apply(transactionalBatch, partitionKeyPath); using (var batchOutcomeResponse = await transactionalBatch.ExecuteAsync(cancellationToken).ConfigureAwait(false)) { if (batchOutcomeResponse.Count > 1) { throw new Exception($"The transactional batch was expected to have a single operation but contained {batchOutcomeResponse.Count} operations."); } var result = batchOutcomeResponse[0]; if (result.IsSuccessStatusCode) { operation.Success(result); return; } // guaranteed to throw operation.Conflict(result); } }
public async Task UpsertStatuses(IReadOnlyCollection <ResourceSearchParameterStatus> statuses) { EnsureArg.IsNotNull(statuses, nameof(statuses)); if (statuses.Count == 0) { return; } foreach (IEnumerable <ResourceSearchParameterStatus> statusBatch in statuses.TakeBatch(100)) { using IScoped <Container> clientScope = _containerScopeFactory.Invoke(); TransactionalBatch batch = clientScope.Value.CreateTransactionalBatch(new PartitionKey(SearchParameterStatusWrapper.SearchParameterStatusPartitionKey)); foreach (SearchParameterStatusWrapper status in statusBatch.Select(x => x.ToSearchParameterStatusWrapper())) { status.LastUpdated = Clock.UtcNow; batch.UpsertItem(status); } await batch.ExecuteAsync(); } }
async Task CreateOrUpdateInBatch(TransactionalBatch batch) { if (etag == null) { batch.CreateItemStream(ToStream(value)); } else { var options = new TransactionalBatchItemRequestOptions { IfMatchEtag = etag }; batch.ReplaceItemStream(TransactionEntityId, ToStream(value), options); } var response = await batch.ExecuteAsync().ConfigureAwait(false); if (!response.IsSuccessStatusCode) { throw new Exception(response.ToString()); } etag = response.Last().ETag; }
public async ValueTask DeleteAsBatchAsync( IEnumerable <TItem> items, CancellationToken cancellationToken = default) { List <TItem> list = items.ToList(); string partitionKey = GetPartitionKeyValue(list); Container container = await _containerProvider.GetContainerAsync(); TransactionalBatch batch = container.CreateTransactionalBatch(new PartitionKey(partitionKey)); foreach (TItem item in list) { batch.DeleteItem(item.Id); } using TransactionalBatchResponse response = await batch.ExecuteAsync(cancellationToken); if (!response.IsSuccessStatusCode) { throw new BatchOperationException <TItem>(response); } }
public async Task BatchOperationDiagnostic() { string pkValue = "DiagnosticTestPk"; TransactionalBatch batch = this.Container.CreateTransactionalBatch(new PartitionKey(pkValue)); List <ToDoActivity> createItems = new List <ToDoActivity>(); for (int i = 0; i < 50; i++) { ToDoActivity item = ToDoActivity.CreateRandomToDoActivity(pk: pkValue); createItems.Add(item); batch.CreateItem <ToDoActivity>(item); } for (int i = 0; i < 20; i++) { batch.ReadItem(createItems[i].id); } TransactionalBatchResponse response = await batch.ExecuteAsync(); Assert.IsNotNull(response); CosmosDiagnosticsTests.VerifyPointDiagnostics(response.Diagnostics); }
public override TransactionalBatch ReplaceItem <T>( string id, T item, TransactionalBatchItemRequestOptions requestOptions = null) { if (!(requestOptions is EncryptionTransactionalBatchItemRequestOptions encryptionItemRequestOptions) || encryptionItemRequestOptions.EncryptionOptions == null) { this.transactionalBatch = this.transactionalBatch.ReplaceItem( id, item, requestOptions); return(this); } using (Stream itemStream = this.cosmosSerializer.ToStream <T>(item)) { return(this.ReplaceItemStream( id, itemStream, requestOptions)); } }
public virtual void Apply(TransactionalBatch transactionalBatch, PartitionKeyPath partitionKeyPath) { WasApplied = true; AppliedBatch = transactionalBatch; }
public TestBatch(DbSerializerBase serializer, TransactionalBatch transactionalBatch, string partitionKey) : base(serializer, transactionalBatch, partitionKey, true) { }
public override void Apply(TransactionalBatch transactionalBatch, PartitionKeyPath partitionKeyPath) { }
public TransactionBatchContext(TransactionalBatch batch, Container applicationStateContainer, PartitionKey partitionKey) { this.Batch = batch; this.partitionKey = partitionKey; Container = applicationStateContainer; }