All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cloud.sdk.frameworks.liquibase.LiquibaseProvider Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020 SAP SE or an SAP affiliate company. All rights reserved.
 */

package com.sap.cloud.sdk.frameworks.liquibase;

import java.io.StringWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.sql.DataSource;

import org.slf4j.Logger;

import com.sap.cloud.sdk.cloudplatform.exception.ShouldNotHappenException;
import com.sap.cloud.sdk.cloudplatform.logging.CloudLoggerFactory;

import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.LiquibaseException;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.CompositeResourceAccessor;
import liquibase.resource.FileSystemResourceAccessor;
import liquibase.resource.ResourceAccessor;

/**
 * Updates the database to the state given by the liquibase configuration file.
 * 

* The default liquibase configuration file is located at {@code liquibase/changelog_master.xml}. */ @Singleton @Startup public class LiquibaseProvider { public static final String DB_MIGRATE_UP_TO_CHANGESET = "db.migrate.changeset"; private static final Logger logger = CloudLoggerFactory.getLogger(LiquibaseProvider.class); @PersistenceContext private EntityManager em; @Resource private DataSource dataSource; /** * Updates the database given by the {@code dataSource} to the current state represented by the liquibase * configuration file in {@code liquibase/changelog_master.xml}. */ @TransactionAttribute( TransactionAttributeType.NEVER ) @PostConstruct public void createDatabase() { try( final Connection connection = dataSource.getConnection() ) { final DatabaseMetaData metaData = connection.getMetaData(); logger.info( "DB driver " + metaData.getDriverName() + " " + metaData.getDriverVersion() + ", major " + metaData.getDriverMajorVersion() + ", minor " + metaData.getDriverMinorVersion()); logger.info( "DB version " + metaData.getDatabaseProductVersion() + ", major " + metaData.getDatabaseMajorVersion() + ", minor " + metaData.getDatabaseMinorVersion()); logger.info( "JDBC version major " + metaData.getJDBCMajorVersion() + ", minor " + metaData.getJDBCMinorVersion()); logger.info("Starting Liquibase migration"); final Thread currentThread = Thread.currentThread(); final ClassLoader contextClassLoader = currentThread.getContextClassLoader(); final ResourceAccessor threadClFO = new ClassLoaderResourceAccessor(contextClassLoader); final ResourceAccessor clFO = new ClassLoaderResourceAccessor(); final ResourceAccessor fsFO = new FileSystemResourceAccessor(); final Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection)); try { final CustomLiquibase liquibase = new CustomLiquibase( "liquibase/changelog_master.xml", new CompositeResourceAccessor(clFO, fsFO, threadClFO), database); liquibase.setUpperBound(getUpperBound()); final String sqlString = simulateMigration(liquibase); logger.info("Will execute:\n " + sqlString); // Do migration liquibase.update(""); } finally { logger.info("Finished Liquibase routine."); try { if( database != null ) { database.close(); } } catch( final Exception e ) { logger.warn("Failed to close connection.", e); } } } catch( final SQLException | LiquibaseException e ) { throw new ShouldNotHappenException(e); } } private String simulateMigration( final CustomLiquibase liquibase ) throws LiquibaseException { final StringWriter sqlToExecute = new StringWriter(); liquibase.update("", sqlToExecute); return sqlToExecute.toString(); } private int getUpperBound() { final String propVal = System.getProperty(DB_MIGRATE_UP_TO_CHANGESET); if( propVal == null ) { throw new IllegalArgumentException("System property " + DB_MIGRATE_UP_TO_CHANGESET + " is not defined."); } try { return Integer.parseInt(propVal); } catch( final NumberFormatException e ) { throw new IllegalArgumentException( "Failed to parse the value " + propVal + " of system property " + DB_MIGRATE_UP_TO_CHANGESET + ".", e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy