public void ValidateSetItemRequestOptions()
        {
            ItemRequestOptions options = new ItemRequestOptions
            {
                PreTriggers = new List <string>()
                {
                    "preTrigger"
                },
                PostTriggers = new List <string>()
                {
                    "postTrigger"
                }
            };

            RequestMessage httpRequest = new RequestMessage(
                HttpMethod.Post,
                new Uri("/dbs/testdb/colls/testcontainer/docs/testId", UriKind.Relative));

            options.PopulateRequestOptions(httpRequest);

            Assert.IsTrue(httpRequest.Headers.TryGetValue(HttpConstants.HttpHeaders.PreTriggerInclude, out string preTriggerHeader));
            Assert.IsTrue(httpRequest.Headers.TryGetValue(HttpConstants.HttpHeaders.PostTriggerInclude, out string postTriggerHeader));
        }
Exemple #2
0
        public async Task AllowBatchingRequestsSendsToExecutor_ReplaceStream()
        {
            (ContainerInternal container, Mock <BatchAsyncContainerExecutor> mockedExecutor) = this.CreateMockBulkCosmosClientContext();

            dynamic testItem = new
            {
                id = Guid.NewGuid().ToString(),
                pk = "FF627B77-568E-4541-A47E-041EAC10E46F",
            };

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                ItemRequestOptions  itemRequestOptions = new ItemRequestOptions();
                Cosmos.PartitionKey partitionKey       = new Cosmos.PartitionKey(testItem.pk);
                using (ResponseMessage streamResponse = await container.ReplaceItemStreamAsync(
                           partitionKey: partitionKey,
                           id: testItem.id,
                           streamPayload: itemStream))
                {
                    mockedExecutor.Verify(c => c.AddAsync(It.IsAny <ItemBatchOperation>(), It.IsAny <ITrace>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
                }
            }
        }
        public async Task AllowBatchingRequestsSendsToExecutor_ReadStream()
        {
            ClientContextCore clientContextCore = new ClientContextCore(
                MockCosmosUtil.CreateMockCosmosClient(),
                new CosmosClientOptions()
            {
                AllowBulkExecution = true
            },
                new CosmosJsonDotNetSerializer(),
                new CosmosJsonDotNetSerializer(),
                new CosmosJsonDotNetSerializer(),
                null,
                null,
                new MockDocumentClient()
                );

            DatabaseCore          db        = new DatabaseCore(clientContextCore, "test");
            ExecutorContainerCore container = new ExecutorContainerCore(clientContextCore, db, "test");

            dynamic testItem = new
            {
                id = Guid.NewGuid().ToString(),
                pk = "FF627B77-568E-4541-A47E-041EAC10E46F",
            };

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                ItemRequestOptions  itemRequestOptions = new ItemRequestOptions();
                Cosmos.PartitionKey partitionKey       = new Cosmos.PartitionKey(testItem.pk);
                using (ResponseMessage streamResponse = await container.ReadItemStreamAsync(
                           partitionKey: partitionKey,
                           id: testItem.id))
                {
                    container.MockedExecutor.Verify(c => c.AddAsync(It.IsAny <ItemBatchOperation>(), It.IsAny <ItemRequestOptions>(), It.IsAny <CancellationToken>()), Times.Once);
                }
            }
        }
Exemple #4
0
        public async override Task <ItemResponse <T> > UpsertItemAsync <T>(
            T item,
            PartitionKey?partitionKey           = null,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            if (requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions)
            {
                if (partitionKey == null)
                {
                    throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}.");
                }

                using (Stream itemStream = this.cosmosSerializer.ToStream <T>(item))
                {
                    using (ResponseMessage responseMessage = await this.UpsertItemStreamAsync(itemStream,
                                                                                              partitionKey.Value,
                                                                                              requestOptions,
                                                                                              cancellationToken))
                    {
                        return(this.responseFactory.CreateItemResponse <T>(responseMessage));
                    }
                }
            }
            else
            {
                return(await this.container.UpsertItemAsync(item,
                                                            partitionKey,
                                                            requestOptions,
                                                            cancellationToken));
            }
        }
Exemple #5
0
        private async Task <DocumentServiceLease> TryReplaceLeaseAsync(
            DocumentServiceLease lease,
            PartitionKey partitionKey,
            string itemId)
        {
            try
            {
                ItemRequestOptions itemRequestOptions        = this.CreateIfMatchOptions(lease);
                ItemResponse <DocumentServiceLease> response = await this.container.TryReplaceItemAsync <DocumentServiceLease>(
                    itemId,
                    lease,
                    partitionKey,
                    itemRequestOptions).ConfigureAwait(false);

                return(response.Resource);
            }
            catch (CosmosException ex)
            {
                DefaultTrace.TraceWarning("Lease operation exception, status code: {0}", ex.StatusCode);
                if (ex.StatusCode == HttpStatusCode.NotFound)
                {
                    throw new LeaseLostException(lease, true);
                }

                if (ex.StatusCode == HttpStatusCode.PreconditionFailed)
                {
                    return(null);
                }

                if (ex.StatusCode == HttpStatusCode.Conflict)
                {
                    throw new LeaseLostException(lease, ex, false);
                }

                throw;
            }
        }
Exemple #6
0
        public async Task VerifyRequestOptionCustomRequestHeaders()
        {
            CustomHeaderValidationHandler headerValidationHandler = new CustomHeaderValidationHandler();

            using CosmosClient client = TestCommon.CreateCosmosClient(x => x.AddCustomHandlers(headerValidationHandler));
            Database database = null;

            try
            {
                database = await client.CreateDatabaseAsync(nameof(VerifyRequestOptionCustomRequestHeaders) + Guid.NewGuid().ToString());

                Container container = await database.CreateContainerAsync(
                    Guid.NewGuid().ToString(),
                    "/pk");

                ToDoActivity       toDoActivity   = ToDoActivity.CreateRandomToDoActivity();
                ItemRequestOptions requestOptions = new ItemRequestOptions
                {
                    AddRequestHeaders = (headers) => headers["x-ms-cosmos-database-rid"] = "databaseRidValue",
                };

                await container.CreateItemAsync(toDoActivity, new PartitionKey(toDoActivity.pk), requestOptions : requestOptions);

                // null pass
                requestOptions.AddRequestHeaders = null;

                await container.ReadItemAsync <ToDoActivity>(toDoActivity.id, new PartitionKey(toDoActivity.pk), requestOptions : requestOptions);
            }
            finally
            {
                if (database != null)
                {
                    await database.DeleteStreamAsync();
                }
            }
        }
Exemple #7
0
        public override async Task <ItemResponse <T> > ReplaceItemAsync <T>(
            T item,
            string id,
            PartitionKey?partitionKey           = null,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            if (partitionKey == null)
            {
                throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}.");
            }

            ResponseMessage responseMessage;

            using (Stream itemStream = this.CosmosSerializer.ToStream <T>(item))
            {
                responseMessage = await this.ReplaceItemHelperAsync(
                    itemStream,
                    id,
                    partitionKey.Value,
                    requestOptions,
                    cancellationToken);
            }

            return(this.ResponseFactory.CreateItemResponse <T>(responseMessage));
        }
Exemple #8
0
        public override async Task <ResponseMessage> ReplaceItemStreamAsync(
            Stream streamPayload,
            string id,
            PartitionKey partitionKey,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (id == null)
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (streamPayload == null)
            {
                throw new ArgumentNullException(nameof(streamPayload));
            }

            return(await this.ReplaceItemHelperAsync(
                       streamPayload,
                       id,
                       partitionKey,
                       requestOptions,
                       cancellationToken));
        }
        public override async Task <ResponseMessage> UpsertItemStreamAsync(
            Stream streamPayload,
            PartitionKey partitionKey,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (streamPayload == null)
            {
                throw new ArgumentNullException(nameof(streamPayload));
            }

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            using (diagnosticsContext.CreateScope("UpsertItemStream"))
            {
                return(await this.UpsertItemHelperAsync(
                           streamPayload,
                           partitionKey,
                           requestOptions,
                           decryptResponse : true,
                           diagnosticsContext,
                           cancellationToken));
            }
        }
Exemple #10
0
        private async Task VerifyItemNullExceptions(
            dynamic testItem,
            ItemRequestOptions requestOptions = null)
        {
            TestHandler testHandler = new TestHandler((request, cancellationToken) =>
            {
                Assert.Fail("Null partition key should be blocked without the correct request option");
                return null;
            });

            CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(
                (cosmosClientBuilder) => cosmosClientBuilder.AddCustomHandlers(testHandler));

            CosmosContainer container = client.Databases["testdb"]
                                        .Containers["testcontainer"];

            await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
            {
                await container.CreateItemAsync<dynamic>(
                    partitionKey: null,
                    item: testItem,
                    requestOptions: requestOptions);
            }, "CreateItemAsync should throw ArgumentNullException without the correct request option set.");

            await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
            {
                await container.ReadItemAsync<dynamic>(
                    partitionKey: null,
                    id: testItem.id,
                    requestOptions: requestOptions);
            }, "ReadItemAsync should throw ArgumentNullException without the correct request option set.");

            await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
            {
                await container.UpsertItemAsync<dynamic>(
                    partitionKey: null,
                    item: testItem,
                    requestOptions: requestOptions);
            }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set.");

            await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
            {
                await container.ReplaceItemAsync<dynamic>(
                    partitionKey: null,
                    id: testItem.id,
                    item: testItem,
                    requestOptions: requestOptions);
            }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set.");

            await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
            {
                await container.DeleteItemAsync<dynamic>(
                    partitionKey: null,
                    id: testItem.id,
                    requestOptions: requestOptions);
            }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set.");

            CosmosJsonSerializerCore jsonSerializer = new CosmosJsonSerializerCore();
            using (Stream itemStream = jsonSerializer.ToStream<dynamic>(testItem))
            {
                await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
                {
                    await container.CreateItemAsStreamAsync(
                        partitionKey: null,
                        streamPayload: itemStream,
                        requestOptions: requestOptions);
                }, "CreateItemAsync should throw ArgumentNullException without the correct request option set.");

                await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
                {
                    await container.ReadItemAsStreamAsync(
                        partitionKey: null,
                        id: testItem.id,
                        requestOptions: requestOptions);
                }, "ReadItemAsync should throw ArgumentNullException without the correct request option set.");

                await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
                {
                    await container.UpsertItemAsStreamAsync(
                        partitionKey: null,
                        streamPayload: itemStream,
                        requestOptions: requestOptions);
                }, "UpsertItemAsync should throw ArgumentNullException without the correct request option set.");

                await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
                {
                    await container.ReplaceItemAsStreamAsync(
                        partitionKey: null,
                        id: testItem.id,
                        streamPayload: itemStream,
                        requestOptions: requestOptions);
                }, "ReplaceItemAsync should throw ArgumentNullException without the correct request option set.");

                await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
                {
                    await container.DeleteItemAsStreamAsync(
                        partitionKey: null,
                        id: testItem.id,
                        requestOptions: requestOptions);
                }, "DeleteItemAsync should throw ArgumentNullException without the correct request option set.");
            }
        }
Exemple #11
0
 /// <summary>
 /// Generates a data encryption key, wraps it using the key wrap metadata provided
 /// with the key wrapping provider in the <see cref="CosmosDataEncryptionKeyProvider"/> for encryption,
 /// and saves the wrapped data encryption key as an asynchronous operation in the Azure Cosmos service.
 /// </summary>
 /// <param name="id">Unique identifier for the data encryption key.</param>
 /// <param name="encryptionAlgorithm">Encryption algorithm that will be used along with this data encryption key to encrypt/decrypt data.</param>
 /// <param name="encryptionKeyWrapMetadata">Metadata used by the configured key wrapping provider in order to wrap the key.</param>
 /// <param name="requestOptions">(Optional) The options for the request.</param>
 /// <param name="cancellationToken">(Optional) Token representing request cancellation.</param>
 /// <returns>An awaitable response which wraps a <see cref="DataEncryptionKeyProperties"/> containing the read resource record.</returns>
 /// <exception cref="ArgumentNullException">If <paramref name="id"/> is not set.</exception>
 /// <exception cref="CosmosException">
 /// This exception can encapsulate many different types of errors.
 /// To determine the specific error always look at the StatusCode property.
 /// Some common codes you may get when creating a data encryption key are:
 /// <list type="table">
 ///     <listheader>
 ///         <term>StatusCode</term><description>Reason for exception</description>
 ///     </listheader>
 ///     <item>
 ///         <term>400</term><description>BadRequest - This means something was wrong with the request supplied. It is likely that an id was not supplied for the new encryption key.</description>
 ///     </item>
 ///     <item>
 ///         <term>409</term><description>Conflict - This means an <see cref="DataEncryptionKeyProperties"/> with an id matching the id you supplied already existed.</description>
 ///     </item>
 /// </list>
 /// </exception>
 /// <example>
 ///
 /// <code language="c#">
 /// <![CDATA[
 /// AzureKeyVaultKeyWrapMetadata wrapMetadata = new AzureKeyVaultKeyWrapMetadata("/path/to/my/akv/secret/v1");
 /// await this.cosmosDatabase.CreateDataEncryptionKeyAsync("myKey", wrapMetadata);
 /// ]]>
 /// </code>
 /// </example>
 public abstract Task <ItemResponse <DataEncryptionKeyProperties> > CreateDataEncryptionKeyAsync(
     string id,
     string encryptionAlgorithm,
     EncryptionKeyWrapMetadata encryptionKeyWrapMetadata,
     ItemRequestOptions requestOptions   = null,
     CancellationToken cancellationToken = default(CancellationToken));
Exemple #12
0
 /// <summary>
 /// Reads the properties of a data encryption key from the Azure Cosmos service as an asynchronous operation.
 /// </summary>
 /// <param name="id">Unique identifier of the data encryption key.</param>
 /// <param name="requestOptions">(Optional) The options for the request.</param>
 /// <param name="cancellationToken">(Optional) Token representing request cancellation.</param>
 /// <returns>An awaitable response which wraps a <see cref="DataEncryptionKeyProperties"/> containing details of the data encryption key that was read.</returns>
 /// <exception cref="CosmosException">
 /// This exception can encapsulate many different types of errors.
 /// To determine the specific error always look at the StatusCode property.
 /// Some common codes you may get when reading a data encryption key are:
 /// <list type="table">
 ///     <listheader>
 ///         <term>StatusCode</term>
 ///         <description>Reason for exception</description>
 ///     </listheader>
 ///     <item>
 ///         <term>404</term>
 ///         <description>
 ///         NotFound - This means the resource or parent resource you tried to read did not exist.
 ///         </description>
 ///     </item>
 ///     <item>
 ///         <term>429</term>
 ///         <description>
 ///         TooManyRequests - This means you have exceeded the number of request units per second.
 ///         Consult the CosmosException.RetryAfter value to see how long you should wait before retrying this operation.
 ///         </description>
 ///     </item>
 /// </list>
 /// </exception>
 /// <example>
 /// <code language="c#">
 /// <![CDATA[
 /// DataEncryptionKey key = this.database.GetDataEncryptionKey("keyId");
 /// DataEncryptionKeyProperties keyProperties = await key.ReadAsync();
 /// ]]>
 /// </code>
 /// </example>
 public abstract Task <ItemResponse <DataEncryptionKeyProperties> > ReadDataEncryptionKeyAsync(
     string id,
     ItemRequestOptions requestOptions   = null,
     CancellationToken cancellationToken = default(CancellationToken));
Exemple #13
0
        public override async Task <ItemResponse <DataEncryptionKeyProperties> > CreateDataEncryptionKeyAsync(
            string id,
            string encryptionAlgorithm,
            EncryptionKeyWrapMetadata encryptionKeyWrapMetadata,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (string.IsNullOrEmpty(id))
            {
                throw new ArgumentNullException(nameof(id));
            }

            if (!CosmosEncryptionAlgorithm.VerifyIfSupportedAlgorithm(encryptionAlgorithm))
            {
                throw new ArgumentException(string.Format("Unsupported Encryption Algorithm {0}", encryptionAlgorithm), nameof(encryptionAlgorithm));
            }

            if (encryptionKeyWrapMetadata == null)
            {
                throw new ArgumentNullException(nameof(encryptionKeyWrapMetadata));
            }

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            byte[] wrappedDek = null;
            EncryptionKeyWrapMetadata updatedMetadata = null;
            InMemoryRawDek            inMemoryRawDek  = null;

            if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
            {
                (wrappedDek, updatedMetadata, inMemoryRawDek) = await this.GenerateAndWrapRawDekForLegacyEncAlgoAsync(
                    id,
                    encryptionAlgorithm,
                    encryptionKeyWrapMetadata,
                    diagnosticsContext,
                    cancellationToken);
            }
            else if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
            {
                (wrappedDek, updatedMetadata) = this.GenerateAndWrapPdekForMdeEncAlgo(encryptionKeyWrapMetadata);
            }

            DataEncryptionKeyProperties dekProperties = new DataEncryptionKeyProperties(
                id,
                encryptionAlgorithm,
                wrappedDek,
                updatedMetadata,
                DateTime.UtcNow);

            ItemResponse <DataEncryptionKeyProperties> dekResponse = await this.DekProvider.Container.CreateItemAsync(
                dekProperties,
                new PartitionKey(dekProperties.Id),
                cancellationToken : cancellationToken);

            this.DekProvider.DekCache.SetDekProperties(id, dekResponse.Resource);

            if (string.Equals(encryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
            {
                this.DekProvider.DekCache.SetRawDek(id, inMemoryRawDek);
            }

            return(dekResponse);
        }
 public async Task UpdateItemAsync(Container container, GeneralModel item, ItemRequestOptions itemRequestOptions = null)
 {
     await container.UpsertItemAsync(item, new PartitionKey(item.ID), itemRequestOptions);
 }
        public async Task PointOperationDiagnostic(bool disableDiagnostics)
        {
            ItemRequestOptions requestOptions = new ItemRequestOptions();

            if (disableDiagnostics)
            {
                requestOptions.DiagnosticContextFactory = () => EmptyCosmosDiagnosticsContext.Singleton;
            }
            else
            {
                // Add 10 seconds to ensure CPU history is recorded
                await Task.Delay(TimeSpan.FromSeconds(10));
            }

            //Checking point operation diagnostics on typed operations
            ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
            ItemResponse <ToDoActivity> createResponse = await this.Container.CreateItemAsync <ToDoActivity>(
                item : testItem,
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                createResponse.Diagnostics,
                disableDiagnostics);

            ItemResponse <ToDoActivity> readResponse = await this.Container.ReadItemAsync <ToDoActivity>(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                readResponse.Diagnostics,
                disableDiagnostics);

            testItem.description = "NewDescription";
            ItemResponse <ToDoActivity> replaceResponse = await this.Container.ReplaceItemAsync <ToDoActivity>(
                item : testItem,
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            Assert.AreEqual(replaceResponse.Resource.description, "NewDescription");

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                replaceResponse.Diagnostics,
                disableDiagnostics);

            testItem.description = "PatchedDescription";
            ContainerInternal     containerInternal = (ContainerInternal)this.Container;
            List <PatchOperation> patch             = new List <PatchOperation>()
            {
                PatchOperation.Replace("/description", testItem.description)
            };
            ItemResponse <ToDoActivity> patchResponse = await containerInternal.PatchItemAsync <ToDoActivity>(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                patchOperations : patch,
                requestOptions : requestOptions);

            Assert.AreEqual(patchResponse.Resource.description, "PatchedDescription");

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                patchResponse.Diagnostics,
                disableDiagnostics);

            ItemResponse <ToDoActivity> deleteResponse = await this.Container.DeleteItemAsync <ToDoActivity>(
                partitionKey : new Cosmos.PartitionKey(testItem.status),
                id : testItem.id,
                requestOptions : requestOptions);

            Assert.IsNotNull(deleteResponse);
            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                deleteResponse.Diagnostics,
                disableDiagnostics);

            //Checking point operation diagnostics on stream operations
            ResponseMessage createStreamResponse = await this.Container.CreateItemStreamAsync(
                partitionKey : new PartitionKey(testItem.status),
                streamPayload : TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                createStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage readStreamResponse = await this.Container.ReadItemStreamAsync(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                readStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage replaceStreamResponse = await this.Container.ReplaceItemStreamAsync(
                streamPayload : TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem),
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                replaceStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage patchStreamResponse = await containerInternal.PatchItemStreamAsync(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                patchOperations : patch,
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                patchStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage deleteStreamResponse = await this.Container.DeleteItemStreamAsync(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                deleteStreamResponse.Diagnostics,
                disableDiagnostics);

            // Ensure diagnostics are set even on failed operations
            testItem.description = new string('x', Microsoft.Azure.Documents.Constants.MaxResourceSizeInBytes + 1);
            ResponseMessage createTooBigStreamResponse = await this.Container.CreateItemStreamAsync(
                partitionKey : new PartitionKey(testItem.status),
                streamPayload : TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem),
                requestOptions : requestOptions);

            Assert.IsFalse(createTooBigStreamResponse.IsSuccessStatusCode);
            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                createTooBigStreamResponse.Diagnostics,
                disableDiagnostics);
        }
Exemple #16
0
 /// <summary>
 /// Creates a new instance of the <see cref="CosmosDbArgs"/> class with the <paramref name="containerId"/> and <paramref name="requestOptions"/>.
 /// </summary>
 /// <param name="containerId">The <see cref="Container"/> identifier.</param>
 /// <param name="partitionKey">The optional <see cref="PartitionKey"/>.</param>
 /// <param name="requestOptions">The optional <see cref="T:ItemRequestOptions"/>.</param>
 /// <returns>The <see cref="CosmosDbArgs"/>.</returns>
 public static CosmosDbArgs Create(string containerId, PartitionKey partitionKey, ItemRequestOptions requestOptions = null)
 {
     return(new CosmosDbArgs(containerId, partitionKey, requestOptions));
 }
Exemple #17
0
 private static Task <ResponseMessage> ExecuteCreateStreamAsync(Container container, ToDoActivity item, ItemRequestOptions itemRequestOptions = null)
 {
     return(container.CreateItemStreamAsync(TestCommon.SerializerCore.ToStream(item), new PartitionKey(item.pk), itemRequestOptions));
 }
        public override async Task <ItemResponse <T> > CreateItemAsync <T>(
            T item,
            PartitionKey?partitionKey           = null,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            if (!(requestOptions is EncryptionItemRequestOptions encryptionItemRequestOptions) ||
                encryptionItemRequestOptions.EncryptionOptions == null)
            {
                return(await this.container.CreateItemAsync <T>(
                           item,
                           partitionKey,
                           requestOptions,
                           cancellationToken));
            }

            if (partitionKey == null)
            {
                throw new NotSupportedException($"{nameof(partitionKey)} cannot be null for operations using {nameof(EncryptionContainer)}.");
            }

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            using (diagnosticsContext.CreateScope("CreateItem"))
            {
                ResponseMessage responseMessage;

                if (item is EncryptableItem encryptableItem)
                {
                    using (Stream streamPayload = encryptableItem.ToStream(this.CosmosSerializer))
                    {
                        responseMessage = await this.CreateItemHelperAsync(
                            streamPayload,
                            partitionKey.Value,
                            requestOptions,
                            decryptResponse : false,
                            diagnosticsContext,
                            cancellationToken);
                    }

                    encryptableItem.SetDecryptableItem(
                        EncryptionProcessor.BaseSerializer.FromStream <JObject>(responseMessage.Content),
                        this.Encryptor,
                        this.CosmosSerializer);

                    return(new EncryptionItemResponse <T>(
                               responseMessage,
                               item));
                }
                else
                {
                    using (Stream itemStream = this.CosmosSerializer.ToStream <T>(item))
                    {
                        responseMessage = await this.CreateItemHelperAsync(
                            itemStream,
                            partitionKey.Value,
                            requestOptions,
                            decryptResponse : true,
                            diagnosticsContext,
                            cancellationToken);
                    }

                    return(this.ResponseFactory.CreateItemResponse <T>(responseMessage));
                }
            }
        }
Exemple #19
0
        private async Task ValidateItemStream(
            ItemRequestOptions requestOptions,
            Action <ResponseMessage> ValidateWrite,
            Action <ResponseMessage> ValidateRead)
        {
            ToDoActivity item = ToDoActivity.CreateRandomToDoActivity();

            using (ResponseMessage responseMessage = await this.container.CreateItemStreamAsync(
                       TestCommon.SerializerCore.ToStream(item),
                       new PartitionKey(item.status),
                       requestOptions: requestOptions))
            {
                Assert.AreEqual(HttpStatusCode.Created, responseMessage.StatusCode);
                ValidateWrite(responseMessage);
            }

            using (ResponseMessage responseMessage = await this.container.ReadItemStreamAsync(
                       item.id,
                       new PartitionKey(item.status),
                       requestOptions: requestOptions))
            {
                Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode);
                ValidateRead(responseMessage);
            }

            item.cost = 424242.42;
            using (ResponseMessage responseMessage = await this.container.UpsertItemStreamAsync(
                       TestCommon.SerializerCore.ToStream(item),
                       new PartitionKey(item.status),
                       requestOptions: requestOptions))
            {
                Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode);
                ValidateWrite(responseMessage);
            }

            item.cost = 9000.42;
            using (ResponseMessage responseMessage = await this.container.ReplaceItemStreamAsync(
                       TestCommon.SerializerCore.ToStream(item),
                       item.id,
                       new PartitionKey(item.status),
                       requestOptions: requestOptions))
            {
                Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode);
                ValidateWrite(responseMessage);
            }

            item.cost = 1000;
            List <PatchOperation> patch = new List <PatchOperation>()
            {
                PatchOperation.CreateReplaceOperation("/cost", item.cost)
            };

            using (ResponseMessage responseMessage = await this.containerInternal.PatchItemStreamAsync(
                       item.id,
                       new PartitionKey(item.status),
                       patchOperations: patch,
                       requestOptions: requestOptions))
            {
                Assert.AreEqual(HttpStatusCode.OK, responseMessage.StatusCode);
                ValidateWrite(responseMessage);
            }

            using (ResponseMessage responseMessage = await this.container.DeleteItemStreamAsync(
                       item.id,
                       new PartitionKey(item.status),
                       requestOptions: requestOptions))
            {
                Assert.AreEqual(HttpStatusCode.NoContent, responseMessage.StatusCode);
                this.ValidateItemStreamNoContentResponse(responseMessage);
            }
        }
        private async Task<ItemResponse<DocumentEntity<T>>> CreateDocumentInternalAsync<T>(T entity, ItemRequestOptions requestOptions = null) where T : IIdentifiable
        {
            DocumentEntity<T> doc = CreateDocumentEntity(entity);

            return await RepositoryContainer.CreateItemAsync(doc, requestOptions: requestOptions);
        }
 public async Task AddItemsAsync<T>(Container container, T item, string partitionKey, ItemRequestOptions itemRequestOptions = null)
 {
     var partitionKeyStruct = new PartitionKey(partitionKey);
     await container.CreateItemAsync<T>(item, partitionKeyStruct, itemRequestOptions);
 }
        public async Task CrossPartitionBiDirectionalItemReadFeedTest(bool useStatelessIteration)
        {
            //create items
            const int     total        = 30;
            const int     maxItemCount = 10;
            List <string> items        = new List <string>();

            for (int i = 0; i < total; i++)
            {
                string item = $@"
                    {{    
                        ""id"": ""{i}""
                    }}";

                using (ResponseMessage createResponse = await this.Container.CreateItemStreamAsync(
                           CosmosReadFeedTests.GenerateStreamFromString(item),
                           new Cosmos.PartitionKey(i.ToString())))
                {
                    Assert.IsTrue(createResponse.IsSuccessStatusCode);
                }
            }

            string       lastKnownContinuationToken = null;
            FeedIterator iter = this.Container.Database.GetContainer(this.Container.Id)
                                .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken);
            int           count        = 0;
            List <string> forwardOrder = new List <string>();

            while (iter.HasMoreResults)
            {
                if (useStatelessIteration)
                {
                    iter = this.Container.Database.GetContainer(this.Container.Id)
                           .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken);
                }

                using (ResponseMessage response = await iter.ReadNextAsync())
                {
                    lastKnownContinuationToken = response.Headers.Continuation;

                    Assert.IsNotNull(response);
                    using (StreamReader reader = new StreamReader(response.Content))
                    {
                        string json = await reader.ReadToEndAsync();

                        JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents");
                        count += documents.Count;
                        if (documents.Any())
                        {
                            forwardOrder.Add(documents.First().SelectToken("id").ToString());
                        }
                    }
                }
            }

            Assert.IsNull(lastKnownContinuationToken);
            Assert.IsNotNull(forwardOrder);
            Assert.AreEqual(total, count);
            Assert.IsFalse(forwardOrder.Where(x => string.IsNullOrEmpty(x)).Any());

            ItemRequestOptions requestOptions = new ItemRequestOptions();

            requestOptions.Properties = requestOptions.Properties = new Dictionary <string, object>();
            requestOptions.Properties.Add(HttpConstants.HttpHeaders.EnumerationDirection, (byte)BinaryScanDirection.Reverse);
            count = 0;
            List <string> reverseOrder = new List <string>();

            lastKnownContinuationToken = null;
            iter = this.Container.Database.GetContainer(this.Container.Id)
                   .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken, requestOptions: requestOptions);
            while (iter.HasMoreResults)
            {
                if (useStatelessIteration)
                {
                    iter = this.Container.Database.GetContainer(this.Container.Id)
                           .GetItemStreamIterator(maxItemCount, continuationToken: lastKnownContinuationToken, requestOptions: requestOptions);
                }

                using (ResponseMessage response = await iter.ReadNextAsync())
                {
                    lastKnownContinuationToken = response.Headers.Continuation;

                    Assert.IsNotNull(response);
                    using (StreamReader reader = new StreamReader(response.Content))
                    {
                        string json = await reader.ReadToEndAsync();

                        JArray documents = (JArray)JObject.Parse(json).SelectToken("Documents");
                        count += documents.Count;
                        if (documents.Any())
                        {
                            reverseOrder.Add(documents.First().SelectToken("id").ToString());
                        }
                    }
                }
            }

            Assert.IsNull(lastKnownContinuationToken);
            Assert.IsNotNull(reverseOrder);

            Assert.AreEqual(total, count);
            forwardOrder.Reverse();

            CollectionAssert.AreEqual(forwardOrder, reverseOrder);
            Assert.IsFalse(reverseOrder.Where(x => string.IsNullOrEmpty(x)).Any());
        }
Exemple #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CosmosDbArgs"/> class.
 /// </summary>
 /// <param name="containerId">The <see cref="Container"/> identifier.</param>
 /// <param name="partitionKey">The optional <see cref="PartitionKey"/>.</param>
 /// <param name="requestOptions">The optional <see cref="T:ItemRequestOptions"/>.</param>
 public CosmosDbArgs(string containerId, PartitionKey partitionKey, ItemRequestOptions requestOptions = null)
 {
     ContainerId        = Check.NotEmpty(containerId, nameof(containerId));
     PartitionKey       = partitionKey;
     ItemRequestOptions = requestOptions;
 }
Exemple #24
0
        public async Task PointOperationDiagnostic(bool disableDiagnostics)
        {
            ItemRequestOptions requestOptions = new ItemRequestOptions();

            if (disableDiagnostics)
            {
                requestOptions.DiagnosticContextFactory = () => EmptyCosmosDiagnosticsContext.Singleton;
            }
            ;

            //Checking point operation diagnostics on typed operations
            ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();
            ItemResponse <ToDoActivity> createResponse = await this.Container.CreateItemAsync <ToDoActivity>(
                item : testItem,
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                createResponse.Diagnostics,
                disableDiagnostics);

            ItemResponse <ToDoActivity> readResponse = await this.Container.ReadItemAsync <ToDoActivity>(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                readResponse.Diagnostics,
                disableDiagnostics);

            testItem.description = "NewDescription";
            ItemResponse <ToDoActivity> replaceResponse = await this.Container.ReplaceItemAsync <ToDoActivity>(
                item : testItem,
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            Assert.AreEqual(replaceResponse.Resource.description, "NewDescription");

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                replaceResponse.Diagnostics,
                disableDiagnostics);

            ItemResponse <ToDoActivity> deleteResponse = await this.Container.DeleteItemAsync <ToDoActivity>(
                partitionKey : new Cosmos.PartitionKey(testItem.status),
                id : testItem.id,
                requestOptions : requestOptions);

            Assert.IsNotNull(deleteResponse);
            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                deleteResponse.Diagnostics,
                disableDiagnostics);

            //Checking point operation diagnostics on stream operations
            ResponseMessage createStreamResponse = await this.Container.CreateItemStreamAsync(
                partitionKey : new PartitionKey(testItem.status),
                streamPayload : TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                createStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage readStreamResponse = await this.Container.ReadItemStreamAsync(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                readStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage replaceStreamResponse = await this.Container.ReplaceItemStreamAsync(
                streamPayload : TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem),
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                replaceStreamResponse.Diagnostics,
                disableDiagnostics);

            ResponseMessage deleteStreamResponse = await this.Container.DeleteItemStreamAsync(
                id : testItem.id,
                partitionKey : new PartitionKey(testItem.status),
                requestOptions : requestOptions);

            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                deleteStreamResponse.Diagnostics,
                disableDiagnostics);

            // Ensure diagnostics are set even on failed operations
            testItem.description = new string('x', Microsoft.Azure.Documents.Constants.MaxResourceSizeInBytes + 1);
            ResponseMessage createTooBigStreamResponse = await this.Container.CreateItemStreamAsync(
                partitionKey : new PartitionKey(testItem.status),
                streamPayload : TestCommon.SerializerCore.ToStream <ToDoActivity>(testItem),
                requestOptions : requestOptions);

            Assert.IsFalse(createTooBigStreamResponse.IsSuccessStatusCode);
            CosmosDiagnosticsTests.VerifyPointDiagnostics(
                createTooBigStreamResponse.Diagnostics,
                disableDiagnostics);
        }
        public async Task PointOperationThrottledDiagnostic(bool disableDiagnostics)
        {
            string errorMessage        = "Mock throttle exception" + Guid.NewGuid().ToString();
            Guid   exceptionActivityId = Guid.NewGuid();
            // Set a small retry count to reduce test time
            CosmosClient throttleClient = TestCommon.CreateCosmosClient(builder =>
                                                                        builder.WithThrottlingRetryOptions(TimeSpan.FromSeconds(5), 5)
                                                                        .WithTransportClientHandlerFactory(transportClient => new TransportClientWrapper(
                                                                                                               transportClient,
                                                                                                               (uri, resourceOperation, request) => TransportClientHelper.ReturnThrottledStoreResponseOnItemOperation(
                                                                                                                   uri,
                                                                                                                   resourceOperation,
                                                                                                                   request,
                                                                                                                   exceptionActivityId,
                                                                                                                   errorMessage)))
                                                                        );

            ItemRequestOptions requestOptions = new ItemRequestOptions();

            if (disableDiagnostics)
            {
                requestOptions.DiagnosticContextFactory = () => EmptyCosmosDiagnosticsContext.Singleton;
            }
            ;

            Container containerWithThrottleException = throttleClient.GetContainer(
                this.database.Id,
                this.Container.Id);

            //Checking point operation diagnostics on typed operations
            ToDoActivity testItem = ToDoActivity.CreateRandomToDoActivity();

            try
            {
                ItemResponse <ToDoActivity> createResponse = await containerWithThrottleException.CreateItemAsync <ToDoActivity>(
                    item : testItem,
                    requestOptions : requestOptions);

                Assert.Fail("Should have thrown a request timeout exception");
            }
            catch (CosmosException ce) when((int)ce.StatusCode == (int)Documents.StatusCodes.TooManyRequests)
            {
                string exception = ce.ToString();

                Assert.IsNotNull(exception);
                Assert.IsTrue(exception.Contains(exceptionActivityId.ToString()));
                Assert.IsTrue(exception.Contains(errorMessage));

                string diagnosics = ce.Diagnostics.ToString();

                if (disableDiagnostics)
                {
                    Assert.IsTrue(string.IsNullOrEmpty(diagnosics));
                }
                else
                {
                    Assert.IsFalse(string.IsNullOrEmpty(diagnosics));
                    Assert.IsTrue(exception.Contains(diagnosics));
                    DiagnosticValidator.ValidatePointOperationDiagnostics(ce.DiagnosticsContext);
                }
            }
        }
Exemple #26
0
        /// <inheritdoc/>
        public override async Task <ItemResponse <DataEncryptionKeyProperties> > RewrapDataEncryptionKeyAsync(
            string id,
            EncryptionKeyWrapMetadata newWrapMetadata,
            ItemRequestOptions requestOptions   = null,
            CancellationToken cancellationToken = default)
        {
            if (newWrapMetadata == null)
            {
                throw new ArgumentNullException(nameof(newWrapMetadata));
            }

            CosmosDiagnosticsContext diagnosticsContext = CosmosDiagnosticsContext.Create(requestOptions);

            DataEncryptionKeyProperties dekProperties = await this.FetchDataEncryptionKeyPropertiesAsync(
                id,
                diagnosticsContext,
                cancellationToken);

            byte[] rawkey = null;

            if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
            {
                InMemoryRawDek inMemoryRawDek = await this.FetchUnwrappedAsync(
                    dekProperties,
                    diagnosticsContext,
                    cancellationToken);

                rawkey = inMemoryRawDek.DataEncryptionKey.RawKey;
            }
            else if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.MdeAeadAes256CbcHmac256Randomized))
            {
                EncryptionKeyUnwrapResult encryptionKeyUnwrapResult = await this.DekProvider.MdeKeyWrapProvider.UnwrapKeyAsync(
                    dekProperties.WrappedDataEncryptionKey,
                    dekProperties.EncryptionKeyWrapMetadata,
                    cancellationToken);

                rawkey = encryptionKeyUnwrapResult.DataEncryptionKey;
            }

            (byte[] wrappedDek, EncryptionKeyWrapMetadata updatedMetadata, InMemoryRawDek updatedRawDek) = await this.WrapAsync(
                id,
                rawkey,
                dekProperties.EncryptionAlgorithm,
                newWrapMetadata,
                diagnosticsContext,
                cancellationToken);

            if (requestOptions == null)
            {
                requestOptions = new ItemRequestOptions();
            }

            requestOptions.IfMatchEtag = dekProperties.ETag;

            DataEncryptionKeyProperties newDekProperties = new DataEncryptionKeyProperties(dekProperties)
            {
                WrappedDataEncryptionKey  = wrappedDek,
                EncryptionKeyWrapMetadata = updatedMetadata,
            };

            ItemResponse <DataEncryptionKeyProperties> response;

            try
            {
                response = await this.DekProvider.Container.ReplaceItemAsync(
                    newDekProperties,
                    newDekProperties.Id,
                    new PartitionKey(newDekProperties.Id),
                    requestOptions,
                    cancellationToken);

                Debug.Assert(response.Resource != null);
            }
            catch (CosmosException ex)
            {
                if (!ex.StatusCode.Equals(HttpStatusCode.PreconditionFailed))
                {
                    throw;
                }

                // Handle if exception is due to etag mismatch. The scenario is as follows - say there are 2 clients A and B that both have the DEK properties cached.
                // From A, rewrap worked and the DEK is updated. Now from B, rewrap was attempted later based on the cached properties which will fail due to etag mismatch.
                // To address this, we do an explicit read, which reads the key from storage and updates the cached properties; and then attempt rewrap again.
                await this.ReadDataEncryptionKeyAsync(
                    newDekProperties.Id,
                    requestOptions,
                    cancellationToken);

                return(await this.RewrapDataEncryptionKeyAsync(
                           id,
                           newWrapMetadata,
                           requestOptions,
                           cancellationToken));
            }

            this.DekProvider.DekCache.SetDekProperties(id, response.Resource);

            if (string.Equals(dekProperties.EncryptionAlgorithm, CosmosEncryptionAlgorithm.AEAes256CbcHmacSha256Randomized))
            {
                this.DekProvider.DekCache.SetRawDek(id, updatedRawDek);
            }

            return(response);
        }
Exemple #27
0
        private async Task VerifyItemOperations(
            Cosmos.PartitionKey partitionKey,
            string partitionKeySerialized,
            dynamic testItem,
            ItemRequestOptions requestOptions = null)
        {
            ResponseMessage response            = null;
            HttpStatusCode  httpStatusCode      = HttpStatusCode.OK;
            int             testHandlerHitCount = 0;
            TestHandler     testHandler         = new TestHandler((request, cancellationToken) =>
            {
                Assert.IsTrue(request.RequestUri.OriginalString.StartsWith(@"dbs/testdb/colls/testcontainer"));
                Assert.AreEqual(requestOptions, request.RequestOptions);
                Assert.AreEqual(ResourceType.Document, request.ResourceType);
                Assert.IsNotNull(request.Headers.PartitionKey);
                Assert.AreEqual(partitionKeySerialized, request.Headers.PartitionKey);
                testHandlerHitCount++;
                response = new ResponseMessage(httpStatusCode, request, errorMessage: null)
                {
                    Content = request.Content
                };
                return(Task.FromResult(response));
            });

            using CosmosClient client = MockCosmosUtil.CreateMockCosmosClient(
                      (builder) => builder.AddCustomHandlers(testHandler));

            Container container = client.GetDatabase("testdb")
                                  .GetContainer("testcontainer");

            ItemResponse <dynamic> itemResponse = await container.CreateItemAsync <dynamic>(
                item : testItem,
                requestOptions : requestOptions);

            Assert.IsNotNull(itemResponse);
            Assert.AreEqual(httpStatusCode, itemResponse.StatusCode);

            itemResponse = await container.ReadItemAsync <dynamic>(
                partitionKey : partitionKey,
                id : testItem.id,
                requestOptions : requestOptions);

            Assert.IsNotNull(itemResponse);
            Assert.AreEqual(httpStatusCode, itemResponse.StatusCode);

            itemResponse = await container.UpsertItemAsync <dynamic>(
                item : testItem,
                requestOptions : requestOptions);

            Assert.IsNotNull(itemResponse);
            Assert.AreEqual(httpStatusCode, itemResponse.StatusCode);

            itemResponse = await container.ReplaceItemAsync <dynamic>(
                id : testItem.id,
                item : testItem,
                requestOptions : requestOptions);

            Assert.IsNotNull(itemResponse);
            Assert.AreEqual(httpStatusCode, itemResponse.StatusCode);

            itemResponse = await container.DeleteItemAsync <dynamic>(
                partitionKey : partitionKey,
                id : testItem.id,
                requestOptions : requestOptions);

            Assert.IsNotNull(itemResponse);
            Assert.AreEqual(httpStatusCode, itemResponse.StatusCode);

            Assert.AreEqual(5, testHandlerHitCount, "An operation did not make it to the handler");

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                using (ResponseMessage streamResponse = await container.CreateItemStreamAsync(
                           partitionKey: partitionKey,
                           streamPayload: itemStream,
                           requestOptions: requestOptions))
                {
                    Assert.IsNotNull(streamResponse);
                    Assert.AreEqual(httpStatusCode, streamResponse.StatusCode);
                }
            }

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                using (ResponseMessage streamResponse = await container.ReadItemStreamAsync(
                           partitionKey: partitionKey,
                           id: testItem.id,
                           requestOptions: requestOptions))
                {
                    Assert.IsNotNull(streamResponse);
                    Assert.AreEqual(httpStatusCode, streamResponse.StatusCode);
                }
            }

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                using (ResponseMessage streamResponse = await container.UpsertItemStreamAsync(
                           partitionKey: partitionKey,
                           streamPayload: itemStream,
                           requestOptions: requestOptions))
                {
                    Assert.IsNotNull(streamResponse);
                    Assert.AreEqual(httpStatusCode, streamResponse.StatusCode);
                }
            }

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                using (ResponseMessage streamResponse = await container.ReplaceItemStreamAsync(
                           partitionKey: partitionKey,
                           id: testItem.id,
                           streamPayload: itemStream,
                           requestOptions: requestOptions))
                {
                    Assert.IsNotNull(streamResponse);
                    Assert.AreEqual(httpStatusCode, streamResponse.StatusCode);
                }
            }

            using (Stream itemStream = MockCosmosUtil.Serializer.ToStream <dynamic>(testItem))
            {
                using (ResponseMessage streamResponse = await container.DeleteItemStreamAsync(
                           partitionKey: partitionKey,
                           id: testItem.id,
                           requestOptions: requestOptions))
                {
                    Assert.IsNotNull(streamResponse);
                    Assert.AreEqual(httpStatusCode, streamResponse.StatusCode);
                }
            }

            Assert.AreEqual(10, testHandlerHitCount, "A stream operation did not make it to the handler");
        }
 public async Task DeleteItemsAsync<T>(Container container, string id, string partitionKey, ItemRequestOptions itemRequestOptions = null)
 {
     var partitionKeyStruct = new PartitionKey(partitionKey);
     await container.DeleteItemAsync<T>(id, partitionKeyStruct, itemRequestOptions);
 }
        public async Task ClearStateAsync(string grainType, GrainReference grainReference, IGrainState grainState)
        {
            if (this._cosmos == null)
            {
                throw new ArgumentException("GrainState collection not initialized.");
            }

            string id           = this.GetKeyString(grainReference);
            string partitionKey = await this.BuildPartitionKey(grainType, grainReference);

            if (this._logger.IsEnabled(LogLevel.Trace))
            {
                this._logger.Trace(
                    "Clearing: GrainType={0} Key={1} Grainid={2} ETag={3} DeleteStateOnClear={4} from Collection={4} with PartitionKey {5}",
                    grainType, id, grainReference, grainState.ETag, this._options.DeleteStateOnClear, this._options.Collection, partitionKey);
            }

            var pk             = new PartitionKey(partitionKey);
            var requestOptions = new ItemRequestOptions {
                IfMatchEtag = grainState.ETag
            };

            try
            {
                if (this._options.DeleteStateOnClear)
                {
                    if (string.IsNullOrWhiteSpace(grainState.ETag))
                    {
                        return;  //state not written
                    }
                    await ExecuteWithRetries(() => this._container.DeleteItemAsync <GrainStateEntity>(
                                                 id, pk, requestOptions));

                    grainState.ETag = null;
                }
                else
                {
                    var entity = new GrainStateEntity
                    {
                        ETag         = grainState.ETag,
                        Id           = id,
                        GrainType    = grainType,
                        State        = null,
                        PartitionKey = partitionKey
                    };

                    var response = await ExecuteWithRetries(() =>
                                                            string.IsNullOrWhiteSpace(grainState.ETag)?
                                                            this._container.CreateItemAsync(entity, pk) :
                                                            this._container.ReplaceItemAsync(entity, entity.Id, pk, requestOptions))
                                   .ConfigureAwait(false);

                    grainState.ETag = response.Resource.ETag;
                }
            }
            catch (Exception exc)
            {
                this._logger.LogError(exc, $"Failure clearing state for Grain Type {grainType} with Id {id}.");
                throw;
            }
        }
 public Task <ItemResponse <T> > ReadItemAsync <T>(string id, ItemRequestOptions requestOptions = null,
                                                   CancellationToken cancellationToken          = default(CancellationToken))
 {
     return(Container.ReadItemAsync <T>(id, partitionKey, requestOptions, cancellationToken));
 }