Page tree
Skip to end of metadata
Go to start of metadata


CAST supports Azure Cosmos DB via its NoSQL for .NET extension. Details about how this support is provided for .NET source code is discussed below.

Supported Client Libraries

Supported Operations

OperationMethods Supported
Create
 Methods Supported for Create - 2.x
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.CreateDocumentCollectionAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentCollectionIfNotExistsAsync
  • Microsoft.Azure.Documents.IDocumentClient.CreateDocumentCollectionIfNotExistsAsync
 Methods Supported for Create - 3.x
  • Microsoft.Azure.Cosmos.Fluent.ContainerBuilder.CreateIfNotExistsAsync
  • Microsoft.Azure.Cosmos.Fluent.ContainerBuilder.CreateAsync
  • Microsoft.Azure.Cosmos.Database.CreateContainerIfNotExistsAsync
  • Microsoft.Azure.Cosmos.CosmosDatabase.CreateContainerIfNotExistsAsync
  • Microsoft.Azure.Cosmos.Database.GetContainer
  • Microsoft.Azure.CosmosDatabase.GetContainer
  • Microsoft.Azure.Cosmos.CosmosClient.GetContainer
  • Microsoft.Azure.Cosmos.Database.CreateContainerStreamAsync
  • Microsoft.Azure.CosmosDatabase.CreateContainerStreamAsync
 Methods Supported for Create - CosmonautClient
  • Cosmonaut.CosmonautClient.CreateCollectionAsync 
  • Cosmonaut.ICosmonautClient.CreateCollectionAsync
  • Cosmonaut.CosmonautClient.GetCollectionAsync
  • Cosmonaut.ICosmonautClient.GetCollectionAsync
Insert
 Methods Supported for Insert - 2.x
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentAsync

  • Microsoft.Azure.Documents.IDocumentClient.CreateDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.UpsertDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.UpsertDocumentAsync
 Methods Supported for Insert - 3.x
  • Microsoft.Azure.Cosmos.Container.CreateItemAsync
  • Microsoft.Azure.CosmosContainer.CreateItemAsync
  • Microsoft.Azure.Cosmos.Container.CreateItemStreamAsync
  • Microsoft.Azure.CosmosContainer.CreateItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemStreamAsync
 Methods Supported for Insert - CosmonautClient
  • Cosmonaut.CosmonautClient.CreateDocumentAsync
  • Cosmonaut.ICosmonautClient.CreateDocumentAsync
  • Cosmonaut.CosmonautClient.UpsertDocumentAsync
  • Cosmonaut.ICosmonautClient.UpsertDocumentAsync
Update
 Methods Supported for Update - 2.x
  • Microsoft.Azure.Documents.Client.DocumentClient.ReplaceDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReplaceDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.ReplaceDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReplaceDocumentCollectionAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.UpsertDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.UpsertDocumentAsync
 Methods Supported for Update - 3.x
  • Microsoft.Azure.Cosmos.Container.ReplaceItemAsync
  • Microsoft.Azure.Cosmos.Container.ReplaceItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReplaceContainerAsync
  • Microsoft.Azure.CosmosContainer.ReplaceContainerStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReplaceContainerStreamAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemAsync
  • Microsoft.Azure.Cosmos.Container.UpsertItemStreamAsync
 Methods Supported for Update - CosmonautClient
  • Cosmonaut.CosmonautClient.UpdateDocumentAsync
  • Cosmonaut.ICosmonautClient.UpdateDocumentAsync
  • Cosmonaut.CosmonautClient.UpdateCollectionAsync
  • Cosmonaut.ICosmonautClient.UpdateCollectionAsync
  • Cosmonaut.CosmonautClient.UpsertDocumentAsync 
  • Cosmonaut.ICosmonautClient.UpsertDocumentAsync
Select
 Methods Supported for Select - 2.x
  • Microsoft.Azure.Documents.Client.DocumentClient.ReadDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReadDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.ReadDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.ReadDocumentCollectionAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentQuery
  • Microsoft.Azure.Documents.Client.DocumentClient.CreateDocumentQuery
 Methods Supported for Select - 3.x
  • Microsoft.Azure.Cosmos.Container.ReadItemAsync
  • Microsoft.Azure.CosmosContainer.ReadItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReadItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.ReadContainerStreamAsync
  • Microsoft.Azure.CosmosContainer.ReadContainerStreamAsync
 Methods Supported for Select - CosmonautClient
  • Cosmonaut.CosmonautClient.GetDocumentAsync 
  • Cosmonaut.ICosmonautClient.GetDocumentAsync
Delete
 Methods Supported for Delete - 2.x
  • Microsoft.Azure.Documents.Client.DocumentClient.DeleteDocumentAsync
  • Microsoft.Azure.Documents.IDocumentClient.DeleteDocumentAsync
  • Microsoft.Azure.Documents.Client.DocumentClient.DeleteDocumentCollectionAsync
  • Microsoft.Azure.Documents.IDocumentClient.DeleteDocumentCollectionAsync
 Methods Supported for Delete - 3.x
  • Microsoft.Azure.Cosmos.Container.DeleteItemAsync
  • Microsoft.Azure.CosmosContainer.DeleteItemAsync
  • Microsoft.Azure.Cosmos.Container.DeleteItemStreamAsync
  • Microsoft.Azure.Cosmos.Container.DeleteContainerAsync
  • Microsoft.Azure.CosmosContainer.DeleteContainerAsync
  • Microsoft.Azure.Cosmos.Container.DeleteContainerStreamAsync
 Methods Supported for Delete - CosmonautClient
  • Cosmonaut.CosmonautClient.DeleteDocumentAsync
  • Cosmonaut.ICosmonautClient.DeleteDocumentAsync
  • Cosmonaut.CosmonautClient.DeleteCollectionAsync
  • Cosmonaut.ICosmonautClient.DeleteCollectionAsync

Objects

IconDescription

DotNet CosmosDB Database

DotNet CosmosDB Collection

 

DotNet CosmosDB Unknown Database 

 

DotNet CosmosDB Unknown Collection 

Links are created for transaction and function point needs:

Link typeWhen is this created? Methods Supported
parentLink

Between Azure CosmosDB database object and Azure CosmosDB collection object


useLinkBetween the caller .NET Method objects and Azure CosmosDB collection object


 Methods
  • CreateDocumentCollectionAsync
  • CreateDocumentCollectionIfNotExistsAsync
  • GetContainer
  • CreateContainerIfNotExistsAsync
  • CreateContainerAsync
  • CreateIfNotExistsAsync
  • CreateAsync
  • CreateContainerStreamAsync
  • CreateCollectionAsync
  • GetCollectionAsync

useInsertLink

 Methods
  • CreateDocumentAsync
  • UpsertDocumentAsync
  • CreateItemAsync
  • CreateItemStreamAsync
  • UpsertItemAsync
  • UpsertItemStreamAsync
useUpdateLink
 Methods
  • ReplaceDocumentAsync
  • ReplaceDocumentCollectionAsync
  • UpsertDocumentAsync
  • ReplaceItemAsync
  • ReplaceItemStreamAsync
  • ReplaceContainerAsync
  • ReplaceContainerStreamAsync
  • UpsertItemAsync
  • UpsertItemStreamAsync
  • UpdateDocumentAsync
  • UpdateCollectionAsync
useSelectLink
 Methods
  • ReadDocumentAsync
  • ReadDocumentCollectionAsync
  • CreateDocumentQuery
  • ReadItemAsync
  • ReadItemStreamAsync
  • ReadContainerAsync
  • ReadContainerStreamAsync
  • GetDocumentAsync
useDeletetLink
 Methods
  • DeleteDocumentAsync
  • DeleteDocumentCollectionAsync
  • DeleteItemAsync
  • DeleteContainerAsync
  • DeleteContainerStreamAsync
  • DeleteCollectionAsync

What results can you expect?

Once the analysis/snapshot generation has completed, you can view the results in the normal manner (for example via CAST Enlighten). Some examples are shown below.

Azure Cosmos DB Database and Table Creation

 DB and Table Creation
CreateDatabase and CreateCollection - 2.x
private static readonly string databaseName = "samples";
private static readonly string collectionName = "document-samples";

