Как настроить MultiTenantSpringLiquibase для AbstractRoutingDataSource? - PullRequest
0 голосов
/ 14 апреля 2020

Я пытаюсь настроить свой проект 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...