public void DefaultIncludesShouldNotBePopulated()
        {
            CosmosContainerSettings containerSettings = new CosmosContainerSettings("TestContainer", "/partitionKey");

            Assert.IsNotNull(containerSettings.IndexingPolicy);

            // Any exclude path should not auto-generate default indexing
            containerSettings.IndexingPolicy = new IndexingPolicy();
            containerSettings.IndexingPolicy.ExcludedPaths.Add(new ExcludedPath()
            {
                Path = "/some"
            });

            Assert.AreEqual(0, containerSettings.IndexingPolicy.IncludedPaths.Count);
            containerSettings.ValidateRequiredProperties();
            Assert.AreEqual(0, containerSettings.IndexingPolicy.IncludedPaths.Count);

            // None indexing mode should not auto-generate the default indexing
            containerSettings.IndexingPolicy = new IndexingPolicy();
            containerSettings.IndexingPolicy.IndexingMode = IndexingMode.None;

            Assert.AreEqual(0, containerSettings.IndexingPolicy.IncludedPaths.Count);
            containerSettings.ValidateRequiredProperties();
            Assert.AreEqual(0, containerSettings.IndexingPolicy.IncludedPaths.Count);
        }
        /// <summary>
        /// Check if a container exists, and if it doesn't, create it.
        /// This will make a read operation, and if the container is not found it will do a create operation.
        /// </summary>
        /// <param name="containerSettings">The <see cref="CosmosContainerSettings"/> object.</param>
        /// <param name="throughput">(Optional) The throughput provisioned for a collection in measurement of Requests-per-Unit in the Azure Cosmos DB service.</param>
        /// <param name="requestOptions">(Optional) The options for the container request <see cref="CosmosRequestOptions"/></param>
        /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param>
        /// <returns>A <see cref="Task"/> containing a <see cref="CosmosContainerResponse"/> which wraps a <see cref="CosmosContainerSettings"/> containing the read resource record.</returns>
        /// <exception cref="ArgumentNullException">If either <paramref name="containerSettings"/> is not set.</exception>
        /// <exception cref="System.AggregateException">Represents a consolidation of failures that occurred during async processing. Look within InnerExceptions to find the actual exception(s).</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 container 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 container.</description>
        ///     </item>
        ///     <item>
        ///         <term>403</term><description>Forbidden - This means you attempted to exceed your quota for containers. Contact support to have this quota increased.</description>
        ///     </item>
        ///     <item>
        ///         <term>409</term><description>Conflict - This means a <see cref="CosmosContainerSettings"/> with an id matching the id you supplied already existed.</description>
        ///     </item>
        /// </list>
        /// </exception>
        /// <example>
        ///
        /// <code language="c#">
        /// <![CDATA[
        /// CosmosContainerSettings settings = new CosmosContainerSettings()
        /// {
        ///     Id = Guid.NewGuid().ToString(),
        ///     IndexingPolicy = new IndexingPolicy()
        ///    {
        ///         Automatic = false,
        ///         IndexingMode = IndexingMode.Lazy,
        ///    };
        /// };
        ///
        /// CosmosContainerResponse response = this.cosmosDatabase.Containers.CreateContainerIfNotExistsAsync(settings);
        /// ]]>
        /// </code>
        /// </example>
        public virtual async Task <CosmosContainerResponse> CreateContainerIfNotExistsAsync(
            CosmosContainerSettings containerSettings,
            int?throughput = null,
            CosmosRequestOptions requestOptions = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (containerSettings == null)
            {
                throw new ArgumentNullException(nameof(containerSettings));
            }

            containerSettings.ValidateRequiredProperties();
            this.database.Client.DocumentClient.ValidateResource(containerSettings);

            CosmosContainer         cosmosContainer         = this[containerSettings.Id];
            CosmosContainerResponse cosmosContainerResponse = await cosmosContainer.ReadAsync(cancellationToken : cancellationToken);

            if (cosmosContainerResponse.StatusCode != HttpStatusCode.NotFound)
            {
                return(cosmosContainerResponse);
            }

            cosmosContainerResponse = await CreateContainerAsync(containerSettings, throughput, requestOptions, cancellationToken : cancellationToken);

            if (cosmosContainerResponse.StatusCode != HttpStatusCode.Conflict)
            {
                return(cosmosContainerResponse);
            }

            // 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 cosmosContainer.ReadAsync(cancellationToken : cancellationToken));
        }
        internal static Task <T> ProcessCollectionCreateAsync <T>(
            CosmosContainerSettings containerSettings,
            CosmosDatabase database,
            int?throughput,
            Func <CosmosResponseMessage, T> responseCreator,
            CosmosRequestOptions requestOptions = null,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (containerSettings == null)
            {
                throw new ArgumentNullException(nameof(containerSettings));
            }

            containerSettings.ValidateRequiredProperties();
            database.Client.DocumentClient.ValidateResource(containerSettings);
            return(ExecUtils.ProcessResourceOperationAsync <T>(
                       database.Client,
                       database.LinkUri,
                       ResourceType.Collection,
                       OperationType.Create,
                       requestOptions,
                       partitionKey: null,
                       streamPayload: containerSettings.GetResourceStream(),
                       requestEnricher: (httpRequestMessage) => httpRequestMessage.AddThroughputHeader(throughput),
                       responseCreator: responseCreator,
                       cancellationToken: cancellationToken));
        }
        public void DefaultIncludesPopulated()
        {
            CosmosContainerSettings containerSettings = new CosmosContainerSettings("TestContainer", "/partitionKey");

            Assert.IsNotNull(containerSettings.IndexingPolicy);

            containerSettings.IndexingPolicy = new IndexingPolicy();
            Assert.AreEqual(0, containerSettings.IndexingPolicy.IncludedPaths.Count);

            // HAKC: Work-around till BE fixes defautls
            containerSettings.ValidateRequiredProperties();
            Assert.AreEqual(1, containerSettings.IndexingPolicy.IncludedPaths.Count);

            IncludedPath defaultEntry = containerSettings.IndexingPolicy.IncludedPaths[0];

            Assert.AreEqual(IndexingPolicy.DefaultPath, defaultEntry.Path);
            Assert.AreEqual(0, defaultEntry.Indexes.Count);
        }
        private static void AssertSerializedPayloads(CosmosContainerSettings settings, DocumentCollection documentCollection)
        {
            var jsonSettings = new JsonSerializerSettings
            {
                NullValueHandling = NullValueHandling.Ignore
            };

            // HAKC: Work-around till BE fixes defautls
            settings.ValidateRequiredProperties();

            string containerSerialized  = JsonConvert.SerializeObject(settings, jsonSettings);
            string collectionSerialized = CosmosContainerSettingsTests.SerializeDocumentCollection(documentCollection);

            JObject containerJObject  = JObject.Parse(containerSerialized);
            JObject collectionJObject = JObject.Parse(collectionSerialized);

            Assert.AreEqual(JsonConvert.SerializeObject(OrderProeprties(collectionJObject)), JsonConvert.SerializeObject(OrderProeprties(containerJObject)));
        }
 internal void ValidateContainerSettings(CosmosContainerSettings containerSettings)
 {
     containerSettings.ValidateRequiredProperties();
     this.client.DocumentClient.ValidateResource(containerSettings.Id);
 }