diff --git a/eng/pipelines/templates/stages/cosmos-sdk-client.yml b/eng/pipelines/templates/stages/cosmos-sdk-client.yml
index 81382ae03867..c88b187cabbb 100644
--- a/eng/pipelines/templates/stages/cosmos-sdk-client.yml
+++ b/eng/pipelines/templates/stages/cosmos-sdk-client.yml
@@ -81,6 +81,9 @@ stages:
ServiceDirectory: cosmos
Artifacts: ${{ parameters.Artifacts }}
AdditionalModules: ${{ parameters.AdditionalModules }}
+ ACCOUNT_HOST: 'https://localhost:8081/'
+ ACCOUNT_KEY: 'C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=='
+ SECONDARY_ACCOUNT_KEY: 'C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=='
# Increased timeout to 90 because of cosmos emulator taking 25-30 mins to download emulator
# Issue filed to improve download speed: https://github.com/Azure/azure-sdk-for-java/issues/12970
TimeoutInMinutes: 90
@@ -106,7 +109,7 @@ stages:
JavaTestVersion: '1.8'
ProfileFlag: '-P integration-test-emulator'
DisplayName: 'Spring Emulator only Integration Tests'
- AdditionalArgs: '-DargLine="-DACCOUNT_HOST=https://localhost:8081/ -DACCOUNT_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw== -DSECONDARY_ACCOUNT_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="'
+ AdditionalArgs: '-DargLine="-DACCOUNT_HOST=https://localhost:8081/ -DACCOUNT_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw== -DSECONDARY_ACCOUNT_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw== -DNEW_ACCOUNT_HOST=https://localhost:8081/ -DNEW_ACCOUNT_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw== -DNEW_SECONDARY_ACCOUNT_KEY=C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw=="'
Encryption_Integration_Tests_Java8:
OSVmImage: 'windows-2019'
JavaTestVersion: '1.8'
diff --git a/sdk/cosmos/azure-spring-data-cosmos/CONTRIBUTING.md b/sdk/cosmos/azure-spring-data-cosmos/CONTRIBUTING.md
index daad18919bf4..89f375ad5188 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/CONTRIBUTING.md
+++ b/sdk/cosmos/azure-spring-data-cosmos/CONTRIBUTING.md
@@ -33,15 +33,22 @@ mvn clean install -Dgpg.skip
- Click Databases, and then click Azure Cosmos DB to create your database.
- Navigate to the database you have created, and click Access keys and copy your URI and access keys for your database.
- 2. Set environment variables ACCOUNT_HOST, ACCOUNT_KEY and SECONDARY_ACCOUNT_KEY, where value of them are Cosmos account URI, primary key and secondary key.
+ 2. Set environment variables ACCOUNT_HOST, ACCOUNT_KEY and SECONDARY_ACCOUNT_KEY, where value of them are Cosmos account URI, primary key and secondary key.
+
+ `azure-spring-data-cosmos` also support multiple database configuration. So set the second group environment variables NEW_ACCOUNT_HOST, NEW_ACCOUNT_KEY and NEW_SECONDARY_ACCOUNT_KEY, the two group environment variables can be same.
3. Run maven command with `integration-test-azure` profile.
```bash
set ACCOUNT_HOST=your-cosmos-account-uri
set ACCOUNT_KEY=your-cosmos-account-primary-key
set SECONDARY_ACCOUNT_KEY=your-cosmos-account-secondary-key
+
+ set NEW_ACCOUNT_HOST=your-cosmos-account-uri
+ set NEW_ACCOUNT_KEY=your-cosmos-account-primary-key
+ set NEW_SECONDARY_ACCOUNT_KEY=your-cosmos-account-secondary-key
mvnw -P integration-test-azure clean install
```
+
- on Emulator
Setup Azure Cosmos DB Emulator by following [this instruction](https://docs.microsoft.com/azure/cosmos-db/local-emulator), and set associated environment variables. Then run test with:
diff --git a/sdk/cosmos/azure-spring-data-cosmos/README.md b/sdk/cosmos/azure-spring-data-cosmos/README.md
index dea72254e765..7165d7f84b5c 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/README.md
+++ b/sdk/cosmos/azure-spring-data-cosmos/README.md
@@ -334,6 +334,143 @@ public class SampleApplication implements CommandLineRunner {
```
Autowired UserRepository interface, then can do save, delete and find operations. Spring Data Azure Cosmos DB uses the CosmosTemplate to execute the queries behind *find*, *save* methods. You can use the template yourself for more complex queries.
+## Support multi-database configuration
+The `azure-spring-data-cosmos` support multi-database configuration, here is a sample to config multiple account database
+
+### Add the dependency
+[//]: # ({x-version-update-start;com.azure:azure-spring-data-cosmos;current})
+```xml
+
+ com.azure
+ azure-spring-data-cosmos
+ 3.0.0-beta.1
+
+```
+[//]: # ({x-version-update-end})
+
+### Config application properties
+The example uses the `application.properties` file
+```properties
+azure.cosmos.primary.uri=your-primary-cosmosDb-uri
+azure.cosmos.primary.key=your-primary-cosmosDb-key
+azure.cosmos.primary.secondaryKey=your-primary-cosmosDb-secondary-key
+azure.cosmos.primary.database=your-primary-cosmosDb-dbName
+azure.cosmos.primary.populateQueryMetrics=if-populate-query-metrics
+
+azure.cosmos.secondary.uri=your-secondary-cosmosDb-uri
+azure.cosmos.secondary.key=your-secondary-cosmosDb-key
+azure.cosmos.secondary.secondaryKey=your-secondary-cosmosDb-secondary-key
+azure.cosmos.secondary.database=your-secondary-cosmosDb-dbName
+azure.cosmos.secondary.populateQueryMetrics=if-populate-query-metrics
+```
+
+### Define Entities and Repositories
+The [Entity](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-spring-data-cosmos#create-repositories) definition is same as above.
+You can put different database entities into different packages.
+
+### Setup configuration
+The `@EnableReactiveCosmosRepositories` or `@EnableCosmosRepositories` support user-define the cosmos template, use `reactiveCosmosTemplateRef` or `cosmosTemplateRef` to config the name of the `ReactiveCosmosTemplate` or `CosmosTemplate` bean to be used with the repositories detected.
+
+```java
+@Configuration
+@PropertySource("classpath:application.properties")
+public class DatabaseConfiguration extends AbstractCosmosConfiguration {
+
+ @Bean
+ @ConfigurationProperties(prefix = "azure.cosmos.primary")
+ public CosmosProperties primaryDataSourceConfiguration() {
+ return new CosmosProperties();
+ }
+
+ @Bean
+ @ConfigurationProperties(prefix = "azure.cosmos.secondary")
+ public CosmosProperties secondaryDataSourceConfiguration() {
+ return new CosmosProperties();
+ }
+
+ @EnableReactiveCosmosRepositories(basePackages = "com.azure.cosmos.multidatasource.primarydatasource")
+ public class PrimaryDataSourceConfiguration {
+ @Autowired
+ @Qualifier("primaryDataSourceConfiguration")
+ CosmosProperties properties;
+ @Bean
+ public CosmosConfig cosmosConfig() {
+ CosmosConfig cosmosConfig = CosmosConfig.builder()
+ .cosmosClientBuilder(new CosmosClientBuilder()
+ .key(properties.getKey()).endpoint(properties.getUri()))
+ .database(properties.getDatabase())
+ .enableQueryMetrics(properties.isQueryMetricsEnabled())
+ .build();
+ return cosmosConfig;
+ }
+
+ }
+
+ @EnableReactiveCosmosRepositories(basePackages = "com.azure.cosmos.multidatasource.secondarydatasource", reactiveCosmosTemplateRef = "secondaryReactiveCosmosTemplate")
+ public class SecondaryDataSourceConfiguration {
+ @Autowired
+ @Qualifier("secondaryDataSourceConfiguration")
+ CosmosProperties properties;
+ @Bean
+ public ReactiveCosmosTemplate secondaryReactiveCosmosTemplate(MappingCosmosConverter mappingCosmosConverter) {
+ CosmosConfig cosmosConfig = CosmosConfig.builder()
+ .cosmosClientBuilder(new CosmosClientBuilder()
+ .key(properties.getKey()).endpoint(properties.getUri()))
+ .database(properties.getDatabase())
+ .enableQueryMetrics(properties.isQueryMetricsEnabled())
+ .build();
+
+ return new ReactiveCosmosTemplate(new CosmosFactory(cosmosConfig), mappingCosmosConverter, cosmosConfig.getDatabase());
+ }
+ }
+}
+```
+
+### Create an Application class
+
+
+```java
+@SpringBootApplication
+public class MultiDatasourceApplication implements CommandLineRunner {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Autowired
+ private BookRepository bookRepository;
+
+
+ private final User user = new User("1024", "1024@geek.com", "1k", "Mars");
+ private final Book book = new Book("9780792745488", "Zen and the Art of Motorcycle Maintenance", "Robert M. Pirsig");
+
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultiDatasourceApplication.class, args);
+ }
+
+ @Override
+ public void run(String... args) {
+ final List users = this.userRepository.findByEmailOrName(this.user.getEmail(), this.user.getName()).collectList().block();
+ users.forEach(System.out::println);
+ final Book book = this.bookRepository.findById("9780792745488").block();
+ System.out.println(book);
+ }
+
+ @PostConstruct
+ public void setup() {
+ this.userRepository.save(user).block();
+ this.bookRepository.save(book).block();
+
+ }
+
+ @PreDestroy
+ public void cleanup() {
+ this.userRepository.deleteAll().block();
+ this.bookRepository.deleteAll().block();
+ }
+}
+```
+
## Beta version package
Beta version built from `master` branch are available, you can refer to the [instruction](https://github.com/Azure/azure-sdk-for-java/blob/master/CONTRIBUTING.md#nightly-package-builds) to use beta version packages.
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/Constants.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/Constants.java
index 16d5c1857659..5ab839e21c31 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/Constants.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/Constants.java
@@ -20,7 +20,6 @@ public final class Constants {
public static final String COSMOS_MODULE_NAME = "cosmos";
public static final String COSMOS_MODULE_PREFIX = "cosmos";
- public static final String COSMOS_MAPPING_CONTEXT = "cosmosMappingContext";
public static final String USER_AGENT_SUFFIX = "spring-data/";
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/CosmosRepositoryConfigurationExtension.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/CosmosRepositoryConfigurationExtension.java
index 4ae480a3b25e..732dea8fcdbf 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/CosmosRepositoryConfigurationExtension.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/CosmosRepositoryConfigurationExtension.java
@@ -4,13 +4,12 @@
package com.azure.spring.data.cosmos.repository.config;
import com.azure.spring.data.cosmos.Constants;
-import com.azure.spring.data.cosmos.core.mapping.CosmosMappingContext;
import com.azure.spring.data.cosmos.repository.CosmosRepository;
import com.azure.spring.data.cosmos.repository.support.CosmosRepositoryFactoryBean;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.RepositoryConfigurationSource;
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -57,19 +56,12 @@ protected Collection> getIdentifyingAnnotations() {
@Override
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource config) {
super.registerBeansForRoot(registry, config);
-
- if (!registry.containsBeanDefinition(Constants.COSMOS_MAPPING_CONTEXT)) {
- final RootBeanDefinition definition = new RootBeanDefinition(CosmosMappingContext.class);
- definition.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
- definition.setSource(config.getSource());
-
- registry.registerBeanDefinition(Constants.COSMOS_MAPPING_CONTEXT, definition);
- }
}
@Override
- public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) {
- super.postProcess(builder, source);
+ public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource source) {
+ final AnnotationAttributes attributes = source.getAttributes();
+ builder.addPropertyReference("cosmosOperations", attributes.getString("cosmosTemplateRef"));
}
// Overriding this to provide reactive repository support.
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableCosmosRepositories.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableCosmosRepositories.java
index a2a0cc4b62f8..c399f5c1fef9 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableCosmosRepositories.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableCosmosRepositories.java
@@ -4,6 +4,7 @@
package com.azure.spring.data.cosmos.repository.config;
import com.azure.spring.data.cosmos.Constants;
+import com.azure.spring.data.cosmos.core.CosmosTemplate;
import com.azure.spring.data.cosmos.repository.support.CosmosRepositoryFactoryBean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
@@ -92,5 +93,12 @@
* @return default value is false
*/
boolean considerNestedRepositories() default false;
+
+ /**
+ * Configures the name of the {@link CosmosTemplate} bean to be used with the repositories detected.
+ *
+ * @return {@literal cosmosTemplate} by default.
+ */
+ String cosmosTemplateRef() default "cosmosTemplate";
}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableReactiveCosmosRepositories.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableReactiveCosmosRepositories.java
index ade7e47fbed2..7ab04879b6e5 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableReactiveCosmosRepositories.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/EnableReactiveCosmosRepositories.java
@@ -4,6 +4,7 @@
package com.azure.spring.data.cosmos.repository.config;
import com.azure.spring.data.cosmos.Constants;
+import com.azure.spring.data.cosmos.core.ReactiveCosmosTemplate;
import com.azure.spring.data.cosmos.repository.support.ReactiveCosmosRepositoryFactoryBean;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Import;
@@ -92,5 +93,12 @@
* @return default value is false
*/
boolean considerNestedRepositories() default false;
+
+ /**
+ * Configures the name of the {@link ReactiveCosmosTemplate} bean to be used with the repositories detected.
+ *
+ * @return {@literal reactiveCosmosTemplate} by default.
+ */
+ String reactiveCosmosTemplateRef() default "reactiveCosmosTemplate";
}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/ReactiveCosmosRepositoryConfigurationExtension.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/ReactiveCosmosRepositoryConfigurationExtension.java
index c8541b2d9ff8..dfc7327fdcaf 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/ReactiveCosmosRepositoryConfigurationExtension.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/config/ReactiveCosmosRepositoryConfigurationExtension.java
@@ -4,13 +4,12 @@
package com.azure.spring.data.cosmos.repository.config;
import com.azure.spring.data.cosmos.Constants;
-import com.azure.spring.data.cosmos.core.mapping.CosmosMappingContext;
import com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository;
import com.azure.spring.data.cosmos.repository.support.ReactiveCosmosRepositoryFactoryBean;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.data.repository.config.AnnotationRepositoryConfigurationSource;
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
import org.springframework.data.repository.config.RepositoryConfigurationSource;
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -57,19 +56,12 @@ protected Collection> getIdentifyingAnnotations() {
@Override
public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource config) {
super.registerBeansForRoot(registry, config);
-
- if (!registry.containsBeanDefinition(Constants.COSMOS_MAPPING_CONTEXT)) {
- final RootBeanDefinition definition = new RootBeanDefinition(CosmosMappingContext.class);
- definition.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
- definition.setSource(config.getSource());
-
- registry.registerBeanDefinition(Constants.COSMOS_MAPPING_CONTEXT, definition);
- }
}
@Override
- public void postProcess(BeanDefinitionBuilder builder, RepositoryConfigurationSource source) {
- super.postProcess(builder, source);
+ public void postProcess(BeanDefinitionBuilder builder, AnnotationRepositoryConfigurationSource source) {
+ final AnnotationAttributes attributes = source.getAttributes();
+ builder.addPropertyReference("reactiveCosmosOperations", attributes.getString("reactiveCosmosTemplateRef"));
}
// Overriding this to provide reactive repository support.
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactory.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactory.java
index 3eab5d73fc0c..ac495642ec7d 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactory.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactory.java
@@ -6,7 +6,6 @@
import com.azure.spring.data.cosmos.core.CosmosOperations;
import com.azure.spring.data.cosmos.repository.query.CosmosQueryMethod;
import com.azure.spring.data.cosmos.repository.query.PartTreeCosmosQuery;
-import org.springframework.context.ApplicationContext;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.NamedQueries;
@@ -27,18 +26,15 @@
*/
public class CosmosRepositoryFactory extends RepositoryFactorySupport {
- private final ApplicationContext applicationContext;
private final CosmosOperations cosmosOperations;
/**
* Initialization
*
* @param cosmosOperations for cosmosDb operations
- * @param applicationContext for the context
*/
- public CosmosRepositoryFactory(CosmosOperations cosmosOperations, ApplicationContext applicationContext) {
+ public CosmosRepositoryFactory(CosmosOperations cosmosOperations) {
this.cosmosOperations = cosmosOperations;
- this.applicationContext = applicationContext;
}
@Override
@@ -49,7 +45,7 @@ protected Class> getRepositoryBaseClass(RepositoryMetadata metadata) {
@Override
protected Object getTargetRepository(RepositoryInformation information) {
final EntityInformation, Serializable> entityInformation = getEntityInformation(information.getDomainType());
- return getTargetRepositoryViaReflection(information, entityInformation, this.applicationContext);
+ return getTargetRepositoryViaReflection(information, entityInformation, this.cosmosOperations);
}
@Override
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryBean.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryBean.java
index 93c62e6294e2..0692a3a2c1e8 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryBean.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryBean.java
@@ -4,11 +4,7 @@
import com.azure.spring.data.cosmos.core.CosmosOperations;
import com.azure.spring.data.cosmos.core.mapping.CosmosMappingContext;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
@@ -21,10 +17,8 @@
* configuration.
*/
public class CosmosRepositoryFactoryBean, S, ID extends Serializable>
- extends RepositoryFactoryBeanSupport
- implements ApplicationContextAware {
+ extends RepositoryFactoryBeanSupport {
- private ApplicationContext applicationContext;
private CosmosOperations operations;
private boolean mappingContextConfigured = false;
@@ -42,23 +36,17 @@ public CosmosRepositoryFactoryBean(Class extends T> repositoryInterface) {
*
* @param operations for cosmos operations
*/
- @Autowired
public void setCosmosOperations(CosmosOperations operations) {
this.operations = operations;
}
@Override
protected final RepositoryFactorySupport createRepositoryFactory() {
- return getFactoryInstance(applicationContext);
+ return getFactoryInstance();
}
- protected RepositoryFactorySupport getFactoryInstance(ApplicationContext applicationContext) {
- return new CosmosRepositoryFactory(operations, applicationContext);
- }
-
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
+ protected RepositoryFactorySupport getFactoryInstance() {
+ return new CosmosRepositoryFactory(operations);
}
@Override
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactory.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactory.java
index f8433d989417..a949964eb463 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactory.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactory.java
@@ -5,7 +5,6 @@
import com.azure.spring.data.cosmos.core.ReactiveCosmosOperations;
import com.azure.spring.data.cosmos.repository.query.PartTreeReactiveCosmosQuery;
import com.azure.spring.data.cosmos.repository.query.ReactiveCosmosQueryMethod;
-import org.springframework.context.ApplicationContext;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.core.NamedQueries;
@@ -26,18 +25,14 @@
*/
public class ReactiveCosmosRepositoryFactory extends ReactiveRepositoryFactorySupport {
- private final ApplicationContext applicationContext;
private final ReactiveCosmosOperations cosmosOperations;
/**
* Initialization
*
* @param cosmosOperations for cosmosDB operations
- * @param applicationContext for the context
*/
- public ReactiveCosmosRepositoryFactory(ReactiveCosmosOperations cosmosOperations,
- ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
+ public ReactiveCosmosRepositoryFactory(ReactiveCosmosOperations cosmosOperations) {
this.cosmosOperations = cosmosOperations;
}
@@ -50,8 +45,7 @@ public EntityInformation getEntityInformation(Class domainType
protected Object getTargetRepository(RepositoryInformation information) {
final EntityInformation, Serializable> entityInformation =
getEntityInformation(information.getDomainType());
- return getTargetRepositoryViaReflection(information, entityInformation,
- this.applicationContext);
+ return getTargetRepositoryViaReflection(information, entityInformation, this.cosmosOperations);
}
@Override
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactoryBean.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactoryBean.java
index de81d5415b91..4657a9077050 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactoryBean.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/ReactiveCosmosRepositoryFactoryBean.java
@@ -4,11 +4,7 @@
import com.azure.spring.data.cosmos.core.ReactiveCosmosOperations;
import com.azure.spring.data.cosmos.core.mapping.CosmosMappingContext;
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
@@ -22,10 +18,8 @@
*/
public class ReactiveCosmosRepositoryFactoryBean, S,
K extends Serializable>
- extends RepositoryFactoryBeanSupport
- implements ApplicationContextAware {
+ extends RepositoryFactoryBeanSupport {
- private ApplicationContext applicationContext;
private ReactiveCosmosOperations cosmosOperations;
private boolean mappingContextConfigured = false;
@@ -43,23 +37,17 @@ public ReactiveCosmosRepositoryFactoryBean(Class extends T> repositoryInterfac
*
* @param operations contains cosmos operations
*/
- @Autowired
public void setReactiveCosmosOperations(ReactiveCosmosOperations operations) {
this.cosmosOperations = operations;
}
@Override
protected final RepositoryFactorySupport createRepositoryFactory() {
- return getFactoryInstance(applicationContext);
+ return getFactoryInstance();
}
- protected RepositoryFactorySupport getFactoryInstance(ApplicationContext applicationContext) {
- return new ReactiveCosmosRepositoryFactory(cosmosOperations, applicationContext);
- }
-
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = applicationContext;
+ protected RepositoryFactorySupport getFactoryInstance() {
+ return new ReactiveCosmosRepositoryFactory(cosmosOperations);
}
@Override
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleCosmosRepository.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleCosmosRepository.java
index 0ea68ee18292..41043a602579 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleCosmosRepository.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleCosmosRepository.java
@@ -10,7 +10,6 @@
import com.azure.spring.data.cosmos.core.query.CriteriaType;
import com.azure.spring.data.cosmos.core.query.DocumentQuery;
import com.azure.spring.data.cosmos.repository.CosmosRepository;
-import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
@@ -32,22 +31,6 @@ public class SimpleCosmosRepository implements Cosmo
private final CosmosOperations operation;
private final CosmosEntityInformation information;
- /**
- * Initialization
- *
- * @param metadata for cosmos entity information
- * @param applicationContext to get bean of CosmosOperations class
- */
- public SimpleCosmosRepository(CosmosEntityInformation metadata,
- ApplicationContext applicationContext) {
- this.operation = applicationContext.getBean(CosmosOperations.class);
- this.information = metadata;
-
- if (this.information.isAutoCreateContainer()) {
- createContainerIfNotExists();
- }
- }
-
/**
* Initialization
*
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleReactiveCosmosRepository.java b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleReactiveCosmosRepository.java
index 4359c52c5e52..e48609d5f917 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleReactiveCosmosRepository.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/main/java/com/azure/spring/data/cosmos/repository/support/SimpleReactiveCosmosRepository.java
@@ -10,7 +10,6 @@
import com.azure.spring.data.cosmos.core.query.DocumentQuery;
import com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository;
import org.reactivestreams.Publisher;
-import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Sort;
import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
@@ -28,22 +27,6 @@ public class SimpleReactiveCosmosRepository implement
private final CosmosEntityInformation entityInformation;
private final ReactiveCosmosOperations cosmosOperations;
- /**
- * Initialization with metadata and applicationContext will create container if required
- *
- * @param metadata for entityInformation
- * @param applicationContext for cosmosOperations
- */
- public SimpleReactiveCosmosRepository(CosmosEntityInformation metadata,
- ApplicationContext applicationContext) {
- this.cosmosOperations = applicationContext.getBean(ReactiveCosmosOperations.class);
- this.entityInformation = metadata;
-
- if (this.entityInformation.isAutoCreateContainer()) {
- createContainerIfNotExists();
- }
- }
-
/**
* Initialization with metadata and reactiveCosmosOperations
*
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/DatabaseConfiguration.java b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/DatabaseConfiguration.java
new file mode 100644
index 000000000000..258e6bd8ff9c
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/DatabaseConfiguration.java
@@ -0,0 +1,76 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.cosmos.multidatasource;
+
+import com.azure.cosmos.CosmosClientBuilder;
+import com.azure.cosmos.CosmosProperties;
+import com.azure.spring.data.cosmos.CosmosFactory;
+import com.azure.spring.data.cosmos.config.AbstractCosmosConfiguration;
+import com.azure.spring.data.cosmos.config.CosmosConfig;
+import com.azure.spring.data.cosmos.core.ReactiveCosmosTemplate;
+import com.azure.spring.data.cosmos.core.convert.MappingCosmosConverter;
+import com.azure.spring.data.cosmos.repository.config.EnableReactiveCosmosRepositories;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+
+/**
+ * WARNING: MODIFYING THIS FILE WILL REQUIRE CORRESPONDING UPDATES TO README.md FILE. LINE NUMBERS
+ * ARE USED TO EXTRACT APPROPRIATE CODE SEGMENTS FROM THIS FILE. ADD NEW CODE AT THE BOTTOM TO AVOID CHANGING
+ * LINE NUMBERS OF EXISTING CODE SAMPLES.
+ */
+@Configuration
+@PropertySource("classpath:application.properties")
+public class DatabaseConfiguration extends AbstractCosmosConfiguration {
+
+ @Bean
+ @ConfigurationProperties(prefix = "azure.cosmos.primary")
+ public CosmosProperties primaryDataSourceConfiguration() {
+ return new CosmosProperties();
+ }
+
+ @Bean
+ @ConfigurationProperties(prefix = "azure.cosmos.secondary")
+ public CosmosProperties secondaryDataSourceConfiguration() {
+ return new CosmosProperties();
+ }
+
+ @EnableReactiveCosmosRepositories(basePackages = "com.azure.cosmos.multidatasource.primarydatasource")
+ public class PrimaryDataSourceConfiguration {
+ @Autowired
+ @Qualifier("primaryDataSourceConfiguration")
+ CosmosProperties properties;
+ @Bean
+ public CosmosConfig cosmosConfig() {
+ CosmosConfig cosmosConfig = CosmosConfig.builder()
+ .cosmosClientBuilder(new CosmosClientBuilder()
+ .key(properties.getKey()).endpoint(properties.getUri()))
+ .database(properties.getDatabase())
+ .enableQueryMetrics(properties.isQueryMetricsEnabled())
+ .build();
+ return cosmosConfig;
+ }
+
+ }
+
+ @EnableReactiveCosmosRepositories(basePackages = "com.azure.cosmos.multidatasource.secondarydatasource", reactiveCosmosTemplateRef = "secondaryReactiveCosmosTemplate")
+ public class SecondaryDataSourceConfiguration {
+ @Autowired
+ @Qualifier("secondaryDataSourceConfiguration")
+ CosmosProperties properties;
+ @Bean
+ public ReactiveCosmosTemplate secondaryReactiveCosmosTemplate(MappingCosmosConverter mappingCosmosConverter) {
+ CosmosConfig cosmosConfig = CosmosConfig.builder()
+ .cosmosClientBuilder(new CosmosClientBuilder()
+ .key(properties.getKey()).endpoint(properties.getUri()))
+ .database(properties.getDatabase())
+ .enableQueryMetrics(properties.isQueryMetricsEnabled())
+ .build();
+
+ return new ReactiveCosmosTemplate(new CosmosFactory(cosmosConfig), mappingCosmosConverter, cosmosConfig.getDatabase());
+ }
+ }
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/MultiDatasourceApplication.java b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/MultiDatasourceApplication.java
new file mode 100644
index 000000000000..85e8d4ae484b
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/MultiDatasourceApplication.java
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.cosmos.multidatasource;
+
+import com.azure.cosmos.multidatasource.primarydatasource.User;
+import com.azure.cosmos.multidatasource.primarydatasource.UserRepository;
+import com.azure.cosmos.multidatasource.secondarydatasource.Book;
+import com.azure.cosmos.multidatasource.secondarydatasource.BookRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.util.List;
+
+/**
+ * WARNING: MODIFYING THIS FILE WILL REQUIRE CORRESPONDING UPDATES TO README.md FILE. LINE NUMBERS
+ * ARE USED TO EXTRACT APPROPRIATE CODE SEGMENTS FROM THIS FILE. ADD NEW CODE AT THE BOTTOM TO AVOID CHANGING
+ * LINE NUMBERS OF EXISTING CODE SAMPLES.
+ */
+@SpringBootApplication
+public class MultiDatasourceApplication implements CommandLineRunner {
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Autowired
+ private BookRepository bookRepository;
+
+
+ private final User user = new User("1024", "1024@geek.com", "1k", "Mars");
+ private final Book book = new Book("9780792745488", "Zen and the Art of Motorcycle Maintenance", "Robert M. Pirsig");
+
+
+ public static void main(String[] args) {
+ SpringApplication.run(MultiDatasourceApplication.class, args);
+ }
+
+ @Override
+ public void run(String... args) {
+ final List users = this.userRepository.findByEmailOrName(this.user.getEmail(), this.user.getName()).collectList().block();
+ users.forEach(System.out::println);
+ final Book book = this.bookRepository.findById("9780792745488").block();
+ System.out.println(book);
+ }
+
+ @PostConstruct
+ public void setup() {
+ this.userRepository.save(user).block();
+ this.bookRepository.save(book).block();
+
+ }
+
+ @PreDestroy
+ public void cleanup() {
+ this.userRepository.deleteAll().block();
+ this.bookRepository.deleteAll().block();
+ }
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/primarydatasource/User.java b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/primarydatasource/User.java
new file mode 100644
index 000000000000..b75ac9a1546d
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/primarydatasource/User.java
@@ -0,0 +1,70 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.cosmos.multidatasource.primarydatasource;
+
+import com.azure.spring.data.cosmos.core.mapping.Document;
+import com.azure.spring.data.cosmos.core.mapping.PartitionKey;
+import org.springframework.data.annotation.Id;
+
+/**
+ * WARNING: MODIFYING THIS FILE WILL REQUIRE CORRESPONDING UPDATES TO README.md FILE. LINE NUMBERS
+ * ARE USED TO EXTRACT APPROPRIATE CODE SEGMENTS FROM THIS FILE. ADD NEW CODE AT THE BOTTOM TO AVOID CHANGING
+ * LINE NUMBERS OF EXISTING CODE SAMPLES.
+ */
+
+@Document(container = "users-container", ru = "400")
+public class User {
+
+ @Id
+ private String id;
+
+ private String email;
+
+ @PartitionKey
+ private String name;
+
+ private String address;
+
+ public User(String id, String email, String name, String address) {
+ this.id = id;
+ this.email = email;
+ this.name = name;
+ this.address = address;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String toString() {
+ return String.format("%s: %s %s %s", this.id, this.email, this.name, this.address);
+ }
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/primarydatasource/UserRepository.java b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/primarydatasource/UserRepository.java
new file mode 100644
index 000000000000..5e64f41369d4
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/primarydatasource/UserRepository.java
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.cosmos.multidatasource.primarydatasource;
+
+import com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository;
+import reactor.core.publisher.Flux;
+
+/**
+ * WARNING: MODIFYING THIS FILE WILL REQUIRE CORRESPONDING UPDATES TO README.md FILE. LINE NUMBERS
+ * ARE USED TO EXTRACT APPROPRIATE CODE SEGMENTS FROM THIS FILE. ADD NEW CODE AT THE BOTTOM TO AVOID CHANGING
+ * LINE NUMBERS OF EXISTING CODE SAMPLES.
+ */
+public interface UserRepository extends ReactiveCosmosRepository {
+
+ Flux findByName(String firstName);
+
+
+ Flux findByEmailOrName(String email, String name);
+
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/secondarydatasource/Book.java b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/secondarydatasource/Book.java
new file mode 100644
index 000000000000..8f1db812033c
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/secondarydatasource/Book.java
@@ -0,0 +1,57 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.cosmos.multidatasource.secondarydatasource;
+
+import com.azure.spring.data.cosmos.core.mapping.Document;
+import org.springframework.data.annotation.Id;
+
+/**
+ * WARNING: MODIFYING THIS FILE WILL REQUIRE CORRESPONDING UPDATES TO README.md FILE. LINE NUMBERS
+ * ARE USED TO EXTRACT APPROPRIATE CODE SEGMENTS FROM THIS FILE. ADD NEW CODE AT THE BOTTOM TO AVOID CHANGING
+ * LINE NUMBERS OF EXISTING CODE SAMPLES.
+ */
+
+@Document(container = "book-container", ru = "400")
+public class Book {
+ @Id
+ private String ibsn;
+
+ private String name;
+
+ private String author;
+
+ public Book(String ibsn, String name, String author) {
+ this.ibsn = ibsn;
+ this.name = name;
+ this.author = author;
+ }
+
+ public String getIbsn() {
+ return ibsn;
+ }
+
+ public void setIbsn(String ibsn) {
+ this.ibsn = ibsn;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s: %s %s", this.ibsn, this.name, this.author);
+ }
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/secondarydatasource/BookRepository.java b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/secondarydatasource/BookRepository.java
new file mode 100644
index 000000000000..80907ac19b83
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/samples/java/com/azure/cosmos/multidatasource/secondarydatasource/BookRepository.java
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.cosmos.multidatasource.secondarydatasource;
+
+import com.azure.spring.data.cosmos.repository.ReactiveCosmosRepository;
+
+/**
+ * WARNING: MODIFYING THIS FILE WILL REQUIRE CORRESPONDING UPDATES TO README.md FILE. LINE NUMBERS
+ * ARE USED TO EXTRACT APPROPRIATE CODE SEGMENTS FROM THIS FILE. ADD NEW CODE AT THE BOTTOM TO AVOID CHANGING
+ * LINE NUMBERS OF EXISTING CODE SAMPLES.
+ */
+public interface BookRepository extends ReactiveCosmosRepository {
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/common/TestConstants.java b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/common/TestConstants.java
index 3bcfbecfa638..026b42aaccbf 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/common/TestConstants.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/common/TestConstants.java
@@ -74,6 +74,7 @@ public final class TestConstants {
};
public static final String DB_NAME = "testdb";
+ public static final String SECONDARY_DB_NAME = "second_testdb";
public static final String FIRST_NAME = "first_name_li";
public static final String LAST_NAME = "last_name_p";
public static final String ID_1 = "id-1";
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/MultiCosmosTemplateIT.java b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/MultiCosmosTemplateIT.java
new file mode 100644
index 000000000000..d852de82373a
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/MultiCosmosTemplateIT.java
@@ -0,0 +1,78 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.data.cosmos.repository;
+
+import com.azure.cosmos.models.PartitionKey;
+import com.azure.spring.data.cosmos.common.TestConstants;
+import com.azure.spring.data.cosmos.core.ReactiveCosmosTemplate;
+import com.azure.spring.data.cosmos.domain.Person;
+import com.azure.spring.data.cosmos.repository.support.CosmosEntityInformation;
+import org.assertj.core.api.Assertions;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import reactor.core.publisher.Mono;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(classes = {TestRepositoryConfig.class, SecondaryTestRepositoryConfig.class})
+public class MultiCosmosTemplateIT {
+ private static final Person PRIMARY_TEST_PERSON = new Person(TestConstants.ID_1,
+ TestConstants.FIRST_NAME,
+ TestConstants.LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES);
+ private static final Person SECONDARY_TEST_PERSON = new Person(TestConstants.ID_2,
+ TestConstants.NEW_FIRST_NAME,
+ TestConstants.NEW_LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES);
+ private static CosmosEntityInformation personInfo;
+ private static boolean initialized;
+ @Autowired
+ @Qualifier("secondaryReactiveCosmosTemplate")
+ private ReactiveCosmosTemplate secondaryReactiveCosmosTemplate;
+ @Autowired
+ @Qualifier("reactiveCosmosTemplate")
+ private ReactiveCosmosTemplate primaryReactiveCosmosTemplate;
+
+ @Before
+ public void setUp() throws ClassNotFoundException {
+ if (!initialized) {
+ personInfo = new CosmosEntityInformation<>(Person.class);
+ initialized = true;
+ }
+ }
+
+ @After
+ public void cleanup() {
+ }
+
+ @AfterClass
+ public static void afterClassCleanup() {
+ }
+
+ @Test
+ public void testPrimaryTemplate() {
+ primaryReactiveCosmosTemplate.createContainerIfNotExists(personInfo).block();
+ primaryReactiveCosmosTemplate.insert(PRIMARY_TEST_PERSON,
+ new PartitionKey(personInfo.getPartitionKeyFieldValue(PRIMARY_TEST_PERSON))).block();
+ final Mono findById = primaryReactiveCosmosTemplate.findById(PRIMARY_TEST_PERSON.getId(), Person.class);
+ Assertions.assertThat(findById.block().getFirstName()).isEqualTo(TestConstants.FIRST_NAME);
+ primaryReactiveCosmosTemplate.deleteAll(Person.class.getSimpleName(), Person.class).block();
+ primaryReactiveCosmosTemplate.deleteContainer(personInfo.getContainerName());
+ }
+
+ @Test
+ public void testSecondaryTemplate() {
+ secondaryReactiveCosmosTemplate.createContainerIfNotExists(personInfo).block();
+ secondaryReactiveCosmosTemplate.insert(SECONDARY_TEST_PERSON,
+ new PartitionKey(personInfo.getPartitionKeyFieldValue(SECONDARY_TEST_PERSON))).block();
+ final Mono findById = secondaryReactiveCosmosTemplate.findById(SECONDARY_TEST_PERSON.getId(), Person.class);
+ Assertions.assertThat(findById.block().getFirstName()).isEqualTo(TestConstants.NEW_FIRST_NAME);
+ secondaryReactiveCosmosTemplate.deleteAll(Person.class.getSimpleName(), Person.class).block();
+ secondaryReactiveCosmosTemplate.deleteContainer(personInfo.getContainerName());
+ }
+
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/SecondaryTestRepositoryConfig.java b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/SecondaryTestRepositoryConfig.java
new file mode 100644
index 000000000000..dc18fbcb180c
--- /dev/null
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/SecondaryTestRepositoryConfig.java
@@ -0,0 +1,49 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+package com.azure.spring.data.cosmos.repository;
+
+import com.azure.cosmos.CosmosClientBuilder;
+import com.azure.spring.data.cosmos.CosmosFactory;
+import com.azure.spring.data.cosmos.common.TestConstants;
+import com.azure.spring.data.cosmos.config.CosmosConfig;
+import com.azure.spring.data.cosmos.core.ReactiveCosmosTemplate;
+import com.azure.spring.data.cosmos.core.convert.MappingCosmosConverter;
+import com.azure.spring.data.cosmos.repository.config.EnableCosmosRepositories;
+import com.azure.spring.data.cosmos.repository.config.EnableReactiveCosmosRepositories;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.util.StringUtils;
+
+@Configuration
+@PropertySource(value = {"classpath:application.properties"})
+@EnableCosmosRepositories
+@EnableReactiveCosmosRepositories(reactiveCosmosTemplateRef = "secondaryReactiveCosmosTemplate")
+public class SecondaryTestRepositoryConfig {
+ @Value("${cosmos.secondary.uri:}")
+ private String cosmosDbUri;
+
+ @Value("${cosmos.secondary.key:}")
+ private String cosmosDbKey;
+
+ @Value("${cosmos.secondary.database:}")
+ private String database;
+
+ @Value("${cosmos.secondary.queryMetricsEnabled}")
+ private boolean queryMetricsEnabled;
+
+ @Bean
+ public ReactiveCosmosTemplate secondaryReactiveCosmosTemplate(MappingCosmosConverter mappingCosmosConverter) {
+ final String dbName = StringUtils.hasText(this.database) ? this.database : TestConstants.SECONDARY_DB_NAME;
+ CosmosConfig config = CosmosConfig.builder()
+ .cosmosClientBuilder(new CosmosClientBuilder()
+ .key(cosmosDbKey)
+ .endpoint(cosmosDbUri)
+ .contentResponseOnWriteEnabled(true))
+ .database(dbName)
+ .enableQueryMetrics(queryMetricsEnabled)
+ .build();
+ return new ReactiveCosmosTemplate(new CosmosFactory(config), mappingCosmosConverter, config.getDatabase());
+ }
+}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryUnitTest.java b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryUnitTest.java
index 086c9cdb29f7..47b03637c98a 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryUnitTest.java
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/test/java/com/azure/spring/data/cosmos/repository/support/CosmosRepositoryFactoryUnitTest.java
@@ -8,8 +8,6 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
import org.springframework.data.repository.core.EntityInformation;
import static org.junit.Assert.assertTrue;
@@ -20,12 +18,9 @@ public class CosmosRepositoryFactoryUnitTest {
@Mock
CosmosTemplate dbTemplate;
- @Autowired
- ApplicationContext applicationContext;
-
@Test
public void useMappingCosmosDBEntityInfoIfMappingContextSet() {
- final CosmosRepositoryFactory factory = new CosmosRepositoryFactory(dbTemplate, applicationContext);
+ final CosmosRepositoryFactory factory = new CosmosRepositoryFactory(dbTemplate);
final EntityInformation entityInfo = factory.getEntityInformation(Person.class);
assertTrue(entityInfo instanceof CosmosEntityInformation);
}
diff --git a/sdk/cosmos/azure-spring-data-cosmos/src/test/resources/application.properties b/sdk/cosmos/azure-spring-data-cosmos/src/test/resources/application.properties
index 5f47ae7f03be..425d26f61755 100644
--- a/sdk/cosmos/azure-spring-data-cosmos/src/test/resources/application.properties
+++ b/sdk/cosmos/azure-spring-data-cosmos/src/test/resources/application.properties
@@ -10,3 +10,13 @@ perf.acceptance.percentage=10
# Populate query metrics
cosmos.queryMetricsEnabled=true
+
+cosmos.secondary.uri=${NEW_ACCOUNT_HOST}
+cosmos.secondary.key=${NEW_ACCOUNT_KEY}
+cosmos.secondary.secondaryKey=${NEW_SECONDARY_ACCOUNT_KEY}
+
+# Populate query metrics
+cosmos.secondary.queryMetricsEnabled=true
+
+
+
diff --git a/sdk/cosmos/test-resources.json b/sdk/cosmos/test-resources.json
index 447dd5729a44..1d6c382d202a 100644
--- a/sdk/cosmos/test-resources.json
+++ b/sdk/cosmos/test-resources.json
@@ -28,7 +28,9 @@
"variables": {
"apiVersion": "2020-04-01",
"accountName": "[toLower(parameters('baseName'))]",
+ "newAccountName": "[toLower(concat(parameters('baseName'), '2'))]",
"resourceId": "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('accountName'))]",
+ "newResourceId": "[resourceId('Microsoft.DocumentDB/databaseAccounts', variables('newAccountName'))]",
"singleRegionConfiguration": [
{
"locationName": "East US 2",
@@ -79,6 +81,32 @@
"capabilities": [],
"ipRules": []
}
+ },
+ {
+ "type": "Microsoft.DocumentDB/databaseAccounts",
+ "apiVersion": "[variables('apiVersion')]",
+ "name": "[variables('newAccountName')]",
+ "location": "[resourceGroup().location]",
+ "kind": "GlobalDocumentDB",
+ "properties": {
+ "publicNetworkAccess": "Enabled",
+ "enableAutomaticFailover": false,
+ "enableMultipleWriteLocations": "[parameters('enableMultipleWriteLocations')]",
+ "isVirtualNetworkFilterEnabled": false,
+ "virtualNetworkRules": [],
+ "disableKeyBasedMetadataWriteAccess": false,
+ "enableFreeTier": false,
+ "enableAnalyticalStorage": false,
+ "databaseAccountOfferType": "Standard",
+ "consistencyPolicy": {
+ "defaultConsistencyLevel": "[parameters('defaultConsistencyLevel')]",
+ "maxIntervalInSeconds": 5,
+ "maxStalenessPrefix": 100
+ },
+ "locations": "[variables('locationsConfiguration')]",
+ "capabilities": [],
+ "ipRules": []
+ }
}
],
"outputs": {
@@ -93,6 +121,18 @@
"SECONDARY_ACCOUNT_KEY": {
"type": "string",
"value": "[listKeys(variables('resourceId'), variables('apiVersion')).secondaryMasterKey]"
+ },
+ "NEW_ACCOUNT_HOST": {
+ "type": "string",
+ "value": "[reference(variables('newResourceId'), variables('apiVersion')).documentEndpoint]"
+ },
+ "NEW_ACCOUNT_KEY": {
+ "type": "string",
+ "value": "[listKeys(variables('newResourceId'), variables('apiVersion')).primaryMasterKey]"
+ },
+ "NEW_SECONDARY_ACCOUNT_KEY": {
+ "type": "string",
+ "value": "[listKeys(variables('newResourceId'), variables('apiVersion')).secondaryMasterKey]"
}
}
}