public async Task BatchItemETagAsync() { Container container = BatchTestBase.JsonContainer; await this.CreateJsonTestDocsAsync(container); { TestDoc testDocToCreate = BatchTestBase.PopulateTestDoc(this.PartitionKey1); TestDoc testDocToReplace = this.GetTestDocCopy(this.TestDocPk1ExistingA); testDocToReplace.Cost++; ItemResponse <TestDoc> readResponse = await BatchTestBase.JsonContainer.ReadItemAsync <TestDoc>( this.TestDocPk1ExistingA.Id, BatchTestBase.GetPartitionKey(this.PartitionKey1)); BatchItemRequestOptions firstReplaceOptions = new BatchItemRequestOptions() { IfMatchEtag = readResponse.ETag }; BatchResponse batchResponse = await new BatchCore((ContainerCore)container, BatchTestBase.GetPartitionKey(this.PartitionKey1)) .CreateItem(testDocToCreate) .ReplaceItem(testDocToReplace.Id, testDocToReplace, requestOptions: firstReplaceOptions) .ExecuteAsync(); BatchSinglePartitionKeyTests.VerifyBatchProcessed(batchResponse, numberOfOperations: 2); Assert.AreEqual(HttpStatusCode.Created, batchResponse[0].StatusCode); Assert.AreEqual(HttpStatusCode.OK, batchResponse[1].StatusCode); await BatchTestBase.VerifyByReadAsync(container, testDocToCreate, eTag : batchResponse[0].ETag); await BatchTestBase.VerifyByReadAsync(container, testDocToReplace, eTag : batchResponse[1].ETag); } { TestDoc testDocToReplace = this.GetTestDocCopy(this.TestDocPk1ExistingB); testDocToReplace.Cost++; BatchItemRequestOptions replaceOptions = new BatchItemRequestOptions() { IfMatchEtag = BatchTestBase.Random.Next().ToString() }; BatchResponse batchResponse = await new BatchCore((ContainerCore)container, BatchTestBase.GetPartitionKey(this.PartitionKey1)) .ReplaceItem(testDocToReplace.Id, testDocToReplace, requestOptions: replaceOptions) .ExecuteAsync(); BatchSinglePartitionKeyTests.VerifyBatchProcessed( batchResponse, numberOfOperations: 1, expectedStatusCode: (HttpStatusCode)StatusCodes.MultiStatus); Assert.AreEqual(HttpStatusCode.PreconditionFailed, batchResponse[0].StatusCode); // ensure the document was not updated await BatchTestBase.VerifyByReadAsync(container, this.TestDocPk1ExistingB); } }
private bool Equals(BatchItemRequestOptions x, BatchItemRequestOptions y) { if (x == null && y == null) { return(true); } else if (x != null && y != null) { RequestMessage xMessage = new RequestMessage(); RequestMessage yMessage = new RequestMessage(); x.PopulateRequestOptions(xMessage); y.PopulateRequestOptions(yMessage); foreach (string headerName in xMessage.Headers) { if (xMessage.Headers[headerName] != yMessage.Headers[headerName]) { return(false); } } return(true); } return(false); }
public void FromItemRequestOptions_WithDefaultValues() { ItemRequestOptions itemRequestOptions = new ItemRequestOptions(); BatchItemRequestOptions batchItemRequestOptions = BatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); Assert.AreEqual(itemRequestOptions.IfMatchEtag, batchItemRequestOptions.IfMatchEtag); Assert.AreEqual(itemRequestOptions.IfNoneMatchEtag, batchItemRequestOptions.IfNoneMatchEtag); Assert.AreEqual(itemRequestOptions.IndexingDirective, batchItemRequestOptions.IndexingDirective); Assert.AreEqual(itemRequestOptions.Properties, batchItemRequestOptions.Properties); }
internal static BatchItemRequestOptions GetBatchItemRequestOptions(TestDoc doc, bool isSchematized, bool useEpk = false, int?ttlInSeconds = null) { BatchItemRequestOptions requestOptions = new BatchItemRequestOptions() { Properties = new Dictionary <string, object>() }; if (PopulateRequestOptions(requestOptions, doc, isSchematized, useEpk, ttlInSeconds)) { return(requestOptions); } return(null); }
private static void VerifyBatchItemRequestOptionsAreEqual(BatchItemRequestOptions expected, BatchItemRequestOptions actual) { if (expected != null) { Assert.AreEqual(expected.IfMatchEtag, actual.IfMatchEtag); Assert.AreEqual(expected.IfNoneMatchEtag, actual.IfNoneMatchEtag); if (expected.IndexingDirective.HasValue) { Assert.AreEqual(expected.IndexingDirective.Value, actual.IndexingDirective.Value); } else { Assert.IsTrue(!actual.IndexingDirective.HasValue); } if (expected.Properties != null) { Assert.IsNotNull(actual.Properties); if (expected.Properties.TryGetValue(WFConstants.BackendHeaders.BinaryId, out object expectedBinaryIdObj)) { byte[] expectedBinaryId = expectedBinaryIdObj as byte[]; Assert.IsTrue(actual.Properties.TryGetValue(WFConstants.BackendHeaders.BinaryId, out object actualBinaryIdObj)); byte[] actualBinaryId = actualBinaryIdObj as byte[]; CollectionAssert.AreEqual(expectedBinaryId, actualBinaryId); } if (expected.Properties.TryGetValue(WFConstants.BackendHeaders.EffectivePartitionKey, out object expectedEpkObj)) { byte[] expectedEpk = expectedEpkObj as byte[]; Assert.IsTrue(actual.Properties.TryGetValue(WFConstants.BackendHeaders.EffectivePartitionKey, out object actualEpkObj)); byte[] actualEpk = actualEpkObj as byte[]; CollectionAssert.AreEqual(expectedEpk, actualEpk); } if (expected.Properties.TryGetValue(WFConstants.BackendHeaders.TimeToLiveInSeconds, out object expectedTtlObj)) { string expectedTtlStr = expectedTtlObj as string; Assert.IsTrue(actual.Properties.TryGetValue(WFConstants.BackendHeaders.TimeToLiveInSeconds, out object actualTtlObj)); Assert.AreEqual(expectedTtlStr, actualTtlObj as string); } } } else { Assert.IsNull(actual); } }
internal static BatchItemRequestOptions FromItemRequestOptions(ItemRequestOptions itemRequestOptions) { if (itemRequestOptions == null) { return(null); } RequestOptions requestOptions = itemRequestOptions as RequestOptions; BatchItemRequestOptions batchItemRequestOptions = new BatchItemRequestOptions(); batchItemRequestOptions.IndexingDirective = itemRequestOptions.IndexingDirective; batchItemRequestOptions.IfMatchEtag = requestOptions.IfMatchEtag; batchItemRequestOptions.IfNoneMatchEtag = requestOptions.IfNoneMatchEtag; batchItemRequestOptions.Properties = requestOptions.Properties; batchItemRequestOptions.IsEffectivePartitionKeyRouting = requestOptions.IsEffectivePartitionKeyRouting; return(batchItemRequestOptions); }
public void FromItemRequestOptions_WithCustomValues() { ItemRequestOptions itemRequestOptions = new ItemRequestOptions(); itemRequestOptions.IfMatchEtag = Guid.NewGuid().ToString(); itemRequestOptions.IfNoneMatchEtag = Guid.NewGuid().ToString(); itemRequestOptions.IndexingDirective = Cosmos.IndexingDirective.Exclude; itemRequestOptions.Properties = new Dictionary <string, object>() { { "test", "test" } }; BatchItemRequestOptions batchItemRequestOptions = BatchItemRequestOptions.FromItemRequestOptions(itemRequestOptions); Assert.AreEqual(itemRequestOptions.IfMatchEtag, batchItemRequestOptions.IfMatchEtag); Assert.AreEqual(itemRequestOptions.IfNoneMatchEtag, batchItemRequestOptions.IfNoneMatchEtag); Assert.AreEqual(itemRequestOptions.IndexingDirective, batchItemRequestOptions.IndexingDirective); Assert.AreEqual(itemRequestOptions.Properties, batchItemRequestOptions.Properties); }
public async Task BatchWithReplaceOfStaleEntityAsync() { Container container = BatchTestBase.JsonContainer; await this.CreateJsonTestDocsAsync(container); TestDoc staleTestDocToReplace = this.GetTestDocCopy(this.TestDocPk1ExistingA); staleTestDocToReplace.Cost++; BatchItemRequestOptions staleReplaceOptions = new BatchItemRequestOptions() { IfMatchEtag = Guid.NewGuid().ToString() }; await this.RunWithErrorAsync( container, batch => batch.ReplaceItem(staleTestDocToReplace.Id, staleTestDocToReplace, staleReplaceOptions), HttpStatusCode.PreconditionFailed); // make sure the stale doc hasn't changed await BatchTestBase.VerifyByReadAsync(container, this.TestDocPk1ExistingA); }
public async Task BatchCrudRequestAsync() { Random random = new Random(); TestItem createItem = new TestItem("create"); byte[] createStreamContent = new byte[20]; random.NextBytes(createStreamContent); byte[] createStreamBinaryId = new byte[20]; random.NextBytes(createStreamBinaryId); int createTtl = 45; BatchItemRequestOptions createRequestOptions = new BatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, createStreamBinaryId }, { WFConstants.BackendHeaders.TimeToLiveInSeconds, createTtl.ToString() }, }, IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude }; string readId = Guid.NewGuid().ToString(); byte[] readStreamBinaryId = new byte[20]; random.NextBytes(readStreamBinaryId); BatchItemRequestOptions readRequestOptions = new BatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, readStreamBinaryId } }, IfNoneMatchEtag = "readCondition" }; TestItem replaceItem = new TestItem("repl"); byte[] replaceStreamContent = new byte[20]; random.NextBytes(replaceStreamContent); const string replaceStreamId = "replStream"; byte[] replaceStreamBinaryId = new byte[20]; random.NextBytes(replaceStreamBinaryId); BatchItemRequestOptions replaceRequestOptions = new BatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, replaceStreamBinaryId } }, IfMatchEtag = "replCondition", IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude }; TestItem upsertItem = new TestItem("upsert"); byte[] upsertStreamContent = new byte[20]; random.NextBytes(upsertStreamContent); byte[] upsertStreamBinaryId = new byte[20]; random.NextBytes(upsertStreamBinaryId); BatchItemRequestOptions upsertRequestOptions = new BatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, upsertStreamBinaryId } }, IfMatchEtag = "upsertCondition", IndexingDirective = Microsoft.Azure.Cosmos.IndexingDirective.Exclude }; string deleteId = Guid.NewGuid().ToString(); byte[] deleteStreamBinaryId = new byte[20]; random.NextBytes(deleteStreamBinaryId); BatchItemRequestOptions deleteRequestOptions = new BatchItemRequestOptions() { Properties = new Dictionary <string, object>() { { WFConstants.BackendHeaders.BinaryId, deleteStreamBinaryId } }, IfNoneMatchEtag = "delCondition" }; CosmosJsonDotNetSerializer jsonSerializer = new CosmosJsonDotNetSerializer(); BatchTestHandler testHandler = new BatchTestHandler((request, operations) => { Assert.AreEqual(new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1).ToString(), request.Headers.PartitionKey); Assert.AreEqual(bool.TrueString, request.Headers[HttpConstants.HttpHeaders.IsBatchAtomic]); Assert.AreEqual(bool.TrueString, request.Headers[HttpConstants.HttpHeaders.IsBatchOrdered]); Assert.IsFalse(request.Headers.TryGetValue(HttpConstants.HttpHeaders.ShouldBatchContinueOnError, out string unused)); Assert.AreEqual(16, operations.Count); int operationIndex = 0; // run the loop twice, once for operations without item request options, and one for with item request options for (int loopCount = 0; loopCount < 2; loopCount++) { bool hasItemRequestOptions = loopCount == 1; ItemBatchOperation operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Create, operation.OperationType); Assert.IsNull(operation.Id); Assert.AreEqual(createItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? createRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Read, operation.OperationType); Assert.AreEqual(readId, operation.Id); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? readRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Replace, operation.OperationType); Assert.AreEqual(replaceItem.Id, operation.Id); Assert.AreEqual(replaceItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? replaceRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Upsert, operation.OperationType); Assert.IsNull(operation.Id); Assert.AreEqual(upsertItem, BatchUnitTests.Deserialize(operation.ResourceBody, jsonSerializer)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? upsertRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Delete, operation.OperationType); Assert.AreEqual(deleteId, operation.Id); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? deleteRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Create, operation.OperationType); Assert.IsNull(operation.Id); Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(createStreamContent)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? createRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Replace, operation.OperationType); Assert.AreEqual(replaceStreamId, operation.Id); Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(replaceStreamContent)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? replaceRequestOptions : null, operation.RequestOptions); operation = operations[operationIndex++]; Assert.AreEqual(OperationType.Upsert, operation.OperationType); Assert.IsNull(operation.Id); Assert.IsTrue(operation.ResourceBody.Span.SequenceEqual(upsertStreamContent)); BatchUnitTests.VerifyBatchItemRequestOptionsAreEqual(hasItemRequestOptions ? upsertRequestOptions : null, operation.RequestOptions); } return(Task.FromResult(new ResponseMessage(HttpStatusCode.OK))); }); Container container = BatchUnitTests.GetContainer(testHandler); BatchResponse batchResponse = await new BatchCore((ContainerCore)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) .CreateItem(createItem) .ReadItem(readId) .ReplaceItem(replaceItem.Id, replaceItem) .UpsertItem(upsertItem) .DeleteItem(deleteId) // stream .CreateItemStream(new MemoryStream(createStreamContent)) .ReplaceItemStream(replaceStreamId, new MemoryStream(replaceStreamContent)) .UpsertItemStream(new MemoryStream(upsertStreamContent)) // regular with options .CreateItem(createItem, createRequestOptions) .ReadItem(readId, readRequestOptions) .ReplaceItem(replaceItem.Id, replaceItem, replaceRequestOptions) .UpsertItem(upsertItem, upsertRequestOptions) .DeleteItem(deleteId, deleteRequestOptions) // stream with options .CreateItemStream(new MemoryStream(createStreamContent), createRequestOptions) .ReplaceItemStream(replaceStreamId, new MemoryStream(replaceStreamContent), replaceRequestOptions) .UpsertItemStream(new MemoryStream(upsertStreamContent), upsertRequestOptions) .ExecuteAsync(); }
public void FromItemRequestOptions_FromNull() { Assert.IsNull(BatchItemRequestOptions.FromItemRequestOptions(null)); }
private static Result ReadOperation(ref RowReader reader, int operationIndex, out ItemBatchOperation operation) { operation = null; OperationType operationType = OperationType.Invalid; string partitionKeyJson = null; byte[] effectivePartitionKey = null; string id = null; byte[] binaryId = null; byte[] resourceBody = null; Cosmos.IndexingDirective?indexingDirective = null; string ifMatch = null; string ifNoneMatch = null; int? ttlInSeconds = null; while (reader.Read()) { Result r; switch (reader.Path) { case "operationType": r = reader.ReadInt32(out int operationTypeInt); if (r != Result.Success) { return(r); } operationType = (OperationType)operationTypeInt; break; case "resourceType": r = reader.ReadInt32(out int resourceType); if (r != Result.Success) { return(r); } Assert.AreEqual(ResourceType.Document, (ResourceType)resourceType); break; case "partitionKey": r = reader.ReadString(out partitionKeyJson); if (r != Result.Success) { return(r); } break; case "effectivePartitionKey": r = reader.ReadBinary(out effectivePartitionKey); if (r != Result.Success) { return(r); } break; case "id": r = reader.ReadString(out id); if (r != Result.Success) { return(r); } break; case "binaryId": r = reader.ReadBinary(out binaryId); if (r != Result.Success) { return(r); } break; case "resourceBody": r = reader.ReadBinary(out resourceBody); if (r != Result.Success) { return(r); } break; case "indexingDirective": r = reader.ReadString(out string indexingDirectiveStr); if (r != Result.Success) { return(r); } if (!Enum.TryParse <Cosmos.IndexingDirective>(indexingDirectiveStr, out Cosmos.IndexingDirective indexingDirectiveEnum)) { return(Result.Failure); } indexingDirective = indexingDirectiveEnum; break; case "ifMatch": r = reader.ReadString(out ifMatch); if (r != Result.Success) { return(r); } break; case "ifNoneMatch": r = reader.ReadString(out ifNoneMatch); if (r != Result.Success) { return(r); } break; case "timeToLiveInSeconds": r = reader.ReadInt32(out int ttl); if (r != Result.Success) { return(r); } ttlInSeconds = ttl; break; } } // Ensure the mandatory fields were populated if (operationType == OperationType.Invalid) { return(Result.Failure); } BatchItemRequestOptions requestOptions = null; if (indexingDirective.HasValue || ifMatch != null || ifNoneMatch != null || binaryId != null || effectivePartitionKey != null || ttlInSeconds.HasValue) { requestOptions = new BatchItemRequestOptions(); if (indexingDirective.HasValue) { requestOptions.IndexingDirective = indexingDirective; } if (ifMatch != null) { requestOptions.IfMatchEtag = ifMatch; } else if (ifNoneMatch != null) { requestOptions.IfNoneMatchEtag = ifNoneMatch; } if (binaryId != null || effectivePartitionKey != null || ttlInSeconds.HasValue) { requestOptions.Properties = new Dictionary <string, object>(); if (binaryId != null) { requestOptions.Properties.Add(WFConstants.BackendHeaders.BinaryId, binaryId); } if (effectivePartitionKey != null) { requestOptions.Properties.Add(WFConstants.BackendHeaders.EffectivePartitionKey, effectivePartitionKey); } if (ttlInSeconds.HasValue) { requestOptions.Properties.Add(WFConstants.BackendHeaders.TimeToLiveInSeconds, ttlInSeconds.ToString()); } } } Documents.PartitionKey parsedPartitionKey = null; if (partitionKeyJson != null) { parsedPartitionKey = Documents.PartitionKey.FromJsonString(partitionKeyJson); } operation = new ItemBatchOperation( operationType: operationType, operationIndex: operationIndex, id: id, requestOptions: requestOptions) { ParsedPartitionKey = parsedPartitionKey, ResourceBody = resourceBody }; return(Result.Success); }