Support of Azure Cosmos DB for Java

CAST supports Azure Cosmos DB via its com.castsoftware.nosqljava extension. Details about how this support is provided for Java source code is discussed below.

Supported Client Libraries

Library Version Supported
Azure Cosmos DB Java SDK for SQL API Up to: 4.32.0 ✔️
Azure Cosmos DB Async Java SDK for SQL API Up to: 4.32.0 ✔️
Azure Cosmos DB Java SDK v4 Up to: 4.32.0 ✔️

Supported Operations

Operations Method Supported
Insert - v2 com.microsoft.azure.documentdb.DocumentClient.createDocument
com.microsoft.azure.documentdb.DocumentClient.createCollection
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.createDocument
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.createCollection
Insert - v4 com.azure.cosmos.CosmosAsyncContainer.createItem
com.azure.cosmos.CosmosContainer.createItem
Update - v2 com.microsoft.azure.documentdb.DocumentClient.replaceDocument
com.microsoft.azure.documentdb.DocumentClient.upsertDocument
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.replaceDocument
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.replaceCollection
Update - v4 com.azure.cosmos.CosmosAsyncContainer.replaceItem
com.azure.cosmos.CosmosAsyncContainer.replace
com.azure.cosmos.CosmosContainer.replace
com.azure.cosmos.CosmosContainer.replaceItem
Select - v2 com.microsoft.azure.documentdb.DocumentClient.queryDocuments
com.microsoft.azure.documentdb.DocumentClient.readDocument
com.microsoft.azure.documentdb.DocumentClient.readCollection
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.queryDocuments
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.readDocument
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.readCollection
com.azure.cosmos.CosmosAsyncContainer.queryItems
Select - v4 com.azure.cosmos.CosmosAsyncContainer.readItem
com.azure.cosmos.CosmosAsyncContainer.getId
com.azure.cosmos.CosmosAsyncContainer.read
com.azure.cosmos.CosmosAsyncContainer.readAllItems
com.azure.cosmos.CosmosAsyncContainer.readMany
com.azure.cosmos.CosmosContainer.getId
com.azure.cosmos.CosmosContainer.queryItems
com.azure.cosmos.CosmosContainer.read
com.azure.cosmos.CosmosContainer.readItem
com.azure.cosmos.CosmosContainer.readAllItems
com.azure.cosmos.CosmosContainer.readMany
Delete - v2 com.microsoft.azure.documentdb.DocumentClient.deleteDocument
com.microsoft.azure.documentdb.DocumentClient.deleteCollection
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.deleteDocument
com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient.deleteCollection
Delete - v4 com.azure.cosmos.CosmosAsyncContainer.delete
com.azure.cosmos.CosmosAsyncContainer.deleteItem
com.azure.cosmos.CosmosContainer.delete
com.azure.cosmos.CosmosContainer.deleteItem

Above mentioned methods are supported for both Synchronous and Asynchronous clients.

Objects

Icon Description
Java CosmosDB Database
Java CosmosDB Collection
Java Unknown CosmosDB Database
Java Unknown CosmosDB Collection
Link type Source and destination of link Methods Supported
belongsTo From Java CosmosDB Collection object to Java CosmosDB Database object -
useLink Between the caller Java Method objects and Java CosmosDB Collection object CreateCollection
useInsertLink Between the caller Java Method objects and Java CosmosDB Collection object CreateDocument
createItem
useUpdateLink Between the caller Java Method objects and Java CosmosDB Collection object ReplaceDocument
replaceItem
useSelectLink Between the caller Java Method objects and Java CosmosDB Collection object ReadDocument
ReadDocuments
QueryDocuments
ReadCollection
queryItems
readItem
readAllItems
readMany
useDeleteLink Between the caller Java Method objects and Java CosmosDB Collection object DeleteDocument
DeleteCollection
deleteItem

What results can you expect?

 Some example scenarios are shown below:

Cosmos DB Client Creation

CosmoDB client creation

private static final String HOST = "[YOUR_ENDPOINT_HERE]";
 private static final String MASTER_KEY = "[YOUR_KEY_HERE]";
 
 private static DocumentClient documentClient = new DocumentClient(HOST, MASTER_KEY,
                 ConnectionPolicy.GetDefault(), ConsistencyLevel.Session);
 
 public static DocumentClient getDocumentClient() {
     return documentClient;
 }

CosmoDb Async client creation

import com.microsoft.azure.cosmosdb.rx.AsyncDocumentClient;
    
public AsyncDocumentClient client = new AsyncDocumentClient.Builder()
            .withServiceEndpoint(AccountSettings.HOST)
            .withMasterKeyOrResourceToken(AccountSettings.MASTER_KEY)
            .withConnectionPolicy(ConnectionPolicy.GetDefault())
            .withConsistencyLevel(ConsistencyLevel.Eventual)
            .build();

Insert Data Operation

v2

  public static Family andersenFamily = new Family();

    public void TestCreateDocument() throws DocumentClientException {
        // Insert your Java objects as documents
        System.out.println("Creating doc");

        andersenFamily.setId("Andersen.1");
        andersenFamily.setLastName("Andersen");

        this.client.createDocument("/dbs/familydb/colls/familycoll", andersenFamily, new RequestOptions(), true);

        System.out.println("Done Creating doc");
    }

v4

@Override
  public Single<OutcomingAccountStatus> createStatus(IncomingCreateAccountStatus incoming) {

    Mono<YapeAccountStatus> createYapeAccountStatus =
        defer(() -> {
          YapeAccountStatus yapeAccountStatus = new YapeAccountStatus();
          yapeAccountStatus.setId(generateId());
          yapeAccountStatus.setIdYapeAccount(incoming.getIdYapeAccount());
          yapeAccountStatus.setStatus(incoming.getStatus());
          yapeAccountStatus.setCreationDate(incoming.getCreationDate());

          return cosmosAsyncDatabase.getContainer(CONTAINER_YAPE_ACCOUNT_STATUS)
              .createItem(yapeAccountStatus,
                  new PartitionKey(yapeAccountStatus.getIdYapeAccount()),
                  new CosmosItemRequestOptions())
              .retryWhen(noLongerAvailable)
              .map(itemResponse -> yapeAccountStatus);
        }

Select Data Operation

v2

public void TestQueryDocuments() {

        System.out.println("Querying db...");
        FeedResponse<Document> queryResults = this.client.queryDocuments("/dbs/familydb/colls/familycoll",
                "SELECT * FROM Family WHERE Family.id = 'Andersen.1'", null);

        System.out.println("Running SQL query...");
        for (Document family : queryResults.getQueryIterable()) {
            System.out.println(String.format("\tRead %s", family));
        }

    }

public void TestReadDocument() throws DocumentClientException {
        this.client.readDocument("/dbs/familydb/colls/familycoll/docs/Andersen.1", null);
    }

public void TestReadDocuments() throws DocumentClientException {
        this.client.readDocuments("/dbs/familydb", null);
    }

v4

private Mono<YapeAccountStatus> getLastStatusMono(String idYapeAccount) {
SqlQuerySpec sqsGetLastStatusQuery = SqlBuilder.create()
.query("select top 1 s.status from s where s.idYapeAccount = @idYapeAccount "
+ "and s.status != @statusDeleted order by s.creationDate desc")
.parameters(
new SqlParameter("@idYapeAccount", idYapeAccount),
new SqlParameter("@statusDeleted", AccountStatus.DELETED.getCode()))
.buildSqlQuerySpec();

CosmosQueryRequestOptions options = new CosmosQueryRequestOptions();
options.setPartitionKey(new PartitionKey(idYapeAccount));

return cosmosAsyncDatabase.getContainer(CONTAINER_YAPE_ACCOUNT_STATUS)
.queryItems(sqsGetLastStatusQuery, options, YapeAccountStatus.class)
.singleOrEmpty()
.retryWhen(noLongerAvailable);
}

Update Operation

v2

public void TestReplaceDocument() throws DocumentClientException {
        // Update a property
        andersenFamily.setLastName("Petersons");
        this.client.replaceDocument("/dbs/familydb/colls/familycoll/docs/Andersen.1", andersenFamily, null);
    }

v4

 private Mono<BlockedResources> replaceItem(BlockedResources blockedResources, CosmosItemRequestOptions options) {

    return getBlockedResourcesContainer().replaceItem(blockedResources, blockedResources.getId(),
        new PartitionKey(blockedResources.getResource()), options)
        .retryWhen(noLongerAvailable)
        .doOnSuccess(itemResponse -> blockedResources.set_etag(itemResponse.getETag()))
        .map(itemResponse -> blockedResources);
  }

Delete Operation

public void TestDeleteDocument() throws DocumentClientException {
        this.client.deleteDocument("", null);
    }

Known Limitations

Major limitations

No support for Cassandra API, MongoDB API, Gremlin API, Table API or other APIs built by Microsoft for accessing an Azure Cosmos DB service. See the API reference here:

Minor limitations     

  • Database and collection names are resolved as known objects when a connection string is passed to the client directly:

    • Example: This connection string is passed to client - “/dbs/familydb/colls/familycoll” 
  • Database and collection are marked as Unknown when Database Collection and document objects are passed as an argument in CRUD methods.

  • Runtime Ambiguities are not resolved:

    • Example: Different databases are accessed in if/else cases based on some conditions