package bo.gotthardt.ebean; import com.avaje.ebean.EbeanServer; import com.avaje.ebean.EbeanServerFactory; import com.avaje.ebean.config.ServerConfig; import com.codahale.metrics.MetricRegistry; import com.google.common.base.Preconditions; import com.google.common.base.Stopwatch; import io.dropwizard.ConfiguredBundle; import io.dropwizard.db.DataSourceFactory; import io.dropwizard.migrations.CloseableLiquibase; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import liquibase.exception.ValidationFailedException; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.TimeUnit; /** * Dropwizard bundle for setting up Ebean. * Also applies Liquibase database migrations when run. */ @Slf4j public class EbeanBundle implements ConfiguredBundle<HasDatabaseConfiguration> { private EbeanServer ebeanServer; @Override public void initialize(Bootstrap<?> bootstrap) { // Empty on purpose. } @Override public void run(HasDatabaseConfiguration configuration, Environment environment) throws Exception { ExtendedDataSourceFactory dbConfig = configuration.getDatabaseConfig(); log.info("Connecting to database on '{}' with username '{}'.", dbConfig.getUrl(), dbConfig.getUser()); if (dbConfig.isMigrationsEnabled()) { try { applyMigrations(dbConfig, environment.metrics()); } catch (Exception e) { log.error("Error applying database migrations! {}", e.getMessage()); throw e; } } else { log.info("Database migrations disabled."); } ServerConfig serverConfig = EbeanConfigUtils.createServerConfig(dbConfig); ebeanServer = EbeanServerFactory.create(serverConfig); Preconditions.checkNotNull(ebeanServer); environment.healthChecks().register("ebean-" + ebeanServer.getName(), new EbeanHealthCheck(ebeanServer)); } /** * Get the configured EbeanServer. * Only available after bundles have been initialized. */ public EbeanServer getEbeanServer() { Preconditions.checkNotNull(ebeanServer, "Ebean server not created yet (this happens during 'run' i.e. after 'initialize')."); return ebeanServer; } private static void applyMigrations(DataSourceFactory dbConfig, MetricRegistry metrics) throws Exception { Stopwatch migrationsTimer = Stopwatch.createStarted(); // Borrowed from AbstractLiquibaseCommand. DataSourceFactory lbConfig = EbeanConfigUtils.clone(dbConfig); lbConfig.setMaxSize(1); lbConfig.setMinSize(1); lbConfig.setInitialSize(1); try (CloseableLiquibase liquibase = new CloseableLiquibase(dbConfig.build(metrics, "liquibase"))) { log.info("Checking for database migrations."); liquibase.update(""); migrationsTimer.stop(); metrics.timer(MetricRegistry.name(EbeanBundle.class, "migrations")).update(migrationsTimer.elapsed(TimeUnit.MILLISECONDS), TimeUnit.MILLISECONDS); log.info("Database migrations complete in {} ms.", migrationsTimer.elapsed(TimeUnit.MILLISECONDS)); } catch (ValidationFailedException e) { e.printDescriptiveError(System.err); throw e; } } }