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

com.sap.cloud.mt.subscription.DbDeployerLiquibase Maven / Gradle / Ivy

There is a newer version: 3.3.1
Show newest version
/*******************************************************************************
 *   © 2019-2024 SAP SE or an SAP affiliate company. All rights reserved.
 ******************************************************************************/

package com.sap.cloud.mt.subscription;

import com.sap.cloud.mt.subscription.exceptions.InternalError;
import liquibase.GlobalConfiguration;
import liquibase.Liquibase;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
import liquibase.exception.LiquibaseException;
import liquibase.resource.ClassLoaderResourceAccessor;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DbDeployerLiquibase implements DbDeployer {
	private final LiquibaseResourceAccessor resourceAccessorForTenant;
	private String fileName;
	private String contexts;

	public DbDeployerLiquibase(LiquibaseParameters parameters) {
		this.fileName = parameters.getFileName() != null ? parameters.getFileName() : "";
		this.contexts = parameters.getContexts() != null ? parameters.getContexts() : "";
		this.resourceAccessorForTenant =
				parameters.getResourceAccessor() != null ?
						parameters.getResourceAccessor()
						: (String tenantId) -> new ClassLoaderResourceAccessor();
	}

	@Override
	public void populate(DataSourceInfo dataSourceInfo, String tenantId) throws InternalError {
		try (Connection connection = getConnection(dataSourceInfo);
			 DatabaseConnection liquibaseConnection = new JdbcConnection(connection)) {
			Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(liquibaseConnection);
			// ToDo
			// Temporary workaround for:  https://github.com/liquibase/liquibase/issues/3205
			System.setProperty(GlobalConfiguration.PRESERVE_SCHEMA_CASE.getKey(), "true");
			// liquibase is not thread safe !!!
			//See https://github.com/liquibase/liquibase/issues/4376
			// https://github.com/liquibase/liquibase/pull/4480
			// 4.24.0 release notes (look for “4480” – the PR number of the fix): Liquibase 4.24.0 Release Notes
			//But our unit test DbDeployerLiquibaseTest still reports errors !!
			synchronized (Liquibase.class) {
				try (Liquibase liquibase = new Liquibase(fileName, resourceAccessorForTenant.getAccessor(tenantId), database)) {
					liquibase.update(contexts);
				}
			}
		} catch (LiquibaseException | SQLException sqlException) {
			throw new InternalError(sqlException);
		}
	}

	private Connection getConnection(DataSourceInfo dataSourceInfo) throws InternalError {
		Connection connection = null;
		try {
			connection = DriverManager.getConnection(dataSourceInfo.getUrl(), dataSourceInfo.getUser(), dataSourceInfo.getPassword());//NOSONAR
			connection.setSchema(dataSourceInfo.getSchema());
			if (!connection.getSchema().equals(dataSourceInfo.getSchema())) {
				connection.close();
				throw new InternalError("Could not set schema to " + dataSourceInfo.getSchema());
			}
			return connection;
		} catch (SQLException sqlException) {
			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException sqlException2) {
					//NOSONAR
				}
			}
			throw new InternalError(sqlException);
		}
	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	public String getContexts() {
		return contexts;
	}

	public void setContexts(String contexts) {
		this.contexts = contexts;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy