/**
* This file is part of lavagna.
*
* lavagna is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lavagna is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with lavagna. If not, see <http://www.gnu.org/licenses/>.
*/
package io.lavagna.config;
import com.zaxxer.hikari.HikariDataSource;
import io.lavagna.common.DatabaseMigrationDoneEvent;
import io.lavagna.common.LavagnaEnvironment;
import io.lavagna.service.DatabaseMigrator;
import org.apache.commons.lang3.ArrayUtils;
import org.flywaydb.core.api.MigrationVersion;
import org.hsqldb.util.DatabaseManagerSwing;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.ConfigurableEnvironment;
import javax.sql.DataSource;
import java.net.URI;
import java.net.URISyntaxException;
public class DataSourceConfig {
public static final MigrationVersion LATEST_STABLE_VERSION = MigrationVersion.fromVersion("23");
@Bean
public LavagnaEnvironment getEnvironment(ConfigurableEnvironment environment) {
return new LavagnaEnvironment(environment);
}
@Bean(destroyMethod = "close")
public DataSource getDataSource(LavagnaEnvironment env) throws URISyntaxException {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setDriverClassName(getDriveClassName(env.getRequiredProperty("datasource.dialect")));
if (env.containsProperty("datasource.url") && //
env.containsProperty("datasource.username")) {
urlAndCredentials(dataSource, env);
} else {
urlWithCredentials(dataSource, env);
}
if (System.getProperty("startDBManager") != null) {
DatabaseManagerSwing.main(new String[] { "--url", "jdbc:hsqldb:mem:lavagna", "--noexit" });
}
return dataSource;
}
// tomcat 8 is picky when we include the drivers in the war
private static String getDriveClassName(String dialect) {
switch (dialect) {
case "HSQLDB":
return "org.hsqldb.jdbcDriver";
case "MYSQL":
return "com.mysql.jdbc.Driver";
case "PGSQL":
return "org.postgresql.Driver";
default:
throw new IllegalStateException("Unknown dialect " + dialect);
}
}
//
/**
* for supporting heroku style url:
*
* <pre>
* [database type]://[username]:[password]@[host]:[port]/[database name]
* </pre>
*
* @param dataSource
* @param env
* @throws URISyntaxException
*/
private static void urlWithCredentials(HikariDataSource dataSource, LavagnaEnvironment env)
throws URISyntaxException {
URI dbUri = new URI(env.getRequiredProperty("datasource.url"));
dataSource.setUsername(dbUri.getUserInfo().split(":")[0]);
dataSource.setPassword(dbUri.getUserInfo().split(":")[1]);
dataSource.setJdbcUrl(String.format("%s://%s:%s%s", scheme(dbUri), dbUri.getHost(), dbUri.getPort(),
dbUri.getPath()));
}
private static String scheme(URI uri) {
return "postgres".equals(uri.getScheme()) ? "jdbc:postgresql" : uri.getScheme();
}
private static void urlAndCredentials(HikariDataSource dataSource, LavagnaEnvironment env) {
dataSource.setJdbcUrl(env.getRequiredProperty("datasource.url"));
dataSource.setUsername(env.getRequiredProperty("datasource.username"));
dataSource.setPassword(env.getProperty("datasource.password") != null ? env.getProperty("datasource.password") : "");
}
@Bean
public DatabaseMigrator migrator(LavagnaEnvironment env, DataSource dataSource, ApplicationEventPublisher publisher) {
boolean isDev = ArrayUtils.contains(env.getActiveProfiles(),"dev");
DatabaseMigrator migrator = new DatabaseMigrator(env, dataSource, isDev ? MigrationVersion.LATEST : LATEST_STABLE_VERSION);
publisher.publishEvent(new DatabaseMigrationDoneEvent(this));
return migrator;
}
}