Skip to content

Commit

Permalink
Merge pull request #1776 from liquibase/LB-1222
Browse files Browse the repository at this point in the history
Refactor LiquibaseConfiguration API
  • Loading branch information
nvoxland committed Apr 22, 2021
2 parents 36b5ed6 + f36374c commit 256675b
Show file tree
Hide file tree
Showing 152 changed files with 2,911 additions and 1,639 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
import liquibase.LabelExpression;
import liquibase.Liquibase;
import liquibase.Scope;
import liquibase.configuration.GlobalConfiguration;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
import liquibase.database.DatabaseFactory;
import liquibase.database.jvm.JdbcConnection;
Expand Down Expand Up @@ -107,12 +106,10 @@ public void onStartup() {
return;
}

LiquibaseConfiguration liquibaseConfiguration = LiquibaseConfiguration.getInstance();
if (!liquibaseConfiguration.getConfiguration(GlobalConfiguration.class).getShouldRun()) {
if (!GlobalConfiguration.SHOULD_RUN.getCurrentValue()) {
log.info(String.format("Liquibase did not run on %s because %s was set to false.",
hostName,
liquibaseConfiguration.describeValueLookupLogic(
GlobalConfiguration.class, GlobalConfiguration.SHOULD_RUN)
GlobalConfiguration.SHOULD_RUN.getKey()
));
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public class CDILiquibaseTest {
public void clearProperty() {
System.clearProperty("liquibase.shouldRun");
System.clearProperty("liquibase.config.shouldRun");
LiquibaseConfiguration.getInstance().reset();
}

private void validateRunningState(boolean shouldBeRunning) {
Expand Down
20 changes: 20 additions & 0 deletions liquibase-cli/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-base-module</artifactId>
<version>${liquibase.version}</version>
<relativePath>../base-module.pom.xml</relativePath>
</parent>

<description>Liquibase CLI interface</description>

<artifactId>liquibase-cli</artifactId>

<dependencies>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package liquibase.integration.commandline;

import liquibase.Scope;
import liquibase.configuration.ConfigurationDefinition;
import liquibase.configuration.LiquibaseConfiguration;

import java.util.SortedSet;

public class NewMain {
public static void main(String[] args) {
System.out.println("New CLI!");

final SortedSet<ConfigurationDefinition> definitions = Scope.getCurrentScope().getSingleton(LiquibaseConfiguration.class).getRegisteredDefinitions();
for (ConfigurationDefinition def : definitions) {
System.out.println("See " + def.getKey() + " = " + def.getCurrentValue() + " -- " + def.getDescription());
}
}
}
145 changes: 145 additions & 0 deletions liquibase-core/src/main/java/liquibase/GlobalConfiguration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package liquibase;

import liquibase.configuration.ConfigurationDefinition;
import liquibase.configuration.AutoloadedConfigurations;

/**
* Configuration container for global properties.
*/
public class GlobalConfiguration implements AutoloadedConfigurations {

public static final ConfigurationDefinition<Boolean> SHOULD_RUN;
public static final ConfigurationDefinition<String> DATABASECHANGELOG_TABLE_NAME;
public static final ConfigurationDefinition<String> DATABASECHANGELOGLOCK_TABLE_NAME;
public static final ConfigurationDefinition<String> LIQUIBASE_TABLESPACE_NAME;
public static final ConfigurationDefinition<String> LIQUIBASE_CATALOG_NAME;
public static final ConfigurationDefinition<String> LIQUIBASE_SCHEMA_NAME;
public static final ConfigurationDefinition<String> OUTPUT_LINE_SEPARATOR;
public static final ConfigurationDefinition<String> OUTPUT_ENCODING;
public static final ConfigurationDefinition<Long> CHANGELOGLOCK_WAIT_TIME;
public static final ConfigurationDefinition<Long> CHANGELOGLOCK_POLL_RATE;
public static final ConfigurationDefinition<Boolean> CONVERT_DATA_TYPES;
public static final ConfigurationDefinition<Boolean> GENERATE_CHANGESET_CREATED_VALUES;
public static final ConfigurationDefinition<Boolean> AUTO_REORG;
public static final ConfigurationDefinition<Boolean> DIFF_COLUMN_ORDER;
public static final ConfigurationDefinition<Boolean> ALWAYS_OVERRIDE_STORED_LOGIC_SCHEMA;
public static final ConfigurationDefinition<Boolean> GENERATED_CHANGESET_IDS_INCLUDE_DESCRIPTION;
public static final ConfigurationDefinition<Boolean> INCLUDE_CATALOG_IN_SPECIFICATION;
public static final ConfigurationDefinition<Boolean> SHOULD_SNAPSHOT_DATA;
public static final ConfigurationDefinition<Boolean> FILTER_LOG_MESSAGES;
public static final ConfigurationDefinition<Boolean> HEADLESS;

static {
ConfigurationDefinition.Builder builder = new ConfigurationDefinition.Builder("liquibase");

SHOULD_RUN = builder.define("shouldRun", Boolean.class)
.setDescription("Should Liquibase commands execute")
.setDefaultValue(true)
.addAliasKey("should.run")
.build();

DATABASECHANGELOG_TABLE_NAME = builder.define("databaseChangelogTableName", String.class)
.addAliasKey("liquibase.databaseChangeLogTableName")
.setDescription("Name of table to use for tracking change history")
.setDefaultValue("DATABASECHANGELOG")
.build();

DATABASECHANGELOGLOCK_TABLE_NAME = builder.define("databaseChangelogLockTableName", String.class)
.addAliasKey("liquibase.databaseChangeLogLockTableName")
.setDescription("Name of table to use for tracking concurrent Liquibase usage")
.setDefaultValue("DATABASECHANGELOGLOCK")
.build();

CHANGELOGLOCK_WAIT_TIME = builder.define("changelogLockWaitTimeInMinutes", Long.class)
.addAliasKey("liquibase.changeLogLockWaitTimeInMinutes")
.setDescription("Number of minutes to wait for the changelog lock to be available before giving up")
.setDefaultValue(5L)
.build();

CHANGELOGLOCK_POLL_RATE = builder.define("changelogLockPollRate", Long.class)
.addAliasKey("liquibase.changeLogLockPollRate")
.setDescription("Number of seconds wait between checks to the changelog lock when it is locked")
.setDefaultValue(10L)
.build();

LIQUIBASE_TABLESPACE_NAME = builder.define("tablespaceName", String.class)
.setDescription("Tablespace to use for Liquibase objects")
.build();

LIQUIBASE_CATALOG_NAME = builder.define("catalogName", String.class)
.setDescription("Catalog to use for Liquibase objects")
.build();

LIQUIBASE_SCHEMA_NAME = builder.define("schemaName", String.class)
.setDescription("Schema to use for Liquibase objects")
.build();

OUTPUT_LINE_SEPARATOR = builder.define("outputLineSeparator", String.class)
.setDescription("Line separator for output. Defaults to OS default")
.setDefaultValue(System.getProperty("line.separator"))
.build();

OUTPUT_ENCODING = builder.define("outputFileEncoding", String.class)
.setDescription("Encoding to output text in. Defaults to file.encoding system property or UTF-8")
.setDefaultValue("UTF-8")
.addAliasKey("file.encoding")
.setCommonlyUsed(true)
.build();

CONVERT_DATA_TYPES = builder.define("convertDataTypes", Boolean.class)
.setDescription("Should Liquibase convert to/from STANDARD data types. Applies to both snapshot and " +
"update commands.")
.setDefaultValue(true)
.build();

GENERATE_CHANGESET_CREATED_VALUES = builder.define("generateChangesetCreatedValues", Boolean.class)
.addAliasKey("liquibase.generateChangeSetCreatedValues")
.setDescription("Should Liquibase include a 'created' attribute in diff/generateChangelog changesets with" +
" the current datetime")
.setDefaultValue(false)
.build();

AUTO_REORG = builder.define("autoReorg", Boolean.class)
.setDescription("Should Liquibase automatically include REORG TABLE commands when needed?")
.setDefaultValue(true)
.build();

DIFF_COLUMN_ORDER = builder.define("diffColumnOrder", Boolean.class)
.setDescription("Should Liquibase compare column order in diff operation?")
.setDefaultValue(true)
.build();

ALWAYS_OVERRIDE_STORED_LOGIC_SCHEMA = builder.define("alwaysOverrideStoredLogicSchema", Boolean.class)
.setDescription("When generating SQL for createProcedure, should the procedure schema be forced to the default schema if no schemaName attribute is set?")
.setDefaultValue(false)
.build();


GENERATED_CHANGESET_IDS_INCLUDE_DESCRIPTION = builder.define("generatedChangesetIdsContainsDescription", Boolean.class)
.addAliasKey("liquibase.generatedChangeSetIdsContainsDescription")
.setDescription("Should Liquibase include the change description in the id when generating changesets?")
.setDefaultValue(false)
.build();

INCLUDE_CATALOG_IN_SPECIFICATION = builder.define("includeCatalogInSpecification", Boolean.class)
.setDescription("Should Liquibase include the catalog name when determining equality?")
.setDefaultValue(false)
.build();

SHOULD_SNAPSHOT_DATA = builder.define("shouldSnapshotData", Boolean.class)
.setDescription("Should Liquibase snapshot data by default?")
.setDefaultValue(false)
.build();

FILTER_LOG_MESSAGES = builder.define("filterLogMessages", Boolean.class)
.setDescription("Should Liquibase filter log messages for potentially insecure data?")
.setDefaultValue(true)
.build();

HEADLESS = builder.define("headless", Boolean.class)
.setDescription("Force liquibase think it has no access to a keyboard?")
.setDefaultValue(false)
.setCommonlyUsed(true)
.build();
}
}
18 changes: 7 additions & 11 deletions liquibase-core/src/main/java/liquibase/Liquibase.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import liquibase.command.CommandExecutionException;
import liquibase.command.CommandFactory;
import liquibase.command.core.DropAllCommand;
import liquibase.configuration.HubConfiguration;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
Expand All @@ -26,10 +25,7 @@
import liquibase.executor.Executor;
import liquibase.executor.ExecutorService;
import liquibase.executor.LoggingExecutor;
import liquibase.hub.HubService;
import liquibase.hub.HubServiceFactory;
import liquibase.hub.HubUpdater;
import liquibase.hub.LiquibaseHubException;
import liquibase.hub.*;
import liquibase.hub.listener.HubChangeExecListener;
import liquibase.hub.model.Connection;
import liquibase.hub.model.HubChangeLog;
Expand Down Expand Up @@ -311,13 +307,12 @@ public Connection getConnection(DatabaseChangeLog changeLog) throws LiquibaseHub
if (executor instanceof LoggingExecutor) {
return null;
}
HubConfiguration hubConfiguration = LiquibaseConfiguration.getInstance().getConfiguration(HubConfiguration.class);
String changeLogId = changeLog.getChangeLogId();
HubUpdater hubUpdater = new HubUpdater(new Date(), changeLog, database);
if (hubUpdater.hubIsNotAvailable(changeLogId)) {
if (StringUtil.isNotEmpty(hubConfiguration.getLiquibaseHubApiKey()) && changeLogId == null) {
if (StringUtil.isNotEmpty(HubConfiguration.LIQUIBASE_HUB_API_KEY.getCurrentValue()) && changeLogId == null) {
String message =
"The API key '" + hubConfiguration.getLiquibaseHubApiKey() + "' was found, but no changelog ID exists.\n" +
"The API key '" + HubConfiguration.LIQUIBASE_HUB_API_KEY.getCurrentValue() + "' was found, but no changelog ID exists.\n" +
"No operations will be reported. Register this changelog with Liquibase Hub to generate free deployment reports.\n" +
"Learn more at https://hub.liquibase.com.";
Scope.getCurrentScope().getUI().sendMessage("WARNING: " + message);
Expand All @@ -329,7 +324,7 @@ public Connection getConnection(DatabaseChangeLog changeLog) throws LiquibaseHub
//
// Warn about the situation where there is a changeLog ID, but no API key
//
if (StringUtil.isEmpty(hubConfiguration.getLiquibaseHubApiKey()) && changeLogId != null) {
if (StringUtil.isEmpty(HubConfiguration.LIQUIBASE_HUB_API_KEY.getCurrentValue()) && changeLogId != null) {
String message = "The changelog ID '" + changeLogId + "' was found, but no API Key exists.\n" +
"No operations will be reported. Simply add a liquibase.hub.apiKey setting to generate free deployment reports.\n" +
"Learn more at https://hub.liquibase.com.";
Expand Down Expand Up @@ -1783,15 +1778,16 @@ public final void dropAll(CatalogAndSchema... schemas) throws DatabaseException
runInScope(new Scope.ScopedRunner() {
@Override
public void run() throws Exception {
final CommandFactory commandFactory = Scope.getCurrentScope().getSingleton(CommandFactory.class);

DropAllCommand dropAll = (DropAllCommand) CommandFactory.getInstance().getCommand("dropAll");
DropAllCommand dropAll = (DropAllCommand) commandFactory.getCommand("dropAll");
dropAll.setDatabase(Liquibase.this.getDatabase());
dropAll.setSchemas(finalSchemas);
dropAll.setLiquibase(Liquibase.this);
dropAll.setChangeLogFile(changeLogFile);

try {
dropAll.execute();
commandFactory.execute(dropAll);
} catch (CommandExecutionException e) {
throw new DatabaseException(e);
}
Expand Down
12 changes: 8 additions & 4 deletions liquibase-core/src/main/java/liquibase/Scope.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package liquibase;

import liquibase.configuration.LiquibaseConfiguration;
import liquibase.database.Database;
import liquibase.database.DatabaseConnection;
import liquibase.database.OfflineConnection;
Expand Down Expand Up @@ -66,6 +67,13 @@ public static Scope getCurrentScope() {
Scope rootScope = new Scope();
scopeManager.setCurrentScope(rootScope);

rootScope.values.put(Attr.logService.name(), new JavaLogService());
rootScope.values.put(Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor());
rootScope.values.put(Attr.serviceLocator.name(), new StandardServiceLocator());

rootScope.values.put(Attr.ui.name(), new ConsoleUIService());
rootScope.getSingleton(LiquibaseConfiguration.class).init(rootScope);

LogService overrideLogService = rootScope.getSingleton(LogServiceFactory.class).getDefaultLogService();
if (overrideLogService == null) {
throw new UnexpectedLiquibaseException("Cannot find default log service");
Expand Down Expand Up @@ -109,10 +117,6 @@ public static void setScopeManager(ScopeManager scopeManager) {
* Defaults serviceLocator to {@link StandardServiceLocator}
*/
private Scope() {
values.put(Attr.logService.name(), new JavaLogService());
values.put(Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor());
values.put(Attr.serviceLocator.name(), new StandardServiceLocator());
values.put(Attr.ui.name(), new ConsoleUIService());
}

protected Scope(Scope parent, Map<String, Object> scopeValues) {
Expand Down
1 change: 0 additions & 1 deletion liquibase-core/src/main/java/liquibase/ScopeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

public abstract class ScopeManager {


public abstract Scope getCurrentScope();

protected abstract void setCurrentScope(Scope scope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import liquibase.change.core.RawSQLChange;
import liquibase.Scope;
import liquibase.configuration.GlobalConfiguration;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
import liquibase.database.core.MSSQLDatabase;
import liquibase.database.core.PostgresDatabase;
Expand Down Expand Up @@ -194,11 +193,7 @@ public CheckSum generateCheckSum() {
}

if (sql != null) {
stream = new ByteArrayInputStream(
sql.getBytes(
LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class)
.getOutputEncoding()
)
stream = new ByteArrayInputStream(sql.getBytes(GlobalConfiguration.OUTPUT_ENCODING.getCurrentValue())
);
}

Expand Down Expand Up @@ -295,7 +290,7 @@ public static class NormalizingStream extends InputStream {
public NormalizingStream(String endDelimiter, Boolean splitStatements, Boolean stripComments, InputStream stream) {
this.stream = new PushbackInputStream(stream, 2048);
try {
this.headerStream = new ByteArrayInputStream((endDelimiter+":"+splitStatements+":"+stripComments+":").getBytes(LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class).getOutputEncoding()));
this.headerStream = new ByteArrayInputStream((endDelimiter+":"+splitStatements+":"+stripComments+":").getBytes(GlobalConfiguration.OUTPUT_ENCODING.getCurrentValue()));
} catch (UnsupportedEncodingException e) {
throw new UnexpectedLiquibaseException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
import liquibase.Scope;
import liquibase.change.*;
import liquibase.changelog.ChangeLogParameters;
import liquibase.changelog.ChangeSet;
import liquibase.configuration.GlobalConfiguration;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
import liquibase.database.DatabaseList;
import liquibase.database.core.*;
Expand Down Expand Up @@ -251,8 +249,7 @@ public CheckSum generateCheckSum() {
procedureText = "";
}

String encoding =
LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class).getOutputEncoding();
String encoding = GlobalConfiguration.OUTPUT_ENCODING.getCurrentValue();
if (procedureText != null) {
try {
stream = new ByteArrayInputStream(procedureText.getBytes(encoding));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
import liquibase.Scope;
import liquibase.change.*;
import liquibase.changelog.ChangeLogParameters;
import liquibase.configuration.GlobalConfiguration;
import liquibase.configuration.LiquibaseConfiguration;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
import liquibase.database.core.OracleDatabase;
import liquibase.database.core.SQLiteDatabase;
Expand Down Expand Up @@ -199,7 +198,7 @@ public CheckSum generateCheckSum() {
selectQuery = "";
}

String encoding = LiquibaseConfiguration.getInstance().getConfiguration(GlobalConfiguration.class).getOutputEncoding();
String encoding = GlobalConfiguration.OUTPUT_ENCODING.getCurrentValue();
if (selectQuery != null) {
try {
stream = new ByteArrayInputStream(selectQuery.getBytes(encoding));
Expand Down

0 comments on commit 256675b

Please sign in to comment.