我有一个多租户的mongoDB应用程序,让我们假设 从HTTP请求标头中的租户名称中选择到正确数据库的正确连接(i使用较早准备的带有租户名称的属性文件)。 当应用程序启动时,mongoDB正在配置,并且我没有有关租户的信息,因为尚未发送对应用程序的任何请求,因此我不知道我应该连接到哪个数据库。当我尝试从mongo存储库中获取一些数据(然后我从HTTP请求获得租户名称)时,是否有可能动态配置mongoDB与数据库的连接?
MongoDbConfiguration:
@Configuration
public class MongoDbConfiguration {
private final MongoConnector mongoConnector;
@Autowired
public MongoDbConfiguration(MongoConnector mongoConnector) {
this.mongoConnector = mongoConnector;
}
@Bean
public MongoDbFactory mongoDbFactory() {
return new MultiTenantSingleMongoDbFactory(mongoConnector, new MongoExceptionTranslator());
}
@Bean
public MongoTemplate mongoTemplate() {
return new MongoTemplate(mongoDbFactory());
}
}
答案 0 :(得分:1)
@Component
@Slf4j
public class MultiTenantMongoDbFactory extends SimpleMongoDbFactory {
private static final Logger logger = LoggerFactory.getLogger(MultiTenantMongoDbFactory.class);
private Map<String, DbConfig> tenantToDbConfig;
private Map<String, MongoDatabase> tenantToMongoDatabase;
@Autowired
public MultiTenantMongoDbFactory(
final @Qualifier("sibTenantContexts") Map<String, DbConfig> dbConfigs,
final SibEnvironment env) {
super(new MongoClientURI(env.getDefaultDatabase()));
this.tenantToDbConfig = dbConfigs;
// Initialize tenantToMongoDatabase map.
buildTenantDbs();
}
@Override
public MongoDatabase getDb() {
String tenantId = (!StringUtils.isEmpty(TenantContext.getId()) ? TenantContext.getId()
: SibConstant.DEFAULT_TENANT);
return this.tenantToMongoDatabase.get(tenantId);
}
/**
* Create tenantToMongoDatabase map.
*/
@SuppressWarnings("resource")
private void buildTenantDbs() {
log.debug("Building tenantDB configuration.");
this.tenantToMongoDatabase = new HashMap<>();
/*
* for each tenant fetch dbConfig and intitialize MongoClient and set it to
* tenantToMongoDatabase
*/
for (Entry<String, DbConfig> idToDbconfig : this.tenantToDbConfig.entrySet()) {
try {
this.tenantToMongoDatabase.put(idToDbconfig.getKey(),
new MongoClient(new MongoClientURI(idToDbconfig.getValue()
.getUri())).getDatabase(idToDbconfig.getValue()
.getDatabase()));
} catch (MongoException e) {
log.error(e.getMessage(), e.getCause());
}
}
}
}
在此,tenantToDbConfig
是我在应用程序启动时创建的一个Bean,我在其中将DBConfiguration((URL /数据库名称))存储在每个租户中。引导时需要一个默认数据库,对于每个请求,我都希望在请求标头中有tenantId。