Пример #1
0
        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);
            }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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();
        }
Пример #10
0
 public void FromItemRequestOptions_FromNull()
 {
     Assert.IsNull(BatchItemRequestOptions.FromItemRequestOptions(null));
 }
Пример #11
0
        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);
        }