Я пытаюсь настроить свой проект SpringBoot для MultiTenancy, используя PostgreSQL схемы. Поэтому у каждого Арендатора будет своя собственная схема с соответствующим именем пользователя и паролем для доступа к нему.
Для обработки всех различных схем, которые я расширил AbstractRoutingDataSource
public class TenantDataSource extends AbstractRoutingDataSource {
private final TenantResolver tenantResolver = new TenantResolver();
@Getter
private Map<Object, Object> targetDataSources;
public TenantDataSource() {
super();
// GOOGLE DataSource
PGSimpleDataSource googleDS = new PGSimpleDataSource();
googleDS.setURL("jdbc:postgresql://localhost:5432/organization");
googleDS.setDatabaseName("organization");
googleDS.setCurrentSchema("google");
googleDS.setUser("google");
googleDS.setPassword("google");
// Microsoft DataSource
PGSimpleDataSource microsoftDS = new PGSimpleDataSource();
microsoftDS.setURL("jdbc:postgresql://localhost:5432/organization");
microsoftDS.setDatabaseName("organization");
microsoftDS.setCurrentSchema("microsoft");
microsoftDS.setUser("microsoft");
microsoftDS.setPassword("microsoft");
// DSs
Map<Object, Object> targetDataSources = new ConcurrentHashMap<>();
targetDataSources.put("GOOGLE", googleDS);
targetDataSources.put("MICROSOFT", microsoftDS);
this.setTargetDataSources(targetDataSources);
}
@Override
protected Object determineCurrentLookupKey() {
String tenant = this.tenantResolver.resolve();
return tenant;
}
@Override
public void setTargetDataSources(Map<Object, Object> targetDataSources) {
super.setTargetDataSources(targetDataSources);
this.targetDataSources = targetDataSources;
}
public Map<Object, Object> getTargetDataSources(){
return this.targetDataSources;
}
}
, и это моя @Configuration
для мультитенантности Liquibase:
@Configuration
@EnableAutoConfiguration(
exclude = {
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
LiquibaseAutoConfiguration.class
}
)
public class IsolatedDatabaseConfiguration{
@Bean
@Qualifier("isolated")
public DataSource isolatedDataSource() {
return new TenantDataSource();
}
@Bean
public MultiTenantSpringLiquibase multiTenantSpringLiquibase(@Qualifier("isolated")
DataSource dataSource) {
MultiTenantSpringLiquibase liquibase = new MultiTenantSpringLiquibase();
if (dataSource instanceof TenantDataSource) {
TenantDataSource ds = (TenantDataSource) dataSource;
liquibase.setDataSource(ds);
Map<Object, Object> targetDS = ds.getTargetDataSources();
List<String> schemas = new ArrayList<>();
targetDS.entrySet().forEach((entry) -> {
String tenant = (String) entry.getKey();
PGSimpleDataSource source = (PGSimpleDataSource) entry.getValue();
String schema = source.getCurrentSchema();
schemas.add(schema);
});
liquibase.setSchemas(schemas);
liquibase.setChangeLog("classpath:/db/changelog/isolated/master.xml");
liquibase.setShouldRun(true);
}
return liquibase;
}
}
При такой конфигурации создаются только следующие таблицы:
- google.databasechangelog
- google.databasechangeloglock
в то время как для схемы «microsoft» я получаю сообщение об ошибке отказа в доступе, как будто оно использует учетные данные источника данных «Google». Если я прав, как я могу сделать MultiTenantSpringLiquibase , чтобы принять список источников данных (Google, Microsoft, ...), каждый с правильными учетными данными, вместо одного (TenantDataSource, который является AbstractRoutingDataSource) что вызывает использование учетных данных по умолчанию для всех схем?
Учетные данные работают нормально, с соответствующими репозиториями, если я не использую bean-компонент Liquibase.