【发布时间】:2018-10-15 14:15:28
【问题描述】:
背景
我正在构建一个包含多个 couchbase 存储桶的 Spring 应用程序。主存储桶包含有关其他租户配置的数据,而其余存储桶特定于租户/客户并共享相同的 DAO、服务。
问题
我想在租户特定的存储桶中保存/检索文档,但 Spring 数据沙发库本质上是静态的,不允许将存储桶动态绑定到存储库或在运行时在存储桶之间切换。 有没有办法在 Spring Data Couchbase 中将存储桶动态映射/绑定到存储库?
配置
我正在初始化 3 个租户模板,将 master 设置为默认值,并希望在运行时根据租户在其他 2 个模板之间切换。
@Configuration
@EnableCouchbaseRepositories(basePackages = {"com.user"})
@EnableCouchbaseAuditing
public class CouchbaseMultiBucketConfig extends AbstractCouchbaseConfiguration {
private static final String ACCESS_FAILED = "Failed to access bucket template: ";
@Value("${bucket.master.name}")
private String masterBucketName;
@Value("${bucket.master.password}")
private String masterBucketPassword;
@Value("${bucket.master.host:#{null}}")
private String masterBucketHost;
@Value("${bucket.tenant1.name}")
private String tenant1BucketName;
@Value("${bucket.tenant1.password}")
private String tenant1BucketPassword;
@Value("${bucket.tenant1.host:#{null}}")
private String tenant1BucketHost;
@Value("${bucket.tenant2.name}")
private String tenant2BucketName;
@Value("${bucket.tenant2.password}")
private String tenant2ucketPassword;
@Value("${bucket.tenant2.host:#{null}}")
private String tenant2ucketHost;
@Value("${cb.hosts}")
private String hosts;
@Bean
@Qualifier("tenant1")
public Bucket tenant1Bucket() {
return openBucket(tenant1BucketName, tenant1BucketPassword, tenant1BucketHost);
}
@Bean
@Qualifier("tenant2")
public Bucket tenant1Bucket() {
return openBucket(tenant2BucketName, tenant2BucketPassword, tenant2BucketHost);
}
@Bean
@Qualifier("master")
public Bucket masterBucket() {
return openBucket(masterBucketName, masterBucketPassword, masterBucketHost);
}
@Bean
@Qualifier("masterTemplate")
public CouchbaseTemplate masterTemplate() {
try {
final CouchbaseTemplate template = new CouchbaseTemplate(
couchbaseClusterInfo(), //reuse the default bean
masterBucket(), //the bucket is non-default
mappingCouchbaseConverter(), translationService() //default beans here as well
);
template.setDefaultConsistency(getDefaultConsistency());
return template;
} catch (Exception ex) {
throw new IllegalStateException(ACCESS_FAILED, ex);
}
}
@Bean
@Qualifier("tenant1Template")
public CouchbaseTemplate tenant1Template() {
try {
final CouchbaseTemplate template = new CouchbaseTemplate(
couchbaseClusterInfo(), //reuse the default bean
tenant1Bucket(), //the bucket is non-default
mappingCouchbaseConverter(), translationService() //default beans here as well
);
template.setDefaultConsistency(getDefaultConsistency());
return template;
} catch (Exception ex) {
throw new IllegalStateException(ACCESS_FAILED, ex);
}
}
@Bean
@Qualifier("tenant2Template")
public CouchbaseTemplate tenant2Template() {
try {
final CouchbaseTemplate template = new CouchbaseTemplate(
couchbaseClusterInfo(), //reuse the default bean
tenant2Bucket(), //the bucket is non-default
mappingCouchbaseConverter(), translationService() //default beans here as well
);
template.setDefaultConsistency(getDefaultConsistency());
return template;
} catch (Exception ex) {
throw new IllegalStateException(ACCESS_FAILED, ex);
}
}
private Bucket openBucket(final String bucketName, final String bucketPassword, final String alternativeHost)
throws IllegalStateException {
try {
return couchbaseCluster(alternativeHost).openBucket(bucketName, bucketPassword);
} catch (Exception ex) {
throw new IllegalStateException("Failed to open bucket " + bucketName, ex);
}
}
@Override
public void configureRepositoryOperationsMapping(final RepositoryOperationsMapping baseMapping) {
baseMapping.setDefault(masterTemplate());
}
@Override
protected List<String> getBootstrapHosts() {
return parse(hosts);
}
@Override
protected String getBucketName() {
return tenant1BucketName;
}
@Override
protected String getBucketPassword() {
return tenant1BucketPassword;
}
private List<String> parse(final String hosts) {
return Arrays.asList(hosts.split(","))
.stream().map(in -> in.trim()).collect(Collectors.toList());
}
}
存储库
@Repository
public interface UserRepository extends CouchbaseRepository<User, String> {
User getByDocKey(final String docKey);
@Query("#{#n1ql.selectEntity} WHERE tenantId= $1")
List<User> findByTenantId(String tenantId);
}
谢谢
【问题讨论】:
标签: spring spring-data couchbase multi-tenant spring-data-couchbase