Travis CI codecov MIT License

Spring Data for Azure Cosmos DB

Azure Cosmos DB is a globally-distributed database service that allows developers to work with data using a variety of standard APIs, such as SQL, MongoDB, Cassandra, Graph, and Table.

Spring Data Azure Cosmos DB provides initial Spring Data support for Azure Cosmos DB using the SQL API, based on Spring Data framework. Currently it only supports SQL API, the other APIs are in the plan.

TOC

Sample Code

Please refer to sample project here.

Spring Data Version Support

Version mapping between spring boot and spring-data-cosmosdb:

Spring boot version spring-data-cosmosdb version
version Maven Central
version Maven Central
version Maven Central
version Maven Central

Feature List

@Document(collection = "myCollection")
class MyDocument {
    String id;
    String data;
    @Version
    String _etag;
}

Quick Start

Add the dependency

spring-data-cosmosdb is published on Maven Central Repository.
If you are using Maven, add the following dependency.

<dependency>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>spring-data-cosmosdb</artifactId>
    <version>2.2.4</version>
</dependency>

Setup Configuration

Setup configuration class.

CosmosKeyCredential feature provides capability to rotate keys on the fly. You can switch keys using switchToSecondaryKey(). For more information on this, see the Sample Application code.

Sync and Reactive Repository support

2.2.x supports both sync and reactive repository support.

Use @EnableCosmosRepositories to enable sync repository support.

For reactive repository support, use @EnableReactiveCosmosRepositories

Response Diagnostics String and Query Metrics

2.2.x supports Response Diagnostics String and Query Metrics. Set populateQueryMetrics flag to true in application.properties to enable query metrics. In addition to setting the flag, implement ResponseDiagnosticsProcessor to log diagnostics information.

@Configuration
@EnableCosmosRepositories
@Slf4j
public class AppConfiguration extends AbstractCosmosConfiguration {

    @Value("${azure.cosmosdb.uri}")
    private String uri;

    @Value("${azure.cosmosdb.key}")
    private String key;

    @Value("${azure.cosmosdb.secondaryKey}")
    private String secondaryKey;

    @Value("${azure.cosmosdb.database}")
    private String dbName;

    @Value("${azure.cosmosdb.populateQueryMetrics}")
    private boolean populateQueryMetrics;

    private CosmosKeyCredential cosmosKeyCredential;

    public CosmosDBConfig getConfig() {
        this.cosmosKeyCredential = new CosmosKeyCredential(key);
        CosmosDbConfig cosmosdbConfig = CosmosDBConfig.builder(uri, 
            this.cosmosKeyCredential, dbName).build();
        cosmosdbConfig.setPopulateQueryMetrics(populateQueryMetrics);
        cosmosdbConfig.setResponseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation());
        return cosmosdbConfig;
    }

    public void switchToSecondaryKey() {
        this.cosmosKeyCredential.key(secondaryKey);
    }

    private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {

        @Override
        public void processResponseDiagnostics(@Nullable ResponseDiagnostics responseDiagnostics) {
            log.info("Response Diagnostics {}", responseDiagnostics);
        }
    }

}

Or if you want to customize your config:

public CosmosDBConfig getConfig() {
    this.cosmosKeyCredential = new CosmosKeyCredential(key);
    CosmosDBConfig cosmosDbConfig = CosmosDBConfig.builder(uri, this.cosmosKeyCredential, dbName).build();
    cosmosDbConfig.getConnectionPolicy().setConnectionMode(ConnectionMode.DIRECT);
    cosmosDbConfig.getConnectionPolicy().setMaxPoolSize(1000);
    return cosmosDbConfig;
}

By default, @EnableCosmosRepositories will scan the current package for any interfaces that extend one of Spring Data's repository interfaces. Using it to annotate your Configuration class to scan a different root package by type if your project layout has multiple projects and it's not finding your repositories.

@Configuration
@EnableCosmosRepositories(basePackageClass=UserRepository.class)
public class AppConfiguration extends AbstractCosmosConfiguration {
    // configuration code
}

Define an entity

Define a simple entity as Document in Azure Cosmos DB.

You can define entities by adding the @Document annotation and specifying properties related to the container, such as the container name, request units (RUs), time to live, and auto-create container.

Containers are created automatically unless you don't want them to: Set autoCreateCollection to false in @Document annotation to disable auto creation of containers.

Note: By default request units assigned to newly created containers is 4000. Specify different ru value to customize request units for container created by the SDK (minimum RU value is 400).

@Document(collection = "myCollection", ru = "400")
public class User {
    private String id;
    private String firstName;

    @PartitionKey
    private String lastName;

    ... // setters and getters

    public User() {
        // If you do not want to create a default constructor, 
        // use annotation @JsonCreator and @JsonProperty in the full args constructor
    }

    public User(String id, String firstName, String lastName) {
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return String.format("User: %s %s, %s", firstName, lastName, id);
    }
}

id field will be used as document id in Azure Cosmos DB. If you want use another field like emailAddress as document id, just annotate that field with @Id annotation.

Annotation @Document(collection="mycollection") is used to specify collection name in Azure Cosmos DB. Annotation @PartitionKey on lastName field is used to specify this field be partition key in Azure Cosmos DB.

@Document(collection = "mycollection")
public class User {
    @Id
    private String emailAddress;

    ...
}

Create repositories

Extends CosmosRepository interface, which provides Spring Data repository support.

import CosmosRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends CosmosRepository<User, String> {
    List<User> findByFirstName(String firstName); 
}

findByFirstName method is custom query method, it will find documents per FirstName.

Create an Application class

Here create an application class with all the components

@SpringBootApplication
public class SampleApplication implements CommandLineRunner {

    @Autowired
    private UserRepository repository;

    @Autowired
    private ApplicationContext applicationContext;

    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }

    public void run(String... var1) throws Exception {

        final User testUser = new User("testId", "testFirstName", "testLastName");

        repository.deleteAll();
        repository.save(testUser);

        // to find by Id, please specify partition key value if collection is partitioned
        final User result = repository.findOne(testUser.getId(), testUser.getLastName);
        // if emailAddress is mapped to id, then 
        // final User result = respository.findOne(testUser.getEmailAddress(), testUser.getLastName());

        //  Switch to secondary key
        UserRepositoryConfiguration bean = 
            applicationContext.getBean(UserRepositoryConfiguration.class);
        bean.switchToSecondaryKey();

        //  Now repository will use secondary key
        repository.save(testUser);

    }
}

Autowired UserRepository interface, then can do save, delete and find operations. Spring Data Azure Cosmos DB uses the CosmosTemplate to execute the queries behind find, save methods. You can use the template yourself for more complex queries.

Snapshots

Nexus OSS

Snapshots built from master branch are available, add maven repositories configuration to your pom file as below.

<repositories>
  <repository>
    <id>nexus-snapshots</id>
    <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
    <snapshots>
      <enabled>true</enabled>
      <updatePolicy>always</updatePolicy>
    </snapshots>
  </repository>
</repositories>

Filing Issues

If you encounter any bug, please file an issue here.

To suggest a new feature or changes that could be made, file an issue the same way you would for a bug.

How To Contribute

Contribution is welcome. Please follow this instruction to contribute code.

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

Data/Telemetry

This project collects usage data and sends it to Microsoft to help improve our products and services. Read our privacy statement to learn more.