Skip to content

Commit

Permalink
Update spring data cosmos to track2 cosmos SDK v4 dependency (#13229)
Browse files Browse the repository at this point in the history
* Updated spring-data-cosmos to cosmos V4 dependency

* Updated CosmosDbUtils name

* Updated CosmosDB* CosmosDb* to Cosmos* class names for rebranding

* Fixed readme and code snippets

* Removed unused imports

* Fixed code snippets because of unused removed import:
  • Loading branch information
kushagraThapar authored Jul 16, 2020
1 parent ab7e851 commit 61b37c9
Show file tree
Hide file tree
Showing 132 changed files with 2,052 additions and 2,437 deletions.
112 changes: 64 additions & 48 deletions sdk/cosmos/azure-spring-data-cosmos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
* [Spring data version support](#spring-data-version-support)
* [Feature List](#feature-list)
* [Quick Start](#quick-start)
* [Query Partitioned Collection](QueryPartitionedCollection.md)
* [Beta version package](#Beta version package)
* [Troubleshooting](#Troubleshooting)
* [Contributing](#Contributing)
Expand All @@ -34,14 +33,14 @@ Please refer to [sample project here](./samplecode).
There're 2 ways to map a field in domain class to `id` field of Azure Cosmos DB document.
- annotate a field in domain class with `@Id`, this field will be mapped to document `id` in Cosmos DB.
- set name of this field to `id`, this field will be mapped to document `id` in Azure Cosmos DB.
- Custom collection Name.
By default, collection name will be class name of user domain class. To customize it, add the `@Document(collection="myCustomCollectionName")` annotation to the domain class. The collection field also supports SpEL expressions (eg. `collection = "${dynamic.collection.name}"` or `collection = "#{@someBean.getContainerName()}"`) in order to provide collection names programmatically/via configuration properties.
- Custom container Name.
By default, container name will be class name of user domain class. To customize it, add the `@Document(container="myCustomContainerName")` annotation to the domain class. The container field also supports SpEL expressions (eg. `container = "${dynamic.container.name}"` or `container = "#{@someBean.getContainerName()}"`) in order to provide container names programmatically/via configuration properties.
- Custom IndexingPolicy
By default, IndexingPolicy will be set by azure service. To customize it add annotation `@DocumentIndexingPolicy` to domain class. This annotation has 4 attributes to customize, see following:
<!-- embedme src/samples/java/com/azure/cosmos/DocumentIndexingPolicyCodeSnippet.java#L16-L26 -->
```java
// Indicate if indexing policy use automatic or not
boolean automatic() default Constants.DEFAULT_INDEXINGPOLICY_AUTOMATIC;
boolean automatic() default Constants.DEFAULT_INDEXING_POLICY_AUTOMATIC;

// Indexing policy mode, option Consistent|Lazy|None.
IndexingMode mode() default IndexingMode.CONSISTENT;
Expand All @@ -53,11 +52,11 @@ String[] includePaths() default {};
String[] excludePaths() default {};
```

- Supports Optimistic Locking for specific collections, which means upserts/deletes by document will fail with an exception in case the document was modified by another process in the meanwhile. To enable Optimistic Locking for a collection, just create a string `_etag` field and mark it with the `@Version` annotation. See the following:
- Supports Optimistic Locking for specific containers, which means upserts/deletes by document will fail with an exception in case the document was modified by another process in the meanwhile. To enable Optimistic Locking for a container, just create a string `_etag` field and mark it with the `@Version` annotation. See the following:

<!-- embedme src/samples/java/com/azure/cosmos/MyDocument.java#L14-L20 -->
```java
@Document(collection = "myCollection")
@Document(container = "myContainer")
public class MyDocument {
String id;
String data;
Expand All @@ -70,23 +69,27 @@ public class MyDocument {
- Supports [Spring Data pagable and sort](https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories.special-parameters).
- Based on available RUs on the database account, cosmosDB can return documents less than or equal to the requested size.
- Due to this variable number of returned documents in every iteration, user should not rely on the totalPageSize, and instead iterating over pageable should be done in this way.
<!-- embedme src/samples/java/com/azure/cosmos/PageableRepositoryCodeSnippet.java#L29-L36 -->
<!-- embedme src/samples/java/com/azure/cosmos/PageableRepositoryCodeSnippet.java#L27-L38 -->
```java
final CosmosPageRequest pageRequest = new CosmosPageRequest(0, pageSize, null);
Page<T> page = repository.findAll(pageRequest);
List<T> pageContent = page.getContent();
while (page.hasNext()) {
Pageable nextPageable = page.nextPageable();
page = repository.findAll(nextPageable);
pageContent = page.getContent();
private List<T> findAllWithPageSize(int pageSize) {

final CosmosPageRequest pageRequest = new CosmosPageRequest(0, pageSize, null);
Page<T> page = repository.findAll(pageRequest);
List<T> pageContent = page.getContent();
while (page.hasNext()) {
Pageable nextPageable = page.nextPageable();
page = repository.findAll(nextPageable);
pageContent = page.getContent();
}
return pageContent;
}
```
- Supports [spring-boot-starter-data-rest](https://projects.spring.io/spring-data-rest/).
- Supports List and nested type in domain class.
- Configurable ObjectMapper bean with unique name `cosmosdbObjectMapper`, only configure customized ObjectMapper if you really need to. e.g.,
- Configurable ObjectMapper bean with unique name `cosmosObjectMapper`, only configure customized ObjectMapper if you really need to. e.g.,
<!-- embedme src/samples/java/com/azure/cosmos/ObjectMapperConfigurationCodeSnippet.java#L17-L20 -->
```java
@Bean(name = "cosmosdbObjectMapper")
@Bean(name = "cosmosObjectMapper")
public ObjectMapper objectMapper() {
return new ObjectMapper(); // Do configuration to the ObjectMapper if required
}
Expand Down Expand Up @@ -122,9 +125,9 @@ 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.
Set `queryMetricsEnabled` flag to true in application.properties to enable query metrics.
In addition to setting the flag, implement `ResponseDiagnosticsProcessor` to log diagnostics information.
<!-- embedme src/samples/java/com/azure/cosmos/AppConfiguration.java#L21-L65 -->
<!-- embedme src/samples/java/com/azure/cosmos/AppConfiguration.java#L22-L73 -->

```java
@Configuration
Expand All @@ -133,34 +136,41 @@ public class AppConfiguration extends AbstractCosmosConfiguration {

private static final Logger logger = LoggerFactory.getLogger(AppConfiguration.class);

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

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

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

@Value("${azure.cosmosdb.database}")
@Value("${azure.cosmos.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;
@Value("${azure.cosmos.queryMetricsEnabled}")
private boolean queryMetricsEnabled;

private AzureKeyCredential azureKeyCredential;

public CosmosConfig getConfig() {
this.azureKeyCredential = new AzureKeyCredential(key);
DirectConnectionConfig directConnectionConfig = new DirectConnectionConfig();
GatewayConnectionConfig gatewayConnectionConfig = new GatewayConnectionConfig();
CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder()
.endpoint(uri)
.credential(azureKeyCredential)
.directMode(directConnectionConfig, gatewayConnectionConfig);
return CosmosConfig.builder()
.database(dbName)
.enableQueryMetrics(queryMetricsEnabled)
.cosmosClientBuilder(cosmosClientBuilder)
.responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
.build();
}

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

private static class ResponseDiagnosticsProcessorImplementation implements ResponseDiagnosticsProcessor {
Expand All @@ -174,14 +184,20 @@ public class AppConfiguration extends AbstractCosmosConfiguration {
}
```
Or if you want to customize your config:
<!-- embedme src/samples/java/com/azure/cosmos/AppConfigurationCodeSnippet.java#L40-L46 -->
<!-- embedme src/samples/java/com/azure/cosmos/AppConfigurationCodeSnippet.java#L44-L56 -->
```java
public CosmosDBConfig getConfig() {
this.cosmosKeyCredential = new CosmosKeyCredential(key);
CosmosDBConfig cosmosDbConfig = CosmosDBConfig.builder(uri, this.cosmosKeyCredential, dbName).build();
cosmosDbConfig.getConnectionPolicy().connectionMode(ConnectionMode.DIRECT);
cosmosDbConfig.getConnectionPolicy().maxPoolSize(1000);
return cosmosDbConfig;
public CosmosConfig getConfig() {
DirectConnectionConfig directConnectionConfig = new DirectConnectionConfig();
GatewayConnectionConfig gatewayConnectionConfig = new GatewayConnectionConfig();
CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder()
.endpoint(uri)
.directMode(directConnectionConfig, gatewayConnectionConfig);
return CosmosConfig.builder()
.database(dbName)
.enableQueryMetrics(queryMetricsEnabled)
.cosmosClientBuilder(cosmosClientBuilder)
.responseDiagnosticsProcessor(new ResponseDiagnosticsProcessorImplementation())
.build();
}
```
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 `@EnableCosmosRepositories(basePackageClass=UserRepository.class)` if your project layout has multiple projects and it's not finding your repositories.
Expand All @@ -192,12 +208,12 @@ 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.
Containers will be created automatically unless you don't want them to: Set `autoCreateContainer` 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).
Note: By default request units assigned to newly created containers is 4000. Specify different ru value to customize request units for the container created by the SDK (minimum RU value is 400).
<!-- embedme src/samples/java/com/azure/cosmos/User.java#L14-L62 -->
```java
@Document(collection = "myCollection", ru = "400")
@Document(container = "myContainer", ru = "400")
public class User {
private String id;
private String firstName;
Expand Down Expand Up @@ -249,11 +265,11 @@ public class User {
```
`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 `@Document(container="myContainer")` is used to specify container name in Azure Cosmos DB.
Annotation `@PartitionKey` on `lastName` field is used to specify this field be partition key in Azure Cosmos DB.
<!-- embedme src/samples/java/com/azure/cosmos/UserSample.java#L14-L19 -->
```java
@Document(collection = "mycollection")
@Document(container = "myContainer")
public class UserSample {
@Id
private String emailAddress;
Expand All @@ -263,7 +279,7 @@ public class UserSample {

### Create repositories
Extends CosmosRepository interface, which provides Spring Data repository support.
<!-- embedme src/samples/java/com/azure/cosmos/UserRepository.java#L17-L22 -->
<!-- embedme src/samples/java/com/azure/cosmos/UserRepository.java#L17-L21 -->

```java
@Repository
Expand Down
35 changes: 17 additions & 18 deletions sdk/cosmos/azure-spring-data-cosmos/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,48 +42,41 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.2.6.RELEASE</version> <!-- {x-version-update;org.springframework:spring-web;external_dependency} -->
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.6.RELEASE</version> <!-- {x-version-update;org.springframework:spring-beans;external_dependency} -->
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version> <!-- {x-version-update;org.springframework:spring-context;external_dependency} -->
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.6.RELEASE</version> <!-- {x-version-update;org.springframework:spring-tx;external_dependency} -->
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.3.0.RELEASE</version> <!-- {x-version-update;org.springframework.data:spring-data-commons;external_dependency} -->
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>5.2.6.RELEASE</version> <!-- {x-version-update;org.springframework:spring-expression;external_dependency} -->
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<groupId>com.azure</groupId>
<artifactId>azure-cosmos</artifactId>
<version>3.7.3</version> <!-- {x-version-update;com.microsoft.azure:azure-cosmos;external_dependency} -->
<version>4.3.0-beta.1</version> <!-- {x-version-update;com.azure:azure-cosmos;current} -->
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-parameter-names</artifactId>
Expand All @@ -104,18 +97,21 @@
<artifactId>json</artifactId>
<version>20140107</version> <!-- {x-version-update;org.json:json;external_dependency} -->
</dependency>

<dependency>
<groupId>org.javatuples</groupId>
<artifactId>javatuples</artifactId>
<version>1.2</version> <!-- {x-version-update;org.javatuples:javatuples;external_dependency} -->
</dependency>

<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version> <!-- {x-version-update;javax.annotation:javax.annotation-api;external_dependency} -->
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.8.1</version> <!-- {x-version-update;org.apache.commons:commons-lang3;external_dependency} -->
</dependency>

<!-- Test -->
<dependency>
Expand Down Expand Up @@ -148,26 +144,29 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<version>3.3.5.RELEASE</version> <!-- {x-version-update;io.projectreactor:reactor-test;external_dependency} -->
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version> <!-- {x-version-update;org.slf4j:slf4j-simple;external_dependency} -->
<scope>test</scope>
</dependency>
<!-- Added this provided dependency to include necessary annotations used by "reactor-core".
Without this dependency, javadoc throws a warning as it cannot find enum When.MAYBE
which is used in @Nullable annotation in reactor core classes.
Similar provided dependency exits for "azure-core" as well.
-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version> <!-- {x-version-update;com.google.code.gson:gson;external_dependency} -->
<scope>test</scope>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version> <!-- {x-version-update;com.google.code.findbugs:jsr305;external_dependency} -->
<scope>provided</scope>
</dependency>
</dependencies>

Expand Down Expand Up @@ -198,13 +197,13 @@
<include>org.springframework:spring-core:[5.2.6.RELEASE]</include> <!-- {x-include-update;org.springframework:spring-core;external_dependency} -->
<include>org.springframework:spring-context:[5.2.6.RELEASE]</include> <!-- {x-include-update;org.springframework:spring-context;external_dependency} -->
<include>org.springframework.data:spring-data-commons:[2.3.0.RELEASE]</include> <!-- {x-include-update;org.springframework.data:spring-data-commons;external_dependency} -->
<include>com.microsoft.azure:azure-cosmos:[3.7.3]</include> <!-- {x-include-update;com.microsoft.azure:azure-cosmos;external_dependency} -->
<include>org.javatuples:javatuples:[1.2]</include> <!-- {x-include-update;org.javatuples:javatuples;external_dependency} -->
<include>com.fasterxml.jackson.datatype:jackson-datatype-jdk8:[2.10.0]</include> <!-- {x-include-update;com.fasterxml.jackson.datatype:jackson-datatype-jdk8;external_dependency} -->
<include>com.fasterxml.jackson.datatype:jackson-datatype-jsr310:[2.10.1]</include> <!-- {x-include-update;com.fasterxml.jackson.datatype:jackson-datatype-jsr310;external_dependency} -->
<include>org.json:json:[20140107]</include> <!-- {x-include-update;org.json:json;external_dependency} -->
<include>com.fasterxml.jackson.module:jackson-module-parameter-names:[2.10.0]</include> <!-- {x-include-update;com.fasterxml.jackson.module:jackson-module-parameter-names;external_dependency} -->
<include>javax.annotation:javax.annotation-api:[1.3.2]</include> <!-- {x-include-update;javax.annotation:javax.annotation-api;external_dependency} -->
<include>org.apache.commons:commons-lang3:[3.8.1]</include> <!-- {x-include-update;org.apache.commons:commons-lang3;external_dependency} -->
</includes>
</bannedDependencies>
</rules>
Expand Down
Loading

0 comments on commit 61b37c9

Please sign in to comment.