refactor: Integrate Flyway for database migrations and simplify Docker Compose and tenant configurations.
This commit is contained in:
@@ -2,10 +2,11 @@ package com.magistr.app;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
|
||||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, FlywayAutoConfiguration.class})
|
||||
@EnableScheduling
|
||||
public class Application {
|
||||
|
||||
|
||||
0
backend/src/main/java/com/magistr/app/config/tenant/ConfigMapUpdater.java
Normal file → Executable file
0
backend/src/main/java/com/magistr/app/config/tenant/ConfigMapUpdater.java
Normal file → Executable file
51
backend/src/main/java/com/magistr/app/config/tenant/TenantConfigWatcher.java
Normal file → Executable file
51
backend/src/main/java/com/magistr/app/config/tenant/TenantConfigWatcher.java
Normal file → Executable file
@@ -120,46 +120,37 @@ public class TenantConfigWatcher {
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализирует БД нового тенанта: проверяет наличие таблиц,
|
||||
* если нет — выполняет init.sql.
|
||||
* Выполняет миграции Flyway для конкретного тенанта пи подключении.
|
||||
* Если БД уже существует, но история Flyway пуста —
|
||||
* делает baseline (считает V1_init.sql уже выполненным).
|
||||
*/
|
||||
public void initDatabaseForTenant(TenantConfig tenant) {
|
||||
String domain = tenant.getDomain();
|
||||
try {
|
||||
TenantContext.setCurrentTenant(domain);
|
||||
|
||||
if (needsInit()) {
|
||||
log.info("[{}] Tables not found — executing init.sql...", domain);
|
||||
executeInitSql();
|
||||
log.info("[{}] init.sql executed successfully", domain);
|
||||
} else {
|
||||
log.info("[{}] Tables already exist, skipping init", domain);
|
||||
log.info("[{}] Starting Flyway migrations...", domain);
|
||||
|
||||
// Получаем DataSource конкретно для этого тенанта
|
||||
javax.sql.DataSource tenantDs = routingDataSource.getResolvedDataSources().get(domain);
|
||||
if (tenantDs == null) {
|
||||
// Если ещё не resolve'нулся (первый запуск), берём обёртку
|
||||
tenantDs = dataSource;
|
||||
}
|
||||
|
||||
org.flywaydb.core.Flyway flyway = org.flywaydb.core.Flyway.configure()
|
||||
.dataSource(tenantDs)
|
||||
.baselineOnMigrate(true)
|
||||
.baselineVersion("1")
|
||||
.load();
|
||||
|
||||
flyway.migrate();
|
||||
log.info("[{}] Flyway migrations completed successfully", domain);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] DB init failed: {}", domain, e.getMessage());
|
||||
log.error("[{}] Flyway migration failed: {}", domain, e.getMessage());
|
||||
} finally {
|
||||
TenantContext.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean needsInit() {
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
ResultSet rs = conn.getMetaData().getTables(null, null, "users", new String[]{"TABLE"})) {
|
||||
return !rs.next();
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void executeInitSql() throws Exception {
|
||||
String sql;
|
||||
try (InputStream is = new ClassPathResource("init.sql").getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
|
||||
sql = reader.lines().collect(Collectors.joining("\n"));
|
||||
}
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
Statement stmt = conn.createStatement()) {
|
||||
stmt.execute(sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,12 +101,12 @@ public class TenantDataSourceConfig implements WebMvcConfigurer {
|
||||
em.setPackagesToScan("com.magistr.app.model");
|
||||
|
||||
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
|
||||
vendorAdapter.setGenerateDdl(true);
|
||||
vendorAdapter.setGenerateDdl(false);
|
||||
vendorAdapter.setDatabasePlatform("org.hibernate.dialect.PostgreSQLDialect");
|
||||
em.setJpaVendorAdapter(vendorAdapter);
|
||||
|
||||
Map<String, Object> props = new HashMap<>();
|
||||
props.put("hibernate.hbm2ddl.auto", "update");
|
||||
props.put("hibernate.hbm2ddl.auto", "none");
|
||||
props.put("hibernate.show_sql", "false");
|
||||
em.setJpaPropertyMap(props);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user