public async Task WithClientEncryptionPolicyTest() { // create ClientEncryptionKeys DatabaseInlineCore databaseInlineCore = (DatabaseInlineCore)this.database; await TestCommon.CreateClientEncryptionKey("dekId1", databaseInlineCore); await TestCommon.CreateClientEncryptionKey("dekId2", databaseInlineCore); string containerName = Guid.NewGuid().ToString(); string partitionKeyPath = "/users"; ClientEncryptionIncludedPath path1 = new ClientEncryptionIncludedPath() { Path = "/path1", ClientEncryptionKeyId = "dekId1", EncryptionType = "Randomized", EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256" }; ClientEncryptionIncludedPath path2 = new ClientEncryptionIncludedPath() { Path = "/path2", ClientEncryptionKeyId = "dekId2", EncryptionType = "Randomized", EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", }; ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath) .WithClientEncryptionPolicy() .WithIncludedPath(path1) .WithIncludedPath(path2) .Attach() .CreateAsync(); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); Container container = containerResponse; ContainerProperties responseSettings = containerResponse; Assert.IsNotNull(responseSettings.ClientEncryptionPolicy); Assert.AreEqual(2, responseSettings.ClientEncryptionPolicy.IncludedPaths.Count()); ClientEncryptionIncludedPath clientEncryptionIncludedPath = responseSettings.ClientEncryptionPolicy.IncludedPaths.First(); Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(path1, clientEncryptionIncludedPath)); clientEncryptionIncludedPath = responseSettings.ClientEncryptionPolicy.IncludedPaths.Last(); Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(path2, clientEncryptionIncludedPath)); ContainerResponse readResponse = await container.ReadContainerAsync(); Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); Assert.IsNotNull(readResponse.Resource.ClientEncryptionPolicy); // update CEP and replace container readResponse.Resource.ClientEncryptionPolicy = null; try { await container.ReplaceContainerAsync(readResponse.Resource); Assert.Fail("ReplaceCollection with update to ClientEncryptionPolicy should have failed."); } catch (CosmosException ex) { Assert.AreEqual(HttpStatusCode.BadRequest, ex.StatusCode); Assert.IsTrue(ex.Message.Contains("'clientEncryptionPolicy' cannot be changed as part of collection replace operation.")); } }
public async Task ContainerContractTest() { DatabaseInlineCore databaseInlineCore = (DatabaseInlineCore)this.database; await TestCommon.CreateClientEncryptionKey("dekId", databaseInlineCore); ClientEncryptionIncludedPath clientEncryptionIncludedPath1 = new ClientEncryptionIncludedPath() { Path = "/path", ClientEncryptionKeyId = "dekId", EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256", EncryptionType = "Randomized" }; Collection <ClientEncryptionIncludedPath> paths = new Collection <ClientEncryptionIncludedPath>() { clientEncryptionIncludedPath1 }; ContainerProperties containerProperties = new ContainerProperties(Guid.NewGuid().ToString(), "/users") { IndexingPolicy = new IndexingPolicy() { Automatic = true, IndexingMode = IndexingMode.Consistent, IncludedPaths = new Collection <IncludedPath>() { new IncludedPath() { Path = "/*" } }, ExcludedPaths = new Collection <ExcludedPath>() { new ExcludedPath() { Path = "/test/*" } }, CompositeIndexes = new Collection <Collection <CompositePath> >() { new Collection <CompositePath>() { new CompositePath() { Path = "/address/city", Order = CompositePathSortOrder.Ascending }, new CompositePath() { Path = "/address/zipcode", Order = CompositePathSortOrder.Descending } } }, SpatialIndexes = new Collection <SpatialPath>() { new SpatialPath() { Path = "/address/spatial/*", SpatialTypes = new Collection <SpatialType>() { SpatialType.LineString } } } }, ClientEncryptionPolicy = new ClientEncryptionPolicy(paths) }; CosmosJsonDotNetSerializer serializer = new CosmosJsonDotNetSerializer(); Stream stream = serializer.ToStream(containerProperties); ContainerProperties deserialziedTest = serializer.FromStream <ContainerProperties>(stream); ContainerResponse response = await this.database.CreateContainerAsync(containerProperties); Assert.IsNotNull(response); Assert.IsTrue(response.RequestCharge > 0); Assert.IsNotNull(response.Headers); Assert.IsNotNull(response.Headers.ActivityId); ContainerProperties responseProperties = response.Resource; Assert.IsNotNull(responseProperties.Id); Assert.IsNotNull(responseProperties.ResourceId); Assert.IsNotNull(responseProperties.ETag); Assert.IsTrue(responseProperties.LastModified.HasValue); Assert.IsTrue(responseProperties.LastModified.Value > new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), responseProperties.LastModified.Value.ToString()); Assert.AreEqual(1, responseProperties.IndexingPolicy.IncludedPaths.Count); IncludedPath includedPath = responseProperties.IndexingPolicy.IncludedPaths.First(); Assert.AreEqual("/*", includedPath.Path); Assert.AreEqual("/test/*", responseProperties.IndexingPolicy.ExcludedPaths.First().Path); Assert.AreEqual(1, responseProperties.IndexingPolicy.CompositeIndexes.Count); Assert.AreEqual(2, responseProperties.IndexingPolicy.CompositeIndexes.First().Count); CompositePath compositePath = responseProperties.IndexingPolicy.CompositeIndexes.First().First(); Assert.AreEqual("/address/city", compositePath.Path); Assert.AreEqual(CompositePathSortOrder.Ascending, compositePath.Order); Assert.AreEqual(1, responseProperties.IndexingPolicy.SpatialIndexes.Count); SpatialPath spatialPath = responseProperties.IndexingPolicy.SpatialIndexes.First(); Assert.AreEqual("/address/spatial/*", spatialPath.Path); Assert.AreEqual(4, spatialPath.SpatialTypes.Count); // All SpatialTypes are returned Assert.AreEqual(1, responseProperties.ClientEncryptionPolicy.IncludedPaths.Count()); Assert.IsTrue(responseProperties.ClientEncryptionPolicy.PolicyFormatVersion <= 1); ClientEncryptionIncludedPath clientEncryptionIncludedPath = responseProperties.ClientEncryptionPolicy.IncludedPaths.First(); Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(clientEncryptionIncludedPath1, clientEncryptionIncludedPath)); }