private static async Task Initialize()
        {
            await client.CreateDatabaseIfNotExistsAsync(new Database { Id = databaseName });

            // 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 OfferThroughput = 250,000)
            // and used to store up to 250 GB of data. You can also skip specifying a partition key to create
            // single partition collections that store up to 10 GB of data.
            DocumentCollection collectionDefinition = new DocumentCollection();
            collectionDefinition.Id = collectionName;

            // For this demo, we create a collection to store SalesOrders. We set the partition key to the account
            // number so that we can retrieve all sales orders for an account efficiently from a single partition,
            // and perform transactions across multiple sales order for a single account number. 
            collectionDefinition.PartitionKey.Paths.Add("/AccountNumber");

            // Use the recommended indexing policy which supports range queries/sorting on strings
            collectionDefinition.IndexingPolicy = new IndexingPolicy(new RangeIndex(DataType.String) { Precision = -1 });

            // Create with a throughput of 1000 RU/s
            await client.CreateDocumentCollectionIfNotExistsAsync(
                UriFactory.CreateDatabaseUri(databaseName),
                collectionDefinition,
                new RequestOptions { OfferThroughput = 1000 });
        }

Create Database and Container - 3.x
private static async Task Initialize(CosmosClient client)
        {
            database = await client.CreateDatabaseIfNotExistsAsync(databaseId);

            ContainerProperties containerProperties = new ContainerProperties(containerId, partitionKeyPath: "/AccountNumber");

            // Create with a throughput of 1000 RU/s
            container = await database.CreateContainerIfNotExistsAsync(
                containerProperties,
                throughput: 1000);
        }

Insert Operation

 Insert Operation
CreateDocumentAsync - 2.x
private static async Task CreateDocumentsAsync()
        {
            Uri collectionUri = UriFactory.CreateDocumentCollectionUri(databaseName, collectionName);
            Console.WriteLine("\n1.1 - Creating documents");
            SalesOrder salesOrder = GetSalesOrderSample("SalesOrder1");
            await client.CreateDocumentAsync(collectionUri, salesOrder);
			SalesOrder2 newSalesOrder = GetSalesOrderV2Sample("SalesOrder2");
            await client.CreateDocumentAsync(collectionUri, newSalesOrder);
		}

CreateItemAsync - 3.x
private static async Task<SalesOrder> CreateItemsAsync()
        {
            Console.WriteLine("\n1.1 - Creating items");

            // Create a SalesOrder object. This object has nested properties and various types including numbers, DateTimes and strings.
            // This can be saved as JSON as is without converting into rows/columns.
            SalesOrder salesOrder = GetSalesOrderSample("SalesOrder1");
            ItemResponse<SalesOrder> response = await container.CreateItemAsync(salesOrder, new PartitionKey(salesOrder.AccountNumber));
            SalesOrder salesOrder1 = response;
            Console.WriteLine($"\n1.1.1 - Item created {salesOrder1.Id}");
		}

CreateDocumentAsync - CosmonautClient
public async Task<DocumentStorageResponse<TEntity>> InsertAsync<TEntity>(TEntity entity, DocumentOptions options = null, CancellationToken cancellationToken = default)
        where TEntity : Entity
        {
            var response = await this.documentClient.CreateDocumentAsync(this.databaseName, this.collectionName, entity, options.ToRequestOptions(),     cancellationToken).ConfigureAwait(false);
            return response.ToDocumentStorageResponse();
        }

Select Operation

 Select Operation
ReadDocumentAsync - 2.x
private static async Task ReadDocumentAsync()
        {
            Console.WriteLine("\n1.2 - Reading Document by Id");

            var response = await client.ReadDocumentAsync(
            	UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder1"), 
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });
		}

ReadDocumentCollectionAsync - 2.x
private static async Task ReadDocumentCollectionAsync()
        {
            Console.WriteLine("\n1.7 - Reading a document");
            ResourceResponse<Document> response = await client.ReadDocumentCollectionAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });
        }

CreateDocumentAsync - 2.x
private static SalesOrder QueryDocuments()
        {
            Console.WriteLine("\n1.4 - Querying for a document using its AccountNumber property");

            SalesOrder querySalesOrder = client.CreateDocumentQuery<SalesOrder>(
                UriFactory.CreateDocumentCollectionUri(databaseName, collectionName))
                .Where(so => so.AccountNumber == "Account1")
                .AsEnumerable()
                .First();

            Console.WriteLine(querySalesOrder.AccountNumber);
            return querySalesOrder;
        }

ReadItemAsync - 3.x
private static async Task ReadItemAsync()
        {
            Console.WriteLine("\n1.2 - Reading Item by Id");

            // Note that Reads require a partition key to be specified.
            ItemResponse<SalesOrder> response = await container.ReadItemAsync<SalesOrder>(
                partitionKey: new PartitionKey("Account1"),
                id: "SalesOrder1");
		}

GetDocumentAsync - CosmonautClient
public Task<TEntity> FindAsync<TEntity>(string id, DocumentOptions options = null, CancellationToken cancellationToken = default)
            where TEntity : Entity
        {
            return this.documentClient.GetDocumentAsync<TEntity>(this.databaseName, this.collectionName, id, options.ToRequestOptions(), cancellationToken);
        }

Update Operation

 Update Operation
ReplaceDocumentAsync - 2.x
	private static async Task ReplaceDocumentAsync(SalesOrder order)
        {
            Console.WriteLine("\n1.5 - Replacing a document using its Id");
            order.ShippedDate = DateTime.UtcNow;
            ResourceResponse<Document> response = await client.ReplaceDocumentAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, order.Id), 
                order);

            var updated = response.Resource;
            Console.WriteLine("Request charge of replace operation: {0}", response.RequestCharge);
            Console.WriteLine("Shipped date of updated document: {0}", updated.GetPropertyValue<DateTime>("ShippedDate"));
        }

ReplaceCollectionDocumentAsync - 2.x
private static async Task ReplaceDocumentCollectionAsync()
        {
            Console.WriteLine("\n1.7 - Updating a document");
            ResourceResponse<Document> response = await client.ReplaceDocumentCollectionAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });

            Console.WriteLine("Request charge of update operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }

ReplaceItemAsync - 3.x
private static async Task ReplaceItemAsync(SalesOrder order)
        {
            Console.WriteLine("\n1.6 - Replacing a item using its Id");

            order.ShippedDate = DateTime.UtcNow;
            ItemResponse<SalesOrder> response = await container.ReplaceItemAsync(
                partitionKey: new PartitionKey(order.AccountNumber),
                id: order.Id,
                item: order);
		}

UpdateDocumentAsync - CosmonautClient
public async Task<DocumentStorageResponse<TEntity>> UpdateAsync<TEntity>(TEntity entity, DocumentOptions options = null, CancellationToken cancellationToken = default)
            where TEntity : Entity
        {
            var requestOptions = options.ToRequestOptions();
            var document = entity.ToCosmonautDocument(this.settings.JsonSerializerSettings);
            var response = await this.documentClient.UpdateDocumentAsync(this.databaseName, this.collectionName, document, requestOptions, cancellationToken)              .ExecuteCosmosCommand(entity).ConfigureAwait(false);
            return response.ToDocumentStorageResponse();
        }

Upsert Operation

 Upsert Operation
UpsertDocumentAsync - 2.x
private static async Task UpsertDocumentAsync()
        {
            Console.WriteLine("\n1.6 - Upserting a document");

            var upsertOrder = GetSalesOrderSample("SalesOrder3");
            ResourceResponse<Document> response = await client.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName), upsertOrder);
            var upserted = response.Resource;

            Console.WriteLine("Request charge of upsert operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of this operation: {0}", response.StatusCode);
            Console.WriteLine("Id of upserted document: {0}", upserted.Id);
            Console.WriteLine("AccountNumber of upserted document: {0}", upserted.GetPropertyValue<string>("AccountNumber"));

            upserted.SetPropertyValue("AccountNumber", "updated account number");
            response = await client.UpsertDocumentAsync(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName), upserted);
            upserted = response.Resource;

            Console.WriteLine("Request charge of upsert operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of this operation: {0}", response.StatusCode);
            Console.WriteLine("Id of upserted document: {0}", upserted.Id);
            Console.WriteLine("AccountNumber of upserted document: {0}", upserted.GetPropertyValue<string>("AccountNumber"));
        }

UpsertItemAsync - 3.x
private static async Task UpsertItemAsync()
        {
            Console.WriteLine("\n1.8 - Upserting a item");

            SalesOrder upsertOrder = GetSalesOrderSample("SalesOrder3");
            
            //creates the initial SalesOrder document. 
            //notice the response.StatusCode returned indicates a Create operation was performed
            ItemResponse<SalesOrder> response = await container.UpsertItemAsync(
                partitionKey: new PartitionKey(upsertOrder.AccountNumber),
                item: upsertOrder);
		}

UpsertDocumentAsync - CosmonautClient
public async Task<DocumentStorageResponse<TEntity>> UpsertAsync<TEntity>(TEntity entity, DocumentOptions options = null, CancellationToken cancellationToken = default)
        where TEntity : Entity
        {
              var requestOptions = options.ToRequestOptions();
              var document = entity.ToCosmonautDocument(this.settings.JsonSerializerSettings);
              var response = await this.documentClient.UpsertDocumentAsync(this.databaseName, this.collectionName, document, requestOptions, cancellationToken).ExecuteCosmosCommand(entity).ConfigureAwait(false);
              return response.ToDocumentStorageResponse();
        }

Delete Operation

 Delete Operation
DeleteDocumentAsync - 2.x
 private static async Task DeleteDocumentAsync()
        {
            Console.WriteLine("\n1.7 - Deleting a document");
            ResourceResponse<Document> response = await client.DeleteDocumentAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });

            Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }

DeleteDocumentCollectionAsync - 2.x
private static async Task DeleteDocumentCollectionAsync()
        {
            Console.WriteLine("\n1.7 - Deleting a document");
            ResourceResponse<Document> response = await client.DeleteDocumentCollectionAsync(
                UriFactory.CreateDocumentUri(databaseName, collectionName, "SalesOrder3"),
                new RequestOptions { PartitionKey = new PartitionKey("Account1") });

            Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }

DeleteItemAsync - 3.x
private static async Task DeleteItemAsync()
        {
            Console.WriteLine("\n1.9 - Deleting a item");
            ItemResponse<SalesOrder> response = await container.DeleteItemAsync<SalesOrder>(
                partitionKey: new PartitionKey("Account1"),
                id: "SalesOrder3");

            Console.WriteLine("Request charge of delete operation: {0}", response.RequestCharge);
            Console.WriteLine("StatusCode of operation: {0}", response.StatusCode);
        }

DeleteDocumentAsync - CosmonautClient
public async Task<DocumentStorageResponse<TEntity>> RemoveAsync<TEntity>(string id, DocumentOptions options = null, CancellationToken cancellationToken = default)
             where TEntity : Entity
             {
                    var response = await this.documentClient.DeleteDocumentAsync(this.databaseName, this.collectionName, id, options.ToRequestOptions(), cancellationToken)
.ExecuteCosmosCommand<TEntity>(null).ConfigureAwait(false);
                    return response.ToDocumentStorageResponse();
             }

Reading App.config

 App.config
CreateDocumentAsync - 2.x
private static readonly string collectionName = ConfigurationManager.AppSettings["CollectionName"];
private static readonly string database = ConfigurationManager.AppSettings["DatabaseName"];
private static void InsertDataWithDatabaseAndCollectionArgument(Family family)
{
	await this.client.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(database, collectionName), family);

}
App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
	<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<appSettings>
	<add key="EndPointUrl" value="https://localhost:443/" />
	<add key="AuthorizationKey" value="C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==" />
	<add key="DatabaseName" value="bulkUpdateDb" />
	<add key="CollectionName" value="bulkUpdateColl" />
	<add key="CollectionThroughput" value="100000" />
	<add key="ShouldCleanupOnStart" value="false" />
	<add key="ShouldCleanupOnFinish" value="false" />
	<add key="NumberOfDocumentsToUpdate" value="2500000" />
	<add key="NumberOfBatches" value="25" />
	<add key="CollectionPartitionKey" value="/profileid" />
</appSettings>

Evolution

  • Support for CosmosDB 3.x
  • Better resolution of Database and Collection names
  • Provided support to additional APIs
  • Reading Database and Collection values from App.config
  • Support for CosmonautClient

Limitations

  • Unknown database and collection objects are created when unable to resolve Database and Collection
  • No labels