diff --git a/eng/jacoco-test-coverage/pom.xml b/eng/jacoco-test-coverage/pom.xml
index 5aa8c39c69a0..7bfc683dcffc 100644
--- a/eng/jacoco-test-coverage/pom.xml
+++ b/eng/jacoco-test-coverage/pom.xml
@@ -252,6 +252,31 @@
azure-active-directory-b2c-spring-boot-starter
2.2.5-beta.1
+
+ com.microsoft.azure
+ azure-spring-boot
+ 2.2.5-beta.1
+
+
+ com.microsoft.azure
+ azure-spring-boot-starter
+ 2.2.5-beta.1
+
+
+ com.microsoft.azure
+ azure-active-directory-spring-boot-starter
+ 2.2.5-beta.1
+
+
+ com.microsoft.azure
+ azure-cosmosdb-spring-boot-starter
+ 2.2.5-beta.1
+
+
+ com.microsoft.azure
+ azure-data-gremlin-spring-boot-starter
+ 2.2.5-beta.1
+
diff --git a/eng/versioning/external_dependencies.txt b/eng/versioning/external_dependencies.txt
index e4368562b8a1..a7adcc60456b 100644
--- a/eng/versioning/external_dependencies.txt
+++ b/eng/versioning/external_dependencies.txt
@@ -15,11 +15,14 @@ com.microsoft.azure:azure-arm-client-runtime;1.7.3
com.microsoft.azure:azure-client-authentication;1.7.3
com.microsoft.azure:azure-client-runtime;1.7.3
com.microsoft.azure:azure-core;0.9.8
+com.microsoft.azure:azure-cosmos;3.7.1
com.microsoft.azure:azure-keyvault-cryptography;1.2.2
com.microsoft.azure:qpid-proton-j-extensions;1.2.3
com.microsoft.azure:spotbugs-maven-plugin;1.2.1
+com.microsoft.azure:spring-data-cosmosdb;2.2.3.FIX1
com.microsoft.rest:client-runtime;1.7.4
com.microsoft.rest.v2:client-runtime;2.1.1
+com.microsoft.spring.data.gremlin:spring-data-gremlin;2.2.3
com.squareup.okhttp3:okhttp;4.2.2
commons-codec:commons-codec;1.13
io.micrometer:micrometer-core;1.2.0
diff --git a/eng/versioning/version_client.txt b/eng/versioning/version_client.txt
index a6bac276a0cc..32060dea7fd7 100644
--- a/eng/versioning/version_client.txt
+++ b/eng/versioning/version_client.txt
@@ -44,8 +44,10 @@ com.azure:perf-test-core;1.0.0-beta.1;1.0.0-beta.1
com.azure:azure-test-watcher;1.0.0-beta.1;1.0.0-beta.1
com.microsoft.azure:azure-spring-boot;2.2.4;2.2.5-beta.1
com.microsoft.azure:azure-spring-boot-starter;2.2.4;2.2.5-beta.1
-com.microsoft.azure:azure-active-directory-b2c-spring-boot-starter;2.2.4;2.2.5-beta.1
com.microsoft.azure:azure-active-directory-spring-boot-starter;2.2.4;2.2.5-beta.1
+com.microsoft.azure:azure-active-directory-b2c-spring-boot-starter;2.2.4;2.2.5-beta.1
+com.microsoft.azure:azure-cosmosdb-spring-boot-starter;2.2.4;2.2.5-beta.1
+com.microsoft.azure:azure-data-gremlin-spring-boot-starter;2.2.4;2.2.5-beta.1
com.microsoft.azure:azure-keyvault-secrets-spring-boot-starter;2.2.4;2.2.5-beta.1
com.microsoft.azure:azure-servicebus-jms-spring-boot-starter;2.2.4;2.2.5-beta.1
com.microsoft.azure:azure-spring-boot-metrics-starter;2.2.4;2.2.5-beta.1
diff --git a/sdk/spring/azure-spring-boot-starter-cosmosdb/CHANGELOG.md b/sdk/spring/azure-spring-boot-starter-cosmosdb/CHANGELOG.md
new file mode 100644
index 000000000000..d51e263177a9
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-cosmosdb/CHANGELOG.md
@@ -0,0 +1,3 @@
+# Release History
+
+## 2.2.5-beta.1 (Unreleased)
diff --git a/sdk/spring/azure-spring-boot-starter-cosmosdb/README.md b/sdk/spring/azure-spring-boot-starter-cosmosdb/README.md
new file mode 100644
index 000000000000..37b71d43fa99
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-cosmosdb/README.md
@@ -0,0 +1,214 @@
+## Azure Cosmos DB Spring Boot Starter client library for Java
+
+[Azure Cosmos DB](https://azure.microsoft.com/services/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, Graph, and Azure Table storage.
+
+## TOC
+
+* [Key concepts](#key-concepts)
+* [Examples](#examples)
+* [Getting started](#getting-started)
+
+## Key concepts
+- Spring Data ReactiveCrudRepository basic CRUD functionality
+ - save
+ - findAll
+ - findOne by Id
+ - deleteAll
+ - delete by Id
+ - delete entity
+- Spring Data [@Id](https://github.com/spring-projects/spring-data-commons/blob/db62390de90c93a78743c97cc2cc9ccd964994a5/src/main/java/org/springframework/data/annotation/Id.java) annotation.
+ There're 2 ways to map a field in domain class to `id` 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 Cosmos DB.
+ [Note] if both way applied,
+- Custom collection Name.
+ By default, collection name will be class name of user domain class. To customize it, add annotation `@Document(collection="myCustomCollectionName")` to your domain class, that's all.
+- Supports [Azure Cosmos DB partition](https://docs.microsoft.com/azure/cosmos-db/partition-data). To specify a field of your domain class to be partition key field, just annotate it with `@PartitionKey`. When you do CRUD operation, please specify your partition value. For more sample on partition CRUD, please refer to [test here](./test/java/com/microsoft/azure/spring/data/cosmosdb/repository/AddressRepositoryIT.java)
+- Supports [Spring Data custom query](https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories.query-methods.details) find operation.
+- Supports [spring-boot-starter-data-rest](https://projects.spring.io/spring-data-rest/).
+- Supports List and nested type in domain class.
+
+## Examples
+Please refer to [sample project here](../azure-spring-boot-samples/azure-spring-boot-sample-cosmosdb).
+
+## Getting started
+
+### Add the dependency
+
+`azure-cosmosdb-spring-boot-starter` is published on Maven Central Repository.
+If you are using Maven, add the following dependency.
+
+[//]: # ({x-version-update-start;com.azure:azure-cosmosdb-spring-boot-starter;current})
+```xml
+
+ com.azure
+ azure-cosmosdb-spring-boot-starter
+ 2.2.5-beta.1
+
+```
+[//]: # ({x-version-update-end})
+
+### Add the property setting
+
+Open `application.properties` file and add below properties with your Cosmos DB credentials.
+
+```properties
+azure.cosmosdb.uri=your-cosmosdb-uri
+azure.cosmosdb.key=your-cosmosdb-key
+azure.cosmosdb.database=your-cosmosdb-databasename
+```
+
+Property `azure.cosmosdb.consistency-level` is also supported.
+
+Property `azure.cosmosdb.cosmosKeyCredential` is also supported. 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.
+
+### Define an entity
+Define a simple entity as Document in Cosmos DB.
+
+```java
+@Document(collection = "mycollection")
+public class User {
+ @Id
+ private String id;
+ private String firstName;
+ @PartitionKey
+ private String lastName;
+ private String address;
+
+ public User() {
+ }
+
+ public User(String id, String firstName, String lastName, String address) {
+ this.id = id;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.address = address;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s %s, %s", firstName, lastName, address);
+ }
+}
+```
+`id` field will be used as document `id` in Azure Cosmos DB. Or you can annotate any field with `@Id` to map it to document `id`.
+
+Annotation `@Document(collection="mycollection")` is used to specify the collection name of your document in Azure Cosmos DB.
+
+### Create repositories
+Extends ReactiveCosmosRepository interface, which provides Spring Data repository support.
+
+```java
+@Repository
+public interface UserRepository extends ReactiveCosmosRepository {
+
+ Flux findByFirstName(String firstName);
+}
+```
+
+So far ReactiveCosmosRepository provides basic save, delete and find operations. More operations will be supported later.
+
+### Create an Application class
+Here create an application class with all the components
+
+```java
+@SpringBootApplication
+public class CosmosSampleApplication implements CommandLineRunner {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CosmosSampleApplication.class);
+
+ @Autowired
+ private UserRepository repository;
+
+ public static void main(String[] args) {
+ SpringApplication.run(CosmosSampleApplication.class, args);
+ }
+
+ public void run(String... var1) {
+ final User testUser = new User("testId", "testFirstName", "testLastName", "test address line one");
+
+ // Save the User class to Azure CosmosDB database.
+ final Mono saveUserMono = repository.save(testUser);
+
+ final Flux firstNameUserFlux = repository.findByFirstName("testFirstName");
+
+ // Nothing happens until we subscribe to these Monos.
+ // findById will not return the user as user is not present.
+ final Mono findByIdMono = repository.findById(testUser.getId());
+ final User findByIdUser = findByIdMono.block();
+ Assert.isNull(findByIdUser, "User must be null");
+
+ final User savedUser = saveUserMono.block();
+ Assert.state(savedUser != null, "Saved user must not be null");
+ Assert.state(savedUser.getFirstName().equals(testUser.getFirstName()), "Saved user first name doesn't match");
+
+ firstNameUserFlux.collectList().block();
+
+ final Optional optionalUserResult = repository.findById(testUser.getId()).blockOptional();
+ Assert.isTrue(optionalUserResult.isPresent(), "Cannot find user.");
+
+ final User result = optionalUserResult.get();
+ Assert.state(result.getFirstName().equals(testUser.getFirstName()), "query result firstName doesn't match!");
+ Assert.state(result.getLastName().equals(testUser.getLastName()), "query result lastName doesn't match!");
+
+ LOGGER.info("findOne in User collection get result: {}", result.toString());
+ }
+
+ @PostConstruct
+ public void setup() {
+ // For this example, remove all of the existing records.
+ this.repository.deleteAll().block();
+ }
+}
+```
+Autowired UserRepository interface, then can do save, delete and find operations.
+
+### Allow telemetry
+Microsoft would like to collect data about how users use this Spring boot starter. Microsoft uses this information to improve our tooling experience. Participation is voluntary. If you don't want to participate, just simply disable it by setting below configuration in `application.properties`.
+```properties
+azure.cosmosdb.allow-telemetry=false
+```
+When telemetry is enabled, an HTTP request will be sent to URL `https://dc.services.visualstudio.com/v2/track`. So please make sure it's not blocked by your firewall.
+Find more information about Azure Service Privacy Statement, please check [Microsoft Online Services Privacy Statement](https://www.microsoft.com/privacystatement/OnlineServices/Default.aspx).
+
+## Troubleshooting
+
+## Next steps
+
+Besides using this Azure CosmosDb Spring Boot Starter, you can directly use Spring Data for Azure CosmosDb package for more complex scenarios. Please refer to [Spring Data for Azure CosmosDB](https://github.com/Microsoft/spring-data-cosmosdb) for more details.
+
+## Contributing
diff --git a/sdk/spring/azure-spring-boot-starter-cosmosdb/pom.xml b/sdk/spring/azure-spring-boot-starter-cosmosdb/pom.xml
new file mode 100644
index 000000000000..18395ccedc3e
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-cosmosdb/pom.xml
@@ -0,0 +1,135 @@
+
+
+ 4.0.0
+
+
+ com.azure
+ azure-client-sdk-parent
+ 1.7.0
+ ../../parents/azure-client-sdk-parent
+
+
+ com.microsoft.azure
+ azure-cosmosdb-spring-boot-starter
+ 2.2.5-beta.1
+
+ Azure Cosmos DB Spring Boot Starter
+ Spring Boot Starter for Azure Document DB service
+ https://github.com/Azure/azure-sdk-for-java
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ 2.2.0.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ 2.2.0.RELEASE
+
+
+ com.microsoft.azure
+ azure-spring-boot
+ 2.2.5-beta.1
+
+
+ com.microsoft.azure
+ spring-data-cosmosdb
+ 2.2.3.FIX1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.0.0-M3
+
+
+
+
+ com.microsoft.azure:*
+ org.springframework.boot:spring-boot-starter:[2.2.0.RELEASE]
+ org.springframework.boot:spring-boot-starter-validation:[2.2.0.RELEASE]
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.1.1
+
+
+ attach-javadocs
+
+ jar
+
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.2
+
+
+ empty-javadoc-jar-with-readme
+ package
+
+ jar
+
+
+ javadoc
+ ${project.basedir}/javadocTemp
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.8
+
+
+ copy-readme-to-javadocTemp
+ prepare-package
+
+
+ Deleting existing ${project.basedir}/javadocTemp
+
+
+
+ Copying ${project.basedir}/README.md to
+ ${project.basedir}/javadocTemp/README.md
+
+
+
+
+
+ run
+
+
+
+
+
+
+
+
diff --git a/sdk/spring/azure-spring-boot-starter-cosmosdb/src/main/resources/cosmosdb.enable.config b/sdk/spring/azure-spring-boot-starter-cosmosdb/src/main/resources/cosmosdb.enable.config
new file mode 100644
index 000000000000..2995a4d0e749
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-cosmosdb/src/main/resources/cosmosdb.enable.config
@@ -0,0 +1 @@
+dummy
\ No newline at end of file
diff --git a/sdk/spring/azure-spring-boot-starter-data-gremlin/CHANGELOG.md b/sdk/spring/azure-spring-boot-starter-data-gremlin/CHANGELOG.md
new file mode 100644
index 000000000000..d51e263177a9
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-data-gremlin/CHANGELOG.md
@@ -0,0 +1,3 @@
+# Release History
+
+## 2.2.5-beta.1 (Unreleased)
diff --git a/sdk/spring/azure-spring-boot-starter-data-gremlin/README.md b/sdk/spring/azure-spring-boot-starter-data-gremlin/README.md
new file mode 100644
index 000000000000..53f13c8f0dab
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-data-gremlin/README.md
@@ -0,0 +1,211 @@
+# Sample for Azure Gremlin Spring Boot Starter client library for Java
+
+## Key concepts
+
+**Spring Data Gremlin** provides initial Spring Data support for those databases using Gremlin query language. With annotation oriented programming model, it simplified the mapping to the database entity. It also provides supports for basic and custom query.
+
+This project works with *any Gremlin-compatible* data store, and also with [Azure Cosmos DB](https://docs.microsoft.com/azure/cosmos-db/introduction). Cosmos is a globally-distributed database service that allows developers to work with data using a variety of standard APIs, such as Graph, MongoDB, and SQL. Spring Data Gremlin provides a delightful experience to interact with Azure Cosmos DB Graph API.
+
+## Examples
+Please refer to [sample project here](../azure-spring-boot-samples/azure-spring-boot-sample-data-gremlin).
+
+## Getting started
+
+### Add the dependency
+`azure-data-gremlin-spring-boot-starter` is published on Maven Central Repository. If you are using Maven, add the following dependency.
+
+[//]: # ({x-version-update-start;com.azure:azure-data-gremlin-spring-boot-starter;current})
+```xml
+
+ com.azure
+ azure-data-gremlin-spring-boot-starter
+ 2.2.5-beta.1
+
+```
+[//]: # ({x-version-update-end})
+
+### Setup Configuration
+Setup ```application.yml``` file.(Use Azure Cosmos DB Graph as an example.)
+
+```yaml
+gremlin:
+ endpoint: url-of-endpoint
+ port: 443
+ username: /dbs/your-db-name/colls/your-collection-name
+ password: your-password
+ telemetryAllowed: true # set false to disable telemetry
+
+```
+
+### Define an entity
+Define a simple Vertex entity with ```@Vertex```.
+
+```java
+@Vertex
+public class Person {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ private String level;
+
+ public Person() {
+ }
+
+ public Person(String id, String name, String level) {
+ this.id = id;
+ this.name = name;
+ this.level = level;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Person person = (Person) o;
+ return Objects.equals(id, person.id)
+ && Objects.equals(name, person.name)
+ && Objects.equals(level, person.level);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, level);
+ }
+
+ @Override
+ public String toString() {
+ return "Person{"
+ + "id='" + id + '\''
+ + ", name='" + name + '\''
+ + ", level='" + level + '\''
+ + '}';
+ }
+}
+```
+
+Define a simple Edge entity with ```@Edge```.
+
+
+```java
+@Edge
+public class Relation {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ @EdgeFrom
+ private Person personFrom;
+
+ @EdgeTo
+ private Person personTo;
+}
+```
+Define a simple Graph entity with ```@Graph```.
+
+```java
+@Graph
+public class Network {
+
+ @Id
+ private String id;
+
+ public Network() {
+ this.edges = new ArrayList();
+ this.vertexes = new ArrayList();
+ }
+
+ @EdgeSet
+ private List edges;
+
+ @VertexSet
+ private List vertexes;
+}
+```
+
+### Create repositories
+Extends CosmosRepository interface, which provides Spring Data repository support.
+
+```java
+@Repository
+public interface PersonRepository extends GremlinRepository {
+ List findByName(String name);
+}
+```
+
+`findByName` method is custom query method, it will find the person with the ```name``` property.
+
+### Create an Application class
+Here create an application class with all the components
+
+```java
+@SpringBootApplication
+public class SampleApplication implements CommandLineRunner {
+
+ @Autowired
+ private PersonRepository repository;
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleApplication.class, args);
+ }
+
+ public void run(String... var1) {
+
+ final Person testUser = new Person("PERSON_ID", "PERSON_NAME", "PERSON_AGE");
+
+ repository.deleteAll();
+ repository.save(testUser);
+ }
+}
+```
+Autowired UserRepository interface, then can do save, delete and find operations. Spring Data Azure Cosmos DB uses the DocumentTemplate to execute the queries behind *find*, *save* methods. You can use the template yourself for more complex queries.
+
+## Allow telemetry
+Microsoft would like to collect data about how users use this Spring boot starter. Microsoft uses this information to improve our tooling experience. Participation is voluntary. If you don't want to participate, just simply disable it by setting below configuration in `application.properties`.
+```properties
+gremlin.allow-telemetry=false
+```
+When telemetry is enabled, an HTTP request will be sent to URL `https://dc.services.visualstudio.com/v2/track`. So please make sure it's not blocked by your firewall.
+Find more information about Azure Service Privacy Statement, please check [Microsoft Online Services Privacy Statement](https://www.microsoft.com/privacystatement/OnlineServices/Default.aspx).
+
+
+## Troubleshooting
+
+If you encounter any bug, please file an issue [here](https://github.com/Microsoft/spring-data-gremlin/issues/new?template=custom.md).
+
+To suggest a new feature or changes that could be made, file an issue the same way you would for a bug.
+
+## Next steps
+## Contributing
diff --git a/sdk/spring/azure-spring-boot-starter-data-gremlin/pom.xml b/sdk/spring/azure-spring-boot-starter-data-gremlin/pom.xml
new file mode 100644
index 000000000000..d8d10a829409
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-data-gremlin/pom.xml
@@ -0,0 +1,141 @@
+
+
+ 4.0.0
+
+ com.azure
+ azure-client-sdk-parent
+ 1.7.0
+ ../../parents/azure-client-sdk-parent
+
+
+ com.microsoft.azure
+ azure-data-gremlin-spring-boot-starter
+ 2.2.5-beta.1
+
+ Spring Data Gremlin Boot Starter
+ Spring Boot Starter for Spring Data Gremlin
+ https://github.com/Azure/azure-sdk-for-java
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+ 2.2.0.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+ 2.2.0.RELEASE
+
+
+ com.microsoft.azure
+ azure-spring-boot
+ 2.2.5-beta.1
+
+
+ com.microsoft.spring.data.gremlin
+ spring-data-gremlin
+ 2.2.3
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+ 2.10.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-enforcer-plugin
+ 3.0.0-M3
+
+
+
+
+ com.microsoft.azure:*
+ com.fasterxml.jackson.core:jackson-core:[2.10.1]
+ com.microsoft.spring.data.gremlin:spring-data-gremlin:[2.2.3]
+ org.springframework.boot:spring-boot-starter:[2.2.0.RELEASE]
+ org.springframework.boot:spring-boot-starter-validation:[2.2.0.RELEASE]
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.1.1
+
+
+ attach-javadocs
+
+ jar
+
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.2
+
+
+ empty-javadoc-jar-with-readme
+ package
+
+ jar
+
+
+ javadoc
+ ${project.basedir}/javadocTemp
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-antrun-plugin
+ 1.8
+
+
+ copy-readme-to-javadocTemp
+ prepare-package
+
+
+ Deleting existing ${project.basedir}/javadocTemp
+
+
+
+ Copying ${project.basedir}/README.md to
+ ${project.basedir}/javadocTemp/README.md
+
+
+
+
+
+ run
+
+
+
+
+
+
+
+
diff --git a/sdk/spring/azure-spring-boot-starter-data-gremlin/src/main/resources/gremlin.enable.config b/sdk/spring/azure-spring-boot-starter-data-gremlin/src/main/resources/gremlin.enable.config
new file mode 100644
index 000000000000..2995a4d0e749
--- /dev/null
+++ b/sdk/spring/azure-spring-boot-starter-data-gremlin/src/main/resources/gremlin.enable.config
@@ -0,0 +1 @@
+dummy
\ No newline at end of file
diff --git a/sdk/spring/azure-spring-boot/pom.xml b/sdk/spring/azure-spring-boot/pom.xml
index 7a21682a9994..c632017b8f1c 100644
--- a/sdk/spring/azure-spring-boot/pom.xml
+++ b/sdk/spring/azure-spring-boot/pom.xml
@@ -106,6 +106,18 @@
true
+
+
+ com.microsoft.spring.data.gremlin
+ spring-data-gremlin
+ 2.2.3
+
+
+ com.microsoft.azure
+ spring-data-cosmosdb
+ 2.2.3.FIX1
+
+
io.micrometer
@@ -246,6 +258,8 @@
com.fasterxml.jackson.core:jackson-databind:[2.10.1]
com.google.code.findbugs:jsr305:[3.0.2]
com.microsoft.azure:msal4j:[1.3.0]
+ com.microsoft.azure:spring-data-cosmosdb:[2.2.3.FIX1]
+ com.microsoft.spring.data.gremlin:spring-data-gremlin:[2.2.3]
com.nimbusds:nimbus-jose-jwt:[7.9]
io.micrometer:micrometer-core:[1.3.0]
io.micrometer:micrometer-registry-azure-monitor:[1.3.0]
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosAutoConfiguration.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosAutoConfiguration.java
new file mode 100644
index 000000000000..56af8d3654a2
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosAutoConfiguration.java
@@ -0,0 +1,55 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.azure.data.cosmos.ConnectionPolicy;
+import com.azure.data.cosmos.CosmosClient;
+import com.microsoft.azure.spring.data.cosmosdb.config.AbstractCosmosConfiguration;
+import com.microsoft.azure.spring.data.cosmosdb.config.CosmosDBConfig;
+import com.microsoft.azure.spring.data.cosmosdb.core.CosmosTemplate;
+import org.springframework.beans.factory.ObjectProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Auto Configure CosmosDB properties and connection policy.
+ */
+@Configuration
+@ConditionalOnClass({ CosmosClient.class, CosmosTemplate.class })
+@ConditionalOnResource(resources = "classpath:cosmosdb.enable.config")
+@EnableConfigurationProperties(CosmosDBProperties.class)
+public class CosmosAutoConfiguration extends AbstractCosmosConfiguration {
+ private final CosmosDBProperties properties;
+ private final ConnectionPolicy policy;
+
+ public CosmosAutoConfiguration(CosmosDBProperties properties,
+ ObjectProvider connectionPolicyObjectProvider) {
+ this.properties = properties;
+ this.policy = connectionPolicyObjectProvider.getIfAvailable();
+ configConnectionPolicy(properties, policy);
+ }
+
+ @Bean
+ public CosmosDBConfig cosmosDBConfig() {
+
+ return CosmosDBConfig.builder(
+ properties.getUri(), properties.getKey(), properties.getDatabase())
+ .consistencyLevel(properties.getConsistencyLevel())
+ .allowTelemetry(properties.isAllowTelemetry())
+ .connectionPolicy(properties.getConnectionPolicy())
+ .responseDiagnosticsProcessor(properties.getResponseDiagnosticsProcessor())
+ .populateQueryMetrics(properties.isPopulateQueryMetrics())
+ .build();
+ }
+
+ private void configConnectionPolicy(CosmosDBProperties properties, ConnectionPolicy connectionPolicy) {
+ // This is a temp fix as CosmosDbFactory does not support loading ConnectionPolicy bean from context
+ final ConnectionPolicy policy = connectionPolicy == null ? ConnectionPolicy.defaultPolicy() : connectionPolicy;
+
+ properties.setConnectionPolicy(policy);
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDBProperties.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDBProperties.java
new file mode 100644
index 000000000000..a1018f4e4293
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDBProperties.java
@@ -0,0 +1,133 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.azure.data.cosmos.ConnectionPolicy;
+import com.azure.data.cosmos.ConsistencyLevel;
+import com.microsoft.azure.spring.data.cosmosdb.core.ResponseDiagnosticsProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * Configuration properties for CosmosDB database, consistency, telemetry, connection, query metrics and diagnostics.
+ */
+@Validated
+@ConfigurationProperties("azure.cosmosdb")
+public class CosmosDBProperties {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CosmosDBProperties.class);
+ /**
+ * Document DB URI.
+ */
+ @NotEmpty
+ private String uri;
+
+ /**
+ * Document DB key.
+ */
+ @NotEmpty
+ private String key;
+
+ /**
+ * Document DB consistency level.
+ */
+ private ConsistencyLevel consistencyLevel;
+
+ /**
+ * Document DB database name.
+ */
+ @NotEmpty
+ private String database;
+
+ /**
+ * Populate Diagnostics Strings and Query metrics
+ */
+ private boolean populateQueryMetrics;
+
+ /**
+ * Whether allow Microsoft to collect telemetry data.
+ */
+ private boolean allowTelemetry = true;
+
+ /**
+ * Response Diagnostics processor
+ * Default implementation is to log the response diagnostics string
+ */
+ private ResponseDiagnosticsProcessor responseDiagnosticsProcessor =
+ responseDiagnostics -> {
+ if (populateQueryMetrics) {
+ LOGGER.info("Response Diagnostics {}", responseDiagnostics);
+ }
+ };
+
+ private ConnectionPolicy connectionPolicy = ConnectionPolicy.defaultPolicy();
+
+ public String getUri() {
+ return uri;
+ }
+
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ public String getDatabase() {
+ return database;
+ }
+
+ public void setDatabase(String databaseName) {
+ this.database = databaseName;
+ }
+
+ public ConsistencyLevel getConsistencyLevel() {
+ return consistencyLevel;
+ }
+
+ public void setConsistencyLevel(ConsistencyLevel consistencyLevel) {
+ this.consistencyLevel = consistencyLevel;
+ }
+
+ public boolean isAllowTelemetry() {
+ return allowTelemetry;
+ }
+
+ public void setAllowTelemetry(boolean allowTelemetry) {
+ this.allowTelemetry = allowTelemetry;
+ }
+
+ public ConnectionPolicy getConnectionPolicy() {
+ return connectionPolicy;
+ }
+
+ public void setConnectionPolicy(ConnectionPolicy connectionPolicy) {
+ this.connectionPolicy = connectionPolicy;
+ }
+
+ public boolean isPopulateQueryMetrics() {
+ return populateQueryMetrics;
+ }
+
+ public void setPopulateQueryMetrics(boolean populateQueryMetrics) {
+ this.populateQueryMetrics = populateQueryMetrics;
+ }
+
+ public ResponseDiagnosticsProcessor getResponseDiagnosticsProcessor() {
+ return responseDiagnosticsProcessor;
+ }
+
+ public void setResponseDiagnosticsProcessor(ResponseDiagnosticsProcessor responseDiagnosticsProcessor) {
+ this.responseDiagnosticsProcessor = responseDiagnosticsProcessor;
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbReactiveRepositoriesAutoConfiguration.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbReactiveRepositoriesAutoConfiguration.java
new file mode 100644
index 000000000000..6188e20f3570
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbReactiveRepositoriesAutoConfiguration.java
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository;
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.ReactiveCosmosRepositoryConfigurationExtension;
+import com.microsoft.azure.spring.data.cosmosdb.repository.support.ReactiveCosmosRepositoryFactoryBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * Import {@link CosmosDbReactiveRepositoriesAutoConfigureRegistrar} class as a Bean in Spring.
+ */
+@Configuration
+@ConditionalOnClass({ ReactiveCosmosRepository.class })
+@ConditionalOnMissingBean({ ReactiveCosmosRepositoryFactoryBean.class,
+ ReactiveCosmosRepositoryConfigurationExtension.class })
+@ConditionalOnProperty(prefix = "azure.cosmosdb.repositories",
+ name = "enabled",
+ havingValue = "true",
+ matchIfMissing = true)
+@Import(CosmosDbReactiveRepositoriesAutoConfigureRegistrar.class)
+public class CosmosDbReactiveRepositoriesAutoConfiguration {
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbReactiveRepositoriesAutoConfigureRegistrar.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbReactiveRepositoriesAutoConfigureRegistrar.java
new file mode 100644
index 000000000000..e2fbce3f74aa
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbReactiveRepositoriesAutoConfigureRegistrar.java
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.EnableReactiveCosmosRepositories;
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.ReactiveCosmosRepositoryConfigurationExtension;
+import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Declare {@link EnableReactiveCosmosRepositories} annotation and {@link EnableCosmosDbReactiveRepositoriesConfiguration} configuration for default async auto-configuration.
+ */
+public class CosmosDbReactiveRepositoriesAutoConfigureRegistrar extends AbstractRepositoryConfigurationSourceSupport {
+ @Override
+ protected Class extends Annotation> getAnnotation() {
+ return EnableReactiveCosmosRepositories.class;
+ }
+
+ @Override
+ protected Class> getConfiguration() {
+ return EnableCosmosDbReactiveRepositoriesConfiguration.class;
+ }
+
+ @Override
+ protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
+ return new ReactiveCosmosRepositoryConfigurationExtension();
+ }
+
+ @EnableReactiveCosmosRepositories
+ private static class EnableCosmosDbReactiveRepositoriesConfiguration {
+
+ }
+
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfiguration.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfiguration.java
new file mode 100644
index 000000000000..e537312ce9db
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfiguration.java
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository;
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.CosmosRepositoryConfigurationExtension;
+import com.microsoft.azure.spring.data.cosmosdb.repository.support.CosmosRepositoryFactoryBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * Import {@link CosmosDbRepositoriesAutoConfigureRegistrar} class as a Bean in Spring.
+ */
+@Configuration
+@ConditionalOnClass({ CosmosRepository.class })
+@ConditionalOnMissingBean({ CosmosRepositoryFactoryBean.class,
+ CosmosRepositoryConfigurationExtension.class })
+@ConditionalOnProperty(prefix = "azure.cosmosdb.repositories",
+ name = "enabled",
+ havingValue = "true",
+ matchIfMissing = true)
+@Import(CosmosDbRepositoriesAutoConfigureRegistrar.class)
+public class CosmosDbRepositoriesAutoConfiguration {
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfigureRegistrar.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfigureRegistrar.java
new file mode 100644
index 000000000000..094a168baccb
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfigureRegistrar.java
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.CosmosRepositoryConfigurationExtension;
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.EnableCosmosRepositories;
+import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Declare {@link EnableCosmosRepositories} annotation and {@link EnableCosmosDbRepositoriesConfiguration} configuration for default non-async auto-configuration.
+ */
+public class CosmosDbRepositoriesAutoConfigureRegistrar extends AbstractRepositoryConfigurationSourceSupport {
+ @Override
+ protected Class extends Annotation> getAnnotation() {
+ return EnableCosmosRepositories.class;
+ }
+
+ @Override
+ protected Class> getConfiguration() {
+ return EnableCosmosDbRepositoriesConfiguration.class;
+ }
+
+ @Override
+ protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
+ return new CosmosRepositoryConfigurationExtension();
+ }
+
+ @EnableCosmosRepositories
+ private static class EnableCosmosDbRepositoriesConfiguration {
+
+ }
+
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinAutoConfiguration.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinAutoConfiguration.java
new file mode 100644
index 000000000000..a872ec1a738a
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinAutoConfiguration.java
@@ -0,0 +1,104 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import com.microsoft.azure.telemetry.TelemetrySender;
+import com.microsoft.spring.data.gremlin.common.GremlinConfig;
+import com.microsoft.spring.data.gremlin.common.GremlinFactory;
+import com.microsoft.spring.data.gremlin.conversion.MappingGremlinConverter;
+import com.microsoft.spring.data.gremlin.mapping.GremlinMappingContext;
+import com.microsoft.spring.data.gremlin.query.GremlinTemplate;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnResource;
+import org.springframework.boot.autoconfigure.domain.EntityScanner;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.annotation.Persistent;
+import org.springframework.lang.NonNull;
+import org.springframework.util.ClassUtils;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.microsoft.azure.telemetry.TelemetryData.SERVICE_NAME;
+import static com.microsoft.azure.telemetry.TelemetryData.getClassPackageSimpleName;
+
+/**
+ * To create Gremlin factory and template for auto-configure Gremlin properties.
+ */
+@Configuration
+@ConditionalOnClass({GremlinFactory.class, GremlinTemplate.class, MappingGremlinConverter.class})
+@ConditionalOnResource(resources = "classpath:gremlin.enable.config")
+@ConditionalOnProperty(prefix = "gremlin", value = {"endpoint", "port", "username", "password"})
+@EnableConfigurationProperties(GremlinProperties.class)
+public class GremlinAutoConfiguration {
+
+ private final GremlinProperties properties;
+
+ private final ApplicationContext applicationContext;
+
+ public GremlinAutoConfiguration(@NonNull GremlinProperties properties, @NonNull ApplicationContext context) {
+ this.properties = properties;
+ this.applicationContext = context;
+ }
+
+ @PostConstruct
+ private void sendTelemetry() {
+ if (properties.isTelemetryAllowed()) {
+ final Map events = new HashMap<>();
+ final TelemetrySender sender = new TelemetrySender();
+
+ events.put(SERVICE_NAME, getClassPackageSimpleName(GremlinAutoConfiguration.class));
+
+ sender.send(ClassUtils.getUserClass(getClass()).getSimpleName(), events);
+ }
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public GremlinConfig getGremlinConfig() {
+ return GremlinConfig.builder(properties.getEndpoint(), properties.getUsername(), properties.getPassword())
+ .port(properties.getPort())
+ .sslEnabled(properties.isSslEnabled())
+ .telemetryAllowed(properties.isTelemetryAllowed())
+ .build();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public GremlinFactory gremlinFactory() {
+ return new GremlinFactory(getGremlinConfig());
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public GremlinTemplate gremlinTemplate(GremlinFactory factory, MappingGremlinConverter converter) {
+ return new GremlinTemplate(factory, converter);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public GremlinMappingContext gremlinMappingContext() {
+ try {
+ final GremlinMappingContext context = new GremlinMappingContext();
+
+ context.setInitialEntitySet(new EntityScanner(this.applicationContext).scan(Persistent.class));
+
+ return context;
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public MappingGremlinConverter mappingGremlinConverter(GremlinMappingContext context) {
+ return new MappingGremlinConverter(context);
+ }
+}
+
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinProperties.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinProperties.java
new file mode 100644
index 000000000000..da4c304f7be6
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinProperties.java
@@ -0,0 +1,79 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * Configuration properties for Gremlin login, telemetry, ssl.
+ */
+@Validated
+@ConfigurationProperties("gremlin")
+public class GremlinProperties {
+
+ @NotEmpty
+ private String endpoint;
+
+ private int port;
+
+ @NotEmpty
+ private String username;
+
+ @NotEmpty
+ private String password;
+
+ private boolean telemetryAllowed = true;
+
+ private boolean sslEnabled = true;
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public int getPort() {
+ return port;
+ }
+
+ public void setPort(int port) {
+ this.port = port;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public boolean isTelemetryAllowed() {
+ return telemetryAllowed;
+ }
+
+ public void setTelemetryAllowed(boolean telemetryAllowed) {
+ this.telemetryAllowed = telemetryAllowed;
+ }
+
+ public boolean isSslEnabled() {
+ return sslEnabled;
+ }
+
+ public void setSslEnabled(boolean sslEnabled) {
+ this.sslEnabled = sslEnabled;
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfiguration.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfiguration.java
new file mode 100644
index 000000000000..45cf4dce478b
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfiguration.java
@@ -0,0 +1,24 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import com.microsoft.spring.data.gremlin.repository.GremlinRepository;
+import com.microsoft.spring.data.gremlin.repository.config.GremlinRepositoryConfigurationExtension;
+import com.microsoft.spring.data.gremlin.repository.support.GremlinRepositoryFactoryBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * Import {@link GremlinRepositoriesAutoConfigureRegistrar} class as a Bean in Spring.
+ */
+@Configuration
+@ConditionalOnClass({GremlinRepository.class})
+@ConditionalOnMissingBean({GremlinRepositoryFactoryBean.class, GremlinRepositoryConfigurationExtension.class})
+@ConditionalOnProperty(prefix = "spring.data.gremlin.repositories", name = "enabled", havingValue = "true",
+ matchIfMissing = true)
+@Import(GremlinRepositoriesAutoConfigureRegistrar.class)
+public class GremlinRepositoriesAutoConfiguration {
+}
diff --git a/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfigureRegistrar.java b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfigureRegistrar.java
new file mode 100644
index 000000000000..2c2c148d2fee
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/main/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfigureRegistrar.java
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import com.microsoft.spring.data.gremlin.repository.config.EnableGremlinRepositories;
+import com.microsoft.spring.data.gremlin.repository.config.GremlinRepositoryConfigurationExtension;
+import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
+import org.springframework.data.repository.config.RepositoryConfigurationExtension;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Declare {@link EnableGremlinRepositories} annotation and {@link EnableGremlinRepositoriesConfiguration} configuration for default non-async auto-configuration.
+ */
+public class GremlinRepositoriesAutoConfigureRegistrar extends AbstractRepositoryConfigurationSourceSupport {
+
+ @Override
+ protected Class extends Annotation> getAnnotation() {
+ return EnableGremlinRepositories.class;
+ }
+
+ @Override
+ protected Class> getConfiguration() {
+ return EnableGremlinRepositoriesConfiguration.class;
+ }
+
+ @Override
+ protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
+ return new GremlinRepositoryConfigurationExtension();
+ }
+
+ @EnableGremlinRepositories
+ private static class EnableGremlinRepositoriesConfiguration {
+
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/CosmosSampleApplication.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/CosmosSampleApplication.java
new file mode 100644
index 000000000000..7a6c092a2e27
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/CosmosSampleApplication.java
@@ -0,0 +1,65 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.cosmosdb;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.util.Assert;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+import javax.annotation.PostConstruct;
+import java.util.Optional;
+
+@SpringBootApplication
+public class CosmosSampleApplication implements CommandLineRunner {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CosmosSampleApplication.class);
+
+ @Autowired
+ private UserRepository repository;
+
+ public static void main(String[] args) {
+ SpringApplication.run(CosmosSampleApplication.class, args);
+ }
+
+ public void run(String... var1) {
+ final User testUser = new User("testId", "testFirstName", "testLastName", "test address line one");
+
+ // Save the User class to Azure CosmosDB database.
+ final Mono saveUserMono = repository.save(testUser);
+
+ final Flux firstNameUserFlux = repository.findByFirstName("testFirstName");
+
+ // Nothing happens until we subscribe to these Monos.
+ // findById will not return the user as user is not present.
+ final Mono findByIdMono = repository.findById(testUser.getId());
+ final User findByIdUser = findByIdMono.block();
+ Assert.isNull(findByIdUser, "User must be null");
+
+ final User savedUser = saveUserMono.block();
+ Assert.state(savedUser != null, "Saved user must not be null");
+ Assert.state(savedUser.getFirstName().equals(testUser.getFirstName()), "Saved user first name doesn't match");
+
+ firstNameUserFlux.collectList().block();
+
+ final Optional optionalUserResult = repository.findById(testUser.getId()).blockOptional();
+ Assert.isTrue(optionalUserResult.isPresent(), "Cannot find user.");
+
+ final User result = optionalUserResult.get();
+ Assert.state(result.getFirstName().equals(testUser.getFirstName()), "query result firstName doesn't match!");
+ Assert.state(result.getLastName().equals(testUser.getLastName()), "query result lastName doesn't match!");
+
+ LOGGER.info("findOne in User collection get result: {}", result.toString());
+ }
+
+ @PostConstruct
+ public void setup() {
+ // For this example, remove all of the existing records.
+ this.repository.deleteAll().block();
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/User.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/User.java
new file mode 100644
index 000000000000..f8fae7a16c19
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/User.java
@@ -0,0 +1,66 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.spring.cosmosdb;
+
+import com.microsoft.azure.spring.data.cosmosdb.core.mapping.Document;
+import com.microsoft.azure.spring.data.cosmosdb.core.mapping.PartitionKey;
+import org.springframework.data.annotation.Id;
+
+@Document(collection = "mycollection")
+public class User {
+ @Id
+ private String id;
+ private String firstName;
+ @PartitionKey
+ private String lastName;
+ private String address;
+
+ public User() {
+ }
+
+ public User(String id, String firstName, String lastName, String address) {
+ this.id = id;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.address = address;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s %s, %s", firstName, lastName, address);
+ }
+}
+
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/UserRepository.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/UserRepository.java
new file mode 100644
index 000000000000..18711be2654b
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/cosmosdb/UserRepository.java
@@ -0,0 +1,14 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.azure.spring.cosmosdb;
+
+import com.microsoft.azure.spring.data.cosmosdb.repository.ReactiveCosmosRepository;
+import org.springframework.stereotype.Repository;
+import reactor.core.publisher.Flux;
+
+@Repository
+public interface UserRepository extends ReactiveCosmosRepository {
+
+ Flux findByFirstName(String firstName);
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Network.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Network.java
new file mode 100644
index 000000000000..2d5c7a71580f
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Network.java
@@ -0,0 +1,29 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.gremlin;
+
+import com.microsoft.spring.data.gremlin.annotation.EdgeSet;
+import com.microsoft.spring.data.gremlin.annotation.Graph;
+import com.microsoft.spring.data.gremlin.annotation.VertexSet;
+import org.springframework.data.annotation.Id;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Graph
+public class Network {
+
+ @Id
+ private String id;
+
+ public Network() {
+ this.edges = new ArrayList();
+ this.vertexes = new ArrayList();
+ }
+
+ @EdgeSet
+ private List edges;
+
+ @VertexSet
+ private List vertexes;
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Person.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Person.java
new file mode 100644
index 000000000000..37d63200d036
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Person.java
@@ -0,0 +1,80 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.gremlin;
+
+import com.microsoft.spring.data.gremlin.annotation.Vertex;
+import org.springframework.data.annotation.Id;
+
+import java.util.Objects;
+
+@Vertex
+public class Person {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ private String level;
+
+ public Person() {
+ }
+
+ public Person(String id, String name, String level) {
+ this.id = id;
+ this.name = name;
+ this.level = level;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Person person = (Person) o;
+ return Objects.equals(id, person.id)
+ && Objects.equals(name, person.name)
+ && Objects.equals(level, person.level);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, level);
+ }
+
+ @Override
+ public String toString() {
+ return "Person{"
+ + "id='" + id + '\''
+ + ", name='" + name + '\''
+ + ", level='" + level + '\''
+ + '}';
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/PersonRepository.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/PersonRepository.java
new file mode 100644
index 000000000000..bef156dd3fe1
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/PersonRepository.java
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.gremlin;
+
+import com.microsoft.spring.data.gremlin.repository.GremlinRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface PersonRepository extends GremlinRepository {
+ List findByName(String name);
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Relation.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Relation.java
new file mode 100644
index 000000000000..6038661d50da
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/Relation.java
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.gremlin;
+
+import com.microsoft.spring.data.gremlin.annotation.Edge;
+import com.microsoft.spring.data.gremlin.annotation.EdgeFrom;
+import com.microsoft.spring.data.gremlin.annotation.EdgeTo;
+import org.springframework.data.annotation.Id;
+
+@Edge
+public class Relation {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ @EdgeFrom
+ private Person personFrom;
+
+ @EdgeTo
+ private Person personTo;
+}
diff --git a/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/SampleApplication.java b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/SampleApplication.java
new file mode 100644
index 000000000000..f434962e276f
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/samples/java/com/azure/spring/gremlin/SampleApplication.java
@@ -0,0 +1,27 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.gremlin;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SampleApplication implements CommandLineRunner {
+
+ @Autowired
+ private PersonRepository repository;
+
+ public static void main(String[] args) {
+ SpringApplication.run(SampleApplication.class, args);
+ }
+
+ public void run(String... var1) {
+
+ final Person testUser = new Person("PERSON_ID", "PERSON_NAME", "PERSON_AGE");
+
+ repository.deleteAll();
+ repository.save(testUser);
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosAutoConfigurationTest.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosAutoConfigurationTest.java
new file mode 100644
index 000000000000..20f127702b41
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosAutoConfigurationTest.java
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+
+import com.azure.data.cosmos.ConnectionPolicy;
+import com.azure.data.cosmos.RetryOptions;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Ignore
+public class CosmosAutoConfigurationTest {
+ @BeforeClass
+ public static void beforeClass() {
+ PropertySettingUtil.setProperties();
+ }
+
+ @AfterClass
+ public static void afterClass() {
+ PropertySettingUtil.unsetProperties();
+ }
+
+ @Configuration
+ static class ConnectionPolicyConfig {
+ @Bean
+ public ConnectionPolicy connectionPolicy() {
+ final ConnectionPolicy connectionPolicy = ConnectionPolicy.defaultPolicy();
+
+ connectionPolicy.requestTimeoutInMillis(PropertySettingUtil.REQUEST_TIMEOUT);
+ connectionPolicy.connectionMode(PropertySettingUtil.CONNECTION_MODE);
+ connectionPolicy.maxPoolSize(PropertySettingUtil.MAX_POOL_SIZE);
+ connectionPolicy.idleConnectionTimeoutInMillis(PropertySettingUtil.IDLE_CONNECTION_TIMEOUT);
+ // TODO (data) User agent from configured ConnectionPolicy is not taken
+ connectionPolicy.userAgentSuffix(PropertySettingUtil.USER_AGENT_SUFFIX);
+
+ final RetryOptions retryOptions = new RetryOptions();
+ retryOptions.maxRetryAttemptsOnThrottledRequests(
+ PropertySettingUtil.RETRY_OPTIONS_MAX_RETRY_ATTEMPTS_ON_THROTTLED_REQUESTS);
+ retryOptions.maxRetryWaitTimeInSeconds(
+ PropertySettingUtil.RETRY_OPTIONS_MAX_RETRY_WAIT_TIME_IN_SECONDS);
+ connectionPolicy.retryOptions(retryOptions);
+
+ connectionPolicy.enableEndpointDiscovery(PropertySettingUtil.ENABLE_ENDPOINT_DISCOVERY);
+ connectionPolicy.preferredLocations(PropertySettingUtil.PREFERRED_LOCATIONS);
+
+ return connectionPolicy;
+ }
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDBPropertiesTest.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDBPropertiesTest.java
new file mode 100644
index 000000000000..73f628b1cbc2
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDBPropertiesTest.java
@@ -0,0 +1,97 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+
+import org.junit.Test;
+import org.springframework.boot.context.properties.ConfigurationPropertiesBindException;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.boot.context.properties.bind.validation.BindValidationException;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.validation.ObjectError;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CosmosDBPropertiesTest {
+ @Test
+ public void canSetAllProperties() {
+ PropertySettingUtil.setProperties();
+
+ try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
+ context.register(Config.class);
+ context.refresh();
+ final CosmosDBProperties properties = context.getBean(CosmosDBProperties.class);
+
+ assertThat(properties.getUri()).isEqualTo(PropertySettingUtil.URI);
+ assertThat(properties.getKey()).isEqualTo(PropertySettingUtil.KEY);
+ assertThat(properties.getConsistencyLevel()).isEqualTo(PropertySettingUtil.CONSISTENCY_LEVEL);
+ assertThat(properties.isAllowTelemetry()).isEqualTo(PropertySettingUtil.ALLOW_TELEMETRY_TRUE);
+ assertThat(properties.isPopulateQueryMetrics()).isEqualTo(PropertySettingUtil.POPULATE_QUERY_METRICS);
+ }
+
+ PropertySettingUtil.unsetProperties();
+ }
+
+ @Test
+ public void canSetAllowTelemetryFalse() {
+ PropertySettingUtil.setAllowTelemetryFalse();
+
+ try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
+ context.register(Config.class);
+ context.refresh();
+ final CosmosDBProperties properties = context.getBean(CosmosDBProperties.class);
+
+ assertThat(properties.isAllowTelemetry()).isEqualTo(PropertySettingUtil.ALLOW_TELEMETRY_FALSE);
+ }
+
+ PropertySettingUtil.unsetProperties();
+ }
+
+ @Test
+ public void emptySettingNotAllowed() {
+ try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext()) {
+ Exception exception = null;
+
+ context.register(Config.class);
+
+ try {
+ context.refresh();
+ } catch (Exception e) {
+ exception = e;
+ }
+
+ assertThat(exception).isNotNull();
+ assertThat(exception).isExactlyInstanceOf(ConfigurationPropertiesBindException.class);
+
+ final BindValidationException bindException = (BindValidationException) exception.getCause().getCause();
+ final List errors = bindException.getValidationErrors().getAllErrors();
+ final List errorStrings = errors.stream().map(e -> e.toString()).collect(Collectors.toList());
+
+ Collections.sort(errorStrings);
+
+ final List errorStringsExpected = Arrays.asList(
+ "Field error in object 'azure.cosmosdb' on field 'database': rejected value [null];",
+ "Field error in object 'azure.cosmosdb' on field 'key': rejected value [null];",
+ "Field error in object 'azure.cosmosdb' on field 'uri': rejected value [null];"
+ );
+
+ assertThat(errorStrings.size()).isEqualTo(errorStringsExpected.size());
+
+ for (int i = 0; i < errorStrings.size(); i++) {
+ assertThat(errorStrings.get(i)).contains(errorStringsExpected.get(i));
+ }
+ }
+ }
+
+ @Configuration
+ @EnableConfigurationProperties(CosmosDBProperties.class)
+ static class Config {
+ }
+}
+
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfigurationUnitTest.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfigurationUnitTest.java
new file mode 100644
index 000000000000..1801dc1d300e
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/CosmosDbRepositoriesAutoConfigurationUnitTest.java
@@ -0,0 +1,85 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.azure.data.cosmos.CosmosClient;
+import com.microsoft.azure.spring.autoconfigure.cosmosdb.domain.Person;
+import com.microsoft.azure.spring.autoconfigure.cosmosdb.domain.PersonRepository;
+import com.microsoft.azure.spring.data.cosmosdb.CosmosDbFactory;
+import com.microsoft.azure.spring.data.cosmosdb.core.CosmosTemplate;
+import com.microsoft.azure.spring.data.cosmosdb.core.convert.MappingCosmosConverter;
+import com.microsoft.azure.spring.data.cosmosdb.repository.config.EnableCosmosRepositories;
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(MockitoJUnitRunner.class)
+@Ignore
+public class CosmosDbRepositoriesAutoConfigurationUnitTest {
+
+ private AnnotationConfigApplicationContext context;
+
+ @InjectMocks
+ private CosmosTemplate cosmosTemplate;
+
+ @Mock
+ private CosmosDbFactory cosmosDbFactory;
+
+ @Mock
+ private MappingCosmosConverter mappingCosmosConverter;
+
+ @Mock
+ private CosmosClient cosmosClient;
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void testDefaultRepositoryConfiguration() throws Exception {
+ prepareApplicationContext(TestConfiguration.class);
+
+ assertThat(this.context.getBean(PersonRepository.class)).isNotNull();
+ }
+
+ @Test(expected = NoSuchBeanDefinitionException.class)
+ public void autConfigNotKickInIfManualConfigDidNotCreateRepositories() throws Exception {
+ prepareApplicationContext(InvalidCustomConfiguration.class);
+ this.context.getBean(PersonRepository.class);
+ }
+
+ private void prepareApplicationContext(Class>... configurationClasses) {
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.register(configurationClasses);
+ this.context.register(CosmosDbRepositoriesAutoConfiguration.class);
+ this.context.getBeanFactory().registerSingleton(CosmosTemplate.class.getName(), cosmosTemplate);
+ this.context.refresh();
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(Person.class)
+ protected static class TestConfiguration {
+ }
+
+ @Configuration
+ @EnableCosmosRepositories("foo.bar")
+ @TestAutoConfigurationPackage(CosmosDbRepositoriesAutoConfigurationUnitTest.class)
+ protected static class InvalidCustomConfiguration {
+
+ }
+
+}
+
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/PropertySettingUtil.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/PropertySettingUtil.java
new file mode 100644
index 000000000000..dda01d1f90fe
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/PropertySettingUtil.java
@@ -0,0 +1,64 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import com.azure.data.cosmos.ConnectionMode;
+import com.azure.data.cosmos.ConsistencyLevel;
+import com.microsoft.azure.utils.PropertyLoader;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class PropertySettingUtil {
+ public static final String URI = "https://test.documents.azure.com:443/";
+ public static final String KEY = "KeyString";
+ public static final String DATABASE_NAME = "test";
+ public static final boolean ALLOW_TELEMETRY_TRUE = true;
+ public static final boolean ALLOW_TELEMETRY_FALSE = false;
+ public static final boolean POPULATE_QUERY_METRICS = true;
+ public static final ConsistencyLevel CONSISTENCY_LEVEL = ConsistencyLevel.STRONG;
+ public static final int REQUEST_TIMEOUT = 4;
+ public static final int MEDIA_REQUEST_TIMEOUT = 3;
+ public static final ConnectionMode CONNECTION_MODE = ConnectionMode.DIRECT;
+ public static final int MAX_POOL_SIZE = 1;
+ public static final int IDLE_CONNECTION_TIMEOUT = 2;
+ public static final String USER_AGENT_SUFFIX = "suffix";
+ public static final String DEFAULT_USER_AGENT_SUFFIX = "spring-data/" + PropertyLoader.getProjectVersion();
+ public static final int RETRY_OPTIONS_MAX_RETRY_ATTEMPTS_ON_THROTTLED_REQUESTS = 5;
+ public static final int RETRY_OPTIONS_MAX_RETRY_WAIT_TIME_IN_SECONDS = 6;
+ public static final boolean ENABLE_ENDPOINT_DISCOVERY = false;
+ public static final List PREFERRED_LOCATIONS = Arrays.asList("East US", "West US", "North Europe");
+ private static final String PROPERTY_URI = "azure.cosmosdb.uri";
+ private static final String PROPERTY_KEY = "azure.cosmosdb.key";
+ private static final String PROPERTY_DBNAME = "azure.cosmosdb.database";
+ private static final String PROPERTY_CONSISTENCY_LEVEL = "azure.cosmosdb.consistency-level";
+ private static final String PROPERTY_ALLOW_TELEMETRY = "azure.cosmosdb.allow-telemetry";
+ private static final String PROPERTY_POPULATE_QUERY_METRICS = "azure.cosmosdb.populateQueryMetrics";
+
+ public static void setProperties() {
+ System.setProperty(PROPERTY_URI, URI);
+ System.setProperty(PROPERTY_KEY, KEY);
+ System.setProperty(PROPERTY_DBNAME, DATABASE_NAME);
+ System.setProperty(PROPERTY_CONSISTENCY_LEVEL, CONSISTENCY_LEVEL.name());
+ System.setProperty(PROPERTY_ALLOW_TELEMETRY, Boolean.toString(ALLOW_TELEMETRY_TRUE));
+ System.setProperty(PROPERTY_POPULATE_QUERY_METRICS, Boolean.toString(POPULATE_QUERY_METRICS));
+ }
+
+ public static void setAllowTelemetryFalse() {
+ setProperties();
+ System.setProperty(PROPERTY_ALLOW_TELEMETRY, Boolean.toString(ALLOW_TELEMETRY_FALSE));
+ }
+
+ public static void unsetProperties() {
+ System.clearProperty(PROPERTY_URI);
+ System.clearProperty(PROPERTY_KEY);
+ System.clearProperty(PROPERTY_DBNAME);
+ System.clearProperty(PROPERTY_CONSISTENCY_LEVEL);
+ System.clearProperty(PROPERTY_ALLOW_TELEMETRY);
+ System.clearProperty(PROPERTY_POPULATE_QUERY_METRICS);
+ }
+
+ public static void unsetAllowTelemetry() {
+ System.clearProperty(PROPERTY_ALLOW_TELEMETRY);
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/TestAutoConfigurationPackage.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/TestAutoConfigurationPackage.java
new file mode 100644
index 000000000000..a697fa5d3b4c
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/TestAutoConfigurationPackage.java
@@ -0,0 +1,19 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Import(TestAutoConfigurationPackageRegistrar.class)
+public @interface TestAutoConfigurationPackage {
+
+ Class> value();
+
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/TestAutoConfigurationPackageRegistrar.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/TestAutoConfigurationPackageRegistrar.java
new file mode 100644
index 000000000000..bf87e7abbc8a
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/TestAutoConfigurationPackageRegistrar.java
@@ -0,0 +1,26 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb;
+
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.util.ClassUtils;
+
+public class TestAutoConfigurationPackageRegistrar
+ implements ImportBeanDefinitionRegistrar {
+
+ @Override
+ public void registerBeanDefinitions(AnnotationMetadata metadata,
+ BeanDefinitionRegistry registry) {
+ final AnnotationAttributes attributes = AnnotationAttributes
+ .fromMap(metadata.getAnnotationAttributes(
+ TestAutoConfigurationPackage.class.getName(), true));
+ AutoConfigurationPackages.register(registry,
+ ClassUtils.getPackageName(attributes.getString("value")));
+ }
+
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/domain/Person.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/domain/Person.java
new file mode 100644
index 000000000000..8032a7c7f8a6
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/domain/Person.java
@@ -0,0 +1,46 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb.domain;
+
+
+public class Person {
+ private String firstName;
+ private String lastName;
+
+ private String id;
+
+ public Person() {
+ this(null, null, null);
+ }
+
+ public Person(String id, String fname, String lname) {
+ this.firstName = fname;
+ this.lastName = lname;
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String fname) {
+ this.firstName = fname;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/domain/PersonRepository.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/domain/PersonRepository.java
new file mode 100644
index 000000000000..cc4d0c39647c
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/cosmosdb/domain/PersonRepository.java
@@ -0,0 +1,11 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+package com.microsoft.azure.spring.autoconfigure.cosmosdb.domain;
+
+import com.microsoft.azure.spring.data.cosmosdb.repository.CosmosRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface PersonRepository extends CosmosRepository {
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinAutoConfigurationUnitTest.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinAutoConfigurationUnitTest.java
new file mode 100644
index 000000000000..8a94a8d10e33
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinAutoConfigurationUnitTest.java
@@ -0,0 +1,37 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import com.microsoft.spring.data.gremlin.common.GremlinFactory;
+import com.microsoft.spring.data.gremlin.conversion.MappingGremlinConverter;
+import com.microsoft.spring.data.gremlin.mapping.GremlinMappingContext;
+import com.microsoft.spring.data.gremlin.query.GremlinTemplate;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import static com.microsoft.azure.spring.autoconfigure.gremlin.PropertiesUtil.*;
+
+public class GremlinAutoConfigurationUnitTest {
+
+ private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(GremlinAutoConfiguration.class));
+
+ @Test
+ public void testAllBeanCreated() {
+ this.contextRunner
+ .withPropertyValues(GREMLIN_ENDPOINT_CONFIG)
+ .withPropertyValues(GREMLIN_PORT_CONFIG)
+ .withPropertyValues(GREMLIN_USERNAME_CONFIG)
+ .withPropertyValues(GREMLIN_PASSWORD_CONFIG)
+ .withPropertyValues(GREMLIN_TELEMETRY_CONFIG_ALLOWED)
+ .run(context -> {
+ Assert.assertNotNull(context.getBean(GremlinFactory.class));
+ Assert.assertNotNull(context.getBean(GremlinFactory.class).getGremlinClient());
+ Assert.assertNotNull(context.getBean(GremlinTemplate.class));
+ Assert.assertNotNull(context.getBean(GremlinMappingContext.class));
+ Assert.assertNotNull(context.getBean(MappingGremlinConverter.class));
+ });
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinPropertiesUnitTest.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinPropertiesUnitTest.java
new file mode 100644
index 000000000000..0159466cdd70
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinPropertiesUnitTest.java
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+
+import static com.microsoft.azure.spring.autoconfigure.gremlin.PropertiesUtil.*;
+
+public class GremlinPropertiesUnitTest {
+
+ private ApplicationContextRunner contextRunner = new ApplicationContextRunner()
+ .withConfiguration(AutoConfigurations.of(GremlinAutoConfiguration.class));
+
+ @Test
+ public void testAllProperties() {
+ this.contextRunner
+ .withPropertyValues(GREMLIN_ENDPOINT_CONFIG)
+ .withPropertyValues(GREMLIN_PORT_CONFIG)
+ .withPropertyValues(GREMLIN_USERNAME_CONFIG)
+ .withPropertyValues(GREMLIN_PASSWORD_CONFIG)
+ .withPropertyValues(GREMLIN_TELEMETRY_CONFIG_NOT_ALLOWED)
+ .run(context -> {
+ Assert.assertEquals(context.getBean(GremlinProperties.class).getEndpoint(), ENDPOINT);
+ Assert.assertEquals(context.getBean(GremlinProperties.class).getPort(), PORT);
+ Assert.assertEquals(context.getBean(GremlinProperties.class).getUsername(), USERNAME);
+ Assert.assertEquals(context.getBean(GremlinProperties.class).getPassword(), PASSWORD);
+ Assert.assertFalse(context.getBean(GremlinProperties.class).isTelemetryAllowed());
+ });
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfigurationUnitTest.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfigurationUnitTest.java
new file mode 100644
index 000000000000..ae3fe095e3f2
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/GremlinRepositoriesAutoConfigurationUnitTest.java
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+import com.microsoft.azure.spring.autoconfigure.cosmosdb.TestAutoConfigurationPackage;
+import com.microsoft.azure.spring.autoconfigure.gremlin.domain.User;
+import com.microsoft.azure.spring.autoconfigure.gremlin.domain.UserRepository;
+import com.microsoft.spring.data.gremlin.common.GremlinFactory;
+import com.microsoft.spring.data.gremlin.conversion.MappingGremlinConverter;
+import com.microsoft.spring.data.gremlin.query.GremlinTemplate;
+import com.microsoft.spring.data.gremlin.repository.config.EnableGremlinRepositories;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Configuration;
+
+@RunWith(MockitoJUnitRunner.class)
+public class GremlinRepositoriesAutoConfigurationUnitTest {
+
+ private AnnotationConfigApplicationContext applicationContext;
+
+ @InjectMocks
+ private GremlinTemplate template;
+
+ @Mock
+ private GremlinFactory factory;
+
+ @Mock
+ private MappingGremlinConverter converter;
+
+ @After
+ public void cleanup() {
+ if (this.applicationContext != null) {
+ this.applicationContext.close();
+ }
+ }
+
+ private void initializeApplicationContext(Class>... classes) {
+ this.applicationContext = new AnnotationConfigApplicationContext();
+ this.applicationContext.register(classes);
+ this.applicationContext.register(GremlinRepositoriesAutoConfiguration.class);
+ this.applicationContext.getBeanFactory().registerSingleton(GremlinTemplate.class.getName(), this.template);
+ this.applicationContext.refresh();
+ }
+
+ @Test
+ public void testDefaultRepositoryConfiguration() {
+ initializeApplicationContext(TestConfiguration.class);
+
+ Assert.assertNotNull(this.applicationContext.getBean(UserRepository.class));
+ }
+
+ @Test(expected = NoSuchBeanDefinitionException.class)
+ public void testInvalidRepositoryConfiguration() {
+ initializeApplicationContext(InvalidConfiguration.class);
+
+ this.applicationContext.getBean(UserRepository.class);
+ }
+
+ @Configuration
+ @TestAutoConfigurationPackage(User.class)
+ protected static class TestConfiguration {
+
+ }
+
+ @Configuration
+ @EnableGremlinRepositories("fake.repository")
+ @TestAutoConfigurationPackage(GremlinRepositoriesAutoConfigurationUnitTest.class)
+ protected static class InvalidConfiguration {
+
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/PropertiesUtil.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/PropertiesUtil.java
new file mode 100644
index 000000000000..b606679bb867
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/PropertiesUtil.java
@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin;
+
+public class PropertiesUtil {
+ private static final String PROPERTY_ENDPOINT = "gremlin.endpoint";
+ private static final String PROPERTY_PORT = "gremlin.port";
+ private static final String PROPERTY_USERNAME = "gremlin.username";
+ private static final String PROPERTY_PASSWORD = "gremlin.password";
+ private static final String PROPERTY_TELEMETRY = "gremlin.telemetryAllowed";
+
+ public static final String ENDPOINT = "localhost";
+ public static final int PORT = 8090;
+ public static final String USERNAME = "fake-username";
+ public static final String PASSWORD = "fake-passowrd";
+
+ public static final String GREMLIN_ENDPOINT_CONFIG = PROPERTY_ENDPOINT + "=" + ENDPOINT;
+ public static final String GREMLIN_PORT_CONFIG = PROPERTY_PORT + "=" + String.valueOf(PORT);
+ public static final String GREMLIN_USERNAME_CONFIG = PROPERTY_USERNAME + "=" + USERNAME;
+ public static final String GREMLIN_PASSWORD_CONFIG = PROPERTY_PASSWORD + "=" + PASSWORD;
+ public static final String GREMLIN_TELEMETRY_CONFIG_NOT_ALLOWED = PROPERTY_TELEMETRY + "=" + "false";
+ public static final String GREMLIN_TELEMETRY_CONFIG_ALLOWED = PROPERTY_TELEMETRY + "=" + "true";
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/domain/User.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/domain/User.java
new file mode 100644
index 000000000000..05a6b7c87b8c
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/domain/User.java
@@ -0,0 +1,41 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin.domain;
+
+import com.microsoft.spring.data.gremlin.annotation.Vertex;
+import org.springframework.data.annotation.Id;
+
+@Vertex
+public class User {
+
+ @Id
+ private String id;
+
+ private String name;
+
+ private boolean enabled;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+}
diff --git a/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/domain/UserRepository.java b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/domain/UserRepository.java
new file mode 100644
index 000000000000..272222c169ad
--- /dev/null
+++ b/sdk/spring/azure-spring-boot/src/test/java/com/microsoft/azure/spring/autoconfigure/gremlin/domain/UserRepository.java
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.microsoft.azure.spring.autoconfigure.gremlin.domain;
+
+import com.microsoft.spring.data.gremlin.repository.GremlinRepository;
+
+import java.util.List;
+
+public interface UserRepository extends GremlinRepository {
+
+ List findByNameAndEnabled(String name, Boolean enabled);
+}
diff --git a/sdk/spring/ci.yml b/sdk/spring/ci.yml
index 623a16f5da47..b8c56af3e4a4 100644
--- a/sdk/spring/ci.yml
+++ b/sdk/spring/ci.yml
@@ -50,6 +50,12 @@ stages:
- name: azure-active-directory-b2c-spring-boot-starter
groupId: com.microsoft.azure
safeName: azurespringbootstarteractivedirectoryb2c
+ - name: azure-cosmosdb-spring-boot-starter
+ groupId: com.microsoft.azure
+ safeName: azurespringbootstartercosmosdb
+ - name: azure-data-gremlin-spring-boot-starter
+ groupId: com.microsoft.azure
+ safeName: azurespringbootstarterdatagremlin
- name: azure-keyvault-secrets-spring-boot-starter
groupId: com.microsoft.azure
safeName: azurespringbootstarterkeyvaultsecrets
diff --git a/sdk/spring/pom.xml b/sdk/spring/pom.xml
index 8e1ee88761f3..6b2e1ea90090 100644
--- a/sdk/spring/pom.xml
+++ b/sdk/spring/pom.xml
@@ -13,6 +13,8 @@
azure-spring-boot-starter
azure-spring-boot-starter-active-directory
azure-spring-boot-starter-active-directory-b2c
+ azure-spring-boot-starter-cosmosdb
+ azure-spring-boot-starter-data-gremlin
azure-spring-boot-starter-keyvault-secrets
azure-spring-boot-starter-metrics
azure-spring-boot-starter-servicebus-jms