Revert "ENH: allow server startup without running ddl and thus allowing starting with the database not yet up and later lazily initializing the database and running ddl"

This reverts commit af0f9a4d15.
This commit is contained in:
Roland Praml
2021-12-17 08:13:02 +01:00
parent 5bf19647fe
commit e5036990f2
7 changed files with 4 additions and 233 deletions
@@ -1717,12 +1717,6 @@ public interface Database {
*/
<T> Set<String> validateQuery(Query<T> query);
/**
* Runs the DbMigration or DDL manually. This is normally executed on startup, as long as
* serverConfig.initDatabase is set to true.
*/
void initDatabase(boolean online);
/**
* Load and lock the bean using {@code select for update}.
* <p>
@@ -301,9 +301,7 @@ public class DatabaseConfig {
*/
private ExternalTransactionManager externalTransactionManager;
private boolean skipDataSourceCheck = false;
private boolean skipInitDatabase = false;
private boolean skipDataSourceCheck;
/**
* The data source (if programmatically provided).
@@ -1649,14 +1647,6 @@ public class DatabaseConfig {
this.skipDataSourceCheck = skipDataSourceCheck;
}
public boolean skipInitDatabase() {
return skipInitDatabase;
}
public void setSkipInitDatabase(final boolean skipInitDatabase) {
this.skipInitDatabase = skipInitDatabase;
}
/**
* Return the DataSource.
*/
@@ -2743,6 +2733,7 @@ public class DatabaseConfig {
}
/**
* Load settings from application.properties, application.yaml and other sources.
* <p>
@@ -2935,7 +2926,6 @@ public class DatabaseConfig {
jsonMutationDetection = p.getEnum(MutationDetection.class, "jsonMutationDetection", jsonMutationDetection);
skipDataSourceCheck = p.getBoolean("skipDataSourceCheck", skipDataSourceCheck);
skipInitDatabase = p.getBoolean("skipInitDatabase", skipInitDatabase);
runMigration = p.getBoolean("migration.run", runMigration);
ddlGenerate = p.getBoolean("ddl.generate", ddlGenerate);
ddlRun = p.getBoolean("ddl.run", ddlRun);
@@ -56,10 +56,6 @@ public class DatabasePlatformFactory {
if (config.getDataSourceConfig().isOffline()) {
throw new PersistenceException("DatabasePlatformName must be specified with offline mode");
}
if (config.getTenantMode().isDynamicDataSource()) {
throw new IllegalStateException("DatabasePlatform must be explicitly set on ServerConfig for TenantMode "
+ config.getTenantMode());
}
// guess using meta data from driver
return byDataSource(config.getDataSource());
@@ -179,7 +179,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
private final long slowQueryMicros;
private final SlowQueryListener slowQueryListener;
private final boolean disableL2Cache;
private final boolean initDatabase;
private boolean shutdown;
/**
@@ -228,7 +227,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
this.tempFileProvider = config.getConfig().getTempFileProvider();
this.ddlGenerator = config.initDdlGenerator(this);
this.scriptRunner = new DScriptRunner(this);
this.initDatabase = !config.getConfig().skipInitDatabase();
configureServerPlugins();
// Register with the JVM Shutdown hook
@@ -253,21 +251,13 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
}
}
@Override
public void initDatabase(boolean online) {
if (!config.isDocStoreOnly()) {
ddlGenerator.execute(online);
}
}
/**
* Execute all the plugins with an online flag indicating the DB is up or not.
*/
public void executePlugins(boolean online) {
if (initDatabase) {
initDatabase(online);
if (!config.isDocStoreOnly()) {
ddlGenerator.execute(online);
}
for (Plugin plugin : serverPlugins) {
plugin.online(online);
}
@@ -44,38 +44,7 @@ public class EbeanServerFactory_MultiTenancy_Test extends BaseTestCase {
database.shutdown();
}
/**
* Tests using multi tenancy per database
*/
@Test
public void create_new_server_with_multi_tenancy_db_with_master() {
String tenant = "customer";
CurrentTenantProvider tenantProvider = Mockito.mock(CurrentTenantProvider.class);
Mockito.doReturn(tenant).when(tenantProvider).currentId();
TenantDataSourceProvider dataSourceProvider = Mockito.mock(TenantDataSourceProvider.class);
DatabaseConfig config = new DatabaseConfig();
config.setName("h2");
config.loadFromProperties();
config.setRegister(false);
config.setDefaultServer(false);
config.setDdlGenerate(false);
config.setDdlRun(false);
config.setTenantMode(TenantMode.DB_WITH_MASTER);
config.setCurrentTenantProvider(tenantProvider);
config.setTenantDataSourceProvider(dataSourceProvider);
Mockito.doReturn(config.getDataSource()).when(dataSourceProvider).dataSource(tenant);
config.setDatabasePlatform(new PostgresPlatform());
final Database database = DatabaseFactory.create(config);
database.shutdown();
}
/**
* Tests using multi tenancy per schema
@@ -1,163 +0,0 @@
package io.ebean.config;
import io.ebean.Database;
import io.ebean.DatabaseFactory;
import io.ebean.annotation.ForPlatform;
import io.ebean.annotation.Platform;
import io.ebean.datasource.DataSourceAlert;
import io.ebean.datasource.DataSourceInitialiseException;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.EBasicVer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.persistence.PersistenceException;
import javax.sql.DataSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class TestServerOffline {
@Test
@ForPlatform({Platform.H2})
public void testOffline_with_failOnStart() throws SQLException {
String url = "jdbc:h2:mem:testoffline1";
try (Connection bootup = DriverManager.getConnection(url, "sa", "secret")) {
Properties props = props(url);
props.setProperty("datasource.h2_offline.failOnStart", "true");
DatabaseConfig config = config(props);
assertThatThrownBy(() -> DatabaseFactory.create(config))
.isInstanceOf(DataSourceInitialiseException.class);
}
}
@Test
@ForPlatform({Platform.H2})
public void testOffline_no_failOnStart() throws SQLException {
String url = "jdbc:h2:mem:testoffline2";
try (Connection bootup = DriverManager.getConnection(url, "sa", "secret")) {
Properties props = props(url);
DatabaseConfig config = config(props);
config.setSkipDataSourceCheck(true);
config.setSkipInitDatabase(true);
Database h2Offline = DatabaseFactory.create(config);
assertThat(h2Offline).isNotNull();
}
}
private static class LazyDatasourceInitializer implements DataSourceAlert {
public Database server;
private boolean initialized;
@Override
public void dataSourceUp(DataSource dataSource) {
if (!initialized) {
initDatabase();
}
}
public synchronized void initDatabase() {
if (!initialized) {
server.initDatabase(true);
initialized = true;
}
}
@Override
public void dataSourceDown(DataSource dataSource, SQLException reason) {}
@Override
public void dataSourceWarning(DataSource dataSource, String msg) {}
}
@Test
@ForPlatform({Platform.H2})
public void testOffline_recovery() throws SQLException {
String url = "jdbc:h2:mem:testoffline3";
try (Connection bootup = DriverManager.getConnection(url, "sa", "secret")) {
Properties props = props(url);
LazyDatasourceInitializer alert = new LazyDatasourceInitializer() ;
DatabaseConfig config = config(props);
config.getDataSourceConfig().setAlert(alert);
config.getDataSourceConfig().setHeartbeatFreqSecs(1);
config.setSkipDataSourceCheck(true);
config.setSkipInitDatabase(true);
Database h2Offline = DatabaseFactory.create(config);
alert.server = h2Offline;
assertThat(h2Offline).isNotNull();
assertThatThrownBy(() -> alert.initDatabase())
.isInstanceOf(PersistenceException.class)
.hasMessageContaining("Failed to obtain connection to run DDL");
assertThatThrownBy(() -> h2Offline.find(EBasicVer.class).findCount()).isInstanceOf(PersistenceException.class);
// so - reset the password so that the server can reconnect
try (Statement stmt = bootup.createStatement()) {
stmt.execute("alter user sa set password 'sa'");
}
assertThat(alert.initialized).isFalse();
// next access to ebean should bring DS online
h2Offline.find(EBasicVer.class).findCount();
assertThat(alert.initialized).isTrue();
// check if server is working (ie ddl was run)
EBasicVer bean = new EBasicVer("foo");
h2Offline.save(bean);
assertThat(h2Offline.find(EBasicVer.class).findCount()).isEqualTo(1);
h2Offline.delete(bean);
}
}
private Properties props(String url) {
Properties props = new Properties();
props.setProperty("datasource.h2_offline.username", "sa");
props.setProperty("datasource.h2_offline.password", "sa");
props.setProperty("datasource.h2_offline.url", url);
props.setProperty("datasource.h2_offline.driver", "org.h2.Driver");
// ensures, that the datasource will come up when DB is not available
props.setProperty("datasource.h2_offline.failOnStart", "false");
props.setProperty("ebean.h2_offline.databasePlatformName", "h2");
props.setProperty("ebean.h2_offline.ddl.extra", "false");
props.setProperty("ebean.h2_offline.ddl.generate", "true");
props.setProperty("ebean.h2_offline.ddl.run", "true");
return props;
}
private DatabaseConfig config(Properties props) {
DatabaseConfig config = new DatabaseConfig();
config.setName("h2_offline");
config.loadFromProperties(props);
config.setDefaultServer(false);
config.setRegister(false);
config.getClasses().add(EBasicVer.class);
return config;
}
}
@@ -583,11 +583,6 @@ public class TDSpiServer implements SpiServer {
return null;
}
@Override
public void initDatabase(final boolean online) {
}
@Override
public void truncate(String... tables) {