From d6dde2f63d5763cf91440014a08466063d801b22 Mon Sep 17 00:00:00 2001 From: Roland Praml Date: Fri, 17 Dec 2021 11:57:23 +0100 Subject: [PATCH] Provide API to run ddl and migration manually (e.g. with offline DB) --- .../src/main/java/io/ebean/Database.java | 22 +++++++++ .../io/ebeaninternal/api/SpiDdlGenerator.java | 10 +++- .../server/core/DefaultServer.java | 48 ++++++++++++++----- .../server/core/InternalConfiguration.java | 9 +++- .../dbmigration/DdlGenerator.java | 43 +++++------------ .../io/ebeaninternal/api/TDSpiServer.java | 10 ++++ 6 files changed, 96 insertions(+), 46 deletions(-) diff --git a/ebean-api/src/main/java/io/ebean/Database.java b/ebean-api/src/main/java/io/ebean/Database.java index 9c69e33fd..31064ee3c 100644 --- a/ebean-api/src/main/java/io/ebean/Database.java +++ b/ebean-api/src/main/java/io/ebean/Database.java @@ -1741,4 +1741,26 @@ public interface Database { */ void truncate(Class... tables); + /** + * Runs the DDL manually. Can be used, if database is offline or if you use a + * TenantMode that does not support DDL run on startup. + *

+ * Note: runDdl is normally executed at startup automatically, if + * ebean.db.runDdl=true is set. Calling this method, will not check + * that flag. + *

+ */ + void runDdl(); + + /** + * Runs the migration manually. Can be used, if database is offline or if you use a + * TenantMode that does not support DDL run on startup. + *

+ * Note: runDdl is normally executed at startup automatically, if + * ebean.db.migration.run=true is set. Calling this method, will not check + * that flag. + *

+ **/ + void runMigration(); + } diff --git a/ebean-core/src/main/java/io/ebeaninternal/api/SpiDdlGenerator.java b/ebean-core/src/main/java/io/ebeaninternal/api/SpiDdlGenerator.java index b3c485813..6c5d2f43c 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/api/SpiDdlGenerator.java +++ b/ebean-core/src/main/java/io/ebeaninternal/api/SpiDdlGenerator.java @@ -8,8 +8,14 @@ public interface SpiDdlGenerator { /** * Generate and run the DDL for drop-all and create-all scripts. *

- * Run based on on property settings for ebean.ddl.generate and ebean.ddl.run etc. + * Run based on on property settings for ebean.ddl.generate */ - void execute(boolean online); + void generateDdl(); + /** + * Runs the created DDL files. + *

+ * Run based on on property settings for ebean.ddl.run etc. + */ + void runDdl(); } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 26bf3fbab..392f509b2 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -256,7 +256,7 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { */ public void executePlugins(boolean online) { if (!config.isDocStoreOnly()) { - ddlGenerator.execute(online); + ddlGenerator.generateDdl(); } for (Plugin plugin : serverPlugins) { plugin.online(online); @@ -369,27 +369,51 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { serverCacheManager.enabledRegions(config.getEnabledL2Regions()); } + /** * Start any services after registering with the ClusterManager. */ public void start() { - if (config.getDataSource() != null && config.isRunMigration() && TenantMode.DB != config.getTenantMode()) { - final AutoMigrationRunner migrationRunner = ServiceUtil.service(AutoMigrationRunner.class); - if (migrationRunner == null) { - throw new IllegalStateException("No AutoMigrationRunner found. Probably ebean-migration is not in the classpath?"); + // check, if DB is available to run DDL and migration + boolean dbAvailable = !config.isDocStoreOnly() + && !config.isDbOffline() + && config.getDataSource() != null + && config.getTenantMode().isDdlEnabled(); + + if (dbAvailable) { + if (config.isDdlRun()) { + runDdl(); } - final String dbSchema = config.getDbSchema(); - if (dbSchema != null) { - migrationRunner.setDefaultDbSchema(dbSchema); + if (config.isRunMigration()) { + runMigration(); } - migrationRunner.setName(config.getName()); - migrationRunner.setPlatform(config.getDatabasePlatform().getPlatform().base().name().toLowerCase()); - migrationRunner.loadProperties(config.getProperties()); - migrationRunner.run(config.getDataSource()); } startQueryPlanCapture(); } + @Override + public void runDdl() { + ddlGenerator.runDdl(); + } + + @Override + public void runMigration() { + final AutoMigrationRunner migrationRunner = ServiceUtil.service(AutoMigrationRunner.class); + if (migrationRunner == null) { + throw new IllegalStateException( + "No AutoMigrationRunner found. Probably ebean-migration is not in the classpath?"); + } + + final String dbSchema = config.getDbSchema(); + if (dbSchema != null) { + migrationRunner.setDefaultDbSchema(dbSchema); + } + migrationRunner.setName(config.getName()); + migrationRunner.setPlatform(config.getDatabasePlatform().getPlatform().base().name().toLowerCase()); + migrationRunner.loadProperties(config.getProperties()); + migrationRunner.run(dataSource()); + } + private void startQueryPlanCapture() { if (config.isQueryPlanCapture()) { long secs = config.getQueryPlanCapturePeriodSecs(); diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java index b1e79b803..544e7b3fb 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/InternalConfiguration.java @@ -617,8 +617,13 @@ public final class InternalConfiguration { } @Override - public void execute(boolean online) { - if (online && ddlRun) { + public void generateDdl() { + // do nothing + } + + @Override + public void runDdl() { + if (ddlRun) { CoreLog.log.error("Configured to run DDL but ebean-ddl-generator is not in the classpath (or ebean-test in the test classpath?)"); } } diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java index 60c5f6bd3..67211c973 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DdlGenerator.java @@ -41,7 +41,6 @@ public class DdlGenerator implements SpiDdlGenerator { private final SpiEbeanServer server; private final boolean generateDdl; - private final boolean runDdl; private final boolean extraDdl; private final boolean createOnly; private final boolean jaxbPresent; @@ -68,16 +67,8 @@ public class DdlGenerator implements SpiDdlGenerator { final DatabasePlatform databasePlatform = server.databasePlatform(); this.platform = databasePlatform.getPlatform(); this.platformName = platform.base().name(); - if (!config.getTenantMode().isDdlEnabled() && config.isDdlRun()) { - log.warn("DDL can't be run on startup with TenantMode " + config.getTenantMode()); - this.runDdl = false; - this.ddlAutoCommit = false; - this.useMigrationStoredProcedures = false; - } else { - this.runDdl = config.isDdlRun(); - this.ddlAutoCommit = databasePlatform.isDdlAutoCommit(); - this.useMigrationStoredProcedures = config.getDatabasePlatform().isUseMigrationStoredProcedures(); - } + this.ddlAutoCommit = databasePlatform.isDdlAutoCommit(); + this.useMigrationStoredProcedures = config.getDatabasePlatform().isUseMigrationStoredProcedures(); this.scriptTransform = createScriptTransform(config); this.baseDir = initBaseDir(); } @@ -92,18 +83,11 @@ public class DdlGenerator implements SpiDdlGenerator { return new File("."); } - @Override - public void execute(boolean online) { - generateDdl(); - if (online) { - runDdl(); - } - } - /** * Generate the DDL drop and create scripts if the properties have been set. */ - protected void generateDdl() { + @Override + public void generateDdl() { if (generateDdl) { if (!createOnly) { writeDrop(getDropFileName()); @@ -115,16 +99,15 @@ public class DdlGenerator implements SpiDdlGenerator { /** * Run the DDL drop and DDL create scripts if properties have been set. */ - protected void runDdl() { - if (runDdl) { - Connection connection = null; - try { - connection = obtainConnection(); - runDdlWith(connection); - } finally { - JdbcClose.rollback(connection); - JdbcClose.close(connection); - } + @Override + public void runDdl() { + Connection connection = null; + try { + connection = obtainConnection(); + runDdlWith(connection); + } finally { + JdbcClose.rollback(connection); + JdbcClose.close(connection); } } diff --git a/ebean-test/src/test/java/io/ebeaninternal/api/TDSpiServer.java b/ebean-test/src/test/java/io/ebeaninternal/api/TDSpiServer.java index 2cf23625b..ba823c057 100644 --- a/ebean-test/src/test/java/io/ebeaninternal/api/TDSpiServer.java +++ b/ebean-test/src/test/java/io/ebeaninternal/api/TDSpiServer.java @@ -642,4 +642,14 @@ public class TDSpiServer implements SpiServer { public void loadBean(EntityBeanIntercept ebi) { } + + @Override + public void runDdl() { + + } + + @Override + public void runMigration() { + + } }