org.nuiton.topia.liquibase.TopiaLiquibaseServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of topia-service-liquibase Show documentation
Show all versions of topia-service-liquibase Show documentation
Integration between topia and Liquibase database migration framework
package org.nuiton.topia.liquibase;
/*
* #%L
* ToPIA :: Liquibase integration service
* $Id$
* $HeadURL$
* %%
* Copyright (C) 2004 - 2014 CodeLutin
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import liquibase.Contexts;
import liquibase.Liquibase;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.exception.DatabaseException;
import liquibase.exception.LiquibaseException;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.CompositeResourceAccessor;
import liquibase.resource.FileSystemResourceAccessor;
import liquibase.resource.ResourceAccessor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.topia.persistence.TopiaApplicationContext;
import org.nuiton.topia.persistence.TopiaMigrationServiceException;
import org.nuiton.topia.persistence.jdbc.JdbcConfiguration;
import java.util.Map;
/**
* Integration with Liquibase migration
* framework.
*
* When {@link org.nuiton.topia.persistence.TopiaApplicationContext} will be started
* all migrations will be run.
*
* @since 3.0
*/
public class TopiaLiquibaseServiceImpl implements TopiaLiquibaseService {
private static final Log log = LogFactory.getLog(TopiaLiquibaseServiceImpl.class);
protected Contexts allContexts = new Contexts("");
/**
* Place to find the changelog, default name has been fixed according
* to best practices.
*/
protected String changeLogPath = "db/changelog-master.xml";
protected Database database;
protected Liquibase liquibase;
@Override
public void initTopiaService(TopiaApplicationContext topiaApplicationContext, Map serviceConfiguration) {
if ( ! serviceConfiguration.isEmpty()) {
throw new UnsupportedOperationException("no configuration expected but " + serviceConfiguration + " given");
}
try {
ResourceAccessor resourceAccessor = getResourceAccessor();
database = openDatabase(topiaApplicationContext, resourceAccessor);
liquibase = getLiquibase(database, resourceAccessor);
} catch (LiquibaseException e) {
close();
throw new TopiaMigrationServiceException("unable to init liquibase", e);
}
}
@Override
public String getSchemaVersion() {
// TODO brendan 18/07/14 use http://www.liquibase.org/documentation/changes/tag_database.html ?
throw new UnsupportedOperationException("schema version is not made available by liquibase");
}
@Override
public void initOnCreateSchema() {
if (log.isInfoEnabled()) {
log.info("init liquibase");
}
try {
liquibase.changeLogSync(allContexts);
} catch (LiquibaseException e) {
close();
throw new TopiaMigrationServiceException("unable to init liquibase", e);
}
}
@Override
public void runSchemaMigration() {
if (log.isInfoEnabled()) {
log.info("migrate schema with liquibase");
}
try {
liquibase.update(allContexts);
} catch (LiquibaseException e) {
close();
throw new TopiaMigrationServiceException("unable to update schema with liquibase", e);
}
}
protected Liquibase getLiquibase(Database database, ResourceAccessor resourceAccessor) throws LiquibaseException {
Liquibase liquibase = new Liquibase(changeLogPath, resourceAccessor, database);
return liquibase;
}
/**
* Implementation highly inspired from {@link liquibase.integration.servlet.LiquibaseServletListener}.
*/
protected ResourceAccessor getResourceAccessor() {
Thread currentThread = Thread.currentThread();
ClassLoader contextClassLoader = currentThread.getContextClassLoader();
ResourceAccessor threadClFO = new ClassLoaderResourceAccessor(contextClassLoader);
ResourceAccessor clFO = new ClassLoaderResourceAccessor();
ResourceAccessor fsFO = new FileSystemResourceAccessor();
return new CompositeResourceAccessor(clFO, fsFO, threadClFO);
}
protected Database openDatabase(TopiaApplicationContext topiaApplicationContext, ResourceAccessor resourceAccessor) {
JdbcConfiguration configuration = topiaApplicationContext.getConfiguration();
String url = configuration.getJdbcConnectionUrl();
String user = configuration.getJdbcConnectionUser();
String password = configuration.getJdbcConnectionPassword();
try {
Database database = DatabaseFactory.getInstance().openDatabase(url, user, password, null, resourceAccessor);
return database;
} catch (DatabaseException e) {
throw new TopiaMigrationServiceException("cannot get database for migration connection", e);
}
}
protected void closeDatabase() {
if (database != null) {
try {
database.close();
database = null;
} catch (DatabaseException e2) {
if (log.isWarnEnabled()) {
log.warn("error while trying to close database after liquibase error", e2);
}
}
}
}
@Override
public void close() {
closeDatabase();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy