diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/BulkSupport/BulkSupport.csproj b/Microsoft.Azure.Cosmos.Samples/Usage/BulkSupport/BulkSupport.csproj
new file mode 100644
index 000000000..c29acac0a
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Usage/BulkSupport/BulkSupport.csproj
@@ -0,0 +1,25 @@
+
+
+
+ Exe
+ netcoreapp2.1
+ Cosmos.Samples.BulkSupport
+ Cosmos.Samples.BulkSupport
+ latest
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/BulkSupport/Program.cs b/Microsoft.Azure.Cosmos.Samples/Usage/BulkSupport/Program.cs
new file mode 100644
index 000000000..2d398f02b
--- /dev/null
+++ b/Microsoft.Azure.Cosmos.Samples/Usage/BulkSupport/Program.cs
@@ -0,0 +1,196 @@
+namespace Cosmos.Samples.Shared
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Net;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Microsoft.Azure.Cosmos;
+ using Microsoft.Extensions.Configuration;
+ using Newtonsoft.Json;
+
+ // ----------------------------------------------------------------------------------------------------------
+ // Prerequisites -
+ //
+ // 1. An Azure Cosmos account -
+ // https://azure.microsoft.com/en-us/itemation/articles/itemdb-create-account/
+ //
+ // 2. Microsoft.Azure.Cosmos NuGet package -
+ // http://www.nuget.org/packages/Microsoft.Azure.Cosmos/
+ // ----------------------------------------------------------------------------------------------------------
+ // Sample - demonstrates the basic usage of the CosmosClient bulk mode by performing a high volume of operations
+ // ----------------------------------------------------------------------------------------------------------
+
+ public class Program
+ {
+ private const int concurrentWorkers = 3;
+ private const int concurrentDocuments = 100;
+ private const string databaseId = "samples";
+ private const string containerId = "bulk-support";
+ private static readonly JsonSerializer Serializer = new JsonSerializer();
+
+ //Reusable instance of ItemClient which represents the connection to a Cosmos endpoint
+ private static Database database = null;
+
+ // Async main requires c# 7.1 which is set in the csproj with the LangVersion attribute
+ //
+ public static async Task Main(string[] args)
+ {
+ try
+ {
+ // Read the Cosmos endpointUrl and authorisationKeys from configuration
+ // These values are available from the Azure Management Portal on the Cosmos Account Blade under "Keys"
+ // Keep these values in a safe & secure location. Together they provide Administrative access to your Cosmos account
+ IConfigurationRoot configuration = new ConfigurationBuilder()
+ .AddJsonFile("appSettings.json")
+ .Build();
+
+ string endpoint = configuration["EndPointUrl"];
+ if (string.IsNullOrEmpty(endpoint))
+ {
+ throw new ArgumentNullException("Please specify a valid endpoint in the appSettings.json");
+ }
+
+ string authKey = configuration["AuthorizationKey"];
+ if (string.IsNullOrEmpty(authKey) || string.Equals(authKey, "Super secret key"))
+ {
+ throw new ArgumentException("Please specify a valid AuthorizationKey in the appSettings.json");
+ }
+
+ CosmosClient bulkClient = Program.GetBulkClientInstance(endpoint, authKey);
+ // Create the require container, can be done with any client
+ await Program.InitializeAsync(bulkClient);
+
+ Console.WriteLine("Running demo with a Bulk enabled CosmosClient...");
+ // Execute inserts for 30 seconds on a Bulk enabled client
+ await Program.CreateItemsConcurrentlyAsync(bulkClient);
+ }
+ catch (CosmosException cre)
+ {
+ Console.WriteLine(cre.ToString());
+ }
+ catch (Exception e)
+ {
+ Exception baseException = e.GetBaseException();
+ Console.WriteLine("Error: {0}, Message: {1}", e.Message, baseException.Message);
+ }
+ finally
+ {
+ await Program.CleanupAsync();
+ Console.WriteLine("End of demo, press any key to exit.");
+ Console.ReadKey();
+ }
+ }
+ //
+
+ private static CosmosClient GetBulkClientInstance(
+ string endpoint,
+ string authKey) =>
+ //
+ new CosmosClient(endpoint, authKey, new CosmosClientOptions() { AllowBulkExecution = true } );
+ //
+
+ private static async Task CreateItemsConcurrentlyAsync(CosmosClient client)
+ {
+ // Create concurrent workers that will insert items for 30 seconds
+ CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
+ cancellationTokenSource.CancelAfter(30000);
+ CancellationToken cancellationToken = cancellationTokenSource.Token;
+
+ Container container = client.GetContainer(Program.databaseId, Program.containerId);
+ List> workerTasks = new List>(Program.concurrentWorkers);
+ Console.WriteLine($"Initiating process with {Program.concurrentWorkers} worker threads writing groups of {Program.concurrentDocuments} items for 30 seconds.");
+ for (var i = 0; i < Program.concurrentWorkers; i++)
+ {
+ workerTasks.Add(CreateItemsAsync(container, cancellationToken));
+ }
+
+ await Task.WhenAll(workerTasks);
+ Console.WriteLine($"Inserted {workerTasks.Sum(task => task.Result)} items.");
+ }
+
+ private static async Task CreateItemsAsync(
+ Container container,
+ CancellationToken cancellationToken)
+ {
+ int itemsCreated = 0;
+ string partitionKeyValue = Guid.NewGuid().ToString();
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ List tasks = new List(Program.concurrentDocuments);
+ for (int i = 0; i < Program.concurrentDocuments; i++)
+ {
+ string id = Guid.NewGuid().ToString();
+ MyDocument myDocument = new MyDocument() { id = id, pk = partitionKeyValue };
+ tasks.Add(
+ container.CreateItemAsync(myDocument, new PartitionKey(partitionKeyValue))
+ .ContinueWith((Task> task) =>
+ {
+ if (!task.IsCompletedSuccessfully)
+ {
+ AggregateException innerExceptions = task.Exception.Flatten();
+ CosmosException cosmosException = innerExceptions.InnerExceptions.FirstOrDefault(innerEx => innerEx is CosmosException) as CosmosException;
+ Console.WriteLine($"Item {myDocument.id} failed with status code {cosmosException.StatusCode}");
+ }
+ }));
+ }
+
+ await Task.WhenAll(tasks);
+
+ itemsCreated += tasks.Count(task => task.IsCompletedSuccessfully);
+ }
+
+ return itemsCreated;
+ }
+
+ //
+ private class MyDocument
+ {
+ public string id { get; set; }
+
+ public string pk { get; set; }
+
+ public bool Updated { get; set; }
+ }
+ //
+
+ private static async Task CleanupAsync()
+ {
+ if (Program.database != null)
+ {
+ await Program.database.DeleteAsync();
+ }
+ }
+
+ private static async Task InitializeAsync(CosmosClient client)
+ {
+ Program.database = await client.CreateDatabaseIfNotExistsAsync(Program.databaseId);
+
+ // Delete the existing container to prevent create item conflicts
+ using (await database.GetContainer(containerId).DeleteContainerStreamAsync())
+ { }
+
+ // We create a partitioned collection here which needs a partition key. Partitioned collections
+ // can be created with very high values of provisioned throughput (up to Throughput = 250,000)
+ // and used to store up to 250 GB of data.
+ ContainerProperties containerProperties = new ContainerProperties(containerId, partitionKeyPath: "/pk");
+
+ Console.WriteLine("The demo will create a 20000 RU/s container, press any key to continue.");
+ Console.ReadKey();
+ // Create with a throughput of 20000 RU/s - this demo is about throughput so it needs a higher degree of RU/s to show volume
+ // Indexing Policy to exclude all attributes to maximize RU/s usage
+ await database.DefineContainer(containerId, "/pk")
+ .WithIndexingPolicy()
+ .WithIndexingMode(IndexingMode.Consistent)
+ .WithIncludedPaths()
+ .Attach()
+ .WithExcludedPaths()
+ .Path("/*")
+ .Attach()
+ .Attach()
+ .CreateAsync(20000);
+ }
+ }
+}
+
diff --git a/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln b/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln
index 7bdfa6810..d9211816d 100644
--- a/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln
+++ b/Microsoft.Azure.Cosmos.Samples/Usage/Cosmos.Samples.Usage.sln
@@ -24,8 +24,11 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomSerialization", "CustomSerialization\CustomSerialization.csproj", "{61EA3F61-F2ED-4FD4-89EC-06342C5AE3C9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerShellRestApi", "PowerShellRestApi\PowerShellRestApi.csproj", "{A67B259B-9E3F-4689-9691-B250A88593BB}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChangeFeed", "ChangeFeed\ChangeFeed.csproj", "{D4959F3F-14FD-4AEA-851F-EEF944393603}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BulkSupport", "BulkSupport\BulkSupport.csproj", "{71ADD826-17CB-4095-B4F7-C5CDEDC731EA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -80,6 +83,10 @@ Global
{D4959F3F-14FD-4AEA-851F-EEF944393603}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4959F3F-14FD-4AEA-851F-EEF944393603}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4959F3F-14FD-4AEA-851F-EEF944393603}.Release|Any CPU.Build.0 = Release|Any CPU
+ {71ADD826-17CB-4095-B4F7-C5CDEDC731EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {71ADD826-17CB-4095-B4F7-C5CDEDC731EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {71ADD826-17CB-4095-B4F7-C5CDEDC731EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {71ADD826-17CB-4095-B4F7-C5CDEDC731EA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE