public override async Task <ContainerResponse> CreateContainerIfNotExistsAsync( ContainerProperties containerProperties, int?throughput = null, RequestOptions requestOptions = null, CancellationToken cancellationToken = default(CancellationToken)) { if (containerProperties == null) { throw new ArgumentNullException(nameof(containerProperties)); } this.ValidateContainerProperties(containerProperties); Container container = this.GetContainer(containerProperties.Id); ResponseMessage response = await container.ReadContainerStreamAsync(cancellationToken : cancellationToken); if (response.StatusCode != HttpStatusCode.NotFound) { ContainerResponse retrivedContainerResponse = await this.ClientContext.ResponseFactory.CreateContainerResponseAsync(container, Task.FromResult(response)); if (!PartitionKeyDefinition.AreEquivalent( retrivedContainerResponse.Resource.PartitionKey, containerProperties.PartitionKey)) { throw new ArgumentException( string.Format( ClientResources.PartitionKeyPathConflict, containerProperties.PartitionKeyPath, containerProperties.Id, retrivedContainerResponse.Resource.PartitionKeyPath), nameof(containerProperties.PartitionKey)); } return(retrivedContainerResponse); } this.ValidateContainerProperties(containerProperties); response = await this.CreateContainerStreamAsync(containerProperties, throughput, requestOptions, cancellationToken); if (response.StatusCode != HttpStatusCode.Conflict) { return(await this.ClientContext.ResponseFactory.CreateContainerResponseAsync(container, Task.FromResult(response))); } // This second Read is to handle the race condition when 2 or more threads have Read the database and only one succeeds with Create // so for the remaining ones we should do a Read instead of throwing Conflict exception return(await container.ReadContainerAsync(cancellationToken : cancellationToken)); }
public void TestPartitionKeyDefinitionAreEquivalent() { //Different partition key path test PartitionKeyDefinition definition1 = new PartitionKeyDefinition(); definition1.Paths.Add("/pk1"); PartitionKeyDefinition definition2 = new PartitionKeyDefinition(); definition2.Paths.Add("/pk2"); Assert.IsFalse(PartitionKeyDefinition.AreEquivalent(definition1, definition2)); //Different partition kind test definition1 = new PartitionKeyDefinition(); definition1.Paths.Add("/pk1"); definition1.Kind = PartitionKind.Hash; definition2 = new PartitionKeyDefinition(); definition2.Paths.Add("/pk1"); definition2.Kind = PartitionKind.Range; Assert.IsFalse(PartitionKeyDefinition.AreEquivalent(definition1, definition2)); //Different partition version test definition1 = new PartitionKeyDefinition(); definition1.Paths.Add("/pk1"); definition1.Version = PartitionKeyDefinitionVersion.V1; definition2 = new PartitionKeyDefinition(); definition2.Paths.Add("/pk1"); definition2.Version = PartitionKeyDefinitionVersion.V2; Assert.IsFalse(PartitionKeyDefinition.AreEquivalent(definition1, definition2)); //Same partition key path test definition1 = new PartitionKeyDefinition(); definition1.Paths.Add("/pk1"); definition2 = new PartitionKeyDefinition(); definition2.Paths.Add("/pk1"); Assert.IsTrue(PartitionKeyDefinition.AreEquivalent(definition1, definition2)); }