From 65eb573e92a1b3f0108abf475b6130571c4e2f21 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Wed, 14 Dec 2022 07:50:51 -0500 Subject: [PATCH 01/28] add MDC interfaces and base classes (DAT-12601) (#3567) Create the basic APIs for MDC in support of structured logging. --- liquibase-core/pom.xml | 19 +- .../src/main/java/liquibase/Beta.java | 31 ++ .../src/main/java/liquibase/Scope.java | 51 ++- .../integration/commandline/Main.java | 388 +++++++++--------- .../liquibase/logging/mdc/MdcManager.java | 31 ++ .../logging/mdc/MdcManagerFactory.java | 26 ++ .../java/liquibase/logging/mdc/MdcObject.java | 22 + .../liquibase/logging/mdc/NoOpMdcManager.java | 28 ++ .../test/groovy/liquibase/ScopeTest.groovy | 56 +++ 9 files changed, 457 insertions(+), 195 deletions(-) create mode 100644 liquibase-core/src/main/java/liquibase/Beta.java create mode 100644 liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java create mode 100644 liquibase-core/src/main/java/liquibase/logging/mdc/MdcManagerFactory.java create mode 100644 liquibase-core/src/main/java/liquibase/logging/mdc/MdcObject.java create mode 100644 liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java diff --git a/liquibase-core/pom.xml b/liquibase-core/pom.xml index d999c444f7b..930584c14eb 100644 --- a/liquibase-core/pom.xml +++ b/liquibase-core/pom.xml @@ -283,7 +283,24 @@ - + + + eu.somatik.serviceloader-maven-plugin + serviceloader-maven-plugin + 1.4.0 + + + liquibase.logging.mdc.MdcManager + + + + + + generate + + + + diff --git a/liquibase-core/src/main/java/liquibase/Beta.java b/liquibase-core/src/main/java/liquibase/Beta.java new file mode 100644 index 00000000000..35271fda652 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/Beta.java @@ -0,0 +1,31 @@ +package liquibase; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Signifies that a public API (public class, method or field) is subject to incompatible changes, + * or even removal, in a future release. An API bearing this annotation is exempt from any + * compatibility guarantees made by its containing library. Note that the presence of this + * annotation implies nothing about the quality or performance of the API in question, only the fact + * that it is not "API-frozen." + * + *

It is generally safe for applications to depend on beta APIs, at the cost of some extra + * work during upgrades. However it is generally inadvisable for libraries (which get + * included on users' CLASSPATHs, outside the library developers' control) to do so. + * + * @author Kevin Bourrillion + */ +@Retention(RetentionPolicy.CLASS) +@Target({ + ElementType.ANNOTATION_TYPE, + ElementType.CONSTRUCTOR, + ElementType.FIELD, + ElementType.METHOD, + ElementType.TYPE +}) +@Documented +public @interface Beta {} \ No newline at end of file diff --git a/liquibase-core/src/main/java/liquibase/Scope.java b/liquibase-core/src/main/java/liquibase/Scope.java index da9ae489376..4e8dee47325 100644 --- a/liquibase-core/src/main/java/liquibase/Scope.java +++ b/liquibase-core/src/main/java/liquibase/Scope.java @@ -7,10 +7,12 @@ import liquibase.database.jvm.JdbcConnection; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.listener.LiquibaseListener; -import liquibase.logging.LogService; -import liquibase.logging.Logger; +import liquibase.logging.*; import liquibase.logging.core.JavaLogService; import liquibase.logging.core.LogServiceFactory; +import liquibase.logging.mdc.MdcManager; +import liquibase.logging.mdc.MdcManagerFactory; +import liquibase.logging.mdc.MdcObject; import liquibase.osgi.Activator; import liquibase.resource.ClassLoaderResourceAccessor; import liquibase.resource.ResourceAccessor; @@ -18,6 +20,7 @@ import liquibase.servicelocator.StandardServiceLocator; import liquibase.ui.ConsoleUIService; import liquibase.ui.UIService; +import liquibase.util.CollectionUtil; import liquibase.util.SmartMap; import liquibase.util.StringUtil; @@ -64,6 +67,7 @@ public enum Attr { private Scope parent; private SmartMap values = new SmartMap(); private String scopeId; + private static final Map> addedMdcEntries = new HashMap<>(); private LiquibaseListener listener; @@ -230,6 +234,12 @@ public static void exit(String scopeId) throws Exception { throw new RuntimeException("Cannot end scope " + scopeId + " when currently at scope " + currentScope.scopeId); } + // clear the MDC values added in this scope + List mdcObjects = addedMdcEntries.get(currentScope.scopeId); + for (MdcObject mdcObject : CollectionUtil.createIfNull(mdcObjects)) { + mdcObject.close(); + } + scopeManager.setCurrentScope(currentScope.getParent()); } @@ -377,6 +387,43 @@ public Charset getFileEncoding() { return get(Attr.fileEncoding, Charset.defaultCharset()); } + /** + * Get the current MDC manager. + */ + public MdcManager getMdcManager() { + MdcManagerFactory mdcManagerFactory = getSingleton(MdcManagerFactory.class); + return mdcManagerFactory.getMdcManager(); + } + + /** + * Add a key value pair to the MDC using the MDC manager. This key value pair will be automatically removed from the + * MDC when this scope exits. + */ + public MdcObject addMdcValue(String key, String value) { + return addMdcValue(key, value, true); + } + + /** + * Add a key value pair to the MDC using the MDC manager. + * @param removeWhenScopeExits if true, this key value pair will be automatically removed from the MDC when this + * scope exits. If there is not a demonstrable reason for setting this parameter to false + * then it should be set to true. + */ + public MdcObject addMdcValue(String key, String value, boolean removeWhenScopeExits) { + MdcObject mdcObject = getMdcManager().put(key, value); + if (removeWhenScopeExits) { + Scope currentScope = getCurrentScope(); + String scopeId = currentScope.scopeId; + if (addedMdcEntries.containsKey(scopeId)) { + addedMdcEntries.get(scopeId).add(mdcObject); + } else { + addedMdcEntries.put(scopeId, new ArrayList<>(Collections.singletonList(mdcObject))); + } + } + + return mdcObject; + } + /** * Returns {@link LiquibaseListener}s defined in this scope and/or all its parents that are of the given type. */ diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index efb4bdc5559..8b43725f19c 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -214,246 +214,250 @@ public static int run(String[] args) throws Exception { scopeObjects.put(Scope.Attr.ui.name(), ui); } - return Scope.child(scopeObjects, new Scope.ScopedRunnerWithReturn() { - @Override - public Integer run() throws Exception { - Main main = new Main(); - - try { - if ((args.length == 0) || ((args.length == 1) && ("--" + OPTIONS.HELP).equals(args[0]))) { - main.printHelp(outputStream); - return Integer.valueOf(0); - } else if (("--" + OPTIONS.VERSION).equals(args[0])) { - main.command = ""; - main.parseDefaultPropertyFiles(); - Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner()); - Scope.getCurrentScope().getUI().sendMessage(String.format(coreBundle.getString("version.number"), LiquibaseUtil.getBuildVersionInfo())); + try { + return Scope.child(scopeObjects, new Scope.ScopedRunnerWithReturn() { + @Override + public Integer run() throws Exception { + Main main = new Main(); - LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService(); - if (licenseService != null && main.liquibaseProLicenseKey != null) { - Location licenseKeyLocation = - new Location("property liquibaseProLicenseKey", main.liquibaseProLicenseKey); - LicenseInstallResult result = licenseService.installLicense(licenseKeyLocation); - if (result.code != 0) { - String allMessages = String.join("\n", result.messages); - Scope.getCurrentScope().getUI().sendErrorMessage(allMessages); + try { + if ((args.length == 0) || ((args.length == 1) && ("--" + OPTIONS.HELP).equals(args[0]))) { + main.printHelp(outputStream); + return Integer.valueOf(0); + } else if (("--" + OPTIONS.VERSION).equals(args[0])) { + main.command = ""; + main.parseDefaultPropertyFiles(); + Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner()); + Scope.getCurrentScope().getUI().sendMessage(String.format(coreBundle.getString("version.number"), LiquibaseUtil.getBuildVersionInfo())); + + LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService(); + if (licenseService != null && main.liquibaseProLicenseKey != null) { + Location licenseKeyLocation = + new Location("property liquibaseProLicenseKey", main.liquibaseProLicenseKey); + LicenseInstallResult result = licenseService.installLicense(licenseKeyLocation); + if (result.code != 0) { + String allMessages = String.join("\n", result.messages); + Scope.getCurrentScope().getUI().sendErrorMessage(allMessages); + } + } + if (licenseService != null) { + Scope.getCurrentScope().getUI().sendMessage(licenseService.getLicenseInfo()); } - } - if (licenseService != null) { - Scope.getCurrentScope().getUI().sendMessage(licenseService.getLicenseInfo()); - } - Scope.getCurrentScope().getUI().sendMessage(String.format("Running Java under %s (Version %s)", - System.getProperties().getProperty("java.home"), - SystemUtil.getJavaVersion() - )); - return Integer.valueOf(0); - } + Scope.getCurrentScope().getUI().sendMessage(String.format("Running Java under %s (Version %s)", + System.getProperties().getProperty("java.home"), + SystemUtil.getJavaVersion() + )); + return Integer.valueOf(0); + } - // - // Look for characters which cannot be handled - // - for (int i = 0; i < args.length; i++) { - CodePointCheck codePointCheck = checkArg(args[i]); - if (codePointCheck != null) { - String message = - "A non-standard character '" + codePointCheck.ch + - "' was detected on the command line at position " + - (codePointCheck.position + 1) + " of argument number " + (i + 1) + - ".\nIf problems occur, please remove the character and try again."; - LOG.warning(message); - System.err.println(message); + // + // Look for characters which cannot be handled + // + for (int i = 0; i < args.length; i++) { + CodePointCheck codePointCheck = checkArg(args[i]); + if (codePointCheck != null) { + String message = + "A non-standard character '" + codePointCheck.ch + + "' was detected on the command line at position " + + (codePointCheck.position + 1) + " of argument number " + (i + 1) + + ".\nIf problems occur, please remove the character and try again."; + LOG.warning(message); + System.err.println(message); + } } - } - try { - main.parseOptions(args); - if (main.command == null) { - main.printHelp(outputStream); - return Integer.valueOf(0); + try { + main.parseOptions(args); + if (main.command == null) { + main.printHelp(outputStream); + return Integer.valueOf(0); + } + } catch (CommandLineParsingException e) { + Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner()); + Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("how.to.display.help")); + throw e; } - } catch (CommandLineParsingException e) { - Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner()); - Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("how.to.display.help")); - throw e; - } - if (!Main.runningFromNewCli) { - final ConsoleUIService ui = (ConsoleUIService) Scope.getCurrentScope().getUI(); - System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT] %4$s [%2$s] %5$s%6$s%n"); + if (!Main.runningFromNewCli) { + final ConsoleUIService ui = (ConsoleUIService) Scope.getCurrentScope().getUI(); + System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT] %4$s [%2$s] %5$s%6$s%n"); - java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger(""); - java.util.logging.Logger liquibaseLogger = java.util.logging.Logger.getLogger("liquibase"); - liquibaseLogger.setParent(rootLogger); + java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger(""); + java.util.logging.Logger liquibaseLogger = java.util.logging.Logger.getLogger("liquibase"); + liquibaseLogger.setParent(rootLogger); - LogService logService = Scope.getCurrentScope().get(Scope.Attr.logService, LogService.class); - if (logService instanceof JavaLogService) { - ((JavaLogService) logService).setParent(liquibaseLogger); - } + LogService logService = Scope.getCurrentScope().get(Scope.Attr.logService, LogService.class); + if (logService instanceof JavaLogService) { + ((JavaLogService) logService).setParent(liquibaseLogger); + } - if (main.logLevel == null) { - String defaultLogLevel = System.getProperty("liquibase.log.level"); - if (defaultLogLevel == null) { - setLogLevel(logService, rootLogger, liquibaseLogger, Level.OFF); + if (main.logLevel == null) { + String defaultLogLevel = System.getProperty("liquibase.log.level"); + if (defaultLogLevel == null) { + setLogLevel(logService, rootLogger, liquibaseLogger, Level.OFF); + } else { + setLogLevel(logService, rootLogger, liquibaseLogger, parseLogLevel(defaultLogLevel, ui)); + } } else { - setLogLevel(logService, rootLogger, liquibaseLogger, parseLogLevel(defaultLogLevel, ui)); + setLogLevel(logService, rootLogger, liquibaseLogger, parseLogLevel(main.logLevel, ui)); } - } else { - setLogLevel(logService, rootLogger, liquibaseLogger, parseLogLevel(main.logLevel, ui)); - } - if (main.logFile != null) { - FileHandler fileHandler = new FileHandler(main.logFile, true); - fileHandler.setFormatter(new SimpleFormatter()); - if (liquibaseLogger.getLevel() == Level.OFF) { - fileHandler.setLevel(Level.FINE); - } + if (main.logFile != null) { + FileHandler fileHandler = new FileHandler(main.logFile, true); + fileHandler.setFormatter(new SimpleFormatter()); + if (liquibaseLogger.getLevel() == Level.OFF) { + fileHandler.setLevel(Level.FINE); + } - rootLogger.addHandler(fileHandler); - for (Handler handler : rootLogger.getHandlers()) { - if (handler instanceof ConsoleHandler) { - handler.setLevel(Level.OFF); + rootLogger.addHandler(fileHandler); + for (Handler handler : rootLogger.getHandlers()) { + if (handler instanceof ConsoleHandler) { + handler.setLevel(Level.OFF); + } } } - } - if (main.command != null && main.command.toLowerCase().endsWith("sql")) { - ui.setOutputStream(System.err); + if (main.command != null && main.command.toLowerCase().endsWith("sql")) { + ui.setOutputStream(System.err); + } } - } - LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService(); - if (licenseService != null) { - if (main.liquibaseProLicenseKey == null) { - if (!Main.runningFromNewCli) { - Scope.getCurrentScope().getLog(getClass()).info("No Liquibase Pro license key supplied. Please set liquibaseProLicenseKey on command line or in liquibase.properties to use Liquibase Pro features."); - } - } else { - Location licenseKeyLocation = new Location("property liquibaseProLicenseKey", main.liquibaseProLicenseKey); - LicenseInstallResult result = licenseService.installLicense(licenseKeyLocation); - if (result.code != 0) { - String allMessages = String.join("\n", result.messages); + LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService(); + if (licenseService != null) { + if (main.liquibaseProLicenseKey == null) { if (!Main.runningFromNewCli) { - Scope.getCurrentScope().getUI().sendMessage(allMessages); + Scope.getCurrentScope().getLog(getClass()).info("No Liquibase Pro license key supplied. Please set liquibaseProLicenseKey on command line or in liquibase.properties to use Liquibase Pro features."); } } else { - main.liquibaseProLicenseValid = true; + Location licenseKeyLocation = new Location("property liquibaseProLicenseKey", main.liquibaseProLicenseKey); + LicenseInstallResult result = licenseService.installLicense(licenseKeyLocation); + if (result.code != 0) { + String allMessages = String.join("\n", result.messages); + if (!Main.runningFromNewCli) { + Scope.getCurrentScope().getUI().sendMessage(allMessages); + } + } else { + main.liquibaseProLicenseValid = true; + } } - } - // - // Check to see if we have an expired license - // - if (licenseService.daysTilExpiration() < 0) { - main.liquibaseProLicenseValid = false; + // + // Check to see if we have an expired license + // + if (licenseService.daysTilExpiration() < 0) { + main.liquibaseProLicenseValid = false; + } + if (!Main.runningFromNewCli) { + Scope.getCurrentScope().getUI().sendMessage(licenseService.getLicenseInfo()); + } } + if (!Main.runningFromNewCli) { - Scope.getCurrentScope().getUI().sendMessage(licenseService.getLicenseInfo()); + Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner()); } - } - - if (!Main.runningFromNewCli) { - Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner()); - } - - if (!LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentValue()) { - Scope.getCurrentScope().getUI().sendErrorMessage(( - String.format(coreBundle.getString("did.not.run.because.param.was.set.to.false"), - LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentConfiguredValue().getProvidedValue().getActualKey()))); - return Integer.valueOf(0); - } - if (setupNeeded(main)) { - List setupMessages = main.checkSetup(); - if (!setupMessages.isEmpty()) { - main.printHelp(setupMessages, isStandardOutputRequired(main.command) ? System.err : outputStream); - return Integer.valueOf(1); + if (!LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentValue()) { + Scope.getCurrentScope().getUI().sendErrorMessage(( + String.format(coreBundle.getString("did.not.run.because.param.was.set.to.false"), + LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentConfiguredValue().getProvidedValue().getActualKey()))); + return Integer.valueOf(0); } - } - // - // Store the Hub API key for later use - // - if (StringUtil.isNotEmpty(main.liquibaseHubApiKey)) { - DeprecatedConfigurationValueProvider.setData(HubConfiguration.LIQUIBASE_HUB_API_KEY, main.liquibaseHubApiKey); - } + if (setupNeeded(main)) { + List setupMessages = main.checkSetup(); + if (!setupMessages.isEmpty()) { + main.printHelp(setupMessages, isStandardOutputRequired(main.command) ? System.err : outputStream); + return Integer.valueOf(1); + } + } - // - // Store the Hub URL for later use - // - if (StringUtil.isNotEmpty(main.liquibaseHubUrl)) { - DeprecatedConfigurationValueProvider.setData(HubConfiguration.LIQUIBASE_HUB_URL, main.liquibaseHubUrl); - } + // + // Store the Hub API key for later use + // + if (StringUtil.isNotEmpty(main.liquibaseHubApiKey)) { + DeprecatedConfigurationValueProvider.setData(HubConfiguration.LIQUIBASE_HUB_API_KEY, main.liquibaseHubApiKey); + } - main.applyDefaults(); - Map innerScopeObjects = new HashMap<>(); - innerScopeObjects.put("defaultsFile", LiquibaseCommandLineConfiguration.DEFAULTS_FILE.getCurrentValue()); - if (!Main.runningFromNewCli) { - innerScopeObjects.put(Scope.Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor(main.configureClassLoader())); - } - Scope.child(innerScopeObjects, () -> { - main.doMigration(); + // + // Store the Hub URL for later use + // + if (StringUtil.isNotEmpty(main.liquibaseHubUrl)) { + DeprecatedConfigurationValueProvider.setData(HubConfiguration.LIQUIBASE_HUB_URL, main.liquibaseHubUrl); + } + main.applyDefaults(); + Map innerScopeObjects = new HashMap<>(); + innerScopeObjects.put("defaultsFile", LiquibaseCommandLineConfiguration.DEFAULTS_FILE.getCurrentValue()); if (!Main.runningFromNewCli) { - if (COMMANDS.UPDATE.equals(main.command)) { - Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("update.successful")); - } else if (main.command.startsWith(COMMANDS.ROLLBACK)) { - Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("rollback.successful")); - } else { - Scope.getCurrentScope().getUI().sendMessage(String.format(coreBundle.getString("command.successful"), main.command)); - } + innerScopeObjects.put(Scope.Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor(main.configureClassLoader())); } - }); - } catch (Throwable e) { - String message = e.getMessage(); - if (e.getCause() != null) { - message = e.getCause().getMessage(); - } - if (message == null) { - message = coreBundle.getString("unknown.reason"); - } - // At a minimum, log the message. We don't need to print the stack - // trace because the logger already did that upstream. - try { - if (e.getCause() instanceof ValidationFailedException) { - ((ValidationFailedException) e.getCause()).printDescriptiveError(outputStream); - } else { + Scope.child(innerScopeObjects, () -> { + main.doMigration(); + if (!Main.runningFromNewCli) { - if (main.outputsLogMessages) { - Scope.getCurrentScope().getUI().sendErrorMessage((String.format(coreBundle.getString("unexpected.error"), message)), e); + if (COMMANDS.UPDATE.equals(main.command)) { + Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("update.successful")); + } else if (main.command.startsWith(COMMANDS.ROLLBACK)) { + Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("rollback.successful")); } else { - Scope.getCurrentScope().getUI().sendMessage((String.format(coreBundle.getString("unexpected.error"), message))); - Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("for.more.information.use.loglevel.flag")); - - //send it to the LOG in case we're using logFile - Scope.getCurrentScope().getLog(getClass()).severe((String.format(coreBundle.getString("unexpected.error"), message)), e); + Scope.getCurrentScope().getUI().sendMessage(String.format(coreBundle.getString("command.successful"), main.command)); } } + }); + } catch (Throwable e) { + String message = e.getMessage(); + if (e.getCause() != null) { + message = e.getCause().getMessage(); } - } catch (IllegalFormatException e1) { - if (Main.runningFromNewCli) { - throw e1; + if (message == null) { + message = coreBundle.getString("unknown.reason"); } + // At a minimum, log the message. We don't need to print the stack + // trace because the logger already did that upstream. + try { + if (e.getCause() instanceof ValidationFailedException) { + ((ValidationFailedException) e.getCause()).printDescriptiveError(outputStream); + } else { + if (!Main.runningFromNewCli) { + if (main.outputsLogMessages) { + Scope.getCurrentScope().getUI().sendErrorMessage((String.format(coreBundle.getString("unexpected.error"), message)), e); + } else { + Scope.getCurrentScope().getUI().sendMessage((String.format(coreBundle.getString("unexpected.error"), message))); + Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("for.more.information.use.loglevel.flag")); + + //send it to the LOG in case we're using logFile + Scope.getCurrentScope().getLog(getClass()).severe((String.format(coreBundle.getString("unexpected.error"), message)), e); + } + } + } + } catch (IllegalFormatException e1) { + if (Main.runningFromNewCli) { + throw e1; + } - e1.printStackTrace(); + e1.printStackTrace(); + } + if (runningFromNewCli) { + throw e; + } else { + throw new LiquibaseException(String.format(coreBundle.getString("unexpected.error"), message), e); + } } - if (runningFromNewCli) { - throw e; - } else { - throw new LiquibaseException(String.format(coreBundle.getString("unexpected.error"), message), e); + + if (isHubEnabled(main.command) && + HubConfiguration.LIQUIBASE_HUB_API_KEY.getCurrentValue() != null && + !Scope.getCurrentScope().getSingleton(HubServiceFactory.class).isOnline()) { + Scope.getCurrentScope().getUI().sendMessage("WARNING: The command " + main.command + " operations were not synced with your Liquibase Hub account because: " + StringUtil.lowerCaseFirst(Scope.getCurrentScope().getSingleton(HubServiceFactory.class).getOfflineReason())); } - } - if (isHubEnabled(main.command) && - HubConfiguration.LIQUIBASE_HUB_API_KEY.getCurrentValue() != null && - !Scope.getCurrentScope().getSingleton(HubServiceFactory.class).isOnline()) { - Scope.getCurrentScope().getUI().sendMessage("WARNING: The command " + main.command + " operations were not synced with your Liquibase Hub account because: " + StringUtil.lowerCaseFirst(Scope.getCurrentScope().getSingleton(HubServiceFactory.class).getOfflineReason())); + return Integer.valueOf(0); } - - return Integer.valueOf(0); - } - }); + }); + } finally { + Scope.getCurrentScope().getMdcManager().clear(); + } } private static boolean setupNeeded(Main main) throws CommandLineParsingException { diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java new file mode 100644 index 00000000000..d579f768914 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java @@ -0,0 +1,31 @@ +package liquibase.logging.mdc; + +import liquibase.Beta; +import liquibase.plugin.Plugin; + +@Beta +public interface MdcManager extends Plugin { + + /** + * Puts a context value (the value parameter) as identified with the key parameter into + * the MDC. The caller is responsible for cleaning up this entry at an appropriate time. + * do so. + */ + @Beta + MdcObject put(String key, String value); + + /** + * Removes the context value identified by the key parameter. + */ + @Beta + void remove(String key); + + /** + * Clear the MDC. + */ + @Beta + void clear(); + + @Beta + int getPriority(); +} diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManagerFactory.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManagerFactory.java new file mode 100644 index 00000000000..9be414ff520 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManagerFactory.java @@ -0,0 +1,26 @@ +package liquibase.logging.mdc; + +import liquibase.plugin.AbstractPluginFactory; + +public class MdcManagerFactory extends AbstractPluginFactory { + private MdcManagerFactory() { + } + + @Override + protected Class getPluginClass() { + return MdcManager.class; + } + + @Override + protected int getPriority(MdcManager obj, Object... args) { + return obj.getPriority(); + } + + public MdcManager getMdcManager() { + return getPlugin(); + } + + public void unregister(MdcManager manager) { + this.removeInstance(manager); + } +} diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcObject.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcObject.java new file mode 100644 index 00000000000..13e2268410a --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcObject.java @@ -0,0 +1,22 @@ +package liquibase.logging.mdc; + +import liquibase.Scope; + +import java.io.Closeable; +import java.io.IOException; + +public class MdcObject implements Closeable { + + private final String key; + private final String value; + + public MdcObject(String key, String value) { + this.key = key; + this.value = value; + } + + @Override + public void close() throws IOException { + Scope.getCurrentScope().getMdcManager().remove(key); + } +} diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java b/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java new file mode 100644 index 00000000000..e821bc705a0 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java @@ -0,0 +1,28 @@ +package liquibase.logging.mdc; + +import liquibase.plugin.Plugin; + +/** + * Default MDC manager, which does nothing. + */ +public class NoOpMdcManager implements MdcManager { + @Override + public MdcObject put(String key, String value) { + return new MdcObject(key, value); + } + + @Override + public void remove(String key) { + + } + + @Override + public void clear() { + + } + + @Override + public int getPriority() { + return Plugin.PRIORITY_DEFAULT; + } +} diff --git a/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy b/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy index e7b974ca4b3..19b40399d29 100644 --- a/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy +++ b/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy @@ -1,8 +1,13 @@ package liquibase import liquibase.exception.UnexpectedLiquibaseException +import liquibase.logging.mdc.MdcManager +import liquibase.logging.mdc.MdcManagerFactory +import liquibase.logging.mdc.MdcObject import spock.lang.Specification +import java.util.concurrent.ConcurrentHashMap + class ScopeTest extends Specification { def "getCurrentScope() creates root scope"() { @@ -49,6 +54,12 @@ class ScopeTest extends Specification { } def "start and end works"() { + def mdcFactory = Scope.currentScope.getSingleton(MdcManagerFactory) + def existingManager = mdcFactory.getMdcManager() + def testManager = new TestMdcManager() + mdcFactory.unregister(existingManager) + mdcFactory.register(testManager) + expect: Scope.currentScope.describe() == "scope(database=null)" @@ -60,21 +71,36 @@ class ScopeTest extends Specification { assert Scope.currentScope.get("test1", String) == "Level 1 A" assert Scope.currentScope.get("test2", String) == "Level 1 B" assert Scope.currentScope.get("test3", String) == null + Scope.currentScope.addMdcValue("scope1", "scope1value") + assert testManager.getValues().containsKey("scope1") def scope2 = Scope.enter(null, ["test1": "Level 2 A", "test3": "Level 2 C"]) assert Scope.currentScope.get("test1", String) == "Level 2 A" assert Scope.currentScope.get("test2", String) == "Level 1 B" assert Scope.currentScope.get("test3", String) == "Level 2 C" + Scope.currentScope.addMdcValue("cleanup1", "value1") + Scope.currentScope.addMdcValue("nocleanup1", "value2", false) + assert testManager.getValues().containsKey("cleanup1") + assert testManager.getValues().containsKey("nocleanup1") + assert testManager.getValues().containsKey("scope1") Scope.exit(scope2) assert Scope.currentScope.get("test1", String) == "Level 1 A" assert Scope.currentScope.get("test2", String) == "Level 1 B" assert Scope.currentScope.get("test3", String) == null + assert !testManager.getValues().containsKey("cleanup1") + assert testManager.getValues().containsKey("nocleanup1") + assert testManager.getValues().containsKey("scope1") Scope.exit(scope1) assert Scope.currentScope.get("test1", String) == null assert Scope.currentScope.get("test2", String) == null assert Scope.currentScope.get("test3", String) == null + assert !testManager.getValues().containsKey("scope1") + + cleanup: + mdcFactory.unregister(testManager) + mdcFactory.register(existingManager) } def "cannot end the wrong scope id"() { @@ -97,4 +123,34 @@ class ScopeTest extends Specification { def e = thrown(UnexpectedLiquibaseException) e.message == "Cannot pass a null parent to a new Scope. Use Scope.child to correctly create a nested scope" } + + private class TestMdcManager implements MdcManager { + + private Map values = new ConcurrentHashMap<>() + + @Override + MdcObject put(String key, String value) { + values.put(key, value) + return new MdcObject(key, value) + } + + @Override + void remove(String key) { + values.remove(key) + } + + @Override + void clear() { + values.clear() + } + + @Override + int getPriority() { + return Integer.MAX_VALUE + } + + Map getValues() { + return values + } + } } From 053e02d2f9bb66b58e423dd221e8957cfa82df3b Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Mon, 19 Dec 2022 07:49:11 -0600 Subject: [PATCH 02/28] set log format in log service --- .../integration/commandline/LiquibaseCommandLine.java | 3 +-- .../src/main/java/liquibase/logging/core/JavaLogService.java | 4 ++++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java index 9a6f963dae0..2903725d86f 100644 --- a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java +++ b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java @@ -636,10 +636,9 @@ private void configureLogging(Level logLevel, String logFile) throws IOException java.util.logging.Logger liquibaseLogger = java.util.logging.Logger.getLogger("liquibase"); if (logService instanceof JavaLogService) { ((JavaLogService) logService).setParent(liquibaseLogger); + ((JavaLogService) logService).setupFormat(); } - System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT] %4$s [%2$s] %5$s%6$s%n"); - java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger(""); Level cliLogLevel = logLevel; diff --git a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java index a0b7065ba31..02910b7ffe5 100644 --- a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java +++ b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java @@ -34,6 +34,10 @@ public Logger getLog(Class clazz) { return logger; } + public void setupFormat() { + System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT] %4$s [%2$s] %5$s%6$s%n"); + } + /** * Because java.util.logging differentiates between the log name and the class/method logging, * we can collapses the log names to a simpler/smaller set to allow configuration to rely on the class name less. From a06f822eca715fb9d4d7ea1222408d06cc71a707 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Mon, 19 Dec 2022 07:49:52 -0600 Subject: [PATCH 03/28] add deprecated annotation --- .../src/main/java/liquibase/logging/core/JavaLogger.java | 1 + 1 file changed, 1 insertion(+) diff --git a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogger.java b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogger.java index 0730cac83fe..8c02a557697 100644 --- a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogger.java +++ b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogger.java @@ -15,6 +15,7 @@ public class JavaLogger extends AbstractLogger { /** * @deprecated use {@link #JavaLogger(java.util.logging.Logger)} */ + @Deprecated public JavaLogger(java.util.logging.Logger logger, LogMessageFilter filter) { this(logger); } From 8e248ccc6e4032e45eb289c35f6d7aec20de3010 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Mon, 19 Dec 2022 13:14:57 -0600 Subject: [PATCH 04/28] Revert "set log format in log service" This reverts commit 096b0676692ab758814cfde011f925ea9a9678e3. --- .../integration/commandline/LiquibaseCommandLine.java | 3 ++- .../src/main/java/liquibase/logging/core/JavaLogService.java | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java index 2903725d86f..9a6f963dae0 100644 --- a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java +++ b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java @@ -636,9 +636,10 @@ private void configureLogging(Level logLevel, String logFile) throws IOException java.util.logging.Logger liquibaseLogger = java.util.logging.Logger.getLogger("liquibase"); if (logService instanceof JavaLogService) { ((JavaLogService) logService).setParent(liquibaseLogger); - ((JavaLogService) logService).setupFormat(); } + System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT] %4$s [%2$s] %5$s%6$s%n"); + java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger(""); Level cliLogLevel = logLevel; diff --git a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java index 02910b7ffe5..a0b7065ba31 100644 --- a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java +++ b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java @@ -34,10 +34,6 @@ public Logger getLog(Class clazz) { return logger; } - public void setupFormat() { - System.setProperty("java.util.logging.SimpleFormatter.format", "[%1$tF %1$tT] %4$s [%2$s] %5$s%6$s%n"); - } - /** * Because java.util.logging differentiates between the log name and the class/method logging, * we can collapses the log names to a simpler/smaller set to allow configuration to rely on the class name less. From 4dabdf91e1bb5652a1642e2c71381138bff72aba Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Tue, 20 Dec 2022 07:27:32 -0600 Subject: [PATCH 05/28] use log formatter for JSON logging --- .../commandline/LiquibaseCommandLine.java | 18 ++++++++++++++++++ .../liquibase/logging/core/JavaLogService.java | 5 +++++ .../serializer/core/yaml/YamlSerializer.java | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java index 9a6f963dae0..d318cd3db6b 100644 --- a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java +++ b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java @@ -37,6 +37,7 @@ import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.logging.*; +import java.util.logging.Formatter; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -648,6 +649,9 @@ private void configureLogging(Level logLevel, String logFile) throws IOException final PathHandlerFactory pathHandlerFactory = Scope.getCurrentScope().getSingleton(PathHandlerFactory.class); OutputStream outputStream = pathHandlerFactory.openResourceOutputStream(logFile, new OpenOptions().setAppend(true)); fileHandler = new StreamHandler(outputStream, new SimpleFormatter()); + + setFormatterOnHandler(logService, fileHandler); + rootLogger.addHandler(fileHandler); } @@ -682,6 +686,20 @@ private void configureLogging(Level logLevel, String logFile) throws IOException if (handler instanceof ConsoleHandler) { handler.setLevel(cliLogLevel); } + setFormatterOnHandler(logService, handler); + } + } + + /** + * Set the formatter for the supplied handler if the supplied log service + * is a JavaLogService and that service specifies a custom formatter. + */ + private void setFormatterOnHandler(LogService logService, Handler handler) { + if (logService instanceof JavaLogService && handler != null) { + Formatter customFormatter = ((JavaLogService) logService).getCustomFormatter(); + if (customFormatter != null) { + handler.setFormatter(customFormatter); + } } } diff --git a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java index a0b7065ba31..d3f6bddce1b 100644 --- a/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java +++ b/liquibase-core/src/main/java/liquibase/logging/core/JavaLogService.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.logging.Formatter; public class JavaLogService extends AbstractLogService { @@ -90,4 +91,8 @@ public java.util.logging.Logger getParent() { public void setParent(java.util.logging.Logger parent) { this.parent = parent; } + + public Formatter getCustomFormatter() { + return null; + } } diff --git a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSerializer.java b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSerializer.java index 0efbebe7888..3b36b11daf5 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSerializer.java +++ b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSerializer.java @@ -166,7 +166,7 @@ public int compare(String o1, String o2) { }; } - private String removeClassTypeMarksFromSerializedJson(String json) { + public static String removeClassTypeMarksFromSerializedJson(String json) { // Handle both negative and positive numbers json = json.replaceAll("!!int \"(-?\\d+)\"", "$1"); json = json.replaceAll("!!bool \"(\\w+)\"", "$1"); From dfa312d96d2f530f4d611151cbf6fc7dea7ae618 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Tue, 20 Dec 2022 08:04:15 -0600 Subject: [PATCH 06/28] add MDC to structured log output --- .../src/main/java/liquibase/logging/mdc/MdcManager.java | 5 +++++ .../main/java/liquibase/logging/mdc/NoOpMdcManager.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java index d579f768914..702edb24210 100644 --- a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcManager.java @@ -3,6 +3,8 @@ import liquibase.Beta; import liquibase.plugin.Plugin; +import java.util.Map; + @Beta public interface MdcManager extends Plugin { @@ -28,4 +30,7 @@ public interface MdcManager extends Plugin { @Beta int getPriority(); + + @Beta + Map getAll(); } diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java b/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java index e821bc705a0..ca741f60c6d 100644 --- a/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/NoOpMdcManager.java @@ -2,6 +2,9 @@ import liquibase.plugin.Plugin; +import java.util.Collections; +import java.util.Map; + /** * Default MDC manager, which does nothing. */ @@ -25,4 +28,9 @@ public void clear() { public int getPriority() { return Plugin.PRIORITY_DEFAULT; } + + @Override + public Map getAll() { + return Collections.emptyMap(); + } } From 5533ed081fbf2f7d4557c5d641fa51fb64b6953c Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Tue, 20 Dec 2022 11:56:19 -0600 Subject: [PATCH 07/28] fix test --- liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy b/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy index 19b40399d29..642a6b7d7ce 100644 --- a/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy +++ b/liquibase-core/src/test/groovy/liquibase/ScopeTest.groovy @@ -149,6 +149,11 @@ class ScopeTest extends Specification { return Integer.MAX_VALUE } + @Override + Map getAll() { + return Collections.unmodifiableMap(values) + } + Map getValues() { return values } From 2c3fa40195b2cee0f93205fc2d537e0ffb5351a6 Mon Sep 17 00:00:00 2001 From: MichaelKern-IVV <102645261+MichaelKern-IVV@users.noreply.github.com> Date: Tue, 20 Dec 2022 21:52:39 +0100 Subject: [PATCH 08/28] Include "path" in databasechangelog's description column for all change types with "path" attributes (#3244) Extends the DESCRIPTION column of the DATABASECHANGELOG for sqlFile by the path specification, for example sqlFile path=IUNT200.sql Co-authored-by: michaelmatthiaskern Co-authored-by: Nathan Voxland --- .../java/liquibase/change/AbstractChange.java | 7 ++-- .../sdk/resource/MockResourceAccessor.java | 4 ++ .../change/AbstractChangeTest.groovy | 19 +++++++++ .../core/MarkChangeSetRanGeneratorTest.java | 39 ++++++++++++++++++- .../dbtest/AbstractIntegrationTest.java | 17 ++++++++ .../changelogs/common/pathChangeLog.xml | 13 +++++++ 6 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 liquibase-integration-tests/src/test/resources/changelogs/common/pathChangeLog.xml diff --git a/liquibase-core/src/main/java/liquibase/change/AbstractChange.java b/liquibase-core/src/main/java/liquibase/change/AbstractChange.java index 4eda6481980..4d7f53073ce 100644 --- a/liquibase-core/src/main/java/liquibase/change/AbstractChange.java +++ b/liquibase-core/src/main/java/liquibase/change/AbstractChange.java @@ -780,9 +780,10 @@ public String getDescription() { SortedSet names = new TreeSet<>(); for (Map.Entry entry : metaData.getParameters().entrySet()) { String lowerCaseKey = entry.getKey().toLowerCase(); - if (lowerCaseKey.endsWith("name") - && !lowerCaseKey.contains("schema") - && !lowerCaseKey.contains("catalog")) { + if ((lowerCaseKey.endsWith("name") + && !lowerCaseKey.contains("schema") + && !lowerCaseKey.contains("catalog")) + || lowerCaseKey.equals("path")) { Object currentValue = entry.getValue().getCurrentValue(this); if (currentValue != null) { names.add(entry.getKey()+"="+ currentValue); diff --git a/liquibase-core/src/main/java/liquibase/sdk/resource/MockResourceAccessor.java b/liquibase-core/src/main/java/liquibase/sdk/resource/MockResourceAccessor.java index 4b2c501f813..920cc2b2ed7 100644 --- a/liquibase-core/src/main/java/liquibase/sdk/resource/MockResourceAccessor.java +++ b/liquibase-core/src/main/java/liquibase/sdk/resource/MockResourceAccessor.java @@ -54,4 +54,8 @@ public List search(String path, boolean recursive) throws IOException public List describeLocations() { return Collections.singletonList("MockResouceAccessor.java"); } + + public void setContent(String fileName, String content) { + this.contentByFileName.put(fileName, content); + } } diff --git a/liquibase-core/src/test/groovy/liquibase/change/AbstractChangeTest.groovy b/liquibase-core/src/test/groovy/liquibase/change/AbstractChangeTest.groovy index c275aca4a58..bacbc855aaa 100644 --- a/liquibase-core/src/test/groovy/liquibase/change/AbstractChangeTest.groovy +++ b/liquibase-core/src/test/groovy/liquibase/change/AbstractChangeTest.groovy @@ -1,5 +1,9 @@ package liquibase.change +import liquibase.change.core.CreateProcedureChange +import liquibase.change.core.CreateTableChange +import liquibase.change.core.CreateViewChange +import liquibase.change.core.SQLFileChange import liquibase.changelog.ChangeSet import liquibase.changelog.DatabaseChangeLog import liquibase.database.Database @@ -12,6 +16,7 @@ import liquibase.serializer.LiquibaseSerializable import liquibase.statement.SqlStatement import org.junit.Test import spock.lang.Specification +import spock.lang.Unroll import static liquibase.test.Assert.assertArraysEqual import static org.junit.Assert.assertSame @@ -324,6 +329,20 @@ class AbstractChangeTest extends Specification { assertArraysEqual(["COMPUTE"].toArray(), new ExampleAbstractChange().createSupportedDatabasesMetaData("x", null)) } + @Unroll("#featureName: #path is included as part of description for a #change") + void pathIsIncludedAsPartOfChangeDescription() { + when: + change.setPath(path); + + then: + change.getDescription().contains(path) == true + + where: + path | change + "This/is/a/test/change/path" | new SQLFileChange() + "This/is/a/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/ver/long/test/change/path" | new CreateProcedureChange() + } + @DatabaseChange(name = "exampleParamelessAbstractChange", description = "Used for the AbstractChangeTest unit test", priority = 1) private static class ExampleParamlessAbstractChange extends AbstractChange { diff --git a/liquibase-core/src/test/java/liquibase/sqlgenerator/core/MarkChangeSetRanGeneratorTest.java b/liquibase-core/src/test/java/liquibase/sqlgenerator/core/MarkChangeSetRanGeneratorTest.java index 109f24fb38d..9dcf1f24a33 100644 --- a/liquibase-core/src/test/java/liquibase/sqlgenerator/core/MarkChangeSetRanGeneratorTest.java +++ b/liquibase-core/src/test/java/liquibase/sqlgenerator/core/MarkChangeSetRanGeneratorTest.java @@ -2,15 +2,21 @@ import liquibase.ContextExpression; import liquibase.Labels; +import liquibase.Scope; +import liquibase.change.core.SQLFileChange; import liquibase.changelog.ChangeSet; import liquibase.changelog.DatabaseChangeLog; import liquibase.database.core.MockDatabase; +import liquibase.sdk.resource.MockResourceAccessor; import liquibase.sql.Sql; import liquibase.sqlgenerator.AbstractSqlGeneratorTest; import liquibase.sqlgenerator.MockSqlGeneratorChain; import liquibase.statement.core.MarkChangeSetRanStatement; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -132,4 +138,35 @@ public void getContextsColumn() { changeSet.setContextFilter(null); assertEquals("p1", new MarkChangeSetRanGenerator().getContextsColumn(changeSet)); - }} + } + + @Test + public void makeSureDescriptionIsTruncatedWhenALongPathIsSet() throws Exception { + + MockResourceAccessor resourceAccessor = new MockResourceAccessor(); + String filePath = "This/is/a/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/ver/long/test/change/path"; + + resourceAccessor.setContent(filePath, "test"); + final DatabaseChangeLog changeLog = new DatabaseChangeLog(); + final ChangeSet changeSet = new ChangeSet("1", "a", false, false, "c", null, null, changeLog); + + SQLFileChange sqlFileChange = new SQLFileChange(); + sqlFileChange.setPath(filePath); + changeSet.addChange(sqlFileChange); + + MarkChangeSetRanStatement changeSetRanStatement = new MarkChangeSetRanStatement(changeSet, ChangeSet.ExecType.EXECUTED); + MarkChangeSetRanGenerator changeSetRanGenerator = new MarkChangeSetRanGenerator(); + Map newMap = new HashMap<>(); + newMap.put(Scope.Attr.resourceAccessor.name(), resourceAccessor); + + String sql = Scope.child(newMap, () -> changeSetRanGenerator.generateSql(changeSetRanStatement, new MockDatabase(), new MockSqlGeneratorChain())[0].toSql()); + + final int descriptionColumnIndex = 18; + String databaseChangeLogDescription = sql.split(",")[descriptionColumnIndex]; + String truncatedPath = databaseChangeLogDescription.split("path=")[1].split("'")[0]; + + assertTrue(truncatedPath.endsWith("/...")); + assertTrue(truncatedPath.length() <= filePath.length()); + + } +} diff --git a/liquibase-integration-tests/src/test/java/liquibase/dbtest/AbstractIntegrationTest.java b/liquibase-integration-tests/src/test/java/liquibase/dbtest/AbstractIntegrationTest.java index 9cf80a8b8d0..167b7dcf9d1 100644 --- a/liquibase-integration-tests/src/test/java/liquibase/dbtest/AbstractIntegrationTest.java +++ b/liquibase-integration-tests/src/test/java/liquibase/dbtest/AbstractIntegrationTest.java @@ -94,6 +94,8 @@ public abstract class AbstractIntegrationTest { private Database database; private String defaultSchemaName; + private final String pathChangeLog; + protected AbstractIntegrationTest(String changelogDir, Database dbms) throws Exception { if (dbms != null) { this.testSystem = (DatabaseTestSystem) Scope.getCurrentScope().getSingleton(TestSystemFactory.class).getTestSystem(dbms.getShortName()); @@ -108,6 +110,7 @@ protected AbstractIntegrationTest(String changelogDir, Database dbms) throws Exc this.invalidReferenceChangeLog= "changelogs/common/invalid.reference.changelog.xml"; this.objectQuotingStrategyChangeLog = "changelogs/common/object.quoting.strategy.changelog.xml"; this.emptyRollbackSqlChangeLog = "changelogs/common/rollbackable.changelog.sql"; + this.pathChangeLog = "changelogs/common/pathChangeLog.xml"; logger = Scope.getCurrentScope().getLog(getClass()); Scope.setScopeManager(new TestScopeManager()); @@ -1162,6 +1165,20 @@ public void testThatMultipleJVMsCanApplyChangelog() throws Exception { } } + @Test + public void testPathFromChangeObjectIsDeployed() throws Exception { + assumeNotNull(this.getDatabase()); + Liquibase liquibase; + clearDatabase(); + + String pathToSet = "changelogs/common/commentTest.sql"; + + liquibase = createLiquibase(pathChangeLog); + liquibase.update(this.contexts); + + assertTrue(liquibase.getDatabaseChangeLog().getChangeSets().stream().allMatch(changeSet -> changeSet.getDescription().contains(pathToSet))); + } + private ProcessBuilder prepareExternalLiquibaseProcess() { String javaHome = System.getProperty("java.home"); String javaBin = javaHome + File.separator + "bin" + File.separator + "java"; diff --git a/liquibase-integration-tests/src/test/resources/changelogs/common/pathChangeLog.xml b/liquibase-integration-tests/src/test/resources/changelogs/common/pathChangeLog.xml new file mode 100644 index 00000000000..d93462b2ec5 --- /dev/null +++ b/liquibase-integration-tests/src/test/resources/changelogs/common/pathChangeLog.xml @@ -0,0 +1,13 @@ + + + + + + create table test_table (id int, name varchar(10)); + + + + \ No newline at end of file From 92182fd9ea4e3a41f098ed0264fdaf689ed769f0 Mon Sep 17 00:00:00 2001 From: skrivenko <72100114+skrivenko@users.noreply.github.com> Date: Wed, 21 Dec 2022 00:01:26 +0300 Subject: [PATCH 09/28] #1466: Add ignore:true changeset attribute to Formatted SQL changeLogs (#3377) Co-authored-by: skrivenko Co-authored-by: filipe lautert --- .../FormattedSqlChangeLogParser.java | 8 ++++++++ .../FormattedSqlChangeLogParserTest.groovy | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/liquibase-core/src/main/java/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParser.java b/liquibase-core/src/main/java/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParser.java index 2f99ea9b1c4..23ee8fb430a 100644 --- a/liquibase-core/src/main/java/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParser.java +++ b/liquibase-core/src/main/java/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParser.java @@ -117,6 +117,7 @@ public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParame Pattern labelsPattern = Pattern.compile(".*labels:(\\S*).*", Pattern.CASE_INSENSITIVE); Pattern runInTransactionPattern = Pattern.compile(".*runInTransaction:(\\w+).*", Pattern.CASE_INSENSITIVE); Pattern dbmsPattern = Pattern.compile(".*dbms:([^,][\\w!,]+).*", Pattern.CASE_INSENSITIVE); + Pattern ignorePattern = Pattern.compile(".*ignore:(\\w*).*", Pattern.CASE_INSENSITIVE); Pattern failOnErrorPattern = Pattern.compile(".*failOnError:(\\w+).*", Pattern.CASE_INSENSITIVE); Pattern onFailPattern = Pattern.compile(".*onFail:(\\w+).*", Pattern.CASE_INSENSITIVE); Pattern onErrorPattern = Pattern.compile(".*onError:(\\w+).*", Pattern.CASE_INSENSITIVE); @@ -274,6 +275,7 @@ public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParame Matcher labelsPatternMatcher = labelsPattern.matcher(line); Matcher runInTransactionPatternMatcher = runInTransactionPattern.matcher(line); Matcher dbmsPatternMatcher = dbmsPattern.matcher(line); + Matcher ignorePatternMatcher = ignorePattern.matcher(line); Matcher failOnErrorPatternMatcher = failOnErrorPattern.matcher(line); boolean stripComments = parseBoolean(stripCommentsPatternMatcher, changeSet, true); @@ -318,6 +320,11 @@ public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParame dbms = changeLogParameters.expandExpressions(dbms, changeLog); } + String ignore = parseString(ignorePatternMatcher); + if (ignore != null) { + ignore = changeLogParameters.expandExpressions(ignore, changeLog); + } + // // Make sure that this line matches the --changeset : with no spaces before ID // @@ -345,6 +352,7 @@ public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParame changeSet = new ChangeSet(changeSetId, changeSetAuthor, runAlways, runOnChange, logicalFilePath, context, dbms, runWith, runInTransaction, changeLog.getObjectQuotingStrategy(), changeLog); changeSet.setLabels(new Labels(labels)); + changeSet.setIgnore(Boolean.parseBoolean(ignore)); changeSet.setFailOnError(failOnError); changeLog.addChangeSet(changeSet); diff --git a/liquibase-core/src/test/groovy/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParserTest.groovy b/liquibase-core/src/test/groovy/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParserTest.groovy index 192de64e005..c28139a7945 100644 --- a/liquibase-core/src/test/groovy/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParserTest.groovy +++ b/liquibase-core/src/test/groovy/liquibase/parser/core/formattedsql/FormattedSqlChangeLogParserTest.groovy @@ -175,6 +175,16 @@ alter table test_table add column name2 varchar(20); -- rollback changesetId:create changeSetAuthor:the_user +""".trim() + + private static final String VALID_CHANGELOG_WITH_IGNORE_PROP = """ +--liquibase formatted sql +-- changeset sk:1 ignore:true +create table changeSetToIgnore ( + id int primary key +); +--rollback drop table changeSetToIgnore; + """.trim() private static final String END_DELIMITER_CHANGELOG = """ @@ -405,6 +415,16 @@ CREATE TABLE ALL_CAPS_TABLE_2 ( ((RawSQLChange) changeLog.getChangeSets().get(24).getRollback().getChanges().get(0)).getSql().startsWith("create table test_table (") } + def parseIgnoreProperty() throws Exception { + expect: + ChangeLogParameters params = new ChangeLogParameters() + DatabaseChangeLog changeLog = new MockFormattedSqlChangeLogParser(VALID_CHANGELOG_WITH_IGNORE_PROP).parse("asdf.sql", params, new JUnitResourceAccessor()) + + changeLog.getChangeSets().get(0).getAuthor() == "sk" + changeLog.getChangeSets().get(0).getId() == "1" + assert changeLog.getChangeSets().get(0).isIgnore() + } + def "parse changeset with colon in ID"() throws Exception { when: String changeLogWithOneGoodOneBad = " \n\n" + From 598755a4df4d310cbe115c9bfad6e0e42143aa1e Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 4 Jan 2023 09:47:21 -0500 Subject: [PATCH 10/28] [DAT-12602] Initial update mdc implementation. --- .../src/main/java/liquibase/Liquibase.java | 5 ++++ .../java/liquibase/changelog/ChangeSet.java | 6 +++- .../changelog/visitor/UpdateVisitor.java | 6 ++++ .../integration/commandline/Main.java | 3 ++ .../java/liquibase/logging/mdc/MdcKey.java | 29 +++++++++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java diff --git a/liquibase-core/src/main/java/liquibase/Liquibase.java b/liquibase-core/src/main/java/liquibase/Liquibase.java index c06bb3efe9c..8f26d892f49 100644 --- a/liquibase-core/src/main/java/liquibase/Liquibase.java +++ b/liquibase-core/src/main/java/liquibase/Liquibase.java @@ -31,6 +31,7 @@ import liquibase.logging.Logger; import liquibase.logging.core.BufferedLogService; import liquibase.logging.core.CompositeLogService; +import liquibase.logging.mdc.MdcKey; import liquibase.parser.ChangeLogParser; import liquibase.parser.ChangeLogParserFactory; import liquibase.parser.core.xml.XMLChangeLogSAXParser; @@ -235,6 +236,8 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c runInScope(() -> { LockService lockService = LockServiceFactory.getInstance().getLockService(database); lockService.waitForLock(); + Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TARGET_VALUE.getKey(), database.getConnection().getURL()); + Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TARGET_TYPE.getKey(), "url"); changeLogParameters.setContexts(contexts); changeLogParameters.setLabels(labelExpression); @@ -252,6 +255,8 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c ChangeLogHistoryService changelogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database); changelogService.generateDeploymentId(); + Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_ID.getKey(), changelogService.getDeploymentId()); + changeLog.validate(database, contexts, labelExpression); // diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java index b0164e8668c..009a7a3d9d7 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java @@ -16,6 +16,7 @@ import liquibase.executor.ExecutorService; import liquibase.executor.LoggingExecutor; import liquibase.logging.Logger; +import liquibase.logging.mdc.MdcKey; import liquibase.parser.ChangeLogParserConfiguration; import liquibase.parser.core.ParsedNode; import liquibase.parser.core.ParsedNodeException; @@ -569,6 +570,7 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener } long startTime = new Date().getTime(); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_START_TIME.getKey(), String.valueOf(startTime)); ExecType execType = null; @@ -697,7 +699,9 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener if (runInTransaction) { database.commit(); } - log.info("ChangeSet " + toString(false) + " ran successfully in " + (new Date().getTime() - startTime + "ms")); + long endTime = new Date().getTime() - startTime; + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_STOP_TIME.getKey(), String.valueOf(endTime)); + log.info("ChangeSet " + toString(false) + " ran successfully in " + endTime + " ms"); if (execType == null) { execType = ExecType.EXECUTED; } diff --git a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java index 7ab6f46e7fc..d7dc305edd1 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java +++ b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java @@ -13,6 +13,7 @@ import liquibase.executor.Executor; import liquibase.executor.ExecutorService; import liquibase.executor.LoggingExecutor; +import liquibase.logging.mdc.MdcKey; import java.util.Set; @@ -43,6 +44,10 @@ public Direction getDirection() { @Override public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database, Set filterResults) throws LiquibaseException { + Scope scope = Scope.getCurrentScope(); + scope.addMdcValue(MdcKey.CHANGESET_ID.getKey(), changeSet.getId()); + scope.addMdcValue(MdcKey.CHANGESET_AUTHOR.getKey(), changeSet.getAuthor()); + scope.addMdcValue(MdcKey.CHANGESET_FILEPATH.getKey(), changeSet.getFilePath()); Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database); if (! (executor instanceof LoggingExecutor)) { Scope.getCurrentScope().getUI().sendMessage("Running Changeset: " + changeSet); @@ -61,6 +66,7 @@ public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Data if (!runStatus.equals(ChangeSet.RunStatus.NOT_RAN)) { execType = ChangeSet.ExecType.RERAN; } + Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME.getKey(), execType.value); fireRan(changeSet, databaseChangeLog, database, execType); // reset object quoting strategy after running changeset this.database.setObjectQuotingStrategy(previousStr); diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 2f1b05b8010..5235743578f 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -26,6 +26,7 @@ import liquibase.logging.LogService; import liquibase.logging.Logger; import liquibase.logging.core.JavaLogService; +import liquibase.logging.mdc.MdcKey; import liquibase.resource.*; import liquibase.ui.ConsoleUIService; import liquibase.util.*; @@ -1832,6 +1833,8 @@ protected void doMigration() throws Exception { try { if (COMMANDS.UPDATE.equalsIgnoreCase(command)) { + Scope.getCurrentScope().addMdcValue(MdcKey.LIQUIBASE_COMMAND_NAME.getKey(), COMMANDS.UPDATE); + Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TYPE.getKey(), COMMANDS.UPDATE); try { liquibase.update(new Contexts(contexts), new LabelExpression(getLabelFilter())); } catch (LiquibaseException updateException) { diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java new file mode 100644 index 00000000000..12c5b259668 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java @@ -0,0 +1,29 @@ +package liquibase.logging.mdc; + +public enum MdcKey { + DEPLOYMENT_ID("deploymentId"), + CHANGESET_ID("changesetId"), + CHANGESET_AUTHOR("changesetAuthor"), + CHANGESET_FILEPATH("changesetFilepath"), + CHANGESET_OUTCOME("changesetOutcome"), + OPERATION_TYPE("liquibaseOperation"), + OPERATION_TARGET_TYPE("liquibaseTargetType"), + OPERATION_TARGET_VALUE("liquibaseTarget"), + CHANGESET_OPERATION_START_TIME("changesetOperationStart"), + CHANGESET_OPERATION_STOP_TIME("changesetOperationStop"), + CHANGESET_SQL("changesetSql"), + CHANGESET_OPERATION_MESSAGE("changesetOperationMessage"), + CHANGESET_DATABASE_OUTPUT("changesetDatabaseOutput"), + DEPLOYMENT_OUTCOME("deploymentOutcome"), + LIQUIBASE_COMMAND_NAME("liquibaseCommandName"); + + private final String key; + + MdcKey(String key) { + this.key = key; + } + + public String getKey() { + return this.key; + } +} From 1faba366c3a76160be5186732cf198e3b6a17a52 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Thu, 5 Jan 2023 07:43:20 -0600 Subject: [PATCH 11/28] add configuration option for log format --- .../commandline/LiquibaseCommandLineConfiguration.java | 9 +++++++++ .../src/main/java/liquibase/logging/LogFormat.java | 6 ++++++ 2 files changed, 15 insertions(+) create mode 100644 liquibase-core/src/main/java/liquibase/logging/LogFormat.java diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java index ed6b3c4aa54..2efa34d1191 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java @@ -3,6 +3,7 @@ import liquibase.configuration.AutoloadedConfigurations; import liquibase.configuration.ConfigurationDefinition; import liquibase.configuration.ConfigurationValueConverter; +import liquibase.logging.LogFormat; import java.util.logging.Level; @@ -22,6 +23,7 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio public static final ConfigurationDefinition LOG_LEVEL; public static final ConfigurationDefinition LOG_CHANNELS; public static final ConfigurationDefinition LOG_FILE; + public static final ConfigurationDefinition LOG_FORMAT; public static final ConfigurationDefinition OUTPUT_FILE; public static final ConfigurationDefinition SHOULD_RUN; public static final ConfigurationDefinition ARGUMENT_CONVERTER; @@ -79,6 +81,13 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio .setDefaultValue(argument -> argument) .build(); + LOG_FORMAT = builder.define("logFormat", LogFormat.class) + .setDescription("Set the format of log output to console or log files\n" + + "[OSS] Defaults to \"TEXT\" logs to the console or output log files\n" + + "[PRO] Can be set to \"JSON\" to enable json-structured log files to the console or output log files") + .setDefaultValue(LogFormat.TEXT) + .build(); + } public interface ArgumentConverter { diff --git a/liquibase-core/src/main/java/liquibase/logging/LogFormat.java b/liquibase-core/src/main/java/liquibase/logging/LogFormat.java new file mode 100644 index 00000000000..c10634858a2 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/LogFormat.java @@ -0,0 +1,6 @@ +package liquibase.logging; + +public enum LogFormat { + TEXT, + JSON +} From 4652f25634168db8065fa0cd4d3a4fae10b0750c Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Thu, 5 Jan 2023 12:12:24 -0500 Subject: [PATCH 12/28] [DAT-12602] Adds remaining mdc values. Reworks to use static strings over enum. --- .../src/main/java/liquibase/Liquibase.java | 7 ++-- .../java/liquibase/changelog/ChangeSet.java | 8 ++-- .../changelog/visitor/UpdateVisitor.java | 8 ++-- .../liquibase/executor/jvm/JdbcExecutor.java | 2 + .../integration/commandline/Main.java | 8 ++-- .../java/liquibase/logging/mdc/MdcKey.java | 42 +++++++------------ .../java/liquibase/logging/mdc/MdcValue.java | 7 ++++ 7 files changed, 42 insertions(+), 40 deletions(-) create mode 100644 liquibase-core/src/main/java/liquibase/logging/mdc/MdcValue.java diff --git a/liquibase-core/src/main/java/liquibase/Liquibase.java b/liquibase-core/src/main/java/liquibase/Liquibase.java index 8f26d892f49..e1ff6fdd807 100644 --- a/liquibase-core/src/main/java/liquibase/Liquibase.java +++ b/liquibase-core/src/main/java/liquibase/Liquibase.java @@ -32,6 +32,7 @@ import liquibase.logging.core.BufferedLogService; import liquibase.logging.core.CompositeLogService; import liquibase.logging.mdc.MdcKey; +import liquibase.logging.mdc.MdcValue; import liquibase.parser.ChangeLogParser; import liquibase.parser.ChangeLogParserFactory; import liquibase.parser.core.xml.XMLChangeLogSAXParser; @@ -236,8 +237,8 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c runInScope(() -> { LockService lockService = LockServiceFactory.getInstance().getLockService(database); lockService.waitForLock(); - Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TARGET_VALUE.getKey(), database.getConnection().getURL()); - Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TARGET_TYPE.getKey(), "url"); + Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TARGET_VALUE, database.getConnection().getURL()); + Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TARGET_TYPE, MdcValue.URL_DATABASE_TARGET); changeLogParameters.setContexts(contexts); changeLogParameters.setLabels(labelExpression); @@ -255,7 +256,7 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c ChangeLogHistoryService changelogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database); changelogService.generateDeploymentId(); - Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_ID.getKey(), changelogService.getDeploymentId()); + Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_ID, changelogService.getDeploymentId()); changeLog.validate(database, contexts, labelExpression); diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java index 009a7a3d9d7..93570da70b2 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java @@ -28,6 +28,7 @@ import liquibase.sql.visitor.SqlVisitor; import liquibase.sql.visitor.SqlVisitorFactory; import liquibase.statement.SqlStatement; +import liquibase.util.ISODateFormat; import liquibase.util.StreamUtil; import liquibase.util.StringUtil; @@ -570,7 +571,7 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener } long startTime = new Date().getTime(); - Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_START_TIME.getKey(), String.valueOf(startTime)); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_START_TIME, new ISODateFormat().format(new Date())); ExecType execType = null; @@ -699,9 +700,8 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener if (runInTransaction) { database.commit(); } - long endTime = new Date().getTime() - startTime; - Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_STOP_TIME.getKey(), String.valueOf(endTime)); - log.info("ChangeSet " + toString(false) + " ran successfully in " + endTime + " ms"); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_STOP_TIME, new ISODateFormat().format(new Date())); + log.info("ChangeSet " + toString(false) + " ran successfully in " + (new Date().getTime() - startTime) + " ms"); if (execType == null) { execType = ExecType.EXECUTED; } diff --git a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java index d7dc305edd1..52bc3407f84 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java +++ b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java @@ -45,9 +45,9 @@ public Direction getDirection() { public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Database database, Set filterResults) throws LiquibaseException { Scope scope = Scope.getCurrentScope(); - scope.addMdcValue(MdcKey.CHANGESET_ID.getKey(), changeSet.getId()); - scope.addMdcValue(MdcKey.CHANGESET_AUTHOR.getKey(), changeSet.getAuthor()); - scope.addMdcValue(MdcKey.CHANGESET_FILEPATH.getKey(), changeSet.getFilePath()); + scope.addMdcValue(MdcKey.CHANGESET_ID, changeSet.getId()); + scope.addMdcValue(MdcKey.CHANGESET_AUTHOR, changeSet.getAuthor()); + scope.addMdcValue(MdcKey.CHANGESET_FILEPATH, changeSet.getFilePath()); Executor executor = Scope.getCurrentScope().getSingleton(ExecutorService.class).getExecutor("jdbc", database); if (! (executor instanceof LoggingExecutor)) { Scope.getCurrentScope().getUI().sendMessage("Running Changeset: " + changeSet); @@ -66,7 +66,7 @@ public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Data if (!runStatus.equals(ChangeSet.RunStatus.NOT_RAN)) { execType = ChangeSet.ExecType.RERAN; } - Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME.getKey(), execType.value); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OUTCOME, execType.value); fireRan(changeSet, databaseChangeLog, database, execType); // reset object quoting strategy after running changeset this.database.setObjectQuotingStrategy(previousStr); diff --git a/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java b/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java index 8fa6f9c3f25..cf17fc9d81c 100644 --- a/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java +++ b/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java @@ -11,6 +11,7 @@ import liquibase.executor.AbstractExecutor; import liquibase.listener.SqlListener; import liquibase.logging.Logger; +import liquibase.logging.mdc.MdcKey; import liquibase.servicelocator.PrioritizedService; import liquibase.sql.CallableSql; import liquibase.sql.Sql; @@ -425,6 +426,7 @@ public Object doInStatement(Statement stmt) throws SQLException, DatabaseExcepti statement = statement.replaceFirst("[\\s\\r\\n]*[^*]/[\\s\\r\\n]*$", ""); } } + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_SQL, statement); for (SqlListener listener : Scope.getCurrentScope().getListeners(SqlListener.class)) { listener.writeSqlWillRun(String.format("%s", statement)); diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 5235743578f..abbf28eea29 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -27,6 +27,7 @@ import liquibase.logging.Logger; import liquibase.logging.core.JavaLogService; import liquibase.logging.mdc.MdcKey; +import liquibase.logging.mdc.MdcValue; import liquibase.resource.*; import liquibase.ui.ConsoleUIService; import liquibase.util.*; @@ -396,7 +397,7 @@ public Integer run() throws Exception { } Scope.child(innerScopeObjects, () -> { main.doMigration(); - + Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_SUCCESSFUL); if (!Main.runningFromNewCli) { if (COMMANDS.UPDATE.equals(main.command)) { Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("update.successful")); @@ -408,6 +409,7 @@ public Integer run() throws Exception { } }); } catch (Throwable e) { + Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_FAILED); String message = e.getMessage(); if (e.getCause() != null) { message = e.getCause().getMessage(); @@ -1833,8 +1835,8 @@ protected void doMigration() throws Exception { try { if (COMMANDS.UPDATE.equalsIgnoreCase(command)) { - Scope.getCurrentScope().addMdcValue(MdcKey.LIQUIBASE_COMMAND_NAME.getKey(), COMMANDS.UPDATE); - Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TYPE.getKey(), COMMANDS.UPDATE); + Scope.getCurrentScope().addMdcValue(MdcKey.LIQUIBASE_COMMAND_NAME, COMMANDS.UPDATE); + Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TYPE, COMMANDS.UPDATE); try { liquibase.update(new Contexts(contexts), new LabelExpression(getLabelFilter())); } catch (LiquibaseException updateException) { diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java index 12c5b259668..f82a41e21eb 100644 --- a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java @@ -1,29 +1,19 @@ package liquibase.logging.mdc; -public enum MdcKey { - DEPLOYMENT_ID("deploymentId"), - CHANGESET_ID("changesetId"), - CHANGESET_AUTHOR("changesetAuthor"), - CHANGESET_FILEPATH("changesetFilepath"), - CHANGESET_OUTCOME("changesetOutcome"), - OPERATION_TYPE("liquibaseOperation"), - OPERATION_TARGET_TYPE("liquibaseTargetType"), - OPERATION_TARGET_VALUE("liquibaseTarget"), - CHANGESET_OPERATION_START_TIME("changesetOperationStart"), - CHANGESET_OPERATION_STOP_TIME("changesetOperationStop"), - CHANGESET_SQL("changesetSql"), - CHANGESET_OPERATION_MESSAGE("changesetOperationMessage"), - CHANGESET_DATABASE_OUTPUT("changesetDatabaseOutput"), - DEPLOYMENT_OUTCOME("deploymentOutcome"), - LIQUIBASE_COMMAND_NAME("liquibaseCommandName"); - - private final String key; - - MdcKey(String key) { - this.key = key; - } - - public String getKey() { - return this.key; - } +public class MdcKey { + public static final String DEPLOYMENT_ID = "deploymentId"; + public static final String CHANGESET_ID = "changesetId"; + public static final String CHANGESET_AUTHOR = "changesetAuthor"; + public static final String CHANGESET_FILEPATH = "changesetFilepath"; + public static final String CHANGESET_OUTCOME = "changesetOutcome"; + public static final String OPERATION_TYPE = "liquibaseOperation"; + public static final String OPERATION_TARGET_TYPE = "liquibaseTargetType"; + public static final String OPERATION_TARGET_VALUE = "liquibaseTarget"; + public static final String CHANGESET_OPERATION_START_TIME = "changesetOperationStart"; + public static final String CHANGESET_OPERATION_STOP_TIME = "changesetOperationStop"; + public static final String CHANGESET_SQL = "changesetSql"; + public static final String CHANGESET_OPERATION_MESSAGE = "changesetOperationMessage"; + public static final String CHANGESET_DATABASE_OUTPUT = "changesetDatabaseOutput"; + public static final String DEPLOYMENT_OUTCOME = "deploymentOutcome"; + public static final String LIQUIBASE_COMMAND_NAME = "liquibaseCommandName"; } diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcValue.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcValue.java new file mode 100644 index 00000000000..6f80ce06a41 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcValue.java @@ -0,0 +1,7 @@ +package liquibase.logging.mdc; + +public class MdcValue { + public static final String COMMAND_SUCCESSFUL = "success"; + public static final String COMMAND_FAILED = "fail"; + public static final String URL_DATABASE_TARGET = "url"; +} From fb0a2f1fbfc8f6e1910508a404d224907de36f29 Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Thu, 5 Jan 2023 13:49:33 -0500 Subject: [PATCH 13/28] [DAT-12602] Remove unused keys, fixed formatting. --- liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java | 2 +- .../main/java/liquibase/changelog/visitor/UpdateVisitor.java | 2 +- liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java index 93570da70b2..ea2142a5c35 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java @@ -701,7 +701,7 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener database.commit(); } Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_STOP_TIME, new ISODateFormat().format(new Date())); - log.info("ChangeSet " + toString(false) + " ran successfully in " + (new Date().getTime() - startTime) + " ms"); + log.info("ChangeSet " + toString(false) + " ran successfully in " + (new Date().getTime() - startTime) + "ms"); if (execType == null) { execType = ExecType.EXECUTED; } diff --git a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java index 52bc3407f84..976243c1c74 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java +++ b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java @@ -66,7 +66,7 @@ public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Data if (!runStatus.equals(ChangeSet.RunStatus.NOT_RAN)) { execType = ChangeSet.ExecType.RERAN; } - Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OUTCOME, execType.value); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OUTCOME, execType.value.toLowerCase()); fireRan(changeSet, databaseChangeLog, database, execType); // reset object quoting strategy after running changeset this.database.setObjectQuotingStrategy(previousStr); diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java index f82a41e21eb..8e1dc3c9e60 100644 --- a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java @@ -12,8 +12,6 @@ public class MdcKey { public static final String CHANGESET_OPERATION_START_TIME = "changesetOperationStart"; public static final String CHANGESET_OPERATION_STOP_TIME = "changesetOperationStop"; public static final String CHANGESET_SQL = "changesetSql"; - public static final String CHANGESET_OPERATION_MESSAGE = "changesetOperationMessage"; - public static final String CHANGESET_DATABASE_OUTPUT = "changesetDatabaseOutput"; public static final String DEPLOYMENT_OUTCOME = "deploymentOutcome"; public static final String LIQUIBASE_COMMAND_NAME = "liquibaseCommandName"; } From 07b67ffad5aef29b5f9f8c38cf18c5e3d9a658e9 Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Fri, 6 Jan 2023 07:41:24 -0500 Subject: [PATCH 14/28] [DAT-12602] Adds system information to mdc. --- .../java/liquibase/integration/commandline/Main.java | 9 +++++++++ .../src/main/java/liquibase/logging/mdc/MdcKey.java | 3 +++ 2 files changed, 12 insertions(+) diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index abbf28eea29..949fcb81b38 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -34,6 +34,7 @@ import java.io.*; import java.lang.reflect.Field; +import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -326,6 +327,10 @@ public Integer run() throws Exception { } } + Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildVersionInfo()); + Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_SYSTEM_USER, System.getProperty("user.name")); + Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_SYSTEM_NAME, InetAddress.getLocalHost().getHostName()); + LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService(); if (licenseService != null) { if (main.liquibaseProLicenseKey == null) { @@ -395,6 +400,10 @@ public Integer run() throws Exception { if (!Main.runningFromNewCli) { innerScopeObjects.put(Scope.Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor(main.configureClassLoader())); } + Scope.getCurrentScope().getMdcManager().remove(MdcKey.LIQUIBASE_VERSION); + Scope.getCurrentScope().getMdcManager().remove(MdcKey.LIQUIBASE_SYSTEM_NAME); + Scope.getCurrentScope().getMdcManager().remove(MdcKey.LIQUIBASE_SYSTEM_USER); + Scope.child(innerScopeObjects, () -> { main.doMigration(); Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_SUCCESSFUL); diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java index 8e1dc3c9e60..ed847694c2f 100644 --- a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java @@ -14,4 +14,7 @@ public class MdcKey { public static final String CHANGESET_SQL = "changesetSql"; public static final String DEPLOYMENT_OUTCOME = "deploymentOutcome"; public static final String LIQUIBASE_COMMAND_NAME = "liquibaseCommandName"; + public static final String LIQUIBASE_VERSION = "liquibaseVersion"; + public static final String LIQUIBASE_SYSTEM_NAME = "liquibaseSystemName"; + public static final String LIQUIBASE_SYSTEM_USER = "liquibaseSystemUser"; } From c601452dde440dd31bcddddfb06e90adc501f364 Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Fri, 6 Jan 2023 07:43:46 -0500 Subject: [PATCH 15/28] [DAT-12602] Fixes formatting for mdckey. --- liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java index ed847694c2f..010d9f9c222 100644 --- a/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java +++ b/liquibase-core/src/main/java/liquibase/logging/mdc/MdcKey.java @@ -4,7 +4,7 @@ public class MdcKey { public static final String DEPLOYMENT_ID = "deploymentId"; public static final String CHANGESET_ID = "changesetId"; public static final String CHANGESET_AUTHOR = "changesetAuthor"; - public static final String CHANGESET_FILEPATH = "changesetFilepath"; + public static final String CHANGESET_FILEPATH = "changesetFilepath"; public static final String CHANGESET_OUTCOME = "changesetOutcome"; public static final String OPERATION_TYPE = "liquibaseOperation"; public static final String OPERATION_TARGET_TYPE = "liquibaseTargetType"; From 1ceec55305d316b1b8906a2cc53c7f1299903b8d Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Fri, 6 Jan 2023 09:17:34 -0500 Subject: [PATCH 16/28] [DAT-12602] Simplifies getting mdc for command name. --- .../src/main/java/liquibase/integration/commandline/Main.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 949fcb81b38..1f8d0a5e723 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -1843,8 +1843,8 @@ protected void doMigration() throws Exception { } try { + Scope.getCurrentScope().addMdcValue(MdcKey.LIQUIBASE_COMMAND_NAME, command); if (COMMANDS.UPDATE.equalsIgnoreCase(command)) { - Scope.getCurrentScope().addMdcValue(MdcKey.LIQUIBASE_COMMAND_NAME, COMMANDS.UPDATE); Scope.getCurrentScope().addMdcValue(MdcKey.OPERATION_TYPE, COMMANDS.UPDATE); try { liquibase.update(new Contexts(contexts), new LabelExpression(getLabelFilter())); From f04e4a24b38ff0284851d3b4c2445572183e7a67 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Fri, 6 Jan 2023 13:48:42 -0600 Subject: [PATCH 17/28] updated logFormat description --- .../commandline/LiquibaseCommandLineConfiguration.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java index 2efa34d1191..3f952ef7232 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java @@ -82,9 +82,9 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio .build(); LOG_FORMAT = builder.define("logFormat", LogFormat.class) - .setDescription("Set the format of log output to console or log files\n" + - "[OSS] Defaults to \"TEXT\" logs to the console or output log files\n" + - "[PRO] Can be set to \"JSON\" to enable json-structured log files to the console or output log files") + .setDescription("Sets the format of log output to console or log files. " + + "Open Source users default to unstructured \"TEXT\" logs to the console or output log files." + + "Pro users have option to set value as \"JSON\" to enable json-structured log files to the console or output log files.") .setDefaultValue(LogFormat.TEXT) .build(); From 718ca6ef0b8c54c2e48cc61d16fb65d0de4d6dc2 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Wed, 11 Jan 2023 11:13:33 -0600 Subject: [PATCH 18/28] warn about invalid values for log format --- .../command/CommandArgumentDefinition.java | 3 ++- .../LiquibaseCommandLineConfiguration.java | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java index 1fb2c6b0c07..a46d3c1e0f3 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java @@ -7,6 +7,7 @@ import liquibase.exception.MissingRequiredArgumentException; import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; import liquibase.util.ObjectUtil; +import liquibase.util.StringUtil; import java.util.*; import java.util.regex.Pattern; @@ -274,7 +275,7 @@ public CommandArgumentDefinition build() throws IllegalArgumentExcepti Scope.getCurrentScope().getSingleton(CommandFactory.class).register(commandName, newCommandArgument); } catch (IllegalArgumentException iae) { Scope.getCurrentScope().getLog(CommandArgumentDefinition.class).warning( - "Unable to register command '" + commandName + "' argument '" + newCommandArgument.getName() + "': " + iae.getMessage()); + "Unable to register command '" + StringUtil.join(commandName, " ") + "' argument '" + newCommandArgument.getName() + "': " + iae.getMessage()); throw iae; } } diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java index 3f952ef7232..f0f8e921fa1 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java @@ -4,7 +4,9 @@ import liquibase.configuration.ConfigurationDefinition; import liquibase.configuration.ConfigurationValueConverter; import liquibase.logging.LogFormat; +import liquibase.util.StringUtil; +import java.util.Arrays; import java.util.logging.Level; /** @@ -86,6 +88,19 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio "Open Source users default to unstructured \"TEXT\" logs to the console or output log files." + "Pro users have option to set value as \"JSON\" to enable json-structured log files to the console or output log files.") .setDefaultValue(LogFormat.TEXT) + .setValueHandler((logFormat) -> { + if (logFormat == null) { + return null; + } + + String logFormatString = (String) logFormat; + + if (Arrays.stream(LogFormat.values()).noneMatch(lf -> lf.toString().equalsIgnoreCase(logFormatString))) { + throw new IllegalArgumentException("WARNING: The log format value '"+logFormatString+"' is not valid. Valid values include: '" + StringUtil.join(LogFormat.values(), "', '", Object::toString) + "'"); + } + + return Enum.valueOf(LogFormat.class, logFormatString.toUpperCase()); + }) .build(); } From 9691becbbb9d7d4accfbf64b74239535e849e899 Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 13:04:09 -0500 Subject: [PATCH 19/28] [DAT-12602] Add changeset outcome to info log, fix deployment outcome to actually show in info. --- liquibase-core/src/main/java/liquibase/Liquibase.java | 6 ++++++ .../src/main/java/liquibase/changelog/ChangeSet.java | 6 ++++-- .../java/liquibase/changelog/visitor/UpdateVisitor.java | 1 - .../main/java/liquibase/integration/commandline/Main.java | 4 +--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/Liquibase.java b/liquibase-core/src/main/java/liquibase/Liquibase.java index fe816fa8b8d..dea8a3b749e 100644 --- a/liquibase-core/src/main/java/liquibase/Liquibase.java +++ b/liquibase-core/src/main/java/liquibase/Liquibase.java @@ -301,7 +301,13 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c // Update Hub with the operation information // hubUpdater.postUpdateHub(updateOperation, bufferLog); + Scope.getCurrentScope().getMdcManager().put(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_SUCCESSFUL); + Scope.getCurrentScope().getLog(getClass()).info("Command completed successfully."); + Scope.getCurrentScope().getMdcManager().remove(MdcKey.DEPLOYMENT_OUTCOME); } catch (Throwable e) { + Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_FAILED); + Scope.getCurrentScope().getLog(getClass()).info("Command encountered an exception."); + Scope.getCurrentScope().getMdcManager().remove(MdcKey.DEPLOYMENT_OUTCOME); if (hubUpdater != null) { hubUpdater.postUpdateHubExceptionHandling(updateOperation, bufferLog, e.getMessage()); } diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java index ea2142a5c35..a65af9a9e59 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java @@ -700,11 +700,13 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener if (runInTransaction) { database.commit(); } - Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_STOP_TIME, new ISODateFormat().format(new Date())); - log.info("ChangeSet " + toString(false) + " ran successfully in " + (new Date().getTime() - startTime) + "ms"); if (execType == null) { execType = ExecType.EXECUTED; } + Date stopTime = new Date(); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OPERATION_STOP_TIME, new ISODateFormat().format(stopTime)); + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OUTCOME, execType.value.toLowerCase()); + log.info("ChangeSet " + toString(false) + " ran successfully in " + (stopTime.getTime() - startTime) + "ms"); } else { log.fine("Skipping ChangeSet: " + toString()); } diff --git a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java index 976243c1c74..6655e671fba 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java +++ b/liquibase-core/src/main/java/liquibase/changelog/visitor/UpdateVisitor.java @@ -66,7 +66,6 @@ public void visit(ChangeSet changeSet, DatabaseChangeLog databaseChangeLog, Data if (!runStatus.equals(ChangeSet.RunStatus.NOT_RAN)) { execType = ChangeSet.ExecType.RERAN; } - Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OUTCOME, execType.value.toLowerCase()); fireRan(changeSet, databaseChangeLog, database, execType); // reset object quoting strategy after running changeset this.database.setObjectQuotingStrategy(previousStr); diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 1f8d0a5e723..89a4a67e6a4 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -327,7 +327,7 @@ public Integer run() throws Exception { } } - Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildVersionInfo()); + Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildNumber()); Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_SYSTEM_USER, System.getProperty("user.name")); Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_SYSTEM_NAME, InetAddress.getLocalHost().getHostName()); @@ -406,7 +406,6 @@ public Integer run() throws Exception { Scope.child(innerScopeObjects, () -> { main.doMigration(); - Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_SUCCESSFUL); if (!Main.runningFromNewCli) { if (COMMANDS.UPDATE.equals(main.command)) { Scope.getCurrentScope().getUI().sendMessage(coreBundle.getString("update.successful")); @@ -418,7 +417,6 @@ public Integer run() throws Exception { } }); } catch (Throwable e) { - Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_FAILED); String message = e.getMessage(); if (e.getCause() != null) { message = e.getCause().getMessage(); From 10d540b62515d06efe9f1ec1985b093afb0566ec Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 13:12:39 -0500 Subject: [PATCH 20/28] Revert "Merge remote-tracking branch 'origin/DAT-11693' into DAT-12602" This reverts commit 6e9163d81307f7f534a13d51797e642921e11532, reversing changes made to 1ceec55305d316b1b8906a2cc53c7f1299903b8d. --- .github/util/package-install4j.sh | 20 +- .github/workflows/create-release.yml | 12 +- .github/workflows/installer-build-check.yml | 4 +- .github/workflows/release-published.yml | 4 +- .../cdi/SchemesCDIConfigBuilder.java | 3 +- liquibase-core/pom.xml | 2 +- .../liquibase/AbstractExtensibleObject.java | 3 - .../src/main/java/liquibase/Liquibase.java | 30 ++- .../change/core/CreateProcedureChange.java | 2 - .../change/core/DropColumnChange.java | 1 - .../liquibase/change/core/LoadDataChange.java | 1 - .../AbstractChangeLogHistoryService.java | 5 - .../ChangeLogHistoryServiceFactory.java | 2 +- .../OfflineChangeLogHistoryService.java | 8 +- .../StandardChangeLogHistoryService.java | 2 - .../filter/IgnoreChangeSetFilter.java | 1 - .../liquibase/command/CleanUpCommandStep.java | 14 -- .../command/CommandArgumentDefinition.java | 30 +-- .../liquibase/command/CommandBuilder.java | 17 -- .../liquibase/command/CommandFactory.java | 28 +-- .../java/liquibase/command/CommandScope.java | 8 - .../core/CalculateChecksumCommandStep.java | 1 - .../core/DbUrlConnectionCommandStep.java | 219 ------------------ .../command/core/DiffToChangeLogCommand.java | 2 - .../command/core/SnapshotCommandStep.java | 134 ++++++++++- .../command/core/TagCommandStep.java | 65 +++--- .../configuration/LiquibaseConfiguration.java | 14 +- .../database/AbstractJdbcDatabase.java | 2 +- .../java/liquibase/database/Database.java | 7 - .../liquibase/database/DatabaseFactory.java | 5 +- .../database/core/AbstractDb2Database.java | 1 - .../DatabaseObjectComparatorComparator.java | 2 +- .../DatabaseObjectComparatorFactory.java | 8 - .../changelog/ChangeGeneratorComparator.java | 2 +- .../output/changelog/DiffToChangeLog.java | 41 ++-- ...issingDataExternalFileChangeGenerator.java | 4 +- .../core/UnexpectedTableChangeGenerator.java | 2 +- .../core/UnexpectedViewChangeGenerator.java | 2 +- .../diff/output/report/DiffToReport.java | 4 +- .../liquibase/executor/AbstractExecutor.java | 1 - .../liquibase/executor/ExecutorService.java | 46 +--- .../liquibase/executor/jvm/JdbcExecutor.java | 2 +- .../liquibase/hub/core/MockHubService.java | 1 - .../java/liquibase/hub/model/Connection.java | 1 - .../commandline/CommandLineUtils.java | 1 - .../servlet/GenericServletListener.java | 2 - ...mptyLineAndCommentSkippingInputStream.java | 2 +- .../lockservice/LockServiceFactory.java | 2 +- .../lockservice/StandardLockService.java | 59 +++-- .../parser/NamespaceDetailsFactory.java | 2 +- .../parser/SnapshotParserFactory.java | 2 +- .../resource/DirectoryPathHandler.java | 2 - .../liquibase/resource/ZipPathHandler.java | 2 - .../liquibase/sdk/resource/MockResource.java | 1 - .../AbstractLiquibaseSerializable.java | 1 - .../ChangeLogSerializerFactory.java | 6 +- .../serializer/SnapshotSerializerFactory.java | 6 +- .../core/yaml/YamlChangeLogSerializer.java | 1 - .../core/yaml/YamlSnapshotSerializer.java | 6 +- .../liquibase/snapshot/DatabaseSnapshot.java | 6 +- .../liquibase/snapshot/ResultSetCache.java | 12 +- .../snapshot/SnapshotGeneratorComparator.java | 2 +- .../UniqueConstraintSnapshotGenerator.java | 6 +- .../sql/visitor/AbstractSqlVisitor.java | 2 - .../sqlgenerator/SqlGeneratorComparator.java | 2 +- .../core/AddPrimaryKeyGenerator.java | 2 +- .../core/AddUniqueConstraintGenerator.java | 2 +- .../structure/DatabaseObjectCollection.java | 15 +- .../DatabaseObjectComparator.java} | 6 +- .../liquibase/structure/core/Catalog.java | 6 +- .../liquibase/structure/core/Relation.java | 1 - .../java/liquibase/structure/core/Schema.java | 6 +- .../structure/core/StoredDatabaseLogic.java | 5 - .../java/liquibase/structure/core/Table.java | 2 - .../main/java/liquibase/util/FileUtil.java | 2 +- .../src/main/java/liquibase/util/MD5Util.java | 2 +- .../main/java/liquibase/util/ObjectUtil.java | 8 +- .../java/liquibase/util/csv/CSVWriter.java | 1 - .../liquibase/util/xml/DefaultXmlWriter.java | 2 +- .../services/liquibase.command.CommandStep | 1 - .../command/core/MockCommandStep.java | 6 +- .../change/VerifyChangeClassesTest.java | 2 +- liquibase-dist/pom.xml | 4 +- ...nse Subscription and Support Agreement.txt | 182 --------------- .../aws-secrets-manager-extension/README.txt | 22 -- .../apache-2.0.txt | 65 ------ .../aws-secrets-manager-extension/mit.txt | 6 - ...nse Subscription and Support Agreement.txt | 182 --------------- .../hashicorp-vault-extension/README.txt | 16 -- .../hashicorp-vault-extension/apache-2.0.txt | 65 ------ .../src/main/install4j/liquibase.install4j | 2 +- liquibase-extension-testing/pom.xml | 2 +- .../testing/command/CommandTests.groovy | 1 + .../extension/testing/command/tag.test.groovy | 4 + liquibase-maven-plugin/pom.xml | 2 +- .../LiquibaseChangeLogSyncToTagSQLMojo.java | 4 +- pom.xml | 8 +- 97 files changed, 371 insertions(+), 1151 deletions(-) delete mode 100644 liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java delete mode 100644 liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java rename liquibase-core/src/main/java/liquibase/{diff/compare/DatabaseObjectCollectionComparator.java => structure/DatabaseObjectComparator.java} (83%) delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt delete mode 100644 liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt diff --git a/.github/util/package-install4j.sh b/.github/util/package-install4j.sh index 5271a0cb13d..9142ffb258a 100755 --- a/.github/util/package-install4j.sh +++ b/.github/util/package-install4j.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash ################################################################### -## This script creates the installer files given an unzipped directory +## This script creates the installer files given an unziped directory ################################################################### set -e @@ -13,14 +13,14 @@ if [ -z ${1+x} ]; then fi version=$1 -if [ -z ${INSTALL4J_10_LICENSE+x} ]; then - echo "INSTALL4J_10_LICENSE must be set"; +if [ -z ${INSTALL4J_LICENSE+x} ]; then + echo "INSTALL4J_LICENSE must be set"; exit 1 fi -mkdir -p ~/.install4j10 -export INSTALL4J_CACHE=$HOME/.install4j10 +mkdir -p ~/.install4j8 +export INSTALL4J_CACHE=$HOME/.install4j8 # install4jc="/usr/local/bin/install4jc" install4jc="/Applications/install4j.app/Contents/Resources/app/bin/install4jc" @@ -31,13 +31,13 @@ else echo "$install4jc does not exist. Installing..." # installer automation for ubuntu-latest; replaced - # wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download.ej-technologies.com/install4j/install4j_linux-x64_10_0_4.deb - # sudo apt install -y $INSTALL4J_CACHE/install4j_linux-x64_10_0_4.deb + # wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download-gcdn.ej-technologies.com/install4j/install4j_linux_8_0_11.deb + # sudo apt install -y $INSTALL4J_CACHE/install4j_linux_8_0_11.deb # installer automation for macos-latest; macos needed for apple notarizing - wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download.ej-technologies.com/install4j/install4j_macos_10_0_4.dmg + wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download-gcdn.ej-technologies.com/install4j/install4j_macos_8_0_11.dmg sleep 5 - hdiutil attach /Users/runner/.install4j10/install4j_macos_10_0_4.dmg + hdiutil attach /Users/runner/.install4j8/install4j_macos_8_0_11.dmg sleep 5 cp -rf /Volumes/install4j/install4j.app /Applications sleep 5 @@ -54,6 +54,6 @@ else INSTALL4J_ARGS="$INSTALL4J_ARGS --win-keystore-password=$INSTALL4J_WINDOWS_KEY_PASSWORD --mac-keystore-password=$INSTALL4J_APPLE_KEY_PASSWORD --apple-id=$INSTALL4J_APPLE_ID --apple-id-password=$INSTALL4J_APPLE_ID_PASSWORD" fi -"$install4jc" --license=$INSTALL4J_10_LICENSE +"$install4jc" --license=$INSTALL4J_LICENSE "$install4jc" $INSTALL4J_ARGS src/main/install4j/liquibase.install4j diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 81014769072..71c4b73751b 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -8,9 +8,7 @@ on: branch: description: 'Branch to release (Defaults to master)' required: false - runId: - description: 'RunId of liquibase/liquibase artifacts to attach' - required: true + jobs: setup: name: Setup @@ -18,7 +16,6 @@ jobs: outputs: version: ${{ steps.collect-data.outputs.version }} branch: ${{ steps.collect-data.outputs.branch }} - runId: ${{ steps.collect-data.outputs.runId }} steps: - name: Collect Data id: collect-data @@ -27,9 +24,9 @@ jobs: script: | core.setOutput("version", context.payload.inputs.version); core.setOutput("branch", context.payload.inputs.branch || "master"); - core.setOutput("runId", context.payload.inputs.runId); + - run: | - echo "Creating version ${{ steps.collect-data.outputs.version }} from ${{ steps.collect-data.outputs.branch }} with artifacts from build ${{ steps.collect-data.outputs.runId }} " + echo "Creating version ${{ steps.collect-data.outputs.version }} from ${{ steps.collect-data.outputs.branch }}" reversion: needs: [ setup ] @@ -51,7 +48,8 @@ jobs: uses: liquibase/action-download-artifact@v2-liquibase with: workflow: build.yml - run_id: ${{ needs.setup.outputs.runId }} + workflow_conclusion: success + branch: ${{ needs.setup.outputs.branch }} name: liquibase-artifacts path: download/liquibase-artifacts diff --git a/.github/workflows/installer-build-check.yml b/.github/workflows/installer-build-check.yml index 15a96a83384..bff2eb2486f 100644 --- a/.github/workflows/installer-build-check.yml +++ b/.github/workflows/installer-build-check.yml @@ -29,7 +29,7 @@ jobs: - name: Set up JDK for GPG uses: actions/setup-java@v3 with: - java-version: '17' + java-version: '8' distribution: 'temurin' gpg-private-key: ${{ secrets.GPG_SECRET }} gpg-passphrase: GPG_PASSPHRASE @@ -38,7 +38,7 @@ jobs: - name: Re-version Installers env: - INSTALL4J_10_LICENSE: ${{ secrets.INSTALL4J_10_LICENSE }} + INSTALL4J_LICENSE: ${{ secrets.INSTALL4J_LICENSE }} INSTALL4J_APPLE_KEY: ${{ secrets.INSTALL4J_APPLE_KEY }} INSTALL4J_APPLE_KEY_PASSWORD: ${{ secrets.INSTALL4J_APPLE_KEY_PASSWORD }} INSTALL4J_APPLE_ID: ${{ secrets.INSTALL4J_APPLE_ID }} diff --git a/.github/workflows/release-published.yml b/.github/workflows/release-published.yml index df5b9171d4a..5837a9b824e 100644 --- a/.github/workflows/release-published.yml +++ b/.github/workflows/release-published.yml @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Download release assets - uses: robinraju/release-downloader@v1.7 + uses: robinraju/release-downloader@v1.6 with: repository: "liquibase/liquibase" tag: "${{ needs.setup.outputs.tag }}" @@ -175,7 +175,7 @@ jobs: contents: read steps: - name: Download release javadocs - uses: robinraju/release-downloader@v1.7 + uses: robinraju/release-downloader@v1.6 with: repository: "liquibase/liquibase" tag: "${{ needs.setup.outputs.tag }}" diff --git a/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java b/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java index 57b36d2c29a..d1812c15ae2 100644 --- a/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java +++ b/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java @@ -68,7 +68,6 @@ public CDILiquibaseConfig createCDILiquibaseConfig() { final InputStream is = SchemesCDIConfigBuilder.class.getResourceAsStream(SCHEMA_NAME); try { return jvmLocked(id, new Callable() { - @Override public CDILiquibaseConfig call() throws Exception { return createCDILiquibaseConfig(id, is); } @@ -191,7 +190,7 @@ CDILiquibaseConfig fileLocked(final String id, Callable acti FileLock lock = null; try ( FileOutputStream fileStream = new FileOutputStream(lockPath); - FileChannel fileChannel = fileStream.getChannel() + FileChannel fileChannel = fileStream.getChannel(); ) { while (null == lock) { diff --git a/liquibase-core/pom.xml b/liquibase-core/pom.xml index d9be3e5a89e..617d20da735 100644 --- a/liquibase-core/pom.xml +++ b/liquibase-core/pom.xml @@ -115,7 +115,7 @@ org.junit.jupiter junit-jupiter-params - 5.9.1 + 5.8.1 test diff --git a/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java b/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java index b78607615ab..ab835ca342b 100644 --- a/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java +++ b/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java @@ -70,7 +70,6 @@ public ObjectMetaData getObjectMetaData() { /** * Return true if the given key is defined. */ - @Override public boolean has(String key) { return get(key, Object.class) != null; } @@ -120,7 +119,6 @@ protected T get(String attribute, T defaultValue, Class type) { } } - @Override public List getValuePath(String attributes, Class lastType) { List path = new ArrayList(); @@ -232,7 +230,6 @@ public ExtensibleObject set(String attribute, Object value) { return this; } - @Override public String describe() { String name = getClass().getSimpleName(); return name + "{" + StringUtil.join(this, ", ", new StringUtil.DefaultFormatter()) + "}"; diff --git a/liquibase-core/src/main/java/liquibase/Liquibase.java b/liquibase-core/src/main/java/liquibase/Liquibase.java index dea8a3b749e..b4febcfe2ad 100644 --- a/liquibase-core/src/main/java/liquibase/Liquibase.java +++ b/liquibase-core/src/main/java/liquibase/Liquibase.java @@ -6,9 +6,7 @@ import liquibase.changelog.filter.*; import liquibase.changelog.visitor.*; import liquibase.command.CommandScope; -import liquibase.command.core.DbUrlConnectionCommandStep; import liquibase.command.core.InternalDropAllCommandStep; -import liquibase.command.core.TagCommandStep; import liquibase.database.Database; import liquibase.database.DatabaseConnection; import liquibase.database.DatabaseFactory; @@ -1895,14 +1893,30 @@ public final void dropAll(CatalogAndSchema... schemas) throws DatabaseException /** * 'Tags' the database for future rollback - * - * @deprecated Use {link {@link CommandScope(String)} to tag instead of this method. */ public void tag(String tagString) throws LiquibaseException { - new CommandScope("tag") - .addArgumentValue(DbUrlConnectionCommandStep.DATABASE_ARG, database) - .addArgumentValue(TagCommandStep.TAG_ARG, tagString) - .execute(); + runInScope(new Scope.ScopedRunner() { + @Override + public void run() throws Exception { + + LockService lockService = LockServiceFactory.getInstance().getLockService(database); + lockService.waitForLock(); + + try { + ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database).generateDeploymentId(); + + checkLiquibaseTables(false, null, new Contexts(), + new LabelExpression()); + getDatabase().tag(tagString); + } finally { + try { + lockService.releaseLock(); + } catch (LockException e) { + LOG.severe(MSG_COULD_NOT_RELEASE_LOCK, e); + } + } + } + }); } public boolean tagExists(String tagString) throws LiquibaseException { diff --git a/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java b/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java index 9f715223819..2aafe1d704a 100644 --- a/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java +++ b/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java @@ -141,7 +141,6 @@ public void setProcedureText(String procedureText) { this.procedureText = procedureText; } - @Override @DatabaseChangeProperty( exampleValue = "h2, oracle", since = "3.1" @@ -150,7 +149,6 @@ public String getDbms() { return dbms; } - @Override public void setDbms(final String dbms) { this.dbms = dbms; } diff --git a/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java b/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java index db60a6518df..2d0ed45f2e6 100644 --- a/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java +++ b/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java @@ -211,7 +211,6 @@ public boolean createThisIndex(Index index) { for (Column column : index.getColumns()) { if (removedColumnNames.contains(column.getName())) { indexContainsColumn = true; - break; } } return !indexContainsColumn; diff --git a/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java b/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java index 228ad715f42..319e7cea853 100644 --- a/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java +++ b/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java @@ -121,7 +121,6 @@ public boolean generateRollbackStatementsVolatile(Database database) { return true; } - @Override @DatabaseChangeProperty(description = "Name of the table to insert data into", requiredForDatabase = ALL, mustEqualExisting = "table") public String getTableName() { diff --git a/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java b/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java index 232166d8926..bdc0f0090c5 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java +++ b/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java @@ -31,7 +31,6 @@ public void reset() { } - @Override public ChangeSet.RunStatus getRunStatus(final ChangeSet changeSet) throws DatabaseException, DatabaseHistoryException { RanChangeSet foundRan = getRanChangeSet(changeSet); @@ -62,7 +61,6 @@ public ChangeSet.RunStatus getRunStatus(final ChangeSet changeSet) } } - @Override public void upgradeChecksums(final DatabaseChangeLog databaseChangeLog, final Contexts contexts, LabelExpression labels) throws DatabaseException { for (RanChangeSet ranChangeSet : this.getRanChangeSets()) { @@ -120,17 +118,14 @@ public String getLastDeploymentId() throws DatabaseException { protected abstract void replaceChecksum(ChangeSet changeSet) throws DatabaseException; - @Override public String getDeploymentId() { return this.deploymentId; } - @Override public void resetDeploymentId() { this.deploymentId = null; } - @Override public void generateDeploymentId() { if (this.deploymentId == null) { String dateString = String.valueOf(new Date().getTime()); diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java index 78b81920d30..424ad2a0abf 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java @@ -56,7 +56,7 @@ public ChangeLogHistoryService getChangeLogService(Database database) { SortedSet foundServices = new TreeSet<>(new Comparator() { @Override public int compare(ChangeLogHistoryService o1, ChangeLogHistoryService o2) { - return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); + return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); } }); diff --git a/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java b/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java index 7f436697990..14afe04cc9c 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java +++ b/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java @@ -151,7 +151,7 @@ public String[] execute(String[] line) { @Override public List getRanChangeSets() throws DatabaseException { try ( - Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()) + Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); ) { CSVReader csvReader = new CSVReader(reader); @@ -210,7 +210,7 @@ protected void replaceChangeSet(ChangeSet changeSet, ReplaceChangeSetLogic repla Reader reader = new InputStreamReader(new FileInputStream(oldFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); Writer writer = new OutputStreamWriter(new FileOutputStream(newFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); CSVReader csvReader = new CSVReader(reader); - CSVWriter csvWriter = new CSVWriter(writer) + CSVWriter csvWriter = new CSVWriter(writer); ) { String[] line; @@ -238,7 +238,7 @@ protected void appendChangeSet(ChangeSet changeSet, ChangeSet.ExecType execType) Reader reader = new InputStreamReader(new FileInputStream(oldFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); Writer writer = new OutputStreamWriter(new FileOutputStream(newFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); CSVReader csvReader = new CSVReader(reader); - CSVWriter csvWriter = new CSVWriter(writer) + CSVWriter csvWriter = new CSVWriter(writer); ) { String[] line; @@ -327,7 +327,7 @@ public int getNextSequenceValue() throws LiquibaseException { lastChangeSetSequenceValue = 0; try ( - Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()) + Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); ) { diff --git a/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java b/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java index 4326825fb88..b4648d3a866 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java +++ b/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java @@ -98,7 +98,6 @@ protected String getCharTypeName() { return "varchar"; } - @Override public void init() throws DatabaseException { if (serviceInitialized) { return; @@ -305,7 +304,6 @@ public void upgradeChecksums(final DatabaseChangeLog databaseChangeLog, final Co /** * Returns the ChangeSets that have been run against the current getDatabase(). */ - @Override public List getRanChangeSets() throws DatabaseException { if (this.ranChangeSetList == null) { Database database = getDatabase(); diff --git a/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java b/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java index b77e291be9c..8d5de72665a 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java +++ b/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java @@ -3,7 +3,6 @@ import liquibase.changelog.ChangeSet; public class IgnoreChangeSetFilter implements ChangeSetFilter { - @Override public ChangeSetFilterResult accepts(ChangeSet changeSet) { if (changeSet.isIgnore()) { return new ChangeSetFilterResult(false, "Changeset is ignored", this.getClass()); diff --git a/liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java b/liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java deleted file mode 100644 index 6f7424e9214..00000000000 --- a/liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java +++ /dev/null @@ -1,14 +0,0 @@ -package liquibase.command; - -/** - * Interface implemented by CommandSteps when they need to execute clean up tasks (such as closing database - * connections, flushing files, etc) after other steps in the pipeline are executed. - */ -public interface CleanUpCommandStep { - - /** - * Method invoked to execute the cleanup action. - * @param resultsBuilder builder used in this pipeline - */ - void cleanUp(CommandResultsBuilder resultsBuilder); -} diff --git a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java index 7b979811452..1fb2c6b0c07 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java @@ -8,10 +8,7 @@ import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; import liquibase.util.ObjectUtil; -import java.util.Collections; -import java.util.Objects; -import java.util.SortedSet; -import java.util.TreeSet; +import java.util.*; import java.util.regex.Pattern; /** @@ -29,6 +26,7 @@ public class CommandArgumentDefinition implements Comparable aliases = new TreeSet<>(); private final Class dataType; + private String description; private boolean required; private boolean hidden; @@ -36,7 +34,6 @@ public class CommandArgumentDefinition implements Comparable valueConverter; private ConfigurationValueObfuscator valueObfuscator; - private CommandArgumentDefinition supersededBy; protected CommandArgumentDefinition(String name, Class type) { this.name = name; @@ -80,14 +77,6 @@ public boolean isRequired() { return required; } - public CommandArgumentDefinition getSupersededBy() { - return this.supersededBy; - } - - public void setSupersededBy(CommandArgumentDefinition supersededBy) { - this.supersededBy = supersededBy; - } - /** * Hidden arguments are ones that can be called via integrations, but should not be normally shown in help to users. */ @@ -132,9 +121,8 @@ public ConfigurationValueObfuscator getValueObfuscator() { */ public void validate(CommandScope commandScope) throws CommandValidationException { final DataType currentValue = commandScope.getArgumentValue(this); - if (this.isRequired() && currentValue == null && - (this.getSupersededBy() == null || commandScope.getArgumentValue(this.getSupersededBy()) == null)) { - throw new CommandValidationException(LiquibaseCommandLineConfiguration.ARGUMENT_CONVERTER.getCurrentValue().convert(this.getName()), "missing required argument", new MissingRequiredArgumentException(this.getName())); + if (this.isRequired() && currentValue == null) { + throw new CommandValidationException(LiquibaseCommandLineConfiguration.ARGUMENT_CONVERTER.getCurrentValue().convert(this.getName()), "missing required argument", new MissingRequiredArgumentException(this.getName())); } } @@ -197,16 +185,6 @@ public Building required() { return this; } - /** - * Specifies a CommandArgument that can replace this one if it is not available. - * - */ - public Building supersededBy(CommandArgumentDefinition commandArgumentDefinition) { - this.newCommandArgument.supersededBy = commandArgumentDefinition; - - return this; - } - /** * Mark argument as optional. * @see #required() diff --git a/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java b/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java index b9f8465190b..ccb49fe6d99 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java @@ -1,9 +1,5 @@ package liquibase.command; -import liquibase.Beta; -import liquibase.command.core.DbUrlConnectionCommandStep; -import liquibase.database.Database; - /** * Builder for configuring {@link CommandStep} settings, such as {@link CommandArgumentDefinition}s and {@link CommandResultDefinition}s */ @@ -32,19 +28,6 @@ public CommandArgumentDefinition.Building argument(CommonAr return new CommandArgumentDefinition.Building<>(commandNames, new CommandArgumentDefinition<>(argument.getArgumentName(), type)); } - - /** - * Creates a database argument and registers the current Step as an applicable command - * to the InternalDatabaseCommandStep. - */ - @Beta - public CommandArgumentDefinition.Building databaseArgument() { - DbUrlConnectionCommandStep.addApplicableCommand(this.commandNames); - return new CommandArgumentDefinition.Building<>(commandNames, - new CommandArgumentDefinition<>("database", Database.class)) - .description("Database connection"); - } - /** * Starts the building of a new {@link CommandResultDefinition}. */ diff --git a/liquibase-core/src/main/java/liquibase/command/CommandFactory.java b/liquibase-core/src/main/java/liquibase/command/CommandFactory.java index a4a21cb1e11..ca083ba5f7d 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandFactory.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandFactory.java @@ -5,7 +5,6 @@ import liquibase.servicelocator.ServiceLocator; import liquibase.util.StringUtil; -import java.lang.reflect.InvocationTargetException; import java.util.*; /** @@ -35,30 +34,18 @@ public CommandDefinition getCommandDefinition(String... commandName) throws Ille CommandDefinition commandDefinition = new CommandDefinition(commandName); for (CommandStep step : findAllInstances()) { if (step.getOrder(commandDefinition) > 0) { - try { - commandDefinition.add(step.getClass().getConstructor().newInstance()); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - throw new IllegalArgumentException(e); - } + commandDefinition.add(step); } } final List pipeline = commandDefinition.getPipeline(); - if (pipeline.isEmpty()) { + if (pipeline.size() == 0) { throw new IllegalArgumentException("Unknown command '" + StringUtil.join(commandName, " ") + "'"); } - final Set> stepArguments = new HashSet<>(); - for (CommandStep step : pipeline) { - String[][] names = step.defineCommandNames(); - if (names != null) { - for (String[] name : names) { - stepArguments.addAll(this.commandArgumentDefinitions.getOrDefault(StringUtil.join(name, " "), new HashSet<>())); - } - } - } + final Set> stepArguments = this.commandArgumentDefinitions.get(StringUtil.join(commandDefinition.getName(), " ")); - if (!stepArguments.isEmpty()) { + if (stepArguments != null) { for (CommandArgumentDefinition commandArg : stepArguments) { commandDefinition.add(commandArg); } @@ -80,11 +67,8 @@ public CommandDefinition getCommandDefinition(String... commandName) throws Ille public SortedSet getCommands(boolean includeInternal) { Map commandNames = new HashMap<>(); for (CommandStep step : findAllInstances()) { - String[][] names = step.defineCommandNames(); - if (names != null) { - for (String[] name : names) { - commandNames.put(StringUtil.join(name, " "), name); - } + for (String[] name : step.defineCommandNames()) { + commandNames.put(StringUtil.join(name, " "), name); } } diff --git a/liquibase-core/src/main/java/liquibase/command/CommandScope.java b/liquibase-core/src/main/java/liquibase/command/CommandScope.java index 24573d03a99..8f8e49c8feb 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandScope.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandScope.java @@ -171,14 +171,6 @@ public CommandResults execute() throws CommandExecutionException { for (CommandStep command : pipeline) { command.run(resultsBuilder); } - - // after executing our pipeline, runs cleanup in inverse order - for (int i = pipeline.size() -1; i >= 0; i--) { - CommandStep command = pipeline.get(i); - if (command instanceof CleanUpCommandStep) { - ((CleanUpCommandStep)command).cleanUp(resultsBuilder); - } - } } catch (Exception e) { if (e instanceof CommandExecutionException) { throw (CommandExecutionException) e; diff --git a/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java index 46944e234af..b5198726cce 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java +++ b/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java @@ -48,7 +48,6 @@ public String[][] defineCommandNames() { } - @Override protected String[] collectArguments(CommandScope commandScope) throws CommandExecutionException { return collectArguments(commandScope, null, CHANGESET_IDENTIFIER_ARG.getName()); } diff --git a/liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java deleted file mode 100644 index 9631859539e..00000000000 --- a/liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java +++ /dev/null @@ -1,219 +0,0 @@ -package liquibase.command.core; - -import liquibase.Beta; -import liquibase.GlobalConfiguration; -import liquibase.Scope; -import liquibase.command.*; -import liquibase.configuration.ConfigurationValueObfuscator; -import liquibase.database.Database; -import liquibase.database.DatabaseFactory; -import liquibase.database.core.DatabaseUtils; -import liquibase.exception.CommandValidationException; -import liquibase.exception.DatabaseException; -import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; -import liquibase.resource.ResourceAccessor; -import liquibase.util.StringUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.ResourceBundle; - -import static java.util.ResourceBundle.getBundle; - -/** - * Internal command step to be used on CommandStep pipeline to manage the database connection. - */ -public class DbUrlConnectionCommandStep extends AbstractCommandStep implements CleanUpCommandStep { - - public static final String[] COMMAND_NAME = {"dbUrlConnectionCommandStep"}; - - private static final List APPLICABLE_COMMANDS = new ArrayList<>(); - private static final ResourceBundle coreBundle = getBundle("liquibase/i18n/liquibase-core"); - - public static final CommandArgumentDefinition DATABASE_ARG; - public static final CommandArgumentDefinition URL_ARG; - public static final CommandArgumentDefinition DEFAULT_SCHEMA_NAME_ARG; - public static final CommandArgumentDefinition DEFAULT_CATALOG_NAME_ARG; - public static final CommandArgumentDefinition USERNAME_ARG; - public static final CommandArgumentDefinition PASSWORD_ARG; - public static final CommandArgumentDefinition DRIVER_ARG; - public static final CommandArgumentDefinition DRIVER_PROPERTIES_FILE_ARG; - - private Database database; - - static { - CommandBuilder builder = new CommandBuilder(COMMAND_NAME); - DEFAULT_SCHEMA_NAME_ARG = builder.argument("defaultSchemaName", String.class) - .description("The default schema name to use for the database connection").build(); - DEFAULT_CATALOG_NAME_ARG = builder.argument("defaultCatalogName", String.class) - .description("The default catalog name to use for the database connection").build(); - DRIVER_ARG = builder.argument("driver", String.class) - .description("The JDBC driver class").build(); - DRIVER_PROPERTIES_FILE_ARG = builder.argument("driverPropertiesFile", String.class) - .description("The JDBC driver properties file").build(); - USERNAME_ARG = builder.argument(CommonArgumentNames.USERNAME, String.class) - .description("Username to use to connect to the database").build(); - PASSWORD_ARG = builder.argument(CommonArgumentNames.PASSWORD, String.class) - .description("Password to use to connect to the database") - .setValueObfuscator(ConfigurationValueObfuscator.STANDARD) - .build(); - DATABASE_ARG = builder.argument("database", Database.class).hidden().build(); - URL_ARG = builder.argument(CommonArgumentNames.URL, String.class).required().supersededBy(DATABASE_ARG) - .description("The JDBC database connection URL").build(); - DATABASE_ARG.setSupersededBy(URL_ARG); - } - - /** - * Method that allows Commands to register themselves to be able to use this CommandStep. - */ - @Beta - public static void addApplicableCommand(String[]... commandName) { - APPLICABLE_COMMANDS.add(commandName); - } - - @Override - public void run(CommandResultsBuilder resultsBuilder) throws Exception { - CommandScope commandScope = resultsBuilder.getCommandScope(); - commandScope.addArgumentValue(DATABASE_ARG.getName(), this.obtainDatabase(commandScope)); - } - - /** - * Try to retrieve and set the database object from the command scope, otherwise creates a new one . - * - * @param commandScope current command scope - * @throws DatabaseException Thrown when there is a connection error - */ - private Database obtainDatabase(CommandScope commandScope) throws DatabaseException, CommandValidationException { - if (commandScope.getArgumentValue(DATABASE_ARG) == null) { - String url = commandScope.getArgumentValue(URL_ARG); - String username = commandScope.getArgumentValue(USERNAME_ARG); - String password = commandScope.getArgumentValue(PASSWORD_ARG); - String defaultSchemaName = commandScope.getArgumentValue(DEFAULT_SCHEMA_NAME_ARG); - String defaultCatalogName = commandScope.getArgumentValue(DEFAULT_CATALOG_NAME_ARG); - String driver = commandScope.getArgumentValue(DRIVER_ARG); - String driverPropertiesFile = commandScope.getArgumentValue(DRIVER_PROPERTIES_FILE_ARG); - this.database = createDatabaseObject(url, username, password, defaultSchemaName, defaultCatalogName, driver, driverPropertiesFile); - return this.database; - } else { - return commandScope.getArgumentValue(DATABASE_ARG); - } - } - - @SuppressWarnings("java:S2095") - /** - * - * Method to create a Database object given these parameters - * - * @param url URL to connect to - * @param username Username credential - * @param password Password credential - * @param defaultSchemaName Default schema for connection - * @param defaultCatalogName Default catalog for connection - * @param driver Driver class - * @param driverPropertiesFile Additional driver properties - * @throws DatabaseException Thrown when there is a connection error - * - */ - private Database createDatabaseObject(String url, - String username, - String password, - String defaultSchemaName, - String defaultCatalogName, - String driver, - String driverPropertiesFile) - throws DatabaseException { - ResourceAccessor resourceAccessor = Scope.getCurrentScope().getResourceAccessor(); - String databaseClassName = null; - Class databaseClass = LiquibaseCommandLineConfiguration.DATABASE_CLASS.getCurrentValue(); - if (databaseClass != null) { - databaseClassName = databaseClass.getCanonicalName(); - } - String propertyProviderClass = null; - Class clazz = LiquibaseCommandLineConfiguration.PROPERTY_PROVIDER_CLASS.getCurrentValue(); - if (clazz != null) { - propertyProviderClass = clazz.getName(); - } - String liquibaseCatalogName = StringUtil.trimToNull(GlobalConfiguration.LIQUIBASE_CATALOG_NAME.getCurrentValue()); - String liquibaseSchemaName = StringUtil.trimToNull(GlobalConfiguration.LIQUIBASE_SCHEMA_NAME.getCurrentValue()); - String databaseChangeLogTablespaceName = StringUtil.trimToNull(GlobalConfiguration.LIQUIBASE_TABLESPACE_NAME.getCurrentValue()); - String databaseChangeLogLockTableName = StringUtil.trimToNull(GlobalConfiguration.DATABASECHANGELOGLOCK_TABLE_NAME.getCurrentValue()); - String databaseChangeLogTableName = StringUtil.trimToNull(GlobalConfiguration.DATABASECHANGELOG_TABLE_NAME.getCurrentValue()); - - try { - defaultCatalogName = StringUtil.trimToNull(defaultCatalogName); - defaultSchemaName = StringUtil.trimToNull(defaultSchemaName); - - database = DatabaseFactory.getInstance().openDatabase(url, username, password, driver, - databaseClassName, driverPropertiesFile, propertyProviderClass, resourceAccessor); - - if (!database.supportsSchemas()) { - if ((defaultSchemaName != null) && (defaultCatalogName == null)) { - defaultCatalogName = defaultSchemaName; - } - if ((liquibaseSchemaName != null) && (liquibaseCatalogName == null)) { - liquibaseCatalogName = liquibaseSchemaName; - } - } - - defaultCatalogName = StringUtil.trimToNull(defaultCatalogName); - defaultSchemaName = StringUtil.trimToNull(defaultSchemaName); - - database.setDefaultCatalogName(defaultCatalogName); - database.setDefaultSchemaName(defaultSchemaName); - database.setOutputDefaultCatalog(true); - database.setOutputDefaultSchema(true); - database.setLiquibaseCatalogName(liquibaseCatalogName); - database.setLiquibaseTablespaceName(databaseChangeLogTablespaceName); - database.setLiquibaseSchemaName(liquibaseSchemaName); - if (databaseChangeLogTableName != null) { - database.setDatabaseChangeLogTableName(databaseChangeLogTableName); - if (databaseChangeLogLockTableName != null) { - database.setDatabaseChangeLogLockTableName(databaseChangeLogLockTableName); - } else { - database.setDatabaseChangeLogLockTableName(databaseChangeLogTableName + "LOCK"); - } - } - DatabaseUtils.initializeDatabase(defaultCatalogName, defaultSchemaName, database); - } catch (Exception e) { - throw new DatabaseException(e); - } - - return database; - } - - @Override - public String[][] defineCommandNames() { - return new String[][] { COMMAND_NAME }; - } - - @Override - public void adjustCommandDefinition(CommandDefinition commandDefinition) { - if (commandDefinition.getPipeline().size() == 1) { - commandDefinition.setInternal(true); - } - } - - @Override - public int getOrder(CommandDefinition commandDefinition) { - for (String[][] commandNames : APPLICABLE_COMMANDS) { - for (String[] commandName : commandNames) { - if (commandDefinition.is(commandName)) { - return 500; - } - } - } - return super.getOrder(commandDefinition); - } - - @Override - public void cleanUp(CommandResultsBuilder resultsBuilder) { - if (database != null) { - try { - database.close(); - database = null; - } catch (Exception e) { - Scope.getCurrentScope().getLog(getClass()).warning(coreBundle.getString("problem.closing.connection"), e); - } - } - } -} diff --git a/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java b/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java index 8bf39523cc8..7557bfae1c1 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java +++ b/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java @@ -29,12 +29,10 @@ public DiffToChangeLogCommand setChangeLogFile(String changeLogFile) { return this; } - @Override public PrintStream getOutputStream() { return outputStream; } - @Override public DiffToChangeLogCommand setOutputStream(PrintStream outputStream) { this.outputStream = outputStream; return this; diff --git a/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java index 0bb214f9e3d..eac670dd647 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java +++ b/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java @@ -2,9 +2,15 @@ import liquibase.CatalogAndSchema; import liquibase.GlobalConfiguration; +import liquibase.Scope; import liquibase.command.*; +import liquibase.configuration.ConfigurationValueObfuscator; import liquibase.database.Database; import liquibase.database.ObjectQuotingStrategy; +import liquibase.exception.DatabaseException; +import liquibase.integration.commandline.CommandLineUtils; +import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; +import liquibase.resource.ResourceAccessor; import liquibase.serializer.SnapshotSerializerFactory; import liquibase.snapshot.DatabaseSnapshot; import liquibase.snapshot.SnapshotControl; @@ -15,29 +21,55 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Map; +import java.util.*; + +import static java.util.ResourceBundle.getBundle; public class SnapshotCommandStep extends AbstractCommandStep { public static final String[] COMMAND_NAME = {"snapshot"}; + private static final ResourceBundle coreBundle = getBundle("liquibase/i18n/liquibase-core"); + public static final CommandArgumentDefinition USERNAME_ARG; + public static final CommandArgumentDefinition PASSWORD_ARG; + public static final CommandArgumentDefinition URL_ARG; public static final CommandArgumentDefinition SCHEMAS_ARG; + public static final CommandArgumentDefinition DEFAULT_SCHEMA_NAME_ARG; + public static final CommandArgumentDefinition DEFAULT_CATALOG_NAME_ARG; public static final CommandArgumentDefinition SNAPSHOT_FORMAT_ARG; + public static final CommandArgumentDefinition DRIVER_ARG; + public static final CommandArgumentDefinition DRIVER_PROPERTIES_FILE_ARG; public static final CommandArgumentDefinition DATABASE_ARG; public static final CommandArgumentDefinition SNAPSHOT_CONTROL_ARG; static { CommandBuilder builder = new CommandBuilder(COMMAND_NAME); - SCHEMAS_ARG = builder.argument("schemas", String.class).description("The schemas to snapshot").build(); + URL_ARG = builder.argument(CommonArgumentNames.URL, String.class).required() + .description("The JDBC database connection URL").build(); + SCHEMAS_ARG = builder.argument("schemas", String.class) + .description("The schemas to snapshot").build(); + DEFAULT_SCHEMA_NAME_ARG = builder.argument("defaultSchemaName", String.class) + .description("The default schema name to use for the database connection").build(); + DEFAULT_CATALOG_NAME_ARG = builder.argument("defaultCatalogName", String.class) + .description("The default catalog name to use for the database connection").build(); + DRIVER_ARG = builder.argument("driver", String.class) + .description("The JDBC driver class").build(); + DRIVER_PROPERTIES_FILE_ARG = builder.argument("driverPropertiesFile", String.class) + .description("The JDBC driver properties file").build(); + USERNAME_ARG = builder.argument(CommonArgumentNames.USERNAME, String.class) + .description("Username to use to connect to the database").build(); + PASSWORD_ARG = builder.argument(CommonArgumentNames.PASSWORD, String.class) + .description("Password to use to connect to the database") + .setValueObfuscator(ConfigurationValueObfuscator.STANDARD) + .build(); SNAPSHOT_FORMAT_ARG = builder.argument("snapshotFormat", String.class) .description("Output format to use (JSON, YAML, or TXT)").build(); + DATABASE_ARG = builder.argument("database", Database.class).hidden().build(); SNAPSHOT_CONTROL_ARG = builder.argument("snapshotControl", SnapshotControl.class).hidden().build(); - DATABASE_ARG = builder.databaseArgument().build(); } + private Database database; + private Map snapshotMetadata; @Override @@ -75,7 +107,19 @@ public void setSnapshotMetadata(Map snapshotMetadata) { @Override public void run(CommandResultsBuilder resultsBuilder) throws Exception { CommandScope commandScope = resultsBuilder.getCommandScope(); - Database database = commandScope.getArgumentValue(DATABASE_ARG); + + if (commandScope.getArgumentValue(DATABASE_ARG) == null) { + String url = commandScope.getArgumentValue(SnapshotCommandStep.URL_ARG); + String username = commandScope.getArgumentValue(SnapshotCommandStep.USERNAME_ARG); + String password = commandScope.getArgumentValue(SnapshotCommandStep.PASSWORD_ARG); + String defaultSchemaName = commandScope.getArgumentValue(SnapshotCommandStep.DEFAULT_SCHEMA_NAME_ARG); + String defaultCatalogName = commandScope.getArgumentValue(SnapshotCommandStep.DEFAULT_CATALOG_NAME_ARG); + String driver = commandScope.getArgumentValue(SnapshotCommandStep.DRIVER_ARG); + String driverPropertiesFile = commandScope.getArgumentValue(SnapshotCommandStep.DRIVER_PROPERTIES_FILE_ARG); + createDatabaseObject(url, username, password, defaultSchemaName, defaultCatalogName, driver, driverPropertiesFile); + } else { + database = commandScope.getArgumentValue(DATABASE_ARG); + } CatalogAndSchema[] schemas = parseSchemas(database, commandScope.getArgumentValue(SCHEMAS_ARG)); @@ -115,6 +159,13 @@ public void run(CommandResultsBuilder resultsBuilder) throws Exception { // Reset the quoting strategy // database.setObjectQuotingStrategy(originalQuotingStrategy); + + // + // Need to clean up here since we created the Database + // + if (commandScope.getArgumentValue(DATABASE_ARG) == null) { + closeDatabase(); + } } } @@ -124,6 +175,75 @@ private Writer getOutputWriter(final OutputStream outputStream) throws IOExcepti return new OutputStreamWriter(outputStream, charsetName); } + /** + * + * Method to create a Database object given these parameters + * + * @param url URL to connect to + * @param username Username credential + * @param password Password credential + * @param defaultSchemaName Default schema for connection + * @param defaultCatalogName Default catalog for connection + * @param driver Driver class + * @param driverPropertiesFile Additional driver properties + * @throws DatabaseException Thrown when there is a connection error + * + */ + private void createDatabaseObject(String url, + String username, + String password, + String defaultSchemaName, + String defaultCatalogName, + String driver, + String driverPropertiesFile) + throws DatabaseException { + ResourceAccessor resourceAccessor = Scope.getCurrentScope().getResourceAccessor(); + String databaseClassName = null; + Class databaseClass = LiquibaseCommandLineConfiguration.DATABASE_CLASS.getCurrentValue(); + if (databaseClass != null) { + databaseClassName = databaseClass.getCanonicalName(); + } + String propertyProviderClass = null; + Class clazz = LiquibaseCommandLineConfiguration.PROPERTY_PROVIDER_CLASS.getCurrentValue(); + if (clazz != null) { + propertyProviderClass = clazz.getName(); + } + String liquibaseCatalogName = GlobalConfiguration.LIQUIBASE_CATALOG_NAME.getCurrentValue(); + String liquibaseSchemaName = GlobalConfiguration.LIQUIBASE_SCHEMA_NAME.getCurrentValue(); + String databaseChangeLogTablespaceName = GlobalConfiguration.LIQUIBASE_TABLESPACE_NAME.getCurrentValue(); + String databaseChangeLogLockTableName = GlobalConfiguration.DATABASECHANGELOGLOCK_TABLE_NAME.getCurrentValue(); + String databaseChangeLogTableName = GlobalConfiguration.DATABASECHANGELOG_TABLE_NAME.getCurrentValue(); + database = + CommandLineUtils.createDatabaseObject(resourceAccessor, + url, + username, + password, + driver, + defaultCatalogName, + defaultSchemaName, + true, + true, + databaseClassName, + driverPropertiesFile, + propertyProviderClass, + liquibaseCatalogName, liquibaseSchemaName, + databaseChangeLogTableName, + databaseChangeLogLockTableName); + database.setLiquibaseTablespaceName(databaseChangeLogTablespaceName); + } + + private void closeDatabase() { + try { + if (database != null) { + database.rollback(); + database.close(); + } + } catch (Exception e) { + Scope.getCurrentScope().getLog(getClass()).warning( + coreBundle.getString("problem.closing.connection"), e); + } + } + private String printSnapshot(CommandScope commandScope, DatabaseSnapshot snapshot) { String format = commandScope.getArgumentValue(SNAPSHOT_FORMAT_ARG); if (format == null) { diff --git a/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java index 9666fc3c14c..620bbd5252a 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java +++ b/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java @@ -1,53 +1,52 @@ package liquibase.command.core; -import liquibase.Liquibase; -import liquibase.Scope; -import liquibase.changelog.ChangeLogHistoryService; -import liquibase.changelog.ChangeLogHistoryServiceFactory; import liquibase.command.*; -import liquibase.database.Database; -import liquibase.exception.LockException; -import liquibase.lockservice.LockService; -import liquibase.lockservice.LockServiceFactory; +import liquibase.configuration.ConfigurationValueObfuscator; +import liquibase.exception.CommandExecutionException; -public class TagCommandStep extends AbstractCommandStep { +public class TagCommandStep extends AbstractCliWrapperCommandStep { public static final String[] COMMAND_NAME = {"tag"}; + public static final CommandArgumentDefinition URL_ARG; + public static final CommandArgumentDefinition DEFAULT_SCHEMA_NAME_ARG; + public static final CommandArgumentDefinition DEFAULT_CATALOG_NAME_ARG; + public static final CommandArgumentDefinition USERNAME_ARG; + public static final CommandArgumentDefinition PASSWORD_ARG; public static final CommandArgumentDefinition TAG_ARG; - public static final CommandArgumentDefinition DATABASE_ARG; + public static final CommandArgumentDefinition DRIVER_ARG; + public static final CommandArgumentDefinition DRIVER_PROPERTIES_FILE_ARG; static { CommandBuilder builder = new CommandBuilder(COMMAND_NAME); - TAG_ARG = builder.argument("tag", String.class).required().description("Tag to add to the database changelog table").build(); - DATABASE_ARG = builder.databaseArgument().build(); + URL_ARG = builder.argument(CommonArgumentNames.URL, String.class).required() + .description("The JDBC database connection URL").build(); + DEFAULT_SCHEMA_NAME_ARG = builder.argument("defaultSchemaName", String.class) + .description("The default schema name to use for the database connection").build(); + DEFAULT_CATALOG_NAME_ARG = builder.argument("defaultCatalogName", String.class) + .description("The default catalog name to use for the database connection").build(); + DRIVER_ARG = builder.argument("driver", String.class) + .description("The JDBC driver class").build(); + DRIVER_PROPERTIES_FILE_ARG = builder.argument("driverPropertiesFile", String.class) + .description("The JDBC driver properties file").build(); + USERNAME_ARG = builder.argument(CommonArgumentNames.USERNAME, String.class) + .description("Username to use to connect to the database").build(); + PASSWORD_ARG = builder.argument(CommonArgumentNames.PASSWORD, String.class) + .description("Password to use to connect to the database") + .setValueObfuscator(ConfigurationValueObfuscator.STANDARD) + .build(); + TAG_ARG = builder.argument("tag", String.class).required() + .description("Tag to add to the database changelog table").build(); } @Override - public void run(CommandResultsBuilder resultsBuilder) throws Exception { - CommandScope commandScope = resultsBuilder.getCommandScope(); - Database database = commandScope.getArgumentValue(DATABASE_ARG); - LockService lockService = LockServiceFactory.getInstance().getLockService(database); - lockService.waitForLock(); - - try { - ChangeLogHistoryService changeLogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database); - changeLogService.generateDeploymentId(); - changeLogService.init(); - LockServiceFactory.getInstance().getLockService(database).init(); - changeLogService.tag(commandScope.getArgumentValue(TagCommandStep.TAG_ARG)); - } finally { - try { - lockService.releaseLock(); - } catch (LockException e) { - Scope.getCurrentScope().getLog(getClass()).severe(Liquibase.MSG_COULD_NOT_RELEASE_LOCK, e); - } - } + public String[][] defineCommandNames() { + return new String[][] { COMMAND_NAME }; } @Override - public String[][] defineCommandNames() { - return new String[][] { COMMAND_NAME }; + protected String[] collectArguments(CommandScope commandScope) throws CommandExecutionException { + return collectArguments(commandScope, null, "tag"); } @Override diff --git a/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java b/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java index 309d0dbf37e..e058931c9da 100644 --- a/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java @@ -158,19 +158,7 @@ public ConfiguredValue getCurrentConfiguredValue(Configurat if (foundFirstValue) { logMessage.append("Overrides "); } - - // - // Only lower case the first character is - // the first two characters are NOT uppercase. This allows provider - // strings like 'AWS' to be displayed correctly, i.e. as 'AWS', not 'aWS' - // - String describe = providedValue.describe(); - char[] chars = describe.toCharArray(); - if (chars.length >= 2 && Character.isUpperCase(chars[0]) && Character.isUpperCase(chars[1])) { - logMessage.append(describe); - } else { - logMessage.append(StringUtil.lowerCaseFirst(describe)); - } + logMessage.append(StringUtil.lowerCaseFirst(providedValue.describe())); Object value = providedValue.getValue(); if (value != null) { String finalValue = String.valueOf(value); diff --git a/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java b/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java index ccba774bd74..ae8cdf12c59 100644 --- a/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java +++ b/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java @@ -1202,7 +1202,7 @@ public int hashCode() { @Override public void close() throws DatabaseException { Scope.getCurrentScope().getSingleton(ExecutorService.class).clearExecutor("jdbc", this); - try (final DatabaseConnection connection = getConnection()) { + try (final DatabaseConnection connection = getConnection();) { if (connection != null && previousAutoCommit != null) { connection.setAutoCommit(previousAutoCommit); } diff --git a/liquibase-core/src/main/java/liquibase/database/Database.java b/liquibase-core/src/main/java/liquibase/database/Database.java index 21fc23b438c..1411b306919 100644 --- a/liquibase-core/src/main/java/liquibase/database/Database.java +++ b/liquibase-core/src/main/java/liquibase/database/Database.java @@ -176,16 +176,9 @@ public interface Database extends PrioritizedService, AutoCloseable { /** * Tags the database changelog with the given string. - * - * @deprecated Use {@link liquibase.changelog.ChangeLogHistoryService#tag(String)} instead */ - @Deprecated void tag(String tagString) throws DatabaseException; - /** - * @deprecated Use {@link liquibase.changelog.ChangeLogHistoryService#tagExists(String)} instead - */ - @Deprecated boolean doesTagExist(String tag) throws DatabaseException; boolean isSystemObject(DatabaseObject example); diff --git a/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java b/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java index ec2c8b73f71..f8f531237db 100644 --- a/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java +++ b/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java @@ -11,7 +11,6 @@ import liquibase.resource.ResourceAccessor; import liquibase.util.StringUtil; import liquibase.util.SystemUtil; -import liquibase.SingletonObject; import java.io.IOException; import java.io.InputStream; @@ -19,7 +18,7 @@ import java.sql.Driver; import java.util.*; -public class DatabaseFactory implements SingletonObject { +public class DatabaseFactory { private static final Logger LOG = Scope.getCurrentScope().getLog(DatabaseFactory.class); private static DatabaseFactory instance; private Map> implementedDatabases = new HashMap<>(); @@ -331,7 +330,7 @@ private Properties buildDriverProperties(String username, String password, Strin private static class DatabaseComparator implements Comparator { @Override public int compare(Database o1, Database o2) { - return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); + return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); } } } diff --git a/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java b/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java index 21f00b4611f..5004854cb6f 100644 --- a/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java +++ b/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java @@ -223,7 +223,6 @@ public boolean isSystemObject(DatabaseObject example) { return super.isSystemObject(example); } - @Override protected boolean mustQuoteObjectName(String objectName, Class objectType) { if (objectType.isAssignableFrom(Schema.class) || objectType.isAssignableFrom(Catalog.class)) { return true; diff --git a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java index 33c32ff8586..4ae972529f1 100644 --- a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java +++ b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java @@ -17,7 +17,7 @@ public DatabaseObjectComparatorComparator(Class object @Override public int compare(DatabaseObjectComparator o1, DatabaseObjectComparator o2) { - int result = -1 * Integer.compare(o1.getPriority(objectType, database), o2.getPriority(objectType, database)); + int result = -1 * Integer.valueOf(o1.getPriority(objectType, database)).compareTo(o2.getPriority(objectType, database)); if (result == 0) { return o1.getClass().getName().compareTo(o2.getClass().getName()); } diff --git a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java index a0f06ea5255..a5a870ece11 100644 --- a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java +++ b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java @@ -69,14 +69,6 @@ public void unregister(Class generatorClass) { unregister(toRemove); } - public DatabaseObjectComparator getComparator(Class comparatorClass, Database database) { - List comparatorsForType = getComparators(comparatorClass, database); - if (! comparatorsForType.isEmpty()) { - return comparatorsForType.get(0); - } - return null; - } - protected List getComparators(Class comparatorClass, Database database) { String key = comparatorClass.getName()+":"+database.getShortName(); if (validComparatorsByClassAndDatabase.containsKey(key)) { diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java index 65acd3789eb..5c5d2e488a4 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java @@ -17,7 +17,7 @@ public ChangeGeneratorComparator(Class objectType, Dat @Override public int compare(ChangeGenerator o1, ChangeGenerator o2) { - int result = -1 * Integer.compare(o1.getPriority(objectType, database), o2.getPriority(objectType, database)); + int result = -1 * Integer.valueOf(o1.getPriority(objectType, database)).compareTo(o2.getPriority(objectType, database)); if (result == 0) { return o1.getClass().getName().compareTo(o2.getClass().getName()); } diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java index 896ab27e087..a0e8643ccd7 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java @@ -11,7 +11,6 @@ import liquibase.diff.DiffResult; import liquibase.diff.ObjectDifferences; import liquibase.diff.compare.CompareControl; -import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.diff.output.DiffOutputControl; import liquibase.exception.DatabaseException; import liquibase.exception.UnexpectedLiquibaseException; @@ -26,17 +25,13 @@ import liquibase.snapshot.EmptyDatabaseSnapshot; import liquibase.statement.core.RawSqlStatement; import liquibase.structure.DatabaseObject; +import liquibase.structure.DatabaseObjectComparator; import liquibase.structure.core.Column; import liquibase.structure.core.StoredDatabaseLogic; -import liquibase.util.DependencyUtil; -import liquibase.util.StreamUtil; -import liquibase.util.StringUtil; +import liquibase.util.*; import javax.xml.parsers.ParserConfigurationException; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; +import java.io.*; import java.text.SimpleDateFormat; import java.util.*; @@ -256,7 +251,7 @@ public void print(final PrintStream out, final ChangeLogSerializer changeLogSeri public List generateChangeSets() { final ChangeGeneratorFactory changeGeneratorFactory = ChangeGeneratorFactory.getInstance(); - DatabaseObjectCollectionComparator comparator = new DatabaseObjectCollectionComparator(); + DatabaseObjectComparator comparator = new DatabaseObjectComparator(); String created = null; if (GlobalConfiguration.GENERATE_CHANGESET_CREATED_VALUES.getCurrentValue()) { @@ -270,9 +265,9 @@ public List generateChangeSets() { // This is to avoid changing the MissingObjectChangeGenerator API and still be able to pass the // initial DiffResult Object which can be used to check for the objects available in the database // without doing any expensive db calls. Example usage is in MissingUniqueConstraintChangeGenerator#alreadyExists() - Database comparisonDatabase = diffResult.getComparisonSnapshot().getDatabase(); - if (comparisonDatabase instanceof AbstractJdbcDatabase) { - ((AbstractJdbcDatabase) comparisonDatabase).set("diffResult", diffResult); + Database comparisionDatabase = diffResult.getComparisonSnapshot().getDatabase(); + if (comparisionDatabase instanceof AbstractJdbcDatabase) { + ((AbstractJdbcDatabase) comparisionDatabase).set("diffResult", diffResult); } for (Class type : types) { @@ -288,7 +283,7 @@ public List generateChangeSets() { types = getOrderedOutputTypes(MissingObjectChangeGenerator.class); List missingObjects = new ArrayList(); for (Class type : types) { - for (DatabaseObject object : diffResult.getMissingObjects(type, getDatabaseObjectCollectionComparator())) { + for (DatabaseObject object : diffResult.getMissingObjects(type, getDbObjectComparator())) { if (object == null) { continue; } @@ -320,8 +315,8 @@ public List generateChangeSets() { } } // remove the diffResult from the database object - if (comparisonDatabase instanceof AbstractJdbcDatabase) { - ((AbstractJdbcDatabase) comparisonDatabase).set("diffResult", null); + if (comparisionDatabase instanceof AbstractJdbcDatabase) { + ((AbstractJdbcDatabase) comparisionDatabase).set("diffResult", null); } @@ -332,8 +327,8 @@ public List generateChangeSets() { return changeSets; } - private DatabaseObjectCollectionComparator getDatabaseObjectCollectionComparator() { - return new DatabaseObjectCollectionComparator() { + private DatabaseObjectComparator getDbObjectComparator() { + return new DatabaseObjectComparator() { @Override public int compare(DatabaseObject o1, DatabaseObject o2) { if (o1 instanceof Column && o1.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null && o2.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null) { @@ -341,15 +336,15 @@ public int compare(DatabaseObject o1, DatabaseObject o2) { if (i != 0) { return i; } - } else if (o1 instanceof StoredDatabaseLogic) { - if (o1.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null && o2.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null) { - int order = o1.getAttribute(ORDER_ATTRIBUTE, Long.class).compareTo(o2.getAttribute(ORDER_ATTRIBUTE, Long.class)); - if (order != 0) { - return order; - } + } else if (o1 instanceof StoredDatabaseLogic && o1.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null + && o2.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null) { + int order = o1.getAttribute(ORDER_ATTRIBUTE, Long.class).compareTo(o2.getAttribute(ORDER_ATTRIBUTE, Long.class)); + if (order != 0) { + return order; } } return super.compare(o1, o2); + } }; } diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java index fc812b31566..48583416b90 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java @@ -53,7 +53,7 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu ResultSet rs = null; try ( Statement stmt = ((JdbcConnection) referenceDatabase.getConnection()).createStatement( - ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY) + ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); ) { Data data = (Data) missingObject; @@ -88,7 +88,7 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu OutputStream fileOutputStream = externalFileResource.openOutputStream(new OpenOptions()); OutputStreamWriter outputStreamWriter = new OutputStreamWriter( fileOutputStream, GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); - CSVWriter outputFile = new CSVWriter(new BufferedWriter(outputStreamWriter)) + CSVWriter outputFile = new CSVWriter(new BufferedWriter(outputStreamWriter)); ) { dataTypes = new String[columnNames.size()]; diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java index 4cc5913c876..a1d459c2e80 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java @@ -47,7 +47,7 @@ public Change[] fixUnexpected(DatabaseObject unexpectedObject, DiffOutputControl for (Column column : unexpectedTable.getColumns()) { control.setAlreadyHandledUnexpected(column); - } + }; control.setAlreadyHandledUnexpected(unexpectedTable.getPrimaryKey()); for (Index index : unexpectedTable.getIndexes()) { diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java index 3d0ddf23db1..008f738ef0e 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java @@ -49,7 +49,7 @@ public Change[] fixUnexpected(DatabaseObject unexpectedObject, DiffOutputControl for (Column column : view.getColumns()) { control.setAlreadyHandledUnexpected(column); - } + }; return new Change[]{change}; diff --git a/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java b/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java index ba9ea26391e..b1cbe0473a8 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java @@ -6,9 +6,9 @@ import liquibase.diff.ObjectDifferences; import liquibase.diff.StringDiff; import liquibase.diff.compare.CompareControl; -import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.exception.DatabaseException; import liquibase.structure.DatabaseObject; +import liquibase.structure.DatabaseObjectComparator; import liquibase.structure.core.Schema; import liquibase.util.StringUtil; @@ -28,7 +28,7 @@ public DiffToReport(DiffResult diffResult, PrintStream out) { } public void print() throws DatabaseException { - final DatabaseObjectCollectionComparator comparator = new DatabaseObjectCollectionComparator(); + final DatabaseObjectComparator comparator = new DatabaseObjectComparator(); out.println("Reference Database: " + diffResult.getReferenceSnapshot().getDatabase()); out.println("Comparison Database: " + diffResult.getComparisonSnapshot().getDatabase()); diff --git a/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java b/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java index cfac65995f4..b798df38e72 100644 --- a/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java +++ b/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java @@ -97,7 +97,6 @@ public void setResourceAccessor(ResourceAccessor resourceAccessor) { this.resourceAccessor = resourceAccessor; } - @Override public void setDatabase(Database database) { this.database = database; } diff --git a/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java b/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java index 7c5da66d1f9..117143aa178 100644 --- a/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java +++ b/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java @@ -10,7 +10,7 @@ public class ExecutorService extends AbstractPluginFactory { - private final Map executors = new ConcurrentHashMap<>(); + private final Map executors = new ConcurrentHashMap<>(); private ExecutorService() { } @@ -32,8 +32,8 @@ protected int getPriority(Executor executor, Object... args) { } - private Key createKey(String executorName, Database database) { - return new Key(executorName, database); + private String createKey(String executorName, Database database) { + return executorName.toLowerCase() + "#" + System.identityHashCode(database); } private Executor getExecutorValue(String executorName, Database database) throws UnexpectedLiquibaseException { @@ -117,44 +117,4 @@ public void clearExecutor(String name, Database database) { public void reset() { executors.clear(); } - - private static class Key { - private final String executorName; - private final Database database; - - Key(String executorName, Database database) { - this.executorName = normalizeExecutorName(executorName); - this.database = database; - } - - private String normalizeExecutorName(String executorName) { - return executorName.toLowerCase(); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Key key = (Key) o; - return Objects.equals(executorName, key.executorName) - && database == key.database; // equality by reference to be consistent with hashCode - } - - @Override - public int hashCode() { - return Objects.hash( - executorName, - // this class already relied on identity hash code. It bypasses e.g. AbstractJdbcDatabase's hashCode - System.identityHashCode(database) - ); - } - - @Override - public String toString() { - return "Key{" + - "executorName='" + executorName + '\'' + - ", database=" + database + - '}'; - } - } } diff --git a/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java b/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java index 08b9638f32a..cf17fc9d81c 100644 --- a/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java +++ b/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java @@ -185,7 +185,7 @@ public Object query(final SqlStatement sql, final ResultSetExtractor rse, final String finalSql = applyVisitors((RawParameterizedSqlStatement) sql, sqlVisitors); - try (PreparedStatement pstmt = factory.create(finalSql)) { + try (PreparedStatement pstmt = factory.create(finalSql);) { final List parameters = ((RawParameterizedSqlStatement) sql).getParameters(); for (int i = 0; i < parameters.size(); i++) { pstmt.setObject(i, parameters.get(0)); diff --git a/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java b/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java index bda0ab81a5a..b4b3def74e1 100644 --- a/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java +++ b/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java @@ -58,7 +58,6 @@ public Project createProject(Project project) { return new Project().setName("Project 1"); } - @Override public HubChangeLog createChangeLog(HubChangeLog hubChangeLog) throws LiquibaseException { if (randomUUID == null) { randomUUID = UUID.randomUUID(); diff --git a/liquibase-core/src/main/java/liquibase/hub/model/Connection.java b/liquibase-core/src/main/java/liquibase/hub/model/Connection.java index c9568e716a5..71d7665c4df 100644 --- a/liquibase-core/src/main/java/liquibase/hub/model/Connection.java +++ b/liquibase-core/src/main/java/liquibase/hub/model/Connection.java @@ -15,7 +15,6 @@ public class Connection implements HubModel { private Project project; - @Override public UUID getId() { return id; } diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java b/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java index aa96d2f668f..0b9f4e3a71d 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java @@ -66,7 +66,6 @@ public static Database createDatabaseObject(ClassLoader classLoader, } @SuppressWarnings("java:S2095") - @Deprecated public static Database createDatabaseObject(ResourceAccessor resourceAccessor, String url, String username, diff --git a/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java b/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java index b5e96451ccf..3c24ab8ee06 100644 --- a/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java +++ b/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java @@ -178,7 +178,6 @@ private boolean checkPreconditions(GenericServletWrapper.ServletContext servletC machine = machine.trim(); if (hostName.equalsIgnoreCase(machine)) { shouldRun = true; - break; } } } else if (machineExcludes != null) { @@ -187,7 +186,6 @@ private boolean checkPreconditions(GenericServletWrapper.ServletContext servletC machine = machine.trim(); if (hostName.equalsIgnoreCase(machine)) { shouldRun = false; - break; } } } diff --git a/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java b/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java index f174252e0ff..0b2c1c36fd2 100644 --- a/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java +++ b/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java @@ -42,7 +42,7 @@ private int read(final int lastRead, final boolean lookAhead) throws IOException if (commentSkipEnabled && (read == this.commentLineStartsWith.toCharArray()[0]) && (lastRead == '\n' || lastRead < 0)) { while ((((read = super.read())) != '\n') && (read != '\r') && (read > 0)) { - //keep looking + ;//keep looking } } diff --git a/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java b/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java index 1c4490d9447..e00bc514e9a 100644 --- a/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java +++ b/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java @@ -55,7 +55,7 @@ public LockService getLockService(Database database) { SortedSet foundServices = new TreeSet<>(new Comparator() { @Override public int compare(LockService o1, LockService o2) { - return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); + return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); } }); diff --git a/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java b/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java index 42d2718b12a..290324870da 100644 --- a/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java +++ b/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java @@ -133,8 +133,33 @@ public void init() throws DatabaseException { database.commit(); } - handleOldChangelogTableFormat(executor); - break; + if (executor.updatesDatabase() && (database instanceof DerbyDatabase) && ((DerbyDatabase) database) + .supportsBooleanDataType() || database.getClass().isAssignableFrom(DB2Database.class) && ((DB2Database) database) + .supportsBooleanDataType()) { + //check if the changelog table is of an old smallint vs. boolean format + String lockTable = database.escapeTableName( + database.getLiquibaseCatalogName(), + database.getLiquibaseSchemaName(), + database.getDatabaseChangeLogLockTableName() + ); + Object obj = executor.queryForObject( + new RawSqlStatement( + "SELECT MIN(locked) AS test FROM " + lockTable + " FETCH FIRST ROW ONLY" + ), Object.class + ); + if (!(obj instanceof Boolean)) { //wrong type, need to recreate table + executor.execute( + new DropTableStatement( + database.getLiquibaseCatalogName(), + database.getLiquibaseSchemaName(), + database.getDatabaseChangeLogLockTableName(), + false + ) + ); + executor.execute(new CreateDatabaseChangeLogLockTableStatement()); + executor.execute(new InitializeDatabaseChangeLogLockTableStatement()); + } + } } catch (Exception e) { if (i == maxIterations - 1) { throw e; @@ -154,36 +179,6 @@ public void init() throws DatabaseException { } } - private void handleOldChangelogTableFormat(Executor executor) throws DatabaseException { - if (executor.updatesDatabase() && (database instanceof DerbyDatabase) && ((DerbyDatabase) database) - .supportsBooleanDataType() || database.getClass().isAssignableFrom(DB2Database.class) && ((DB2Database) database) - .supportsBooleanDataType()) { - //check if the changelog table is of an old smallint vs. boolean format - String lockTable = database.escapeTableName( - database.getLiquibaseCatalogName(), - database.getLiquibaseSchemaName(), - database.getDatabaseChangeLogLockTableName() - ); - Object obj = executor.queryForObject( - new RawSqlStatement( - "SELECT MIN(locked) AS test FROM " + lockTable + " FETCH FIRST ROW ONLY" - ), Object.class - ); - if (!(obj instanceof Boolean)) { //wrong type, need to recreate table - executor.execute( - new DropTableStatement( - database.getLiquibaseCatalogName(), - database.getLiquibaseSchemaName(), - database.getDatabaseChangeLogLockTableName(), - false - ) - ); - executor.execute(new CreateDatabaseChangeLogLockTableStatement()); - executor.execute(new InitializeDatabaseChangeLogLockTableStatement()); - } - } - } - public boolean isDatabaseChangeLogLockTableInitialized(final boolean tableJustCreated) { return isDatabaseChangeLogLockTableInitialized(tableJustCreated, false); } diff --git a/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java b/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java index 75e49459bf0..8c8d69dfe91 100644 --- a/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java +++ b/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java @@ -82,7 +82,7 @@ public void unregister(NamespaceDetails namespaceDetails) { private class SerializerNamespaceDetailsComparator implements Comparator { @Override public int compare(NamespaceDetails o1, NamespaceDetails o2) { - return Integer.compare(o2.getPriority(), o1.getPriority()); + return Integer.valueOf(o2.getPriority()).compareTo(o1.getPriority()); } } } diff --git a/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java b/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java index c70dbc8c8ed..019171783d3 100644 --- a/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java +++ b/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java @@ -41,7 +41,7 @@ private SnapshotParserFactory() { snapshotParserComparator = new Comparator() { @Override public int compare(SnapshotParser o1, SnapshotParser o2) { - return Integer.compare(o2.getPriority(), o1.getPriority()); + return Integer.valueOf(o2.getPriority()).compareTo(o1.getPriority()); } }; diff --git a/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java b/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java index 32c7822d2fe..711564aa579 100644 --- a/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java +++ b/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java @@ -11,7 +11,6 @@ public class DirectoryPathHandler extends AbstractPathHandler { /** * Returns {@link #PRIORITY_DEFAULT} for all paths except for ones that are for a non-"file:" protocol. */ - @Override public int getPriority(String root) { if (root == null) { return PRIORITY_NOT_APPLICABLE; @@ -28,7 +27,6 @@ public int getPriority(String root) { } } - @Override public ResourceAccessor getResourceAccessor(String root) throws FileNotFoundException { root = root .replace("file:", "") diff --git a/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java b/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java index 0f10edea1ec..f93c133fe3f 100644 --- a/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java +++ b/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java @@ -17,7 +17,6 @@ public class ZipPathHandler extends AbstractPathHandler { /** * Returns {@link #PRIORITY_SPECIALIZED} for all "jar:file:" or files that end in ".jar" or ".zip" */ - @Override public int getPriority(String root) { if (root == null) { return PRIORITY_NOT_APPLICABLE; @@ -34,7 +33,6 @@ public int getPriority(String root) { return PRIORITY_NOT_APPLICABLE; } - @Override public ResourceAccessor getResourceAccessor(String root) throws FileNotFoundException { root = root.replace("jar:", "").replace("!/", ""); diff --git a/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java b/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java index 2fcf966c58a..b5b5f6e989a 100644 --- a/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java +++ b/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java @@ -27,7 +27,6 @@ public Resource resolve(String other) { return new MockResource(resolvePath(other), "Resource relative to " + getPath()); } - @Override public Resource resolveSibling(String other) { return new MockResource(resolveSiblingPath(other), "Sibling resource to " + getPath()); } diff --git a/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java b/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java index 1c9d13ad420..8d4fbb8f204 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java +++ b/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java @@ -18,7 +18,6 @@ public abstract class AbstractLiquibaseSerializable implements LiquibaseSerializ private Set serializableFields; - @Override public void load(ParsedNode parsedNode, ResourceAccessor resourceAccessor) throws ParsedNodeException { for (ParsedNode childNode : parsedNode.getChildren()) { if (!shouldAutoLoad(childNode)) { diff --git a/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java b/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java index 0784409a4c6..0da76d05069 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java +++ b/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java @@ -56,7 +56,11 @@ public ChangeLogSerializer getSerializer(String fileNameOrExtension) { public void register(ChangeLogSerializer changeLogSerializer) { for (String extension : changeLogSerializer.getValidFileExtensions()) { - List changeLogSerializers = serializers.computeIfAbsent(extension, k -> new ArrayList<>()); + List changeLogSerializers = serializers.get(extension); + if (changeLogSerializers == null) { + changeLogSerializers = new ArrayList<>(); + serializers.put(extension, changeLogSerializers); + } changeLogSerializers.add(changeLogSerializer); Collections.sort(changeLogSerializers, PrioritizedService.COMPARATOR); } diff --git a/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java b/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java index f2ef1b02937..1c8b9c3db81 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java +++ b/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java @@ -56,7 +56,11 @@ public SnapshotSerializer getSerializer(String fileNameOrExtension) { public void register(SnapshotSerializer snapshotSerializer) { for (String extension : snapshotSerializer.getValidFileExtensions()) { - List snapshotSerializers = serializers.computeIfAbsent(extension, k -> new ArrayList<>()); + List snapshotSerializers = serializers.get(extension); + if (snapshotSerializers == null) { + snapshotSerializers = new ArrayList<>(); + serializers.put(extension, snapshotSerializers); + } snapshotSerializers.add(snapshotSerializer); Collections.sort(snapshotSerializers, PrioritizedService.COMPARATOR); } diff --git a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java index 9eade3550ec..52d6b980510 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java +++ b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java @@ -11,7 +11,6 @@ public class YamlChangeLogSerializer extends YamlSerializer implements ChangeLogSerializer { - @Override protected Comparator getComparator(LiquibaseSerializable object) { if (object instanceof ChangeSet) { return new ChangeSetComparator(); diff --git a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java index e13da1a9ba6..2772da4137b 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java +++ b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java @@ -1,7 +1,6 @@ package liquibase.serializer.core.yaml; import liquibase.GlobalConfiguration; -import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.serializer.LiquibaseSerializable; import liquibase.serializer.SnapshotSerializer; @@ -11,6 +10,7 @@ import liquibase.statement.SequenceNextValueFunction; import liquibase.structure.DatabaseObject; import liquibase.structure.DatabaseObjectCollection; +import liquibase.structure.DatabaseObjectComparator; import liquibase.structure.core.Column; import liquibase.util.ISODateFormat; import liquibase.util.StringUtil; @@ -86,7 +86,7 @@ protected Object toMap(final LiquibaseSerializable object) { SortedMap returnMap = new TreeMap<>(); for (Map.Entry, Set> entry : ((DatabaseObjectCollection) object).toMap().entrySet()) { ArrayList value = new ArrayList(entry.getValue()); - Collections.sort(value, new DatabaseObjectCollectionComparator()); + Collections.sort(value, new DatabaseObjectComparator()); returnMap.put(entry.getKey().getName(), value); } return returnMap; @@ -94,7 +94,6 @@ protected Object toMap(final LiquibaseSerializable object) { return super.toMap(object); } - @Override protected LiquibaseRepresenter getLiquibaseRepresenter() { return new SnapshotLiquibaseRepresenter(); } @@ -106,7 +105,6 @@ public int getPriority() { public static class SnapshotLiquibaseRepresenter extends LiquibaseRepresenter { - @Override protected void init() { multiRepresenters.put(DatabaseFunction.class, new TypeStoringAsStringRepresenter()); multiRepresenters.put(SequenceNextValueFunction.class, new TypeStoringAsStringRepresenter()); diff --git a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java index 1ff02078d25..864f893a06b 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java @@ -312,7 +312,11 @@ protected T include(T example) throws DatabaseExcepti T object = chain.snapshot(example, this); if (object == null) { - Set collection = knownNull.computeIfAbsent(example.getClass(), k -> new HashSet<>()); + Set collection = knownNull.get(example.getClass()); + if (collection == null) { + collection = new HashSet<>(); + knownNull.put(example.getClass(), collection); + } collection.add(example); if (example instanceof Schema) { diff --git a/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java b/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java index 796f3b2a3fa..4ff868b2e40 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java @@ -31,7 +31,11 @@ public List get(ResultSetExtractor resultSetExtractor) throws Databas String schemaKey = resultSetExtractor.wantedKeyParameters().createSchemaKey(resultSetExtractor.database); - Map> cache = cacheBySchema.computeIfAbsent(schemaKey, k -> new HashMap<>()); + Map> cache = cacheBySchema.get(schemaKey); + if (cache == null) { + cache = new HashMap<>(); + cacheBySchema.put(schemaKey, cache); + } if (cache.containsKey(wantedKey)) { return cache.get(wantedKey); @@ -74,7 +78,11 @@ public List get(ResultSetExtractor resultSetExtractor) throws Databas String rowSchema = CatalogAndSchema.CatalogAndSchemaCase.ORIGINAL_CASE. equals(resultSetExtractor.database.getSchemaAndCatalogCase())?resultSetExtractor.getSchemaKey(row): resultSetExtractor.getSchemaKey(row).toLowerCase(); - cache = cacheBySchema.computeIfAbsent(rowSchema, k -> new HashMap>()); + cache = cacheBySchema.get(rowSchema); + if (cache == null) { + cache = new HashMap>(); + cacheBySchema.put(rowSchema, cache); + } } if (!cache.containsKey(rowKey)) { cache.put(rowKey, new ArrayList()); diff --git a/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java b/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java index f93db624dc1..8ab85d2886f 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java @@ -17,7 +17,7 @@ public SnapshotGeneratorComparator(Class objectType, D @Override public int compare(SnapshotGenerator o1, SnapshotGenerator o2) { - int result = -1 * Integer.compare(o1.getPriority(objectType, database), o2.getPriority(objectType, database)); + int result = -1 * Integer.valueOf(o1.getPriority(objectType, database)).compareTo(o2.getPriority(objectType, database)); if (result == 0) { return o1.getClass().getName().compareTo(o2.getClass().getName()); } diff --git a/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java b/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java index 3b8036f15b0..abfc2bbaa33 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java @@ -406,7 +406,11 @@ protected List listConstraints(Table table, DatabaseSnapshot snapshot snapshot.setScratchData(cacheKey, columnCache); for (Map row : rows) { String key = getCacheKey(row, database); - List> constraintRows = columnCache.computeIfAbsent(key, k -> new ArrayList<>()); + List> constraintRows = columnCache.get(key); + if (constraintRows == null) { + constraintRows = new ArrayList<>(); + columnCache.put(key, constraintRows); + } constraintRows.add(row); } diff --git a/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java b/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java index eec78fd6ef2..2ea3bcfda2e 100644 --- a/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java +++ b/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java @@ -66,12 +66,10 @@ public void setContextFilter(ContextExpression contextFilter) { this.contextFilter = contextFilter; } - @Override public Labels getLabels() { return labels; } - @Override public void setLabels(Labels labels) { this.labels = labels; } diff --git a/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java b/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java index 470abbba3fa..78404151796 100644 --- a/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java +++ b/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java @@ -5,6 +5,6 @@ class SqlGeneratorComparator implements Comparator { @Override public int compare(SqlGenerator o1, SqlGenerator o2) { - return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); + return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); } } diff --git a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java index 1d319c325cc..ab946c9969c 100644 --- a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java +++ b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java @@ -66,7 +66,7 @@ public Sql[] generateSql(AddPrimaryKeyStatement statement, Database database, Sq if (database instanceof MSSQLDatabase) { sql += " ON "+statement.getTablespace(); } else if ((database instanceof AbstractDb2Database) || (database instanceof SybaseASADatabase)) { - //not supported + ; //not supported } else { sql += " USING INDEX TABLESPACE "+statement.getTablespace(); } diff --git a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java index 9a0c179a1df..bb7d53a9958 100644 --- a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java +++ b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java @@ -83,7 +83,7 @@ public Sql[] generateSql(AddUniqueConstraintStatement statement, Database databa sql += " ON " + statement.getTablespace(); } else if ((database instanceof AbstractDb2Database) || (database instanceof SybaseASADatabase) || (database instanceof InformixDatabase)) { - //not supported + ; //not supported } else if (database instanceof OracleDatabase) { /* * In Oracle, you can use only exactly one of these clauses: diff --git a/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java b/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java index 364d9670495..dae92c362b9 100644 --- a/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java +++ b/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java @@ -2,7 +2,6 @@ import liquibase.database.Database; import liquibase.diff.compare.CompareControl; -import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.diff.compare.DatabaseObjectComparatorFactory; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.parser.core.ParsedNode; @@ -49,7 +48,7 @@ public Set getSerializableFields() { @Override public Object getSerializableFieldValue(String field) { - SortedSet objects = new TreeSet<>(new DatabaseObjectCollectionComparator()); + SortedSet objects = new TreeSet<>(new DatabaseObjectComparator()); try { Map> map = cache.get(Class.forName(field)); if (map == null) { @@ -73,12 +72,20 @@ public void add(DatabaseObject databaseObject) { if (databaseObject == null) { return; } - Map> collectionMap = cache.computeIfAbsent(databaseObject.getClass(), k -> new HashMap<>()); + Map> collectionMap = cache.get(databaseObject.getClass()); + if (collectionMap == null) { + collectionMap = new HashMap<>(); + cache.put(databaseObject.getClass(), collectionMap); + } String[] hashes = DatabaseObjectComparatorFactory.getInstance().hash(databaseObject, null, database); for (String hash : hashes) { - Set collection = collectionMap.computeIfAbsent(hash, k -> new HashSet<>()); + Set collection = collectionMap.get(hash); + if (collection == null) { + collection = new HashSet<>(); + collectionMap.put(hash, collection); + } collection.add(databaseObject); } } diff --git a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectCollectionComparator.java b/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectComparator.java similarity index 83% rename from liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectCollectionComparator.java rename to liquibase-core/src/main/java/liquibase/structure/DatabaseObjectComparator.java index 4df96019a2b..d5624c4324b 100644 --- a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectCollectionComparator.java +++ b/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectComparator.java @@ -1,12 +1,11 @@ -package liquibase.diff.compare; +package liquibase.structure; -import liquibase.structure.DatabaseObject; import liquibase.structure.core.Schema; import liquibase.util.StringUtil; import java.util.Comparator; -public class DatabaseObjectCollectionComparator implements Comparator { +public class DatabaseObjectComparator implements Comparator { @Override public int compare(DatabaseObject o1, DatabaseObject o2) { @@ -18,6 +17,7 @@ public int compare(DatabaseObject o1, DatabaseObject o2) { if (i != 0) { return i; } + } String name1 = StringUtil.trimToEmpty(o1.getName()); diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java b/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java index d95e93ae578..ddd3ac84ec8 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java @@ -71,7 +71,11 @@ public void addDatabaseObject(DatabaseObject databaseObject) { if (databaseObject == null) { return; } - Set objects = this.getObjects().computeIfAbsent(databaseObject.getClass(), k -> new HashSet<>()); + Set objects = this.getObjects().get(databaseObject.getClass()); + if (objects == null) { + objects = new HashSet<>(); + this.getObjects().put(databaseObject.getClass(), objects); + } objects.add(databaseObject); } diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Relation.java b/liquibase-core/src/main/java/liquibase/structure/core/Relation.java index de5819eeafb..eb93416255b 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Relation.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Relation.java @@ -101,7 +101,6 @@ public Relation setSchema(String catalog, String schema) { return setSchema(new Schema(catalog, schema)); } - @Override public int compareTo(Object o) { Relation that = (Relation) o; int returnValue = 0; diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Schema.java b/liquibase-core/src/main/java/liquibase/structure/core/Schema.java index 4208bf340b4..0cf0b506706 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Schema.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Schema.java @@ -138,7 +138,11 @@ public void addDatabaseObject(DatabaseObject databaseObject) { if (databaseObject == null) { return; } - Set objects = this.getObjects().computeIfAbsent(databaseObject.getClass(), k -> new HashSet<>()); + Set objects = this.getObjects().get(databaseObject.getClass()); + if (objects == null) { + objects = new HashSet<>(); + this.getObjects().put(databaseObject.getClass(), objects); + } objects.add(databaseObject); } diff --git a/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java b/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java index 965211ae731..136c1efdee0 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java @@ -1,6 +1,5 @@ package liquibase.structure.core; -import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.license.LicenseServiceUtils; import liquibase.structure.AbstractDatabaseObject; import liquibase.structure.DatabaseObject; @@ -58,10 +57,6 @@ public T setBody(String body) { return (T) this; } - public DatabaseObjectCollectionComparator getDbObjectComparator() { - return null; - } - @Override public boolean equals(Object obj) { if (this == obj) return true; diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Table.java b/liquibase-core/src/main/java/liquibase/structure/core/Table.java index 88dfd75dc5b..4309c577228 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Table.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Table.java @@ -38,12 +38,10 @@ public List getOutgoingForeignKeys() { return ((fkList == null) ? new ArrayList(0) : fkList); } - @Override public List getIndexes() { return getAttribute("indexes", List.class); } - @Override public List getUniqueConstraints() { return getAttribute("uniqueConstraints", List.class); } diff --git a/liquibase-core/src/main/java/liquibase/util/FileUtil.java b/liquibase-core/src/main/java/liquibase/util/FileUtil.java index c7419a05015..3cd117443dc 100644 --- a/liquibase-core/src/main/java/liquibase/util/FileUtil.java +++ b/liquibase-core/src/main/java/liquibase/util/FileUtil.java @@ -16,7 +16,7 @@ public static String getContents(File file) throws IOException { return null; } try ( - FileInputStream fileInputStream = new FileInputStream(file) + FileInputStream fileInputStream = new FileInputStream(file); ) { return StreamUtil.readStreamAsString(fileInputStream); diff --git a/liquibase-core/src/main/java/liquibase/util/MD5Util.java b/liquibase-core/src/main/java/liquibase/util/MD5Util.java index 548aacb8ebb..4d55aaccc47 100644 --- a/liquibase-core/src/main/java/liquibase/util/MD5Util.java +++ b/liquibase-core/src/main/java/liquibase/util/MD5Util.java @@ -57,7 +57,7 @@ public static String computeMD5(InputStream stream) { DigestInputStream digestStream = new DigestInputStream(stream, digest); byte[] buf = new byte[20480]; while (digestStream.read(buf) != -1) { - //digest is updating + ; //digest is updating } } catch (Exception e) { throw new RuntimeException(e); diff --git a/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java b/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java index 00baa0e34b2..b0a7f561e1d 100644 --- a/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java +++ b/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java @@ -242,7 +242,13 @@ private static Method getWriteMethod(Object object, String propertyName) { * @return a list of methods belonging to the class of the object */ private static Method[] getMethods(Object object) { - return methodCache.computeIfAbsent(object.getClass(), k -> object.getClass().getMethods()); + Method[] methods = methodCache.get(object.getClass()); + + if (methods == null) { + methods = object.getClass().getMethods(); + methodCache.put(object.getClass(), methods); + } + return methods; } /** diff --git a/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java b/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java index ac3df5637d3..5fa21d699c2 100644 --- a/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java +++ b/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java @@ -23,7 +23,6 @@ public void writeNext(String[] nextLine) { delegate.writeNext(nextLine); } - @Override public void flush() throws IOException { delegate.flush(); } diff --git a/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java b/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java index 18ea509f7f8..d22ec135524 100644 --- a/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java +++ b/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java @@ -23,7 +23,7 @@ public void write(Document doc, OutputStream outputStream) throws IOException { try { factory.setAttribute("indent-number", 4); } catch (Exception e) { - //guess we can't set it, that's ok + ; //guess we can't set it, that's ok } Transformer transformer = factory.newTransformer(); diff --git a/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep b/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep index 6bbab0ad936..bbe41212c38 100644 --- a/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep +++ b/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep @@ -5,7 +5,6 @@ liquibase.command.core.ChangelogSyncToTagCommandStep liquibase.command.core.ChangelogSyncToTagSqlCommandStep liquibase.command.core.ClearChecksumsCommandStep liquibase.command.core.DbDocCommandStep -liquibase.command.core.DbUrlConnectionCommandStep liquibase.command.core.DeactivateChangelogCommandStep liquibase.command.core.DiffChangelogCommandStep liquibase.command.core.DiffCommandStep diff --git a/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java b/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java index e31d94a071b..520933c7a8d 100644 --- a/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java +++ b/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java @@ -9,12 +9,10 @@ public class MockCommandStep extends AbstractCommandStep { public static MockCommandStep logic; - public static final String[] COMMAND_NAME = {"mock"}; - public static final CommandArgumentDefinition VALUE_1_ARG; static { - CommandBuilder builder = new CommandBuilder(COMMAND_NAME); + CommandBuilder builder = new CommandBuilder(new String[]{"mock"}); VALUE_1_ARG = builder.argument("value1", String.class) .description("Value 1").build(); @@ -29,7 +27,7 @@ public static void reset() { @Override public String[][] defineCommandNames() { - return new String[][]{COMMAND_NAME}; + return new String[][]{new String[] {"mock"}}; } @Override diff --git a/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java b/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java index acda488299c..460b4c39b93 100644 --- a/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java +++ b/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java @@ -227,7 +227,7 @@ public void extraParamsIsValidSql() throws Exception { Collections.sort(paramLists, new Comparator>() { @Override public int compare(List o1, List o2) { - int comp = Integer.compare(o1.size(), o2.size()); + int comp = Integer.valueOf(o1.size()).compareTo(o2.size()); if (comp == 0) { comp = StringUtil.join(o1,",").compareTo(StringUtil.join(o2, ",")); } diff --git a/liquibase-dist/pom.xml b/liquibase-dist/pom.xml index 19071669dcc..a53aff2c7cf 100644 --- a/liquibase-dist/pom.xml +++ b/liquibase-dist/pom.xml @@ -20,7 +20,7 @@ 11.2.1.jre8 8.0.21 3.1.0 - 21.8.0.0 + 21.7.0.0 3.40.0.0 11.5.8.0 4.0.8.java8 @@ -76,7 +76,7 @@ net.snowflake snowflake-jdbc - 3.13.26 + 3.13.25 diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt deleted file mode 100644 index 10adb95aea8..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt +++ /dev/null @@ -1,182 +0,0 @@ -SOFTWARE LICENSE SUBSCRIPTION AND SUPPORT AGREEMENT - -PLEASE READ THIS AGREEMENT CAREFULLY BEFORE USING THIS SERVICE. - -BY USING THE SOFTWARE OR CLICKING AGREE, CUSTOMER IS AGREEING TO BE BOUND BY -THIS AGREEMENT. IF YOU ARE AGREEING TO THIS AGREEMENT ON BEHALF OF OR FOR THE -BENEFIT OF YOUR EMPLOYER OR A THIRD PARTY, THEN YOU REPRESENT AND WARRANT THAT -YOU HAVE THE NECESSARY AUTHORITY TO AGREE TO THIS AGREEMENT ON YOUR EMPLOYER'S -OR THAT THIRD PARTY'S BEHALF. - -This agreement is between Liquibase, Inc. a Delaware corporation (Liquibase) and -you, the customer entering into this agreement (Customer). The LiquibasePro -software, updates, documentation and license keys provided to Customer -(Software) are licensed and are not sold. - -SCOPE. This agreement describes the licensing of the Software and support -provided to Customer under an order. Third party contractors and majority owned -affiliates of Customer can use and access the Software under the terms of this -agreement, and Customer is responsible for each of their compliance with such -terms. - -1. LICENSE. Subject to the other terms of this agreement, Liquibase grants -Customer, under an order, a term based non-exclusive, non-transferable license -up to the license capacity purchased to use the Software only in Customer’s -internal business operations. Third party licenses delivered with the Software -may be subject to additional license rights and restrictions a set forth at -https://www.liquibase.com/licenses/liquibase_pro_tpl.html. - -2. RESTRICTIONS. Customer may not: -a. Transfer, assign, sublicense, rent the Software, create derivative works of -the Software, or use it in any type of service provider environment; -b. Reverse engineer, decompile, disassemble, or translate the Software; or -c. Evaluate the Software for the purpose of competing with Liquibase Pro or -operate the Software other than in accordance with its technical documentation. - -3. PROPRIETARY RIGHTS AND MUTUAL CONFIDENTIALITY. -a. Proprietary Rights. The Software, workflow processes, user interface, -designs and other technologies provided by Liquibase as part of the Software are -the proprietary property of Liquibase and its licensors, and all right, title and -interest in and to such items, including all associated intellectual property -rights, remain only with Liquibase and its licensors. The Software is protected -by copyright and other intellectual property laws. Customer may not remove any -product identification, copyright, trademark or other notice from the Software. -Liquibase reserves all rights not expressly granted. -b. Mutual Confidentiality. Recipient may not disclose Confidential Information -of Discloser to any third party or use the Confidential Information in -violation of this agreement. -Confidential Information means all information that is disclosed to the -recipient (Recipient) by the discloser (Discloser), and includes, among other -things: - * any and all information relating to products or services provided by a -Discloser, software code, flow charts, techniques, specifications, development -and marketing plans, strategies, and forecasts; - * as to Liquibase, the Software and the terms of this agreement, including -without limitation, all pricing information. -Confidential Information excludes information that: - * was rightfully in Recipient's possession without any obligation of -confidentiality before receipt from the Discloser; - * is or becomes a matter of public knowledge through no fault of Recipient; - * is rightfully received by Recipient from a third party without violation of -a duty of confidentiality; or - * is independently developed by or for Recipient without use or access to the -Confidential Information. - -Recipient may disclose Confidential Information if required by law, but it will -attempt to provide notice to the Discloser in advance so it may seek a -protective order. Each party acknowledges that any misuse of the other party’s -Confidential Information may cause irreparable harm for which there is no -adequate remedy at law. Either party may seek immediate injunctive relief in -such event. - -4. WARRANTY, REMEDY and DISCLAIMER. For new license purchases, Liquibase warrants -that the Software will perform in substantial accordance with its accompanying -technical documentation for a period of 60 days from the date of the order. -This warranty will not apply to any problems caused by software not licensed to -Customer by Liquibase, use other than in accordance with the technical -documentation, or misuse of the Software. The warranty only covers problems -reported to Liquibase during the warranty period or 30 days after. Customer will -cooperate with Liquibase in resolving any warranty claim. -A. EXCLUSIVE REMEDY AND SOLE LIABILITY. Liquibase will use commercially -reasonable efforts to remedy covered warranty claims within a reasonable period -of time or replace the Software, or if Liquibase cannot do so it will refund to -Customer the license fee paid. THIS REMEDY IS CUSTOMER’S EXCLUSIVE REMEDY, AND -LIQUIBASE’S SOLE LIABILITY FOR THESE WARRANTY CLAIMS. -B. DISCLAIMER OF WARRANTIES. LIQUIBASE DISCLAIMS ALL OTHER EXPRESS AND IMPLIED -WARRANTIES, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTY OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. CUSTOMER UNDERSTANDS THAT -THE SOFTWARE MAY NOT BE ERROR FREE, AND USE MAY BE INTERRUPTED. - -5. TERMINATION. This agreement expires at the end of the license period -specified. Either party may terminate this agreement upon a material breach of -the other party after a 30 days’ notice/cure period, if the breach is not cured -during such time period. Upon terminationof this agreement or a license, -Customer must discontinue using the Software, de-install and destroy or return -the Software and all copies, within 5 days. Upon Liquibase's request, Customer -will provide written certification of such compliance. - -6. SUPPORT. Liquibase’s technical support and maintenance services (Support) is -included with the license fees. Customer will receive best efforts e-mail -response for support within two business days from receipt of issue. Liquibase -may change its Support terms, but Support will not materially degrade during -any Support term. - -7. LIMIT ON LIABILITY. There may be situations in which (as a result of -material breach or other liability) Customer is entitled to make a claim -against Liquibase. In each situation (regardless of the form of the legal action -(e.g. contract or tort claims)), Liquibase is not responsible for any damage and -does not have any liability beyond the greater of the amount paid or payable by -Customer to Liquibase within the 12 months prior to the event that gave rise to -the claim and in no event is Liquibase responsible for any: loss of data or -information; lost profits, revenue, or productivity; or other special, -consequential, incidental or indirect damages. - -8. INTELLECTUAL PROPERTY INDEMNITY -a. Defense of Third Party Claims. Liquibase will defend or settle any third party -claim against Customer to the extent that such claim alleges that the Software -violates a copyright, patent, trademark or other intellectual property right, -if Customer, promptly notifies Liquibase of the claim in writing, cooperates with -Liquibase in the defense, and allows Liquibase to solely control the defense or -settlement of the claim. Costs. Liquibase will pay infringement claim defense -costs incurred as part of its obligations above, and Liquibase negotiated -settlement amounts, and court awarded damages. Process. If such a claim appears -likely, then Liquibase may modify the Software, procure the necessary rights, or -replace it with the functional equivalent. If Liquibase determines that none of -these are reasonably available, then Liquibase may terminate the Software and -refund any prepaid and unused fees. Exclusions. Liquibase has no obligation for -any claim arising from: Liquibase’s compliance with Customer’s specifications; A -combination of the Software with other technology where the infringement would -not occur but for the combination; or Technology not provided by Liquibase. THIS -SECTION CONTAINS CUSTOMER’S EXCLUSIVE REMEDIES AND LIQUIBASE’S SOLE LIABILITY FOR -INTELLECTUAL PROPERTY INFRINGEMENT CLAIMS. - -9. GOVERNING LAW AND EXCLUSIVE FORUM. This agreement is governed by the laws of -the State of Delaware (without regard to conflicts of law principles) for any -dispute between the parties or relating in any way to the subject matter of -this agreement. Any suit or legal proceeding must be exclusively brought in the -federal or state courts for Travis County, Texas, and Customer submits to this -personal jurisdiction and venue. Nothing in this agreement prevents either -party from seeking injunctive relief in a court of competent jurisdiction. The -prevailing party in litigation is entitled to recover its attorneys’ fees and -costs from the other party. - -10. OTHER TERMS. -a. Entire Agreement. This agreement and the order constitute the entire -agreement between the parties and supersede any prior or contemporaneous -negotiations or agreements, whether oral or written, related to this subject -matter. Customer is not relying on any representation concerning this subject -matter, oral or written, not included in this agreement. No representation, -promise or inducement not included in this agreement is binding. -b. Non-Assignment. Neither party may assign or transfer this agreement to a -third party, nor delegate any duty, except that the agreement and all orders -may be assigned, without the consent of the other party, as part of a merger, -or sale of all or substantially all of the business or assets, of a party. -c. Independent Contractors. The parties are independent contractors with -respect to each other. -d. Enforceability. If any term of this agreement is invalid or unenforceable, -the other terms remain in effect. -e. Survival of Terms and Force Majeure. All terms that by their nature survive -termination of this agreement for each party to receive the benefits and -protections of this agreement, will survive. Neither party is liable for events -beyond its reasonable control, including, without limitation force majeure -events. -f. Modification Only in Writing. No modification or waiver of any term of this -agreement is effective unless signed by both parties. -g. Export Compliance. Customer must comply with all applicable export control -laws of the United States, foreign jurisdictions and other applicable laws and -regulations. -h. US GOVERNMENT RESTRICTED RIGHTS. If Customer is a United States government -agency or acquired the license to the Software hereunder pursuant to a -government contract or with government funds, then as defined in FAR §2.101, -DFAR §252.227-7014(a)(1) and DFAR §252.227-7014(a)(5) or otherwise, all -Software provided in connection with this agreement are “commercial items,” -“commercial computer software” or “commercial computer software documentation.” -Consistent with DFAR §227.7202 and FAR §12.212, any use, modification, -reproduction, release, performance, display, disclosure or distribution by or -for the United States government is governed solely by the terms of this -agreement and is prohibited except to the extent permitted by the terms of this -agreement. -i. No PO Terms. Liquibase rejects conflicting terms of a Customer’s -form-purchasing document. -j. Order of Precedence. If there is an inconsistency between this agreement and -an order, the order prevails. diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt deleted file mode 100644 index 76cff2883af..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt +++ /dev/null @@ -1,22 +0,0 @@ -Liquibase License Information (Used by Liquibase AWS Secrets Manager Extension) -Version: ${project.version} - -Liquibase ships with 3rd party components using the following licenses: -- Apache 2.0 License - https://www.apache.org/licenses/LICENSE-2.0.txt -- MIT License - http://www.opensource.org/licenses/mit-license.php -- Liquibase Pro EULA Software License Subscription and Support Agreement - -Libraries and their licenses: - -Apache 2.0 License -- org.liquibase:liquibase-core -- software.amazon.awssdk:secretsmanager -- software.amazon.awssdk:ssm -- com.google.code.gson:gjson - -MIT License -- org.slf4j:slf4j-api -- org.slf4j:slf4j-jdk14 - -Liquibase Pro EULA Software License Subscription and Support Agreement -- org.liquibase:liquibase-commercial diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt deleted file mode 100644 index 8e77af12431..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt +++ /dev/null @@ -1,65 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt deleted file mode 100644 index fe45399e37a..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt +++ /dev/null @@ -1,6 +0,0 @@ -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt deleted file mode 100644 index 10adb95aea8..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt +++ /dev/null @@ -1,182 +0,0 @@ -SOFTWARE LICENSE SUBSCRIPTION AND SUPPORT AGREEMENT - -PLEASE READ THIS AGREEMENT CAREFULLY BEFORE USING THIS SERVICE. - -BY USING THE SOFTWARE OR CLICKING AGREE, CUSTOMER IS AGREEING TO BE BOUND BY -THIS AGREEMENT. IF YOU ARE AGREEING TO THIS AGREEMENT ON BEHALF OF OR FOR THE -BENEFIT OF YOUR EMPLOYER OR A THIRD PARTY, THEN YOU REPRESENT AND WARRANT THAT -YOU HAVE THE NECESSARY AUTHORITY TO AGREE TO THIS AGREEMENT ON YOUR EMPLOYER'S -OR THAT THIRD PARTY'S BEHALF. - -This agreement is between Liquibase, Inc. a Delaware corporation (Liquibase) and -you, the customer entering into this agreement (Customer). The LiquibasePro -software, updates, documentation and license keys provided to Customer -(Software) are licensed and are not sold. - -SCOPE. This agreement describes the licensing of the Software and support -provided to Customer under an order. Third party contractors and majority owned -affiliates of Customer can use and access the Software under the terms of this -agreement, and Customer is responsible for each of their compliance with such -terms. - -1. LICENSE. Subject to the other terms of this agreement, Liquibase grants -Customer, under an order, a term based non-exclusive, non-transferable license -up to the license capacity purchased to use the Software only in Customer’s -internal business operations. Third party licenses delivered with the Software -may be subject to additional license rights and restrictions a set forth at -https://www.liquibase.com/licenses/liquibase_pro_tpl.html. - -2. RESTRICTIONS. Customer may not: -a. Transfer, assign, sublicense, rent the Software, create derivative works of -the Software, or use it in any type of service provider environment; -b. Reverse engineer, decompile, disassemble, or translate the Software; or -c. Evaluate the Software for the purpose of competing with Liquibase Pro or -operate the Software other than in accordance with its technical documentation. - -3. PROPRIETARY RIGHTS AND MUTUAL CONFIDENTIALITY. -a. Proprietary Rights. The Software, workflow processes, user interface, -designs and other technologies provided by Liquibase as part of the Software are -the proprietary property of Liquibase and its licensors, and all right, title and -interest in and to such items, including all associated intellectual property -rights, remain only with Liquibase and its licensors. The Software is protected -by copyright and other intellectual property laws. Customer may not remove any -product identification, copyright, trademark or other notice from the Software. -Liquibase reserves all rights not expressly granted. -b. Mutual Confidentiality. Recipient may not disclose Confidential Information -of Discloser to any third party or use the Confidential Information in -violation of this agreement. -Confidential Information means all information that is disclosed to the -recipient (Recipient) by the discloser (Discloser), and includes, among other -things: - * any and all information relating to products or services provided by a -Discloser, software code, flow charts, techniques, specifications, development -and marketing plans, strategies, and forecasts; - * as to Liquibase, the Software and the terms of this agreement, including -without limitation, all pricing information. -Confidential Information excludes information that: - * was rightfully in Recipient's possession without any obligation of -confidentiality before receipt from the Discloser; - * is or becomes a matter of public knowledge through no fault of Recipient; - * is rightfully received by Recipient from a third party without violation of -a duty of confidentiality; or - * is independently developed by or for Recipient without use or access to the -Confidential Information. - -Recipient may disclose Confidential Information if required by law, but it will -attempt to provide notice to the Discloser in advance so it may seek a -protective order. Each party acknowledges that any misuse of the other party’s -Confidential Information may cause irreparable harm for which there is no -adequate remedy at law. Either party may seek immediate injunctive relief in -such event. - -4. WARRANTY, REMEDY and DISCLAIMER. For new license purchases, Liquibase warrants -that the Software will perform in substantial accordance with its accompanying -technical documentation for a period of 60 days from the date of the order. -This warranty will not apply to any problems caused by software not licensed to -Customer by Liquibase, use other than in accordance with the technical -documentation, or misuse of the Software. The warranty only covers problems -reported to Liquibase during the warranty period or 30 days after. Customer will -cooperate with Liquibase in resolving any warranty claim. -A. EXCLUSIVE REMEDY AND SOLE LIABILITY. Liquibase will use commercially -reasonable efforts to remedy covered warranty claims within a reasonable period -of time or replace the Software, or if Liquibase cannot do so it will refund to -Customer the license fee paid. THIS REMEDY IS CUSTOMER’S EXCLUSIVE REMEDY, AND -LIQUIBASE’S SOLE LIABILITY FOR THESE WARRANTY CLAIMS. -B. DISCLAIMER OF WARRANTIES. LIQUIBASE DISCLAIMS ALL OTHER EXPRESS AND IMPLIED -WARRANTIES, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTY OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. CUSTOMER UNDERSTANDS THAT -THE SOFTWARE MAY NOT BE ERROR FREE, AND USE MAY BE INTERRUPTED. - -5. TERMINATION. This agreement expires at the end of the license period -specified. Either party may terminate this agreement upon a material breach of -the other party after a 30 days’ notice/cure period, if the breach is not cured -during such time period. Upon terminationof this agreement or a license, -Customer must discontinue using the Software, de-install and destroy or return -the Software and all copies, within 5 days. Upon Liquibase's request, Customer -will provide written certification of such compliance. - -6. SUPPORT. Liquibase’s technical support and maintenance services (Support) is -included with the license fees. Customer will receive best efforts e-mail -response for support within two business days from receipt of issue. Liquibase -may change its Support terms, but Support will not materially degrade during -any Support term. - -7. LIMIT ON LIABILITY. There may be situations in which (as a result of -material breach or other liability) Customer is entitled to make a claim -against Liquibase. In each situation (regardless of the form of the legal action -(e.g. contract or tort claims)), Liquibase is not responsible for any damage and -does not have any liability beyond the greater of the amount paid or payable by -Customer to Liquibase within the 12 months prior to the event that gave rise to -the claim and in no event is Liquibase responsible for any: loss of data or -information; lost profits, revenue, or productivity; or other special, -consequential, incidental or indirect damages. - -8. INTELLECTUAL PROPERTY INDEMNITY -a. Defense of Third Party Claims. Liquibase will defend or settle any third party -claim against Customer to the extent that such claim alleges that the Software -violates a copyright, patent, trademark or other intellectual property right, -if Customer, promptly notifies Liquibase of the claim in writing, cooperates with -Liquibase in the defense, and allows Liquibase to solely control the defense or -settlement of the claim. Costs. Liquibase will pay infringement claim defense -costs incurred as part of its obligations above, and Liquibase negotiated -settlement amounts, and court awarded damages. Process. If such a claim appears -likely, then Liquibase may modify the Software, procure the necessary rights, or -replace it with the functional equivalent. If Liquibase determines that none of -these are reasonably available, then Liquibase may terminate the Software and -refund any prepaid and unused fees. Exclusions. Liquibase has no obligation for -any claim arising from: Liquibase’s compliance with Customer’s specifications; A -combination of the Software with other technology where the infringement would -not occur but for the combination; or Technology not provided by Liquibase. THIS -SECTION CONTAINS CUSTOMER’S EXCLUSIVE REMEDIES AND LIQUIBASE’S SOLE LIABILITY FOR -INTELLECTUAL PROPERTY INFRINGEMENT CLAIMS. - -9. GOVERNING LAW AND EXCLUSIVE FORUM. This agreement is governed by the laws of -the State of Delaware (without regard to conflicts of law principles) for any -dispute between the parties or relating in any way to the subject matter of -this agreement. Any suit or legal proceeding must be exclusively brought in the -federal or state courts for Travis County, Texas, and Customer submits to this -personal jurisdiction and venue. Nothing in this agreement prevents either -party from seeking injunctive relief in a court of competent jurisdiction. The -prevailing party in litigation is entitled to recover its attorneys’ fees and -costs from the other party. - -10. OTHER TERMS. -a. Entire Agreement. This agreement and the order constitute the entire -agreement between the parties and supersede any prior or contemporaneous -negotiations or agreements, whether oral or written, related to this subject -matter. Customer is not relying on any representation concerning this subject -matter, oral or written, not included in this agreement. No representation, -promise or inducement not included in this agreement is binding. -b. Non-Assignment. Neither party may assign or transfer this agreement to a -third party, nor delegate any duty, except that the agreement and all orders -may be assigned, without the consent of the other party, as part of a merger, -or sale of all or substantially all of the business or assets, of a party. -c. Independent Contractors. The parties are independent contractors with -respect to each other. -d. Enforceability. If any term of this agreement is invalid or unenforceable, -the other terms remain in effect. -e. Survival of Terms and Force Majeure. All terms that by their nature survive -termination of this agreement for each party to receive the benefits and -protections of this agreement, will survive. Neither party is liable for events -beyond its reasonable control, including, without limitation force majeure -events. -f. Modification Only in Writing. No modification or waiver of any term of this -agreement is effective unless signed by both parties. -g. Export Compliance. Customer must comply with all applicable export control -laws of the United States, foreign jurisdictions and other applicable laws and -regulations. -h. US GOVERNMENT RESTRICTED RIGHTS. If Customer is a United States government -agency or acquired the license to the Software hereunder pursuant to a -government contract or with government funds, then as defined in FAR §2.101, -DFAR §252.227-7014(a)(1) and DFAR §252.227-7014(a)(5) or otherwise, all -Software provided in connection with this agreement are “commercial items,” -“commercial computer software” or “commercial computer software documentation.” -Consistent with DFAR §227.7202 and FAR §12.212, any use, modification, -reproduction, release, performance, display, disclosure or distribution by or -for the United States government is governed solely by the terms of this -agreement and is prohibited except to the extent permitted by the terms of this -agreement. -i. No PO Terms. Liquibase rejects conflicting terms of a Customer’s -form-purchasing document. -j. Order of Precedence. If there is an inconsistency between this agreement and -an order, the order prevails. diff --git a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt deleted file mode 100644 index 255dcf61cff..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt +++ /dev/null @@ -1,16 +0,0 @@ -Liquibase License Information (Used by Liquibase Hashicorp Vault Extension) -Version: ${project.version} - -Liquibase ships with 3rd party components using the following licenses: -- Apache 2.0 License - https://www.apache.org/licenses/LICENSE-2.0.txt -- Liquibase Pro EULA Software License Subscription and Support Agreement - -Libraries and their licenses: - -Apache 2.0 License -- org.liquibase:liquibase-core -- org.apache.httpcomponents:httpclient -- com.google.code.gson:gjson - -Liquibase Pro EULA Software License Subscription and Support Agreement -- org.liquibase:liquibase-commercial diff --git a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt deleted file mode 100644 index 8e77af12431..00000000000 --- a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt +++ /dev/null @@ -1,65 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. diff --git a/liquibase-dist/src/main/install4j/liquibase.install4j b/liquibase-dist/src/main/install4j/liquibase.install4j index 2c75a356bf1..b7751d6c10e 100644 --- a/liquibase-dist/src/main/install4j/liquibase.install4j +++ b/liquibase-dist/src/main/install4j/liquibase.install4j @@ -16,7 +16,7 @@ sqlite-* - + diff --git a/liquibase-extension-testing/pom.xml b/liquibase-extension-testing/pom.xml index 1069d1bee25..4967b860617 100644 --- a/liquibase-extension-testing/pom.xml +++ b/liquibase-extension-testing/pom.xml @@ -67,7 +67,7 @@ org.slf4j slf4j-jdk14 - 2.0.6 + 2.0.4 diff --git a/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy b/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy index f4c1b1d4f43..d00ccfda2dc 100644 --- a/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy +++ b/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy @@ -257,6 +257,7 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"} outputStream = new FileOutputStream(testDef.outputFile) } + commandScope.addArgumentValue("database", database) commandScope.setOutput(outputStream) if (testDef.setup != null) { diff --git a/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy b/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy index 07836192e8c..8d518db1670 100644 --- a/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy +++ b/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy @@ -34,6 +34,10 @@ Optional Args: password: { it.password }, tag: "version_2.0" ] + + expectedResults = [ + statusCode : 0 + ] } run "Run without a tag should throw an exception", { diff --git a/liquibase-maven-plugin/pom.xml b/liquibase-maven-plugin/pom.xml index e7c817126cc..df52feead2a 100644 --- a/liquibase-maven-plugin/pom.xml +++ b/liquibase-maven-plugin/pom.xml @@ -14,7 +14,7 @@ A Maven plugin wraps up some of the functionality of Liquibase - 3.8.7 + 3.8.5 diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java index 837cc473486..c55027db438 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java @@ -84,8 +84,8 @@ protected Liquibase createLiquibase(Database db) + migrationSqlOutputFile.getAbsolutePath()); } } - outputWriter = getOutputWriter(migrationSqlOutputFile); - } catch (IOException e) { + outputWriter = getOutputWriter(migrationSqlOutputFile);; + } catch (IOException e) { getLog().error(e); throw new MojoExecutionException( "Failed to create SQL output writer", e); diff --git a/pom.xml b/pom.xml index 1060da385ad..b8aaf95dca6 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.mockito mockito-inline - 4.10.0 + 4.8.1 test @@ -215,7 +215,7 @@ com.oracle.database.jdbc ojdbc8 - 21.8.0.0 + 21.7.0.0 test @@ -229,13 +229,13 @@ net.snowflake snowflake-jdbc - 3.13.26 + 3.13.25 org.firebirdsql.jdbc jaybird - 4.0.8.java8 + 4.0.6.java8 test From 12f65395db094819833d035af8606ff4e36e62f1 Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 13:16:03 -0500 Subject: [PATCH 21/28] Revert "Merge remote-tracking branch 'origin/DAT-12727' into DAT-12602" This reverts commit 8554e29120310c29bace0cd6e4c744af6a898262, reversing changes made to 10d540b62515d06efe9f1ec1985b093afb0566ec. --- .../command/CommandArgumentDefinition.java | 3 +-- .../LiquibaseCommandLineConfiguration.java | 21 +++---------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java index a46d3c1e0f3..1fb2c6b0c07 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java @@ -7,7 +7,6 @@ import liquibase.exception.MissingRequiredArgumentException; import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; import liquibase.util.ObjectUtil; -import liquibase.util.StringUtil; import java.util.*; import java.util.regex.Pattern; @@ -275,7 +274,7 @@ public CommandArgumentDefinition build() throws IllegalArgumentExcepti Scope.getCurrentScope().getSingleton(CommandFactory.class).register(commandName, newCommandArgument); } catch (IllegalArgumentException iae) { Scope.getCurrentScope().getLog(CommandArgumentDefinition.class).warning( - "Unable to register command '" + StringUtil.join(commandName, " ") + "' argument '" + newCommandArgument.getName() + "': " + iae.getMessage()); + "Unable to register command '" + commandName + "' argument '" + newCommandArgument.getName() + "': " + iae.getMessage()); throw iae; } } diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java index f0f8e921fa1..2efa34d1191 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java @@ -4,9 +4,7 @@ import liquibase.configuration.ConfigurationDefinition; import liquibase.configuration.ConfigurationValueConverter; import liquibase.logging.LogFormat; -import liquibase.util.StringUtil; -import java.util.Arrays; import java.util.logging.Level; /** @@ -84,23 +82,10 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio .build(); LOG_FORMAT = builder.define("logFormat", LogFormat.class) - .setDescription("Sets the format of log output to console or log files. " + - "Open Source users default to unstructured \"TEXT\" logs to the console or output log files." + - "Pro users have option to set value as \"JSON\" to enable json-structured log files to the console or output log files.") + .setDescription("Set the format of log output to console or log files\n" + + "[OSS] Defaults to \"TEXT\" logs to the console or output log files\n" + + "[PRO] Can be set to \"JSON\" to enable json-structured log files to the console or output log files") .setDefaultValue(LogFormat.TEXT) - .setValueHandler((logFormat) -> { - if (logFormat == null) { - return null; - } - - String logFormatString = (String) logFormat; - - if (Arrays.stream(LogFormat.values()).noneMatch(lf -> lf.toString().equalsIgnoreCase(logFormatString))) { - throw new IllegalArgumentException("WARNING: The log format value '"+logFormatString+"' is not valid. Valid values include: '" + StringUtil.join(LogFormat.values(), "', '", Object::toString) + "'"); - } - - return Enum.valueOf(LogFormat.class, logFormatString.toUpperCase()); - }) .build(); } From ddfe3f3eb6031d1c13b8337fdb35326571158a7a Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 13:22:06 -0500 Subject: [PATCH 22/28] Revert "Revert "Merge remote-tracking branch 'origin/DAT-11693' into DAT-12602"" This reverts commit 10d540b62515d06efe9f1ec1985b093afb0566ec. --- .github/util/package-install4j.sh | 20 +- .github/workflows/create-release.yml | 12 +- .github/workflows/installer-build-check.yml | 4 +- .github/workflows/release-published.yml | 4 +- .../cdi/SchemesCDIConfigBuilder.java | 3 +- liquibase-core/pom.xml | 2 +- .../liquibase/AbstractExtensibleObject.java | 3 + .../src/main/java/liquibase/Liquibase.java | 30 +-- .../change/core/CreateProcedureChange.java | 2 + .../change/core/DropColumnChange.java | 1 + .../liquibase/change/core/LoadDataChange.java | 1 + .../AbstractChangeLogHistoryService.java | 5 + .../ChangeLogHistoryServiceFactory.java | 2 +- .../OfflineChangeLogHistoryService.java | 8 +- .../StandardChangeLogHistoryService.java | 2 + .../filter/IgnoreChangeSetFilter.java | 1 + .../liquibase/command/CleanUpCommandStep.java | 14 ++ .../command/CommandArgumentDefinition.java | 30 ++- .../liquibase/command/CommandBuilder.java | 17 ++ .../liquibase/command/CommandFactory.java | 28 ++- .../java/liquibase/command/CommandScope.java | 8 + .../core/CalculateChecksumCommandStep.java | 1 + .../core/DbUrlConnectionCommandStep.java | 219 ++++++++++++++++++ .../command/core/DiffToChangeLogCommand.java | 2 + .../command/core/SnapshotCommandStep.java | 134 +---------- .../command/core/TagCommandStep.java | 65 +++--- .../configuration/LiquibaseConfiguration.java | 14 +- .../database/AbstractJdbcDatabase.java | 2 +- .../java/liquibase/database/Database.java | 7 + .../liquibase/database/DatabaseFactory.java | 5 +- .../database/core/AbstractDb2Database.java | 1 + .../DatabaseObjectCollectionComparator.java} | 6 +- .../DatabaseObjectComparatorComparator.java | 2 +- .../DatabaseObjectComparatorFactory.java | 8 + .../changelog/ChangeGeneratorComparator.java | 2 +- .../output/changelog/DiffToChangeLog.java | 41 ++-- ...issingDataExternalFileChangeGenerator.java | 4 +- .../core/UnexpectedTableChangeGenerator.java | 2 +- .../core/UnexpectedViewChangeGenerator.java | 2 +- .../diff/output/report/DiffToReport.java | 4 +- .../liquibase/executor/AbstractExecutor.java | 1 + .../liquibase/executor/ExecutorService.java | 46 +++- .../liquibase/executor/jvm/JdbcExecutor.java | 2 +- .../liquibase/hub/core/MockHubService.java | 1 + .../java/liquibase/hub/model/Connection.java | 1 + .../commandline/CommandLineUtils.java | 1 + .../servlet/GenericServletListener.java | 2 + ...mptyLineAndCommentSkippingInputStream.java | 2 +- .../lockservice/LockServiceFactory.java | 2 +- .../lockservice/StandardLockService.java | 59 ++--- .../parser/NamespaceDetailsFactory.java | 2 +- .../parser/SnapshotParserFactory.java | 2 +- .../resource/DirectoryPathHandler.java | 2 + .../liquibase/resource/ZipPathHandler.java | 2 + .../liquibase/sdk/resource/MockResource.java | 1 + .../AbstractLiquibaseSerializable.java | 1 + .../ChangeLogSerializerFactory.java | 6 +- .../serializer/SnapshotSerializerFactory.java | 6 +- .../core/yaml/YamlChangeLogSerializer.java | 1 + .../core/yaml/YamlSnapshotSerializer.java | 6 +- .../liquibase/snapshot/DatabaseSnapshot.java | 6 +- .../liquibase/snapshot/ResultSetCache.java | 12 +- .../snapshot/SnapshotGeneratorComparator.java | 2 +- .../UniqueConstraintSnapshotGenerator.java | 6 +- .../sql/visitor/AbstractSqlVisitor.java | 2 + .../sqlgenerator/SqlGeneratorComparator.java | 2 +- .../core/AddPrimaryKeyGenerator.java | 2 +- .../core/AddUniqueConstraintGenerator.java | 2 +- .../structure/DatabaseObjectCollection.java | 15 +- .../liquibase/structure/core/Catalog.java | 6 +- .../liquibase/structure/core/Relation.java | 1 + .../java/liquibase/structure/core/Schema.java | 6 +- .../structure/core/StoredDatabaseLogic.java | 5 + .../java/liquibase/structure/core/Table.java | 2 + .../main/java/liquibase/util/FileUtil.java | 2 +- .../src/main/java/liquibase/util/MD5Util.java | 2 +- .../main/java/liquibase/util/ObjectUtil.java | 8 +- .../java/liquibase/util/csv/CSVWriter.java | 1 + .../liquibase/util/xml/DefaultXmlWriter.java | 2 +- .../services/liquibase.command.CommandStep | 1 + .../command/core/MockCommandStep.java | 6 +- .../change/VerifyChangeClassesTest.java | 2 +- liquibase-dist/pom.xml | 4 +- ...nse Subscription and Support Agreement.txt | 182 +++++++++++++++ .../aws-secrets-manager-extension/README.txt | 22 ++ .../apache-2.0.txt | 65 ++++++ .../aws-secrets-manager-extension/mit.txt | 6 + ...nse Subscription and Support Agreement.txt | 182 +++++++++++++++ .../hashicorp-vault-extension/README.txt | 16 ++ .../hashicorp-vault-extension/apache-2.0.txt | 65 ++++++ .../src/main/install4j/liquibase.install4j | 2 +- liquibase-extension-testing/pom.xml | 2 +- .../testing/command/CommandTests.groovy | 1 - .../extension/testing/command/tag.test.groovy | 4 - liquibase-maven-plugin/pom.xml | 2 +- .../LiquibaseChangeLogSyncToTagSQLMojo.java | 4 +- pom.xml | 8 +- 97 files changed, 1151 insertions(+), 371 deletions(-) create mode 100644 liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java create mode 100644 liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java rename liquibase-core/src/main/java/liquibase/{structure/DatabaseObjectComparator.java => diff/compare/DatabaseObjectCollectionComparator.java} (83%) create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt create mode 100644 liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt diff --git a/.github/util/package-install4j.sh b/.github/util/package-install4j.sh index 9142ffb258a..5271a0cb13d 100755 --- a/.github/util/package-install4j.sh +++ b/.github/util/package-install4j.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash ################################################################### -## This script creates the installer files given an unziped directory +## This script creates the installer files given an unzipped directory ################################################################### set -e @@ -13,14 +13,14 @@ if [ -z ${1+x} ]; then fi version=$1 -if [ -z ${INSTALL4J_LICENSE+x} ]; then - echo "INSTALL4J_LICENSE must be set"; +if [ -z ${INSTALL4J_10_LICENSE+x} ]; then + echo "INSTALL4J_10_LICENSE must be set"; exit 1 fi -mkdir -p ~/.install4j8 -export INSTALL4J_CACHE=$HOME/.install4j8 +mkdir -p ~/.install4j10 +export INSTALL4J_CACHE=$HOME/.install4j10 # install4jc="/usr/local/bin/install4jc" install4jc="/Applications/install4j.app/Contents/Resources/app/bin/install4jc" @@ -31,13 +31,13 @@ else echo "$install4jc does not exist. Installing..." # installer automation for ubuntu-latest; replaced - # wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download-gcdn.ej-technologies.com/install4j/install4j_linux_8_0_11.deb - # sudo apt install -y $INSTALL4J_CACHE/install4j_linux_8_0_11.deb + # wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download.ej-technologies.com/install4j/install4j_linux-x64_10_0_4.deb + # sudo apt install -y $INSTALL4J_CACHE/install4j_linux-x64_10_0_4.deb # installer automation for macos-latest; macos needed for apple notarizing - wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download-gcdn.ej-technologies.com/install4j/install4j_macos_8_0_11.dmg + wget -nv --directory-prefix=$INSTALL4J_CACHE -nc https://download.ej-technologies.com/install4j/install4j_macos_10_0_4.dmg sleep 5 - hdiutil attach /Users/runner/.install4j8/install4j_macos_8_0_11.dmg + hdiutil attach /Users/runner/.install4j10/install4j_macos_10_0_4.dmg sleep 5 cp -rf /Volumes/install4j/install4j.app /Applications sleep 5 @@ -54,6 +54,6 @@ else INSTALL4J_ARGS="$INSTALL4J_ARGS --win-keystore-password=$INSTALL4J_WINDOWS_KEY_PASSWORD --mac-keystore-password=$INSTALL4J_APPLE_KEY_PASSWORD --apple-id=$INSTALL4J_APPLE_ID --apple-id-password=$INSTALL4J_APPLE_ID_PASSWORD" fi -"$install4jc" --license=$INSTALL4J_LICENSE +"$install4jc" --license=$INSTALL4J_10_LICENSE "$install4jc" $INSTALL4J_ARGS src/main/install4j/liquibase.install4j diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 71c4b73751b..81014769072 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -8,7 +8,9 @@ on: branch: description: 'Branch to release (Defaults to master)' required: false - + runId: + description: 'RunId of liquibase/liquibase artifacts to attach' + required: true jobs: setup: name: Setup @@ -16,6 +18,7 @@ jobs: outputs: version: ${{ steps.collect-data.outputs.version }} branch: ${{ steps.collect-data.outputs.branch }} + runId: ${{ steps.collect-data.outputs.runId }} steps: - name: Collect Data id: collect-data @@ -24,9 +27,9 @@ jobs: script: | core.setOutput("version", context.payload.inputs.version); core.setOutput("branch", context.payload.inputs.branch || "master"); - + core.setOutput("runId", context.payload.inputs.runId); - run: | - echo "Creating version ${{ steps.collect-data.outputs.version }} from ${{ steps.collect-data.outputs.branch }}" + echo "Creating version ${{ steps.collect-data.outputs.version }} from ${{ steps.collect-data.outputs.branch }} with artifacts from build ${{ steps.collect-data.outputs.runId }} " reversion: needs: [ setup ] @@ -48,8 +51,7 @@ jobs: uses: liquibase/action-download-artifact@v2-liquibase with: workflow: build.yml - workflow_conclusion: success - branch: ${{ needs.setup.outputs.branch }} + run_id: ${{ needs.setup.outputs.runId }} name: liquibase-artifacts path: download/liquibase-artifacts diff --git a/.github/workflows/installer-build-check.yml b/.github/workflows/installer-build-check.yml index bff2eb2486f..15a96a83384 100644 --- a/.github/workflows/installer-build-check.yml +++ b/.github/workflows/installer-build-check.yml @@ -29,7 +29,7 @@ jobs: - name: Set up JDK for GPG uses: actions/setup-java@v3 with: - java-version: '8' + java-version: '17' distribution: 'temurin' gpg-private-key: ${{ secrets.GPG_SECRET }} gpg-passphrase: GPG_PASSPHRASE @@ -38,7 +38,7 @@ jobs: - name: Re-version Installers env: - INSTALL4J_LICENSE: ${{ secrets.INSTALL4J_LICENSE }} + INSTALL4J_10_LICENSE: ${{ secrets.INSTALL4J_10_LICENSE }} INSTALL4J_APPLE_KEY: ${{ secrets.INSTALL4J_APPLE_KEY }} INSTALL4J_APPLE_KEY_PASSWORD: ${{ secrets.INSTALL4J_APPLE_KEY_PASSWORD }} INSTALL4J_APPLE_ID: ${{ secrets.INSTALL4J_APPLE_ID }} diff --git a/.github/workflows/release-published.yml b/.github/workflows/release-published.yml index 5837a9b824e..df5b9171d4a 100644 --- a/.github/workflows/release-published.yml +++ b/.github/workflows/release-published.yml @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-20.04 steps: - name: Download release assets - uses: robinraju/release-downloader@v1.6 + uses: robinraju/release-downloader@v1.7 with: repository: "liquibase/liquibase" tag: "${{ needs.setup.outputs.tag }}" @@ -175,7 +175,7 @@ jobs: contents: read steps: - name: Download release javadocs - uses: robinraju/release-downloader@v1.6 + uses: robinraju/release-downloader@v1.7 with: repository: "liquibase/liquibase" tag: "${{ needs.setup.outputs.tag }}" diff --git a/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java b/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java index d1812c15ae2..57b36d2c29a 100644 --- a/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java +++ b/liquibase-cdi/src/main/java/liquibase/integration/cdi/SchemesCDIConfigBuilder.java @@ -68,6 +68,7 @@ public CDILiquibaseConfig createCDILiquibaseConfig() { final InputStream is = SchemesCDIConfigBuilder.class.getResourceAsStream(SCHEMA_NAME); try { return jvmLocked(id, new Callable() { + @Override public CDILiquibaseConfig call() throws Exception { return createCDILiquibaseConfig(id, is); } @@ -190,7 +191,7 @@ CDILiquibaseConfig fileLocked(final String id, Callable acti FileLock lock = null; try ( FileOutputStream fileStream = new FileOutputStream(lockPath); - FileChannel fileChannel = fileStream.getChannel(); + FileChannel fileChannel = fileStream.getChannel() ) { while (null == lock) { diff --git a/liquibase-core/pom.xml b/liquibase-core/pom.xml index 617d20da735..d9be3e5a89e 100644 --- a/liquibase-core/pom.xml +++ b/liquibase-core/pom.xml @@ -115,7 +115,7 @@ org.junit.jupiter junit-jupiter-params - 5.8.1 + 5.9.1 test diff --git a/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java b/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java index ab835ca342b..b78607615ab 100644 --- a/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java +++ b/liquibase-core/src/main/java/liquibase/AbstractExtensibleObject.java @@ -70,6 +70,7 @@ public ObjectMetaData getObjectMetaData() { /** * Return true if the given key is defined. */ + @Override public boolean has(String key) { return get(key, Object.class) != null; } @@ -119,6 +120,7 @@ protected T get(String attribute, T defaultValue, Class type) { } } + @Override public List getValuePath(String attributes, Class lastType) { List path = new ArrayList(); @@ -230,6 +232,7 @@ public ExtensibleObject set(String attribute, Object value) { return this; } + @Override public String describe() { String name = getClass().getSimpleName(); return name + "{" + StringUtil.join(this, ", ", new StringUtil.DefaultFormatter()) + "}"; diff --git a/liquibase-core/src/main/java/liquibase/Liquibase.java b/liquibase-core/src/main/java/liquibase/Liquibase.java index b4febcfe2ad..dea8a3b749e 100644 --- a/liquibase-core/src/main/java/liquibase/Liquibase.java +++ b/liquibase-core/src/main/java/liquibase/Liquibase.java @@ -6,7 +6,9 @@ import liquibase.changelog.filter.*; import liquibase.changelog.visitor.*; import liquibase.command.CommandScope; +import liquibase.command.core.DbUrlConnectionCommandStep; import liquibase.command.core.InternalDropAllCommandStep; +import liquibase.command.core.TagCommandStep; import liquibase.database.Database; import liquibase.database.DatabaseConnection; import liquibase.database.DatabaseFactory; @@ -1893,30 +1895,14 @@ public final void dropAll(CatalogAndSchema... schemas) throws DatabaseException /** * 'Tags' the database for future rollback + * + * @deprecated Use {link {@link CommandScope(String)} to tag instead of this method. */ public void tag(String tagString) throws LiquibaseException { - runInScope(new Scope.ScopedRunner() { - @Override - public void run() throws Exception { - - LockService lockService = LockServiceFactory.getInstance().getLockService(database); - lockService.waitForLock(); - - try { - ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database).generateDeploymentId(); - - checkLiquibaseTables(false, null, new Contexts(), - new LabelExpression()); - getDatabase().tag(tagString); - } finally { - try { - lockService.releaseLock(); - } catch (LockException e) { - LOG.severe(MSG_COULD_NOT_RELEASE_LOCK, e); - } - } - } - }); + new CommandScope("tag") + .addArgumentValue(DbUrlConnectionCommandStep.DATABASE_ARG, database) + .addArgumentValue(TagCommandStep.TAG_ARG, tagString) + .execute(); } public boolean tagExists(String tagString) throws LiquibaseException { diff --git a/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java b/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java index 2aafe1d704a..9f715223819 100644 --- a/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java +++ b/liquibase-core/src/main/java/liquibase/change/core/CreateProcedureChange.java @@ -141,6 +141,7 @@ public void setProcedureText(String procedureText) { this.procedureText = procedureText; } + @Override @DatabaseChangeProperty( exampleValue = "h2, oracle", since = "3.1" @@ -149,6 +150,7 @@ public String getDbms() { return dbms; } + @Override public void setDbms(final String dbms) { this.dbms = dbms; } diff --git a/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java b/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java index 2d0ed45f2e6..db60a6518df 100644 --- a/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java +++ b/liquibase-core/src/main/java/liquibase/change/core/DropColumnChange.java @@ -211,6 +211,7 @@ public boolean createThisIndex(Index index) { for (Column column : index.getColumns()) { if (removedColumnNames.contains(column.getName())) { indexContainsColumn = true; + break; } } return !indexContainsColumn; diff --git a/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java b/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java index 319e7cea853..228ad715f42 100644 --- a/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java +++ b/liquibase-core/src/main/java/liquibase/change/core/LoadDataChange.java @@ -121,6 +121,7 @@ public boolean generateRollbackStatementsVolatile(Database database) { return true; } + @Override @DatabaseChangeProperty(description = "Name of the table to insert data into", requiredForDatabase = ALL, mustEqualExisting = "table") public String getTableName() { diff --git a/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java b/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java index bdc0f0090c5..232166d8926 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java +++ b/liquibase-core/src/main/java/liquibase/changelog/AbstractChangeLogHistoryService.java @@ -31,6 +31,7 @@ public void reset() { } + @Override public ChangeSet.RunStatus getRunStatus(final ChangeSet changeSet) throws DatabaseException, DatabaseHistoryException { RanChangeSet foundRan = getRanChangeSet(changeSet); @@ -61,6 +62,7 @@ public ChangeSet.RunStatus getRunStatus(final ChangeSet changeSet) } } + @Override public void upgradeChecksums(final DatabaseChangeLog databaseChangeLog, final Contexts contexts, LabelExpression labels) throws DatabaseException { for (RanChangeSet ranChangeSet : this.getRanChangeSets()) { @@ -118,14 +120,17 @@ public String getLastDeploymentId() throws DatabaseException { protected abstract void replaceChecksum(ChangeSet changeSet) throws DatabaseException; + @Override public String getDeploymentId() { return this.deploymentId; } + @Override public void resetDeploymentId() { this.deploymentId = null; } + @Override public void generateDeploymentId() { if (this.deploymentId == null) { String dateString = String.valueOf(new Date().getTime()); diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java index 424ad2a0abf..78b81920d30 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeLogHistoryServiceFactory.java @@ -56,7 +56,7 @@ public ChangeLogHistoryService getChangeLogService(Database database) { SortedSet foundServices = new TreeSet<>(new Comparator() { @Override public int compare(ChangeLogHistoryService o1, ChangeLogHistoryService o2) { - return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); + return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); } }); diff --git a/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java b/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java index 14afe04cc9c..7f436697990 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java +++ b/liquibase-core/src/main/java/liquibase/changelog/OfflineChangeLogHistoryService.java @@ -151,7 +151,7 @@ public String[] execute(String[] line) { @Override public List getRanChangeSets() throws DatabaseException { try ( - Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); + Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()) ) { CSVReader csvReader = new CSVReader(reader); @@ -210,7 +210,7 @@ protected void replaceChangeSet(ChangeSet changeSet, ReplaceChangeSetLogic repla Reader reader = new InputStreamReader(new FileInputStream(oldFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); Writer writer = new OutputStreamWriter(new FileOutputStream(newFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); CSVReader csvReader = new CSVReader(reader); - CSVWriter csvWriter = new CSVWriter(writer); + CSVWriter csvWriter = new CSVWriter(writer) ) { String[] line; @@ -238,7 +238,7 @@ protected void appendChangeSet(ChangeSet changeSet, ChangeSet.ExecType execType) Reader reader = new InputStreamReader(new FileInputStream(oldFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); Writer writer = new OutputStreamWriter(new FileOutputStream(newFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); CSVReader csvReader = new CSVReader(reader); - CSVWriter csvWriter = new CSVWriter(writer); + CSVWriter csvWriter = new CSVWriter(writer) ) { String[] line; @@ -327,7 +327,7 @@ public int getNextSequenceValue() throws LiquibaseException { lastChangeSetSequenceValue = 0; try ( - Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); + Reader reader = new InputStreamReader(new FileInputStream(this.changeLogFile), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()) ) { diff --git a/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java b/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java index b4648d3a866..4326825fb88 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java +++ b/liquibase-core/src/main/java/liquibase/changelog/StandardChangeLogHistoryService.java @@ -98,6 +98,7 @@ protected String getCharTypeName() { return "varchar"; } + @Override public void init() throws DatabaseException { if (serviceInitialized) { return; @@ -304,6 +305,7 @@ public void upgradeChecksums(final DatabaseChangeLog databaseChangeLog, final Co /** * Returns the ChangeSets that have been run against the current getDatabase(). */ + @Override public List getRanChangeSets() throws DatabaseException { if (this.ranChangeSetList == null) { Database database = getDatabase(); diff --git a/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java b/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java index 8d5de72665a..b77e291be9c 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java +++ b/liquibase-core/src/main/java/liquibase/changelog/filter/IgnoreChangeSetFilter.java @@ -3,6 +3,7 @@ import liquibase.changelog.ChangeSet; public class IgnoreChangeSetFilter implements ChangeSetFilter { + @Override public ChangeSetFilterResult accepts(ChangeSet changeSet) { if (changeSet.isIgnore()) { return new ChangeSetFilterResult(false, "Changeset is ignored", this.getClass()); diff --git a/liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java b/liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java new file mode 100644 index 00000000000..6f7424e9214 --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/command/CleanUpCommandStep.java @@ -0,0 +1,14 @@ +package liquibase.command; + +/** + * Interface implemented by CommandSteps when they need to execute clean up tasks (such as closing database + * connections, flushing files, etc) after other steps in the pipeline are executed. + */ +public interface CleanUpCommandStep { + + /** + * Method invoked to execute the cleanup action. + * @param resultsBuilder builder used in this pipeline + */ + void cleanUp(CommandResultsBuilder resultsBuilder); +} diff --git a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java index 1fb2c6b0c07..7b979811452 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java @@ -8,7 +8,10 @@ import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; import liquibase.util.ObjectUtil; -import java.util.*; +import java.util.Collections; +import java.util.Objects; +import java.util.SortedSet; +import java.util.TreeSet; import java.util.regex.Pattern; /** @@ -26,7 +29,6 @@ public class CommandArgumentDefinition implements Comparable aliases = new TreeSet<>(); private final Class dataType; - private String description; private boolean required; private boolean hidden; @@ -34,6 +36,7 @@ public class CommandArgumentDefinition implements Comparable valueConverter; private ConfigurationValueObfuscator valueObfuscator; + private CommandArgumentDefinition supersededBy; protected CommandArgumentDefinition(String name, Class type) { this.name = name; @@ -77,6 +80,14 @@ public boolean isRequired() { return required; } + public CommandArgumentDefinition getSupersededBy() { + return this.supersededBy; + } + + public void setSupersededBy(CommandArgumentDefinition supersededBy) { + this.supersededBy = supersededBy; + } + /** * Hidden arguments are ones that can be called via integrations, but should not be normally shown in help to users. */ @@ -121,8 +132,9 @@ public ConfigurationValueObfuscator getValueObfuscator() { */ public void validate(CommandScope commandScope) throws CommandValidationException { final DataType currentValue = commandScope.getArgumentValue(this); - if (this.isRequired() && currentValue == null) { - throw new CommandValidationException(LiquibaseCommandLineConfiguration.ARGUMENT_CONVERTER.getCurrentValue().convert(this.getName()), "missing required argument", new MissingRequiredArgumentException(this.getName())); + if (this.isRequired() && currentValue == null && + (this.getSupersededBy() == null || commandScope.getArgumentValue(this.getSupersededBy()) == null)) { + throw new CommandValidationException(LiquibaseCommandLineConfiguration.ARGUMENT_CONVERTER.getCurrentValue().convert(this.getName()), "missing required argument", new MissingRequiredArgumentException(this.getName())); } } @@ -185,6 +197,16 @@ public Building required() { return this; } + /** + * Specifies a CommandArgument that can replace this one if it is not available. + * + */ + public Building supersededBy(CommandArgumentDefinition commandArgumentDefinition) { + this.newCommandArgument.supersededBy = commandArgumentDefinition; + + return this; + } + /** * Mark argument as optional. * @see #required() diff --git a/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java b/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java index ccb49fe6d99..b9f8465190b 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandBuilder.java @@ -1,5 +1,9 @@ package liquibase.command; +import liquibase.Beta; +import liquibase.command.core.DbUrlConnectionCommandStep; +import liquibase.database.Database; + /** * Builder for configuring {@link CommandStep} settings, such as {@link CommandArgumentDefinition}s and {@link CommandResultDefinition}s */ @@ -28,6 +32,19 @@ public CommandArgumentDefinition.Building argument(CommonAr return new CommandArgumentDefinition.Building<>(commandNames, new CommandArgumentDefinition<>(argument.getArgumentName(), type)); } + + /** + * Creates a database argument and registers the current Step as an applicable command + * to the InternalDatabaseCommandStep. + */ + @Beta + public CommandArgumentDefinition.Building databaseArgument() { + DbUrlConnectionCommandStep.addApplicableCommand(this.commandNames); + return new CommandArgumentDefinition.Building<>(commandNames, + new CommandArgumentDefinition<>("database", Database.class)) + .description("Database connection"); + } + /** * Starts the building of a new {@link CommandResultDefinition}. */ diff --git a/liquibase-core/src/main/java/liquibase/command/CommandFactory.java b/liquibase-core/src/main/java/liquibase/command/CommandFactory.java index ca083ba5f7d..a4a21cb1e11 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandFactory.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandFactory.java @@ -5,6 +5,7 @@ import liquibase.servicelocator.ServiceLocator; import liquibase.util.StringUtil; +import java.lang.reflect.InvocationTargetException; import java.util.*; /** @@ -34,18 +35,30 @@ public CommandDefinition getCommandDefinition(String... commandName) throws Ille CommandDefinition commandDefinition = new CommandDefinition(commandName); for (CommandStep step : findAllInstances()) { if (step.getOrder(commandDefinition) > 0) { - commandDefinition.add(step); + try { + commandDefinition.add(step.getClass().getConstructor().newInstance()); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { + throw new IllegalArgumentException(e); + } } } final List pipeline = commandDefinition.getPipeline(); - if (pipeline.size() == 0) { + if (pipeline.isEmpty()) { throw new IllegalArgumentException("Unknown command '" + StringUtil.join(commandName, " ") + "'"); } - final Set> stepArguments = this.commandArgumentDefinitions.get(StringUtil.join(commandDefinition.getName(), " ")); + final Set> stepArguments = new HashSet<>(); + for (CommandStep step : pipeline) { + String[][] names = step.defineCommandNames(); + if (names != null) { + for (String[] name : names) { + stepArguments.addAll(this.commandArgumentDefinitions.getOrDefault(StringUtil.join(name, " "), new HashSet<>())); + } + } + } - if (stepArguments != null) { + if (!stepArguments.isEmpty()) { for (CommandArgumentDefinition commandArg : stepArguments) { commandDefinition.add(commandArg); } @@ -67,8 +80,11 @@ public CommandDefinition getCommandDefinition(String... commandName) throws Ille public SortedSet getCommands(boolean includeInternal) { Map commandNames = new HashMap<>(); for (CommandStep step : findAllInstances()) { - for (String[] name : step.defineCommandNames()) { - commandNames.put(StringUtil.join(name, " "), name); + String[][] names = step.defineCommandNames(); + if (names != null) { + for (String[] name : names) { + commandNames.put(StringUtil.join(name, " "), name); + } } } diff --git a/liquibase-core/src/main/java/liquibase/command/CommandScope.java b/liquibase-core/src/main/java/liquibase/command/CommandScope.java index 8f8e49c8feb..24573d03a99 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandScope.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandScope.java @@ -171,6 +171,14 @@ public CommandResults execute() throws CommandExecutionException { for (CommandStep command : pipeline) { command.run(resultsBuilder); } + + // after executing our pipeline, runs cleanup in inverse order + for (int i = pipeline.size() -1; i >= 0; i--) { + CommandStep command = pipeline.get(i); + if (command instanceof CleanUpCommandStep) { + ((CleanUpCommandStep)command).cleanUp(resultsBuilder); + } + } } catch (Exception e) { if (e instanceof CommandExecutionException) { throw (CommandExecutionException) e; diff --git a/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java index b5198726cce..46944e234af 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java +++ b/liquibase-core/src/main/java/liquibase/command/core/CalculateChecksumCommandStep.java @@ -48,6 +48,7 @@ public String[][] defineCommandNames() { } + @Override protected String[] collectArguments(CommandScope commandScope) throws CommandExecutionException { return collectArguments(commandScope, null, CHANGESET_IDENTIFIER_ARG.getName()); } diff --git a/liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java new file mode 100644 index 00000000000..9631859539e --- /dev/null +++ b/liquibase-core/src/main/java/liquibase/command/core/DbUrlConnectionCommandStep.java @@ -0,0 +1,219 @@ +package liquibase.command.core; + +import liquibase.Beta; +import liquibase.GlobalConfiguration; +import liquibase.Scope; +import liquibase.command.*; +import liquibase.configuration.ConfigurationValueObfuscator; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.core.DatabaseUtils; +import liquibase.exception.CommandValidationException; +import liquibase.exception.DatabaseException; +import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; +import liquibase.resource.ResourceAccessor; +import liquibase.util.StringUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.ResourceBundle; + +import static java.util.ResourceBundle.getBundle; + +/** + * Internal command step to be used on CommandStep pipeline to manage the database connection. + */ +public class DbUrlConnectionCommandStep extends AbstractCommandStep implements CleanUpCommandStep { + + public static final String[] COMMAND_NAME = {"dbUrlConnectionCommandStep"}; + + private static final List APPLICABLE_COMMANDS = new ArrayList<>(); + private static final ResourceBundle coreBundle = getBundle("liquibase/i18n/liquibase-core"); + + public static final CommandArgumentDefinition DATABASE_ARG; + public static final CommandArgumentDefinition URL_ARG; + public static final CommandArgumentDefinition DEFAULT_SCHEMA_NAME_ARG; + public static final CommandArgumentDefinition DEFAULT_CATALOG_NAME_ARG; + public static final CommandArgumentDefinition USERNAME_ARG; + public static final CommandArgumentDefinition PASSWORD_ARG; + public static final CommandArgumentDefinition DRIVER_ARG; + public static final CommandArgumentDefinition DRIVER_PROPERTIES_FILE_ARG; + + private Database database; + + static { + CommandBuilder builder = new CommandBuilder(COMMAND_NAME); + DEFAULT_SCHEMA_NAME_ARG = builder.argument("defaultSchemaName", String.class) + .description("The default schema name to use for the database connection").build(); + DEFAULT_CATALOG_NAME_ARG = builder.argument("defaultCatalogName", String.class) + .description("The default catalog name to use for the database connection").build(); + DRIVER_ARG = builder.argument("driver", String.class) + .description("The JDBC driver class").build(); + DRIVER_PROPERTIES_FILE_ARG = builder.argument("driverPropertiesFile", String.class) + .description("The JDBC driver properties file").build(); + USERNAME_ARG = builder.argument(CommonArgumentNames.USERNAME, String.class) + .description("Username to use to connect to the database").build(); + PASSWORD_ARG = builder.argument(CommonArgumentNames.PASSWORD, String.class) + .description("Password to use to connect to the database") + .setValueObfuscator(ConfigurationValueObfuscator.STANDARD) + .build(); + DATABASE_ARG = builder.argument("database", Database.class).hidden().build(); + URL_ARG = builder.argument(CommonArgumentNames.URL, String.class).required().supersededBy(DATABASE_ARG) + .description("The JDBC database connection URL").build(); + DATABASE_ARG.setSupersededBy(URL_ARG); + } + + /** + * Method that allows Commands to register themselves to be able to use this CommandStep. + */ + @Beta + public static void addApplicableCommand(String[]... commandName) { + APPLICABLE_COMMANDS.add(commandName); + } + + @Override + public void run(CommandResultsBuilder resultsBuilder) throws Exception { + CommandScope commandScope = resultsBuilder.getCommandScope(); + commandScope.addArgumentValue(DATABASE_ARG.getName(), this.obtainDatabase(commandScope)); + } + + /** + * Try to retrieve and set the database object from the command scope, otherwise creates a new one . + * + * @param commandScope current command scope + * @throws DatabaseException Thrown when there is a connection error + */ + private Database obtainDatabase(CommandScope commandScope) throws DatabaseException, CommandValidationException { + if (commandScope.getArgumentValue(DATABASE_ARG) == null) { + String url = commandScope.getArgumentValue(URL_ARG); + String username = commandScope.getArgumentValue(USERNAME_ARG); + String password = commandScope.getArgumentValue(PASSWORD_ARG); + String defaultSchemaName = commandScope.getArgumentValue(DEFAULT_SCHEMA_NAME_ARG); + String defaultCatalogName = commandScope.getArgumentValue(DEFAULT_CATALOG_NAME_ARG); + String driver = commandScope.getArgumentValue(DRIVER_ARG); + String driverPropertiesFile = commandScope.getArgumentValue(DRIVER_PROPERTIES_FILE_ARG); + this.database = createDatabaseObject(url, username, password, defaultSchemaName, defaultCatalogName, driver, driverPropertiesFile); + return this.database; + } else { + return commandScope.getArgumentValue(DATABASE_ARG); + } + } + + @SuppressWarnings("java:S2095") + /** + * + * Method to create a Database object given these parameters + * + * @param url URL to connect to + * @param username Username credential + * @param password Password credential + * @param defaultSchemaName Default schema for connection + * @param defaultCatalogName Default catalog for connection + * @param driver Driver class + * @param driverPropertiesFile Additional driver properties + * @throws DatabaseException Thrown when there is a connection error + * + */ + private Database createDatabaseObject(String url, + String username, + String password, + String defaultSchemaName, + String defaultCatalogName, + String driver, + String driverPropertiesFile) + throws DatabaseException { + ResourceAccessor resourceAccessor = Scope.getCurrentScope().getResourceAccessor(); + String databaseClassName = null; + Class databaseClass = LiquibaseCommandLineConfiguration.DATABASE_CLASS.getCurrentValue(); + if (databaseClass != null) { + databaseClassName = databaseClass.getCanonicalName(); + } + String propertyProviderClass = null; + Class clazz = LiquibaseCommandLineConfiguration.PROPERTY_PROVIDER_CLASS.getCurrentValue(); + if (clazz != null) { + propertyProviderClass = clazz.getName(); + } + String liquibaseCatalogName = StringUtil.trimToNull(GlobalConfiguration.LIQUIBASE_CATALOG_NAME.getCurrentValue()); + String liquibaseSchemaName = StringUtil.trimToNull(GlobalConfiguration.LIQUIBASE_SCHEMA_NAME.getCurrentValue()); + String databaseChangeLogTablespaceName = StringUtil.trimToNull(GlobalConfiguration.LIQUIBASE_TABLESPACE_NAME.getCurrentValue()); + String databaseChangeLogLockTableName = StringUtil.trimToNull(GlobalConfiguration.DATABASECHANGELOGLOCK_TABLE_NAME.getCurrentValue()); + String databaseChangeLogTableName = StringUtil.trimToNull(GlobalConfiguration.DATABASECHANGELOG_TABLE_NAME.getCurrentValue()); + + try { + defaultCatalogName = StringUtil.trimToNull(defaultCatalogName); + defaultSchemaName = StringUtil.trimToNull(defaultSchemaName); + + database = DatabaseFactory.getInstance().openDatabase(url, username, password, driver, + databaseClassName, driverPropertiesFile, propertyProviderClass, resourceAccessor); + + if (!database.supportsSchemas()) { + if ((defaultSchemaName != null) && (defaultCatalogName == null)) { + defaultCatalogName = defaultSchemaName; + } + if ((liquibaseSchemaName != null) && (liquibaseCatalogName == null)) { + liquibaseCatalogName = liquibaseSchemaName; + } + } + + defaultCatalogName = StringUtil.trimToNull(defaultCatalogName); + defaultSchemaName = StringUtil.trimToNull(defaultSchemaName); + + database.setDefaultCatalogName(defaultCatalogName); + database.setDefaultSchemaName(defaultSchemaName); + database.setOutputDefaultCatalog(true); + database.setOutputDefaultSchema(true); + database.setLiquibaseCatalogName(liquibaseCatalogName); + database.setLiquibaseTablespaceName(databaseChangeLogTablespaceName); + database.setLiquibaseSchemaName(liquibaseSchemaName); + if (databaseChangeLogTableName != null) { + database.setDatabaseChangeLogTableName(databaseChangeLogTableName); + if (databaseChangeLogLockTableName != null) { + database.setDatabaseChangeLogLockTableName(databaseChangeLogLockTableName); + } else { + database.setDatabaseChangeLogLockTableName(databaseChangeLogTableName + "LOCK"); + } + } + DatabaseUtils.initializeDatabase(defaultCatalogName, defaultSchemaName, database); + } catch (Exception e) { + throw new DatabaseException(e); + } + + return database; + } + + @Override + public String[][] defineCommandNames() { + return new String[][] { COMMAND_NAME }; + } + + @Override + public void adjustCommandDefinition(CommandDefinition commandDefinition) { + if (commandDefinition.getPipeline().size() == 1) { + commandDefinition.setInternal(true); + } + } + + @Override + public int getOrder(CommandDefinition commandDefinition) { + for (String[][] commandNames : APPLICABLE_COMMANDS) { + for (String[] commandName : commandNames) { + if (commandDefinition.is(commandName)) { + return 500; + } + } + } + return super.getOrder(commandDefinition); + } + + @Override + public void cleanUp(CommandResultsBuilder resultsBuilder) { + if (database != null) { + try { + database.close(); + database = null; + } catch (Exception e) { + Scope.getCurrentScope().getLog(getClass()).warning(coreBundle.getString("problem.closing.connection"), e); + } + } + } +} diff --git a/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java b/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java index 7557bfae1c1..8bf39523cc8 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java +++ b/liquibase-core/src/main/java/liquibase/command/core/DiffToChangeLogCommand.java @@ -29,10 +29,12 @@ public DiffToChangeLogCommand setChangeLogFile(String changeLogFile) { return this; } + @Override public PrintStream getOutputStream() { return outputStream; } + @Override public DiffToChangeLogCommand setOutputStream(PrintStream outputStream) { this.outputStream = outputStream; return this; diff --git a/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java index eac670dd647..0bb214f9e3d 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java +++ b/liquibase-core/src/main/java/liquibase/command/core/SnapshotCommandStep.java @@ -2,15 +2,9 @@ import liquibase.CatalogAndSchema; import liquibase.GlobalConfiguration; -import liquibase.Scope; import liquibase.command.*; -import liquibase.configuration.ConfigurationValueObfuscator; import liquibase.database.Database; import liquibase.database.ObjectQuotingStrategy; -import liquibase.exception.DatabaseException; -import liquibase.integration.commandline.CommandLineUtils; -import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; -import liquibase.resource.ResourceAccessor; import liquibase.serializer.SnapshotSerializerFactory; import liquibase.snapshot.DatabaseSnapshot; import liquibase.snapshot.SnapshotControl; @@ -21,55 +15,29 @@ import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; -import java.util.*; - -import static java.util.ResourceBundle.getBundle; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; public class SnapshotCommandStep extends AbstractCommandStep { public static final String[] COMMAND_NAME = {"snapshot"}; - private static final ResourceBundle coreBundle = getBundle("liquibase/i18n/liquibase-core"); - public static final CommandArgumentDefinition USERNAME_ARG; - public static final CommandArgumentDefinition PASSWORD_ARG; - public static final CommandArgumentDefinition URL_ARG; public static final CommandArgumentDefinition SCHEMAS_ARG; - public static final CommandArgumentDefinition DEFAULT_SCHEMA_NAME_ARG; - public static final CommandArgumentDefinition DEFAULT_CATALOG_NAME_ARG; public static final CommandArgumentDefinition SNAPSHOT_FORMAT_ARG; - public static final CommandArgumentDefinition DRIVER_ARG; - public static final CommandArgumentDefinition DRIVER_PROPERTIES_FILE_ARG; public static final CommandArgumentDefinition DATABASE_ARG; public static final CommandArgumentDefinition SNAPSHOT_CONTROL_ARG; static { CommandBuilder builder = new CommandBuilder(COMMAND_NAME); - URL_ARG = builder.argument(CommonArgumentNames.URL, String.class).required() - .description("The JDBC database connection URL").build(); - SCHEMAS_ARG = builder.argument("schemas", String.class) - .description("The schemas to snapshot").build(); - DEFAULT_SCHEMA_NAME_ARG = builder.argument("defaultSchemaName", String.class) - .description("The default schema name to use for the database connection").build(); - DEFAULT_CATALOG_NAME_ARG = builder.argument("defaultCatalogName", String.class) - .description("The default catalog name to use for the database connection").build(); - DRIVER_ARG = builder.argument("driver", String.class) - .description("The JDBC driver class").build(); - DRIVER_PROPERTIES_FILE_ARG = builder.argument("driverPropertiesFile", String.class) - .description("The JDBC driver properties file").build(); - USERNAME_ARG = builder.argument(CommonArgumentNames.USERNAME, String.class) - .description("Username to use to connect to the database").build(); - PASSWORD_ARG = builder.argument(CommonArgumentNames.PASSWORD, String.class) - .description("Password to use to connect to the database") - .setValueObfuscator(ConfigurationValueObfuscator.STANDARD) - .build(); + SCHEMAS_ARG = builder.argument("schemas", String.class).description("The schemas to snapshot").build(); SNAPSHOT_FORMAT_ARG = builder.argument("snapshotFormat", String.class) .description("Output format to use (JSON, YAML, or TXT)").build(); - DATABASE_ARG = builder.argument("database", Database.class).hidden().build(); SNAPSHOT_CONTROL_ARG = builder.argument("snapshotControl", SnapshotControl.class).hidden().build(); + DATABASE_ARG = builder.databaseArgument().build(); } - private Database database; - private Map snapshotMetadata; @Override @@ -107,19 +75,7 @@ public void setSnapshotMetadata(Map snapshotMetadata) { @Override public void run(CommandResultsBuilder resultsBuilder) throws Exception { CommandScope commandScope = resultsBuilder.getCommandScope(); - - if (commandScope.getArgumentValue(DATABASE_ARG) == null) { - String url = commandScope.getArgumentValue(SnapshotCommandStep.URL_ARG); - String username = commandScope.getArgumentValue(SnapshotCommandStep.USERNAME_ARG); - String password = commandScope.getArgumentValue(SnapshotCommandStep.PASSWORD_ARG); - String defaultSchemaName = commandScope.getArgumentValue(SnapshotCommandStep.DEFAULT_SCHEMA_NAME_ARG); - String defaultCatalogName = commandScope.getArgumentValue(SnapshotCommandStep.DEFAULT_CATALOG_NAME_ARG); - String driver = commandScope.getArgumentValue(SnapshotCommandStep.DRIVER_ARG); - String driverPropertiesFile = commandScope.getArgumentValue(SnapshotCommandStep.DRIVER_PROPERTIES_FILE_ARG); - createDatabaseObject(url, username, password, defaultSchemaName, defaultCatalogName, driver, driverPropertiesFile); - } else { - database = commandScope.getArgumentValue(DATABASE_ARG); - } + Database database = commandScope.getArgumentValue(DATABASE_ARG); CatalogAndSchema[] schemas = parseSchemas(database, commandScope.getArgumentValue(SCHEMAS_ARG)); @@ -159,13 +115,6 @@ public void run(CommandResultsBuilder resultsBuilder) throws Exception { // Reset the quoting strategy // database.setObjectQuotingStrategy(originalQuotingStrategy); - - // - // Need to clean up here since we created the Database - // - if (commandScope.getArgumentValue(DATABASE_ARG) == null) { - closeDatabase(); - } } } @@ -175,75 +124,6 @@ private Writer getOutputWriter(final OutputStream outputStream) throws IOExcepti return new OutputStreamWriter(outputStream, charsetName); } - /** - * - * Method to create a Database object given these parameters - * - * @param url URL to connect to - * @param username Username credential - * @param password Password credential - * @param defaultSchemaName Default schema for connection - * @param defaultCatalogName Default catalog for connection - * @param driver Driver class - * @param driverPropertiesFile Additional driver properties - * @throws DatabaseException Thrown when there is a connection error - * - */ - private void createDatabaseObject(String url, - String username, - String password, - String defaultSchemaName, - String defaultCatalogName, - String driver, - String driverPropertiesFile) - throws DatabaseException { - ResourceAccessor resourceAccessor = Scope.getCurrentScope().getResourceAccessor(); - String databaseClassName = null; - Class databaseClass = LiquibaseCommandLineConfiguration.DATABASE_CLASS.getCurrentValue(); - if (databaseClass != null) { - databaseClassName = databaseClass.getCanonicalName(); - } - String propertyProviderClass = null; - Class clazz = LiquibaseCommandLineConfiguration.PROPERTY_PROVIDER_CLASS.getCurrentValue(); - if (clazz != null) { - propertyProviderClass = clazz.getName(); - } - String liquibaseCatalogName = GlobalConfiguration.LIQUIBASE_CATALOG_NAME.getCurrentValue(); - String liquibaseSchemaName = GlobalConfiguration.LIQUIBASE_SCHEMA_NAME.getCurrentValue(); - String databaseChangeLogTablespaceName = GlobalConfiguration.LIQUIBASE_TABLESPACE_NAME.getCurrentValue(); - String databaseChangeLogLockTableName = GlobalConfiguration.DATABASECHANGELOGLOCK_TABLE_NAME.getCurrentValue(); - String databaseChangeLogTableName = GlobalConfiguration.DATABASECHANGELOG_TABLE_NAME.getCurrentValue(); - database = - CommandLineUtils.createDatabaseObject(resourceAccessor, - url, - username, - password, - driver, - defaultCatalogName, - defaultSchemaName, - true, - true, - databaseClassName, - driverPropertiesFile, - propertyProviderClass, - liquibaseCatalogName, liquibaseSchemaName, - databaseChangeLogTableName, - databaseChangeLogLockTableName); - database.setLiquibaseTablespaceName(databaseChangeLogTablespaceName); - } - - private void closeDatabase() { - try { - if (database != null) { - database.rollback(); - database.close(); - } - } catch (Exception e) { - Scope.getCurrentScope().getLog(getClass()).warning( - coreBundle.getString("problem.closing.connection"), e); - } - } - private String printSnapshot(CommandScope commandScope, DatabaseSnapshot snapshot) { String format = commandScope.getArgumentValue(SNAPSHOT_FORMAT_ARG); if (format == null) { diff --git a/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java b/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java index 620bbd5252a..9666fc3c14c 100644 --- a/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java +++ b/liquibase-core/src/main/java/liquibase/command/core/TagCommandStep.java @@ -1,52 +1,53 @@ package liquibase.command.core; +import liquibase.Liquibase; +import liquibase.Scope; +import liquibase.changelog.ChangeLogHistoryService; +import liquibase.changelog.ChangeLogHistoryServiceFactory; import liquibase.command.*; -import liquibase.configuration.ConfigurationValueObfuscator; -import liquibase.exception.CommandExecutionException; +import liquibase.database.Database; +import liquibase.exception.LockException; +import liquibase.lockservice.LockService; +import liquibase.lockservice.LockServiceFactory; -public class TagCommandStep extends AbstractCliWrapperCommandStep { +public class TagCommandStep extends AbstractCommandStep { public static final String[] COMMAND_NAME = {"tag"}; - public static final CommandArgumentDefinition URL_ARG; - public static final CommandArgumentDefinition DEFAULT_SCHEMA_NAME_ARG; - public static final CommandArgumentDefinition DEFAULT_CATALOG_NAME_ARG; - public static final CommandArgumentDefinition USERNAME_ARG; - public static final CommandArgumentDefinition PASSWORD_ARG; public static final CommandArgumentDefinition TAG_ARG; - public static final CommandArgumentDefinition DRIVER_ARG; - public static final CommandArgumentDefinition DRIVER_PROPERTIES_FILE_ARG; + public static final CommandArgumentDefinition DATABASE_ARG; static { CommandBuilder builder = new CommandBuilder(COMMAND_NAME); - URL_ARG = builder.argument(CommonArgumentNames.URL, String.class).required() - .description("The JDBC database connection URL").build(); - DEFAULT_SCHEMA_NAME_ARG = builder.argument("defaultSchemaName", String.class) - .description("The default schema name to use for the database connection").build(); - DEFAULT_CATALOG_NAME_ARG = builder.argument("defaultCatalogName", String.class) - .description("The default catalog name to use for the database connection").build(); - DRIVER_ARG = builder.argument("driver", String.class) - .description("The JDBC driver class").build(); - DRIVER_PROPERTIES_FILE_ARG = builder.argument("driverPropertiesFile", String.class) - .description("The JDBC driver properties file").build(); - USERNAME_ARG = builder.argument(CommonArgumentNames.USERNAME, String.class) - .description("Username to use to connect to the database").build(); - PASSWORD_ARG = builder.argument(CommonArgumentNames.PASSWORD, String.class) - .description("Password to use to connect to the database") - .setValueObfuscator(ConfigurationValueObfuscator.STANDARD) - .build(); - TAG_ARG = builder.argument("tag", String.class).required() - .description("Tag to add to the database changelog table").build(); + TAG_ARG = builder.argument("tag", String.class).required().description("Tag to add to the database changelog table").build(); + DATABASE_ARG = builder.databaseArgument().build(); } @Override - public String[][] defineCommandNames() { - return new String[][] { COMMAND_NAME }; + public void run(CommandResultsBuilder resultsBuilder) throws Exception { + CommandScope commandScope = resultsBuilder.getCommandScope(); + Database database = commandScope.getArgumentValue(DATABASE_ARG); + LockService lockService = LockServiceFactory.getInstance().getLockService(database); + lockService.waitForLock(); + + try { + ChangeLogHistoryService changeLogService = ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(database); + changeLogService.generateDeploymentId(); + changeLogService.init(); + LockServiceFactory.getInstance().getLockService(database).init(); + changeLogService.tag(commandScope.getArgumentValue(TagCommandStep.TAG_ARG)); + } finally { + try { + lockService.releaseLock(); + } catch (LockException e) { + Scope.getCurrentScope().getLog(getClass()).severe(Liquibase.MSG_COULD_NOT_RELEASE_LOCK, e); + } + } } @Override - protected String[] collectArguments(CommandScope commandScope) throws CommandExecutionException { - return collectArguments(commandScope, null, "tag"); + public String[][] defineCommandNames() { + return new String[][] { COMMAND_NAME }; } @Override diff --git a/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java b/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java index e058931c9da..309d0dbf37e 100644 --- a/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/configuration/LiquibaseConfiguration.java @@ -158,7 +158,19 @@ public ConfiguredValue getCurrentConfiguredValue(Configurat if (foundFirstValue) { logMessage.append("Overrides "); } - logMessage.append(StringUtil.lowerCaseFirst(providedValue.describe())); + + // + // Only lower case the first character is + // the first two characters are NOT uppercase. This allows provider + // strings like 'AWS' to be displayed correctly, i.e. as 'AWS', not 'aWS' + // + String describe = providedValue.describe(); + char[] chars = describe.toCharArray(); + if (chars.length >= 2 && Character.isUpperCase(chars[0]) && Character.isUpperCase(chars[1])) { + logMessage.append(describe); + } else { + logMessage.append(StringUtil.lowerCaseFirst(describe)); + } Object value = providedValue.getValue(); if (value != null) { String finalValue = String.valueOf(value); diff --git a/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java b/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java index ae8cdf12c59..ccba774bd74 100644 --- a/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java +++ b/liquibase-core/src/main/java/liquibase/database/AbstractJdbcDatabase.java @@ -1202,7 +1202,7 @@ public int hashCode() { @Override public void close() throws DatabaseException { Scope.getCurrentScope().getSingleton(ExecutorService.class).clearExecutor("jdbc", this); - try (final DatabaseConnection connection = getConnection();) { + try (final DatabaseConnection connection = getConnection()) { if (connection != null && previousAutoCommit != null) { connection.setAutoCommit(previousAutoCommit); } diff --git a/liquibase-core/src/main/java/liquibase/database/Database.java b/liquibase-core/src/main/java/liquibase/database/Database.java index 1411b306919..21fc23b438c 100644 --- a/liquibase-core/src/main/java/liquibase/database/Database.java +++ b/liquibase-core/src/main/java/liquibase/database/Database.java @@ -176,9 +176,16 @@ public interface Database extends PrioritizedService, AutoCloseable { /** * Tags the database changelog with the given string. + * + * @deprecated Use {@link liquibase.changelog.ChangeLogHistoryService#tag(String)} instead */ + @Deprecated void tag(String tagString) throws DatabaseException; + /** + * @deprecated Use {@link liquibase.changelog.ChangeLogHistoryService#tagExists(String)} instead + */ + @Deprecated boolean doesTagExist(String tag) throws DatabaseException; boolean isSystemObject(DatabaseObject example); diff --git a/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java b/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java index f8f531237db..ec2c8b73f71 100644 --- a/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java +++ b/liquibase-core/src/main/java/liquibase/database/DatabaseFactory.java @@ -11,6 +11,7 @@ import liquibase.resource.ResourceAccessor; import liquibase.util.StringUtil; import liquibase.util.SystemUtil; +import liquibase.SingletonObject; import java.io.IOException; import java.io.InputStream; @@ -18,7 +19,7 @@ import java.sql.Driver; import java.util.*; -public class DatabaseFactory { +public class DatabaseFactory implements SingletonObject { private static final Logger LOG = Scope.getCurrentScope().getLog(DatabaseFactory.class); private static DatabaseFactory instance; private Map> implementedDatabases = new HashMap<>(); @@ -330,7 +331,7 @@ private Properties buildDriverProperties(String username, String password, Strin private static class DatabaseComparator implements Comparator { @Override public int compare(Database o1, Database o2) { - return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); + return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); } } } diff --git a/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java b/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java index 5004854cb6f..21f00b4611f 100644 --- a/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java +++ b/liquibase-core/src/main/java/liquibase/database/core/AbstractDb2Database.java @@ -223,6 +223,7 @@ public boolean isSystemObject(DatabaseObject example) { return super.isSystemObject(example); } + @Override protected boolean mustQuoteObjectName(String objectName, Class objectType) { if (objectType.isAssignableFrom(Schema.class) || objectType.isAssignableFrom(Catalog.class)) { return true; diff --git a/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectComparator.java b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectCollectionComparator.java similarity index 83% rename from liquibase-core/src/main/java/liquibase/structure/DatabaseObjectComparator.java rename to liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectCollectionComparator.java index d5624c4324b..4df96019a2b 100644 --- a/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectComparator.java +++ b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectCollectionComparator.java @@ -1,11 +1,12 @@ -package liquibase.structure; +package liquibase.diff.compare; +import liquibase.structure.DatabaseObject; import liquibase.structure.core.Schema; import liquibase.util.StringUtil; import java.util.Comparator; -public class DatabaseObjectComparator implements Comparator { +public class DatabaseObjectCollectionComparator implements Comparator { @Override public int compare(DatabaseObject o1, DatabaseObject o2) { @@ -17,7 +18,6 @@ public int compare(DatabaseObject o1, DatabaseObject o2) { if (i != 0) { return i; } - } String name1 = StringUtil.trimToEmpty(o1.getName()); diff --git a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java index 4ae972529f1..33c32ff8586 100644 --- a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java +++ b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorComparator.java @@ -17,7 +17,7 @@ public DatabaseObjectComparatorComparator(Class object @Override public int compare(DatabaseObjectComparator o1, DatabaseObjectComparator o2) { - int result = -1 * Integer.valueOf(o1.getPriority(objectType, database)).compareTo(o2.getPriority(objectType, database)); + int result = -1 * Integer.compare(o1.getPriority(objectType, database), o2.getPriority(objectType, database)); if (result == 0) { return o1.getClass().getName().compareTo(o2.getClass().getName()); } diff --git a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java index a5a870ece11..a0f06ea5255 100644 --- a/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java +++ b/liquibase-core/src/main/java/liquibase/diff/compare/DatabaseObjectComparatorFactory.java @@ -69,6 +69,14 @@ public void unregister(Class generatorClass) { unregister(toRemove); } + public DatabaseObjectComparator getComparator(Class comparatorClass, Database database) { + List comparatorsForType = getComparators(comparatorClass, database); + if (! comparatorsForType.isEmpty()) { + return comparatorsForType.get(0); + } + return null; + } + protected List getComparators(Class comparatorClass, Database database) { String key = comparatorClass.getName()+":"+database.getShortName(); if (validComparatorsByClassAndDatabase.containsKey(key)) { diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java index 5c5d2e488a4..65acd3789eb 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/ChangeGeneratorComparator.java @@ -17,7 +17,7 @@ public ChangeGeneratorComparator(Class objectType, Dat @Override public int compare(ChangeGenerator o1, ChangeGenerator o2) { - int result = -1 * Integer.valueOf(o1.getPriority(objectType, database)).compareTo(o2.getPriority(objectType, database)); + int result = -1 * Integer.compare(o1.getPriority(objectType, database), o2.getPriority(objectType, database)); if (result == 0) { return o1.getClass().getName().compareTo(o2.getClass().getName()); } diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java index a0e8643ccd7..896ab27e087 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/DiffToChangeLog.java @@ -11,6 +11,7 @@ import liquibase.diff.DiffResult; import liquibase.diff.ObjectDifferences; import liquibase.diff.compare.CompareControl; +import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.diff.output.DiffOutputControl; import liquibase.exception.DatabaseException; import liquibase.exception.UnexpectedLiquibaseException; @@ -25,13 +26,17 @@ import liquibase.snapshot.EmptyDatabaseSnapshot; import liquibase.statement.core.RawSqlStatement; import liquibase.structure.DatabaseObject; -import liquibase.structure.DatabaseObjectComparator; import liquibase.structure.core.Column; import liquibase.structure.core.StoredDatabaseLogic; -import liquibase.util.*; +import liquibase.util.DependencyUtil; +import liquibase.util.StreamUtil; +import liquibase.util.StringUtil; import javax.xml.parsers.ParserConfigurationException; -import java.io.*; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; import java.text.SimpleDateFormat; import java.util.*; @@ -251,7 +256,7 @@ public void print(final PrintStream out, final ChangeLogSerializer changeLogSeri public List generateChangeSets() { final ChangeGeneratorFactory changeGeneratorFactory = ChangeGeneratorFactory.getInstance(); - DatabaseObjectComparator comparator = new DatabaseObjectComparator(); + DatabaseObjectCollectionComparator comparator = new DatabaseObjectCollectionComparator(); String created = null; if (GlobalConfiguration.GENERATE_CHANGESET_CREATED_VALUES.getCurrentValue()) { @@ -265,9 +270,9 @@ public List generateChangeSets() { // This is to avoid changing the MissingObjectChangeGenerator API and still be able to pass the // initial DiffResult Object which can be used to check for the objects available in the database // without doing any expensive db calls. Example usage is in MissingUniqueConstraintChangeGenerator#alreadyExists() - Database comparisionDatabase = diffResult.getComparisonSnapshot().getDatabase(); - if (comparisionDatabase instanceof AbstractJdbcDatabase) { - ((AbstractJdbcDatabase) comparisionDatabase).set("diffResult", diffResult); + Database comparisonDatabase = diffResult.getComparisonSnapshot().getDatabase(); + if (comparisonDatabase instanceof AbstractJdbcDatabase) { + ((AbstractJdbcDatabase) comparisonDatabase).set("diffResult", diffResult); } for (Class type : types) { @@ -283,7 +288,7 @@ public List generateChangeSets() { types = getOrderedOutputTypes(MissingObjectChangeGenerator.class); List missingObjects = new ArrayList(); for (Class type : types) { - for (DatabaseObject object : diffResult.getMissingObjects(type, getDbObjectComparator())) { + for (DatabaseObject object : diffResult.getMissingObjects(type, getDatabaseObjectCollectionComparator())) { if (object == null) { continue; } @@ -315,8 +320,8 @@ public List generateChangeSets() { } } // remove the diffResult from the database object - if (comparisionDatabase instanceof AbstractJdbcDatabase) { - ((AbstractJdbcDatabase) comparisionDatabase).set("diffResult", null); + if (comparisonDatabase instanceof AbstractJdbcDatabase) { + ((AbstractJdbcDatabase) comparisonDatabase).set("diffResult", null); } @@ -327,8 +332,8 @@ public List generateChangeSets() { return changeSets; } - private DatabaseObjectComparator getDbObjectComparator() { - return new DatabaseObjectComparator() { + private DatabaseObjectCollectionComparator getDatabaseObjectCollectionComparator() { + return new DatabaseObjectCollectionComparator() { @Override public int compare(DatabaseObject o1, DatabaseObject o2) { if (o1 instanceof Column && o1.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null && o2.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null) { @@ -336,15 +341,15 @@ public int compare(DatabaseObject o1, DatabaseObject o2) { if (i != 0) { return i; } - } else if (o1 instanceof StoredDatabaseLogic && o1.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null - && o2.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null) { - int order = o1.getAttribute(ORDER_ATTRIBUTE, Long.class).compareTo(o2.getAttribute(ORDER_ATTRIBUTE, Long.class)); - if (order != 0) { - return order; + } else if (o1 instanceof StoredDatabaseLogic) { + if (o1.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null && o2.getAttribute(ORDER_ATTRIBUTE, Integer.class) != null) { + int order = o1.getAttribute(ORDER_ATTRIBUTE, Long.class).compareTo(o2.getAttribute(ORDER_ATTRIBUTE, Long.class)); + if (order != 0) { + return order; + } } } return super.compare(o1, o2); - } }; } diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java index 48583416b90..fc812b31566 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/MissingDataExternalFileChangeGenerator.java @@ -53,7 +53,7 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu ResultSet rs = null; try ( Statement stmt = ((JdbcConnection) referenceDatabase.getConnection()).createStatement( - ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); + ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY) ) { Data data = (Data) missingObject; @@ -88,7 +88,7 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu OutputStream fileOutputStream = externalFileResource.openOutputStream(new OpenOptions()); OutputStreamWriter outputStreamWriter = new OutputStreamWriter( fileOutputStream, GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()); - CSVWriter outputFile = new CSVWriter(new BufferedWriter(outputStreamWriter)); + CSVWriter outputFile = new CSVWriter(new BufferedWriter(outputStreamWriter)) ) { dataTypes = new String[columnNames.size()]; diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java index a1d459c2e80..4cc5913c876 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedTableChangeGenerator.java @@ -47,7 +47,7 @@ public Change[] fixUnexpected(DatabaseObject unexpectedObject, DiffOutputControl for (Column column : unexpectedTable.getColumns()) { control.setAlreadyHandledUnexpected(column); - }; + } control.setAlreadyHandledUnexpected(unexpectedTable.getPrimaryKey()); for (Index index : unexpectedTable.getIndexes()) { diff --git a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java index 008f738ef0e..3d0ddf23db1 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/changelog/core/UnexpectedViewChangeGenerator.java @@ -49,7 +49,7 @@ public Change[] fixUnexpected(DatabaseObject unexpectedObject, DiffOutputControl for (Column column : view.getColumns()) { control.setAlreadyHandledUnexpected(column); - }; + } return new Change[]{change}; diff --git a/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java b/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java index b1cbe0473a8..ba9ea26391e 100644 --- a/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java +++ b/liquibase-core/src/main/java/liquibase/diff/output/report/DiffToReport.java @@ -6,9 +6,9 @@ import liquibase.diff.ObjectDifferences; import liquibase.diff.StringDiff; import liquibase.diff.compare.CompareControl; +import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.exception.DatabaseException; import liquibase.structure.DatabaseObject; -import liquibase.structure.DatabaseObjectComparator; import liquibase.structure.core.Schema; import liquibase.util.StringUtil; @@ -28,7 +28,7 @@ public DiffToReport(DiffResult diffResult, PrintStream out) { } public void print() throws DatabaseException { - final DatabaseObjectComparator comparator = new DatabaseObjectComparator(); + final DatabaseObjectCollectionComparator comparator = new DatabaseObjectCollectionComparator(); out.println("Reference Database: " + diffResult.getReferenceSnapshot().getDatabase()); out.println("Comparison Database: " + diffResult.getComparisonSnapshot().getDatabase()); diff --git a/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java b/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java index b798df38e72..cfac65995f4 100644 --- a/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java +++ b/liquibase-core/src/main/java/liquibase/executor/AbstractExecutor.java @@ -97,6 +97,7 @@ public void setResourceAccessor(ResourceAccessor resourceAccessor) { this.resourceAccessor = resourceAccessor; } + @Override public void setDatabase(Database database) { this.database = database; } diff --git a/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java b/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java index 117143aa178..7c5da66d1f9 100644 --- a/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java +++ b/liquibase-core/src/main/java/liquibase/executor/ExecutorService.java @@ -10,7 +10,7 @@ public class ExecutorService extends AbstractPluginFactory { - private final Map executors = new ConcurrentHashMap<>(); + private final Map executors = new ConcurrentHashMap<>(); private ExecutorService() { } @@ -32,8 +32,8 @@ protected int getPriority(Executor executor, Object... args) { } - private String createKey(String executorName, Database database) { - return executorName.toLowerCase() + "#" + System.identityHashCode(database); + private Key createKey(String executorName, Database database) { + return new Key(executorName, database); } private Executor getExecutorValue(String executorName, Database database) throws UnexpectedLiquibaseException { @@ -117,4 +117,44 @@ public void clearExecutor(String name, Database database) { public void reset() { executors.clear(); } + + private static class Key { + private final String executorName; + private final Database database; + + Key(String executorName, Database database) { + this.executorName = normalizeExecutorName(executorName); + this.database = database; + } + + private String normalizeExecutorName(String executorName) { + return executorName.toLowerCase(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Key key = (Key) o; + return Objects.equals(executorName, key.executorName) + && database == key.database; // equality by reference to be consistent with hashCode + } + + @Override + public int hashCode() { + return Objects.hash( + executorName, + // this class already relied on identity hash code. It bypasses e.g. AbstractJdbcDatabase's hashCode + System.identityHashCode(database) + ); + } + + @Override + public String toString() { + return "Key{" + + "executorName='" + executorName + '\'' + + ", database=" + database + + '}'; + } + } } diff --git a/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java b/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java index cf17fc9d81c..08b9638f32a 100644 --- a/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java +++ b/liquibase-core/src/main/java/liquibase/executor/jvm/JdbcExecutor.java @@ -185,7 +185,7 @@ public Object query(final SqlStatement sql, final ResultSetExtractor rse, final String finalSql = applyVisitors((RawParameterizedSqlStatement) sql, sqlVisitors); - try (PreparedStatement pstmt = factory.create(finalSql);) { + try (PreparedStatement pstmt = factory.create(finalSql)) { final List parameters = ((RawParameterizedSqlStatement) sql).getParameters(); for (int i = 0; i < parameters.size(); i++) { pstmt.setObject(i, parameters.get(0)); diff --git a/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java b/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java index b4b3def74e1..bda0ab81a5a 100644 --- a/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java +++ b/liquibase-core/src/main/java/liquibase/hub/core/MockHubService.java @@ -58,6 +58,7 @@ public Project createProject(Project project) { return new Project().setName("Project 1"); } + @Override public HubChangeLog createChangeLog(HubChangeLog hubChangeLog) throws LiquibaseException { if (randomUUID == null) { randomUUID = UUID.randomUUID(); diff --git a/liquibase-core/src/main/java/liquibase/hub/model/Connection.java b/liquibase-core/src/main/java/liquibase/hub/model/Connection.java index 71d7665c4df..c9568e716a5 100644 --- a/liquibase-core/src/main/java/liquibase/hub/model/Connection.java +++ b/liquibase-core/src/main/java/liquibase/hub/model/Connection.java @@ -15,6 +15,7 @@ public class Connection implements HubModel { private Project project; + @Override public UUID getId() { return id; } diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java b/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java index 0b9f4e3a71d..aa96d2f668f 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/CommandLineUtils.java @@ -66,6 +66,7 @@ public static Database createDatabaseObject(ClassLoader classLoader, } @SuppressWarnings("java:S2095") + @Deprecated public static Database createDatabaseObject(ResourceAccessor resourceAccessor, String url, String username, diff --git a/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java b/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java index 3c24ab8ee06..b5e96451ccf 100644 --- a/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java +++ b/liquibase-core/src/main/java/liquibase/integration/servlet/GenericServletListener.java @@ -178,6 +178,7 @@ private boolean checkPreconditions(GenericServletWrapper.ServletContext servletC machine = machine.trim(); if (hostName.equalsIgnoreCase(machine)) { shouldRun = true; + break; } } } else if (machineExcludes != null) { @@ -186,6 +187,7 @@ private boolean checkPreconditions(GenericServletWrapper.ServletContext servletC machine = machine.trim(); if (hostName.equalsIgnoreCase(machine)) { shouldRun = false; + break; } } } diff --git a/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java b/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java index 0b2c1c36fd2..f174252e0ff 100644 --- a/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java +++ b/liquibase-core/src/main/java/liquibase/io/EmptyLineAndCommentSkippingInputStream.java @@ -42,7 +42,7 @@ private int read(final int lastRead, final boolean lookAhead) throws IOException if (commentSkipEnabled && (read == this.commentLineStartsWith.toCharArray()[0]) && (lastRead == '\n' || lastRead < 0)) { while ((((read = super.read())) != '\n') && (read != '\r') && (read > 0)) { - ;//keep looking + //keep looking } } diff --git a/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java b/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java index e00bc514e9a..1c4490d9447 100644 --- a/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java +++ b/liquibase-core/src/main/java/liquibase/lockservice/LockServiceFactory.java @@ -55,7 +55,7 @@ public LockService getLockService(Database database) { SortedSet foundServices = new TreeSet<>(new Comparator() { @Override public int compare(LockService o1, LockService o2) { - return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); + return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); } }); diff --git a/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java b/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java index 290324870da..42d2718b12a 100644 --- a/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java +++ b/liquibase-core/src/main/java/liquibase/lockservice/StandardLockService.java @@ -133,33 +133,8 @@ public void init() throws DatabaseException { database.commit(); } - if (executor.updatesDatabase() && (database instanceof DerbyDatabase) && ((DerbyDatabase) database) - .supportsBooleanDataType() || database.getClass().isAssignableFrom(DB2Database.class) && ((DB2Database) database) - .supportsBooleanDataType()) { - //check if the changelog table is of an old smallint vs. boolean format - String lockTable = database.escapeTableName( - database.getLiquibaseCatalogName(), - database.getLiquibaseSchemaName(), - database.getDatabaseChangeLogLockTableName() - ); - Object obj = executor.queryForObject( - new RawSqlStatement( - "SELECT MIN(locked) AS test FROM " + lockTable + " FETCH FIRST ROW ONLY" - ), Object.class - ); - if (!(obj instanceof Boolean)) { //wrong type, need to recreate table - executor.execute( - new DropTableStatement( - database.getLiquibaseCatalogName(), - database.getLiquibaseSchemaName(), - database.getDatabaseChangeLogLockTableName(), - false - ) - ); - executor.execute(new CreateDatabaseChangeLogLockTableStatement()); - executor.execute(new InitializeDatabaseChangeLogLockTableStatement()); - } - } + handleOldChangelogTableFormat(executor); + break; } catch (Exception e) { if (i == maxIterations - 1) { throw e; @@ -179,6 +154,36 @@ public void init() throws DatabaseException { } } + private void handleOldChangelogTableFormat(Executor executor) throws DatabaseException { + if (executor.updatesDatabase() && (database instanceof DerbyDatabase) && ((DerbyDatabase) database) + .supportsBooleanDataType() || database.getClass().isAssignableFrom(DB2Database.class) && ((DB2Database) database) + .supportsBooleanDataType()) { + //check if the changelog table is of an old smallint vs. boolean format + String lockTable = database.escapeTableName( + database.getLiquibaseCatalogName(), + database.getLiquibaseSchemaName(), + database.getDatabaseChangeLogLockTableName() + ); + Object obj = executor.queryForObject( + new RawSqlStatement( + "SELECT MIN(locked) AS test FROM " + lockTable + " FETCH FIRST ROW ONLY" + ), Object.class + ); + if (!(obj instanceof Boolean)) { //wrong type, need to recreate table + executor.execute( + new DropTableStatement( + database.getLiquibaseCatalogName(), + database.getLiquibaseSchemaName(), + database.getDatabaseChangeLogLockTableName(), + false + ) + ); + executor.execute(new CreateDatabaseChangeLogLockTableStatement()); + executor.execute(new InitializeDatabaseChangeLogLockTableStatement()); + } + } + } + public boolean isDatabaseChangeLogLockTableInitialized(final boolean tableJustCreated) { return isDatabaseChangeLogLockTableInitialized(tableJustCreated, false); } diff --git a/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java b/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java index 8c8d69dfe91..75e49459bf0 100644 --- a/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java +++ b/liquibase-core/src/main/java/liquibase/parser/NamespaceDetailsFactory.java @@ -82,7 +82,7 @@ public void unregister(NamespaceDetails namespaceDetails) { private class SerializerNamespaceDetailsComparator implements Comparator { @Override public int compare(NamespaceDetails o1, NamespaceDetails o2) { - return Integer.valueOf(o2.getPriority()).compareTo(o1.getPriority()); + return Integer.compare(o2.getPriority(), o1.getPriority()); } } } diff --git a/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java b/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java index 019171783d3..c70dbc8c8ed 100644 --- a/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java +++ b/liquibase-core/src/main/java/liquibase/parser/SnapshotParserFactory.java @@ -41,7 +41,7 @@ private SnapshotParserFactory() { snapshotParserComparator = new Comparator() { @Override public int compare(SnapshotParser o1, SnapshotParser o2) { - return Integer.valueOf(o2.getPriority()).compareTo(o1.getPriority()); + return Integer.compare(o2.getPriority(), o1.getPriority()); } }; diff --git a/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java b/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java index 711564aa579..32c7822d2fe 100644 --- a/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java +++ b/liquibase-core/src/main/java/liquibase/resource/DirectoryPathHandler.java @@ -11,6 +11,7 @@ public class DirectoryPathHandler extends AbstractPathHandler { /** * Returns {@link #PRIORITY_DEFAULT} for all paths except for ones that are for a non-"file:" protocol. */ + @Override public int getPriority(String root) { if (root == null) { return PRIORITY_NOT_APPLICABLE; @@ -27,6 +28,7 @@ public int getPriority(String root) { } } + @Override public ResourceAccessor getResourceAccessor(String root) throws FileNotFoundException { root = root .replace("file:", "") diff --git a/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java b/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java index f93c133fe3f..0f10edea1ec 100644 --- a/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java +++ b/liquibase-core/src/main/java/liquibase/resource/ZipPathHandler.java @@ -17,6 +17,7 @@ public class ZipPathHandler extends AbstractPathHandler { /** * Returns {@link #PRIORITY_SPECIALIZED} for all "jar:file:" or files that end in ".jar" or ".zip" */ + @Override public int getPriority(String root) { if (root == null) { return PRIORITY_NOT_APPLICABLE; @@ -33,6 +34,7 @@ public int getPriority(String root) { return PRIORITY_NOT_APPLICABLE; } + @Override public ResourceAccessor getResourceAccessor(String root) throws FileNotFoundException { root = root.replace("jar:", "").replace("!/", ""); diff --git a/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java b/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java index b5b5f6e989a..2fcf966c58a 100644 --- a/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java +++ b/liquibase-core/src/main/java/liquibase/sdk/resource/MockResource.java @@ -27,6 +27,7 @@ public Resource resolve(String other) { return new MockResource(resolvePath(other), "Resource relative to " + getPath()); } + @Override public Resource resolveSibling(String other) { return new MockResource(resolveSiblingPath(other), "Sibling resource to " + getPath()); } diff --git a/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java b/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java index 8d4fbb8f204..1c9d13ad420 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java +++ b/liquibase-core/src/main/java/liquibase/serializer/AbstractLiquibaseSerializable.java @@ -18,6 +18,7 @@ public abstract class AbstractLiquibaseSerializable implements LiquibaseSerializ private Set serializableFields; + @Override public void load(ParsedNode parsedNode, ResourceAccessor resourceAccessor) throws ParsedNodeException { for (ParsedNode childNode : parsedNode.getChildren()) { if (!shouldAutoLoad(childNode)) { diff --git a/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java b/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java index 0da76d05069..0784409a4c6 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java +++ b/liquibase-core/src/main/java/liquibase/serializer/ChangeLogSerializerFactory.java @@ -56,11 +56,7 @@ public ChangeLogSerializer getSerializer(String fileNameOrExtension) { public void register(ChangeLogSerializer changeLogSerializer) { for (String extension : changeLogSerializer.getValidFileExtensions()) { - List changeLogSerializers = serializers.get(extension); - if (changeLogSerializers == null) { - changeLogSerializers = new ArrayList<>(); - serializers.put(extension, changeLogSerializers); - } + List changeLogSerializers = serializers.computeIfAbsent(extension, k -> new ArrayList<>()); changeLogSerializers.add(changeLogSerializer); Collections.sort(changeLogSerializers, PrioritizedService.COMPARATOR); } diff --git a/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java b/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java index 1c8b9c3db81..f2ef1b02937 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java +++ b/liquibase-core/src/main/java/liquibase/serializer/SnapshotSerializerFactory.java @@ -56,11 +56,7 @@ public SnapshotSerializer getSerializer(String fileNameOrExtension) { public void register(SnapshotSerializer snapshotSerializer) { for (String extension : snapshotSerializer.getValidFileExtensions()) { - List snapshotSerializers = serializers.get(extension); - if (snapshotSerializers == null) { - snapshotSerializers = new ArrayList<>(); - serializers.put(extension, snapshotSerializers); - } + List snapshotSerializers = serializers.computeIfAbsent(extension, k -> new ArrayList<>()); snapshotSerializers.add(snapshotSerializer); Collections.sort(snapshotSerializers, PrioritizedService.COMPARATOR); } diff --git a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java index 52d6b980510..9eade3550ec 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java +++ b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlChangeLogSerializer.java @@ -11,6 +11,7 @@ public class YamlChangeLogSerializer extends YamlSerializer implements ChangeLogSerializer { + @Override protected Comparator getComparator(LiquibaseSerializable object) { if (object instanceof ChangeSet) { return new ChangeSetComparator(); diff --git a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java index 2772da4137b..e13da1a9ba6 100644 --- a/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java +++ b/liquibase-core/src/main/java/liquibase/serializer/core/yaml/YamlSnapshotSerializer.java @@ -1,6 +1,7 @@ package liquibase.serializer.core.yaml; import liquibase.GlobalConfiguration; +import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.serializer.LiquibaseSerializable; import liquibase.serializer.SnapshotSerializer; @@ -10,7 +11,6 @@ import liquibase.statement.SequenceNextValueFunction; import liquibase.structure.DatabaseObject; import liquibase.structure.DatabaseObjectCollection; -import liquibase.structure.DatabaseObjectComparator; import liquibase.structure.core.Column; import liquibase.util.ISODateFormat; import liquibase.util.StringUtil; @@ -86,7 +86,7 @@ protected Object toMap(final LiquibaseSerializable object) { SortedMap returnMap = new TreeMap<>(); for (Map.Entry, Set> entry : ((DatabaseObjectCollection) object).toMap().entrySet()) { ArrayList value = new ArrayList(entry.getValue()); - Collections.sort(value, new DatabaseObjectComparator()); + Collections.sort(value, new DatabaseObjectCollectionComparator()); returnMap.put(entry.getKey().getName(), value); } return returnMap; @@ -94,6 +94,7 @@ protected Object toMap(final LiquibaseSerializable object) { return super.toMap(object); } + @Override protected LiquibaseRepresenter getLiquibaseRepresenter() { return new SnapshotLiquibaseRepresenter(); } @@ -105,6 +106,7 @@ public int getPriority() { public static class SnapshotLiquibaseRepresenter extends LiquibaseRepresenter { + @Override protected void init() { multiRepresenters.put(DatabaseFunction.class, new TypeStoringAsStringRepresenter()); multiRepresenters.put(SequenceNextValueFunction.class, new TypeStoringAsStringRepresenter()); diff --git a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java index 864f893a06b..1ff02078d25 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/DatabaseSnapshot.java @@ -312,11 +312,7 @@ protected T include(T example) throws DatabaseExcepti T object = chain.snapshot(example, this); if (object == null) { - Set collection = knownNull.get(example.getClass()); - if (collection == null) { - collection = new HashSet<>(); - knownNull.put(example.getClass(), collection); - } + Set collection = knownNull.computeIfAbsent(example.getClass(), k -> new HashSet<>()); collection.add(example); if (example instanceof Schema) { diff --git a/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java b/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java index 4ff868b2e40..796f3b2a3fa 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/ResultSetCache.java @@ -31,11 +31,7 @@ public List get(ResultSetExtractor resultSetExtractor) throws Databas String schemaKey = resultSetExtractor.wantedKeyParameters().createSchemaKey(resultSetExtractor.database); - Map> cache = cacheBySchema.get(schemaKey); - if (cache == null) { - cache = new HashMap<>(); - cacheBySchema.put(schemaKey, cache); - } + Map> cache = cacheBySchema.computeIfAbsent(schemaKey, k -> new HashMap<>()); if (cache.containsKey(wantedKey)) { return cache.get(wantedKey); @@ -78,11 +74,7 @@ public List get(ResultSetExtractor resultSetExtractor) throws Databas String rowSchema = CatalogAndSchema.CatalogAndSchemaCase.ORIGINAL_CASE. equals(resultSetExtractor.database.getSchemaAndCatalogCase())?resultSetExtractor.getSchemaKey(row): resultSetExtractor.getSchemaKey(row).toLowerCase(); - cache = cacheBySchema.get(rowSchema); - if (cache == null) { - cache = new HashMap>(); - cacheBySchema.put(rowSchema, cache); - } + cache = cacheBySchema.computeIfAbsent(rowSchema, k -> new HashMap>()); } if (!cache.containsKey(rowKey)) { cache.put(rowKey, new ArrayList()); diff --git a/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java b/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java index 8ab85d2886f..f93db624dc1 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/SnapshotGeneratorComparator.java @@ -17,7 +17,7 @@ public SnapshotGeneratorComparator(Class objectType, D @Override public int compare(SnapshotGenerator o1, SnapshotGenerator o2) { - int result = -1 * Integer.valueOf(o1.getPriority(objectType, database)).compareTo(o2.getPriority(objectType, database)); + int result = -1 * Integer.compare(o1.getPriority(objectType, database), o2.getPriority(objectType, database)); if (result == 0) { return o1.getClass().getName().compareTo(o2.getClass().getName()); } diff --git a/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java b/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java index abfc2bbaa33..3b8036f15b0 100644 --- a/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java +++ b/liquibase-core/src/main/java/liquibase/snapshot/jvm/UniqueConstraintSnapshotGenerator.java @@ -406,11 +406,7 @@ protected List listConstraints(Table table, DatabaseSnapshot snapshot snapshot.setScratchData(cacheKey, columnCache); for (Map row : rows) { String key = getCacheKey(row, database); - List> constraintRows = columnCache.get(key); - if (constraintRows == null) { - constraintRows = new ArrayList<>(); - columnCache.put(key, constraintRows); - } + List> constraintRows = columnCache.computeIfAbsent(key, k -> new ArrayList<>()); constraintRows.add(row); } diff --git a/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java b/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java index 2ea3bcfda2e..eec78fd6ef2 100644 --- a/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java +++ b/liquibase-core/src/main/java/liquibase/sql/visitor/AbstractSqlVisitor.java @@ -66,10 +66,12 @@ public void setContextFilter(ContextExpression contextFilter) { this.contextFilter = contextFilter; } + @Override public Labels getLabels() { return labels; } + @Override public void setLabels(Labels labels) { this.labels = labels; } diff --git a/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java b/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java index 78404151796..470abbba3fa 100644 --- a/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java +++ b/liquibase-core/src/main/java/liquibase/sqlgenerator/SqlGeneratorComparator.java @@ -5,6 +5,6 @@ class SqlGeneratorComparator implements Comparator { @Override public int compare(SqlGenerator o1, SqlGenerator o2) { - return -1 * Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); + return -1 * Integer.compare(o1.getPriority(), o2.getPriority()); } } diff --git a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java index ab946c9969c..1d319c325cc 100644 --- a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java +++ b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddPrimaryKeyGenerator.java @@ -66,7 +66,7 @@ public Sql[] generateSql(AddPrimaryKeyStatement statement, Database database, Sq if (database instanceof MSSQLDatabase) { sql += " ON "+statement.getTablespace(); } else if ((database instanceof AbstractDb2Database) || (database instanceof SybaseASADatabase)) { - ; //not supported + //not supported } else { sql += " USING INDEX TABLESPACE "+statement.getTablespace(); } diff --git a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java index bb7d53a9958..9a0c179a1df 100644 --- a/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java +++ b/liquibase-core/src/main/java/liquibase/sqlgenerator/core/AddUniqueConstraintGenerator.java @@ -83,7 +83,7 @@ public Sql[] generateSql(AddUniqueConstraintStatement statement, Database databa sql += " ON " + statement.getTablespace(); } else if ((database instanceof AbstractDb2Database) || (database instanceof SybaseASADatabase) || (database instanceof InformixDatabase)) { - ; //not supported + //not supported } else if (database instanceof OracleDatabase) { /* * In Oracle, you can use only exactly one of these clauses: diff --git a/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java b/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java index dae92c362b9..364d9670495 100644 --- a/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java +++ b/liquibase-core/src/main/java/liquibase/structure/DatabaseObjectCollection.java @@ -2,6 +2,7 @@ import liquibase.database.Database; import liquibase.diff.compare.CompareControl; +import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.diff.compare.DatabaseObjectComparatorFactory; import liquibase.exception.UnexpectedLiquibaseException; import liquibase.parser.core.ParsedNode; @@ -48,7 +49,7 @@ public Set getSerializableFields() { @Override public Object getSerializableFieldValue(String field) { - SortedSet objects = new TreeSet<>(new DatabaseObjectComparator()); + SortedSet objects = new TreeSet<>(new DatabaseObjectCollectionComparator()); try { Map> map = cache.get(Class.forName(field)); if (map == null) { @@ -72,20 +73,12 @@ public void add(DatabaseObject databaseObject) { if (databaseObject == null) { return; } - Map> collectionMap = cache.get(databaseObject.getClass()); - if (collectionMap == null) { - collectionMap = new HashMap<>(); - cache.put(databaseObject.getClass(), collectionMap); - } + Map> collectionMap = cache.computeIfAbsent(databaseObject.getClass(), k -> new HashMap<>()); String[] hashes = DatabaseObjectComparatorFactory.getInstance().hash(databaseObject, null, database); for (String hash : hashes) { - Set collection = collectionMap.get(hash); - if (collection == null) { - collection = new HashSet<>(); - collectionMap.put(hash, collection); - } + Set collection = collectionMap.computeIfAbsent(hash, k -> new HashSet<>()); collection.add(databaseObject); } } diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java b/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java index ddd3ac84ec8..d95e93ae578 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Catalog.java @@ -71,11 +71,7 @@ public void addDatabaseObject(DatabaseObject databaseObject) { if (databaseObject == null) { return; } - Set objects = this.getObjects().get(databaseObject.getClass()); - if (objects == null) { - objects = new HashSet<>(); - this.getObjects().put(databaseObject.getClass(), objects); - } + Set objects = this.getObjects().computeIfAbsent(databaseObject.getClass(), k -> new HashSet<>()); objects.add(databaseObject); } diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Relation.java b/liquibase-core/src/main/java/liquibase/structure/core/Relation.java index eb93416255b..de5819eeafb 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Relation.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Relation.java @@ -101,6 +101,7 @@ public Relation setSchema(String catalog, String schema) { return setSchema(new Schema(catalog, schema)); } + @Override public int compareTo(Object o) { Relation that = (Relation) o; int returnValue = 0; diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Schema.java b/liquibase-core/src/main/java/liquibase/structure/core/Schema.java index 0cf0b506706..4208bf340b4 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Schema.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Schema.java @@ -138,11 +138,7 @@ public void addDatabaseObject(DatabaseObject databaseObject) { if (databaseObject == null) { return; } - Set objects = this.getObjects().get(databaseObject.getClass()); - if (objects == null) { - objects = new HashSet<>(); - this.getObjects().put(databaseObject.getClass(), objects); - } + Set objects = this.getObjects().computeIfAbsent(databaseObject.getClass(), k -> new HashSet<>()); objects.add(databaseObject); } diff --git a/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java b/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java index 136c1efdee0..965211ae731 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/StoredDatabaseLogic.java @@ -1,5 +1,6 @@ package liquibase.structure.core; +import liquibase.diff.compare.DatabaseObjectCollectionComparator; import liquibase.license.LicenseServiceUtils; import liquibase.structure.AbstractDatabaseObject; import liquibase.structure.DatabaseObject; @@ -57,6 +58,10 @@ public T setBody(String body) { return (T) this; } + public DatabaseObjectCollectionComparator getDbObjectComparator() { + return null; + } + @Override public boolean equals(Object obj) { if (this == obj) return true; diff --git a/liquibase-core/src/main/java/liquibase/structure/core/Table.java b/liquibase-core/src/main/java/liquibase/structure/core/Table.java index 4309c577228..88dfd75dc5b 100644 --- a/liquibase-core/src/main/java/liquibase/structure/core/Table.java +++ b/liquibase-core/src/main/java/liquibase/structure/core/Table.java @@ -38,10 +38,12 @@ public List getOutgoingForeignKeys() { return ((fkList == null) ? new ArrayList(0) : fkList); } + @Override public List getIndexes() { return getAttribute("indexes", List.class); } + @Override public List getUniqueConstraints() { return getAttribute("uniqueConstraints", List.class); } diff --git a/liquibase-core/src/main/java/liquibase/util/FileUtil.java b/liquibase-core/src/main/java/liquibase/util/FileUtil.java index 3cd117443dc..c7419a05015 100644 --- a/liquibase-core/src/main/java/liquibase/util/FileUtil.java +++ b/liquibase-core/src/main/java/liquibase/util/FileUtil.java @@ -16,7 +16,7 @@ public static String getContents(File file) throws IOException { return null; } try ( - FileInputStream fileInputStream = new FileInputStream(file); + FileInputStream fileInputStream = new FileInputStream(file) ) { return StreamUtil.readStreamAsString(fileInputStream); diff --git a/liquibase-core/src/main/java/liquibase/util/MD5Util.java b/liquibase-core/src/main/java/liquibase/util/MD5Util.java index 4d55aaccc47..548aacb8ebb 100644 --- a/liquibase-core/src/main/java/liquibase/util/MD5Util.java +++ b/liquibase-core/src/main/java/liquibase/util/MD5Util.java @@ -57,7 +57,7 @@ public static String computeMD5(InputStream stream) { DigestInputStream digestStream = new DigestInputStream(stream, digest); byte[] buf = new byte[20480]; while (digestStream.read(buf) != -1) { - ; //digest is updating + //digest is updating } } catch (Exception e) { throw new RuntimeException(e); diff --git a/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java b/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java index b0a7f561e1d..00baa0e34b2 100644 --- a/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java +++ b/liquibase-core/src/main/java/liquibase/util/ObjectUtil.java @@ -242,13 +242,7 @@ private static Method getWriteMethod(Object object, String propertyName) { * @return a list of methods belonging to the class of the object */ private static Method[] getMethods(Object object) { - Method[] methods = methodCache.get(object.getClass()); - - if (methods == null) { - methods = object.getClass().getMethods(); - methodCache.put(object.getClass(), methods); - } - return methods; + return methodCache.computeIfAbsent(object.getClass(), k -> object.getClass().getMethods()); } /** diff --git a/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java b/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java index 5fa21d699c2..ac3df5637d3 100644 --- a/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java +++ b/liquibase-core/src/main/java/liquibase/util/csv/CSVWriter.java @@ -23,6 +23,7 @@ public void writeNext(String[] nextLine) { delegate.writeNext(nextLine); } + @Override public void flush() throws IOException { delegate.flush(); } diff --git a/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java b/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java index d22ec135524..18ea509f7f8 100644 --- a/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java +++ b/liquibase-core/src/main/java/liquibase/util/xml/DefaultXmlWriter.java @@ -23,7 +23,7 @@ public void write(Document doc, OutputStream outputStream) throws IOException { try { factory.setAttribute("indent-number", 4); } catch (Exception e) { - ; //guess we can't set it, that's ok + //guess we can't set it, that's ok } Transformer transformer = factory.newTransformer(); diff --git a/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep b/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep index bbe41212c38..6bbab0ad936 100644 --- a/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep +++ b/liquibase-core/src/main/resources/META-INF/services/liquibase.command.CommandStep @@ -5,6 +5,7 @@ liquibase.command.core.ChangelogSyncToTagCommandStep liquibase.command.core.ChangelogSyncToTagSqlCommandStep liquibase.command.core.ClearChecksumsCommandStep liquibase.command.core.DbDocCommandStep +liquibase.command.core.DbUrlConnectionCommandStep liquibase.command.core.DeactivateChangelogCommandStep liquibase.command.core.DiffChangelogCommandStep liquibase.command.core.DiffCommandStep diff --git a/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java b/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java index 520933c7a8d..e31d94a071b 100644 --- a/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java +++ b/liquibase-core/src/test/java/liquibase/command/core/MockCommandStep.java @@ -9,10 +9,12 @@ public class MockCommandStep extends AbstractCommandStep { public static MockCommandStep logic; + public static final String[] COMMAND_NAME = {"mock"}; + public static final CommandArgumentDefinition VALUE_1_ARG; static { - CommandBuilder builder = new CommandBuilder(new String[]{"mock"}); + CommandBuilder builder = new CommandBuilder(COMMAND_NAME); VALUE_1_ARG = builder.argument("value1", String.class) .description("Value 1").build(); @@ -27,7 +29,7 @@ public static void reset() { @Override public String[][] defineCommandNames() { - return new String[][]{new String[] {"mock"}}; + return new String[][]{COMMAND_NAME}; } @Override diff --git a/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java b/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java index 460b4c39b93..acda488299c 100644 --- a/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java +++ b/liquibase-core/src/test/java/liquibase/verify/change/VerifyChangeClassesTest.java @@ -227,7 +227,7 @@ public void extraParamsIsValidSql() throws Exception { Collections.sort(paramLists, new Comparator>() { @Override public int compare(List o1, List o2) { - int comp = Integer.valueOf(o1.size()).compareTo(o2.size()); + int comp = Integer.compare(o1.size(), o2.size()); if (comp == 0) { comp = StringUtil.join(o1,",").compareTo(StringUtil.join(o2, ",")); } diff --git a/liquibase-dist/pom.xml b/liquibase-dist/pom.xml index a53aff2c7cf..19071669dcc 100644 --- a/liquibase-dist/pom.xml +++ b/liquibase-dist/pom.xml @@ -20,7 +20,7 @@ 11.2.1.jre8 8.0.21 3.1.0 - 21.7.0.0 + 21.8.0.0 3.40.0.0 11.5.8.0 4.0.8.java8 @@ -76,7 +76,7 @@ net.snowflake snowflake-jdbc - 3.13.25 + 3.13.26 diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt new file mode 100644 index 00000000000..10adb95aea8 --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt @@ -0,0 +1,182 @@ +SOFTWARE LICENSE SUBSCRIPTION AND SUPPORT AGREEMENT + +PLEASE READ THIS AGREEMENT CAREFULLY BEFORE USING THIS SERVICE. + +BY USING THE SOFTWARE OR CLICKING AGREE, CUSTOMER IS AGREEING TO BE BOUND BY +THIS AGREEMENT. IF YOU ARE AGREEING TO THIS AGREEMENT ON BEHALF OF OR FOR THE +BENEFIT OF YOUR EMPLOYER OR A THIRD PARTY, THEN YOU REPRESENT AND WARRANT THAT +YOU HAVE THE NECESSARY AUTHORITY TO AGREE TO THIS AGREEMENT ON YOUR EMPLOYER'S +OR THAT THIRD PARTY'S BEHALF. + +This agreement is between Liquibase, Inc. a Delaware corporation (Liquibase) and +you, the customer entering into this agreement (Customer). The LiquibasePro +software, updates, documentation and license keys provided to Customer +(Software) are licensed and are not sold. + +SCOPE. This agreement describes the licensing of the Software and support +provided to Customer under an order. Third party contractors and majority owned +affiliates of Customer can use and access the Software under the terms of this +agreement, and Customer is responsible for each of their compliance with such +terms. + +1. LICENSE. Subject to the other terms of this agreement, Liquibase grants +Customer, under an order, a term based non-exclusive, non-transferable license +up to the license capacity purchased to use the Software only in Customer’s +internal business operations. Third party licenses delivered with the Software +may be subject to additional license rights and restrictions a set forth at +https://www.liquibase.com/licenses/liquibase_pro_tpl.html. + +2. RESTRICTIONS. Customer may not: +a. Transfer, assign, sublicense, rent the Software, create derivative works of +the Software, or use it in any type of service provider environment; +b. Reverse engineer, decompile, disassemble, or translate the Software; or +c. Evaluate the Software for the purpose of competing with Liquibase Pro or +operate the Software other than in accordance with its technical documentation. + +3. PROPRIETARY RIGHTS AND MUTUAL CONFIDENTIALITY. +a. Proprietary Rights. The Software, workflow processes, user interface, +designs and other technologies provided by Liquibase as part of the Software are +the proprietary property of Liquibase and its licensors, and all right, title and +interest in and to such items, including all associated intellectual property +rights, remain only with Liquibase and its licensors. The Software is protected +by copyright and other intellectual property laws. Customer may not remove any +product identification, copyright, trademark or other notice from the Software. +Liquibase reserves all rights not expressly granted. +b. Mutual Confidentiality. Recipient may not disclose Confidential Information +of Discloser to any third party or use the Confidential Information in +violation of this agreement. +Confidential Information means all information that is disclosed to the +recipient (Recipient) by the discloser (Discloser), and includes, among other +things: + * any and all information relating to products or services provided by a +Discloser, software code, flow charts, techniques, specifications, development +and marketing plans, strategies, and forecasts; + * as to Liquibase, the Software and the terms of this agreement, including +without limitation, all pricing information. +Confidential Information excludes information that: + * was rightfully in Recipient's possession without any obligation of +confidentiality before receipt from the Discloser; + * is or becomes a matter of public knowledge through no fault of Recipient; + * is rightfully received by Recipient from a third party without violation of +a duty of confidentiality; or + * is independently developed by or for Recipient without use or access to the +Confidential Information. + +Recipient may disclose Confidential Information if required by law, but it will +attempt to provide notice to the Discloser in advance so it may seek a +protective order. Each party acknowledges that any misuse of the other party’s +Confidential Information may cause irreparable harm for which there is no +adequate remedy at law. Either party may seek immediate injunctive relief in +such event. + +4. WARRANTY, REMEDY and DISCLAIMER. For new license purchases, Liquibase warrants +that the Software will perform in substantial accordance with its accompanying +technical documentation for a period of 60 days from the date of the order. +This warranty will not apply to any problems caused by software not licensed to +Customer by Liquibase, use other than in accordance with the technical +documentation, or misuse of the Software. The warranty only covers problems +reported to Liquibase during the warranty period or 30 days after. Customer will +cooperate with Liquibase in resolving any warranty claim. +A. EXCLUSIVE REMEDY AND SOLE LIABILITY. Liquibase will use commercially +reasonable efforts to remedy covered warranty claims within a reasonable period +of time or replace the Software, or if Liquibase cannot do so it will refund to +Customer the license fee paid. THIS REMEDY IS CUSTOMER’S EXCLUSIVE REMEDY, AND +LIQUIBASE’S SOLE LIABILITY FOR THESE WARRANTY CLAIMS. +B. DISCLAIMER OF WARRANTIES. LIQUIBASE DISCLAIMS ALL OTHER EXPRESS AND IMPLIED +WARRANTIES, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTY OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. CUSTOMER UNDERSTANDS THAT +THE SOFTWARE MAY NOT BE ERROR FREE, AND USE MAY BE INTERRUPTED. + +5. TERMINATION. This agreement expires at the end of the license period +specified. Either party may terminate this agreement upon a material breach of +the other party after a 30 days’ notice/cure period, if the breach is not cured +during such time period. Upon terminationof this agreement or a license, +Customer must discontinue using the Software, de-install and destroy or return +the Software and all copies, within 5 days. Upon Liquibase's request, Customer +will provide written certification of such compliance. + +6. SUPPORT. Liquibase’s technical support and maintenance services (Support) is +included with the license fees. Customer will receive best efforts e-mail +response for support within two business days from receipt of issue. Liquibase +may change its Support terms, but Support will not materially degrade during +any Support term. + +7. LIMIT ON LIABILITY. There may be situations in which (as a result of +material breach or other liability) Customer is entitled to make a claim +against Liquibase. In each situation (regardless of the form of the legal action +(e.g. contract or tort claims)), Liquibase is not responsible for any damage and +does not have any liability beyond the greater of the amount paid or payable by +Customer to Liquibase within the 12 months prior to the event that gave rise to +the claim and in no event is Liquibase responsible for any: loss of data or +information; lost profits, revenue, or productivity; or other special, +consequential, incidental or indirect damages. + +8. INTELLECTUAL PROPERTY INDEMNITY +a. Defense of Third Party Claims. Liquibase will defend or settle any third party +claim against Customer to the extent that such claim alleges that the Software +violates a copyright, patent, trademark or other intellectual property right, +if Customer, promptly notifies Liquibase of the claim in writing, cooperates with +Liquibase in the defense, and allows Liquibase to solely control the defense or +settlement of the claim. Costs. Liquibase will pay infringement claim defense +costs incurred as part of its obligations above, and Liquibase negotiated +settlement amounts, and court awarded damages. Process. If such a claim appears +likely, then Liquibase may modify the Software, procure the necessary rights, or +replace it with the functional equivalent. If Liquibase determines that none of +these are reasonably available, then Liquibase may terminate the Software and +refund any prepaid and unused fees. Exclusions. Liquibase has no obligation for +any claim arising from: Liquibase’s compliance with Customer’s specifications; A +combination of the Software with other technology where the infringement would +not occur but for the combination; or Technology not provided by Liquibase. THIS +SECTION CONTAINS CUSTOMER’S EXCLUSIVE REMEDIES AND LIQUIBASE’S SOLE LIABILITY FOR +INTELLECTUAL PROPERTY INFRINGEMENT CLAIMS. + +9. GOVERNING LAW AND EXCLUSIVE FORUM. This agreement is governed by the laws of +the State of Delaware (without regard to conflicts of law principles) for any +dispute between the parties or relating in any way to the subject matter of +this agreement. Any suit or legal proceeding must be exclusively brought in the +federal or state courts for Travis County, Texas, and Customer submits to this +personal jurisdiction and venue. Nothing in this agreement prevents either +party from seeking injunctive relief in a court of competent jurisdiction. The +prevailing party in litigation is entitled to recover its attorneys’ fees and +costs from the other party. + +10. OTHER TERMS. +a. Entire Agreement. This agreement and the order constitute the entire +agreement between the parties and supersede any prior or contemporaneous +negotiations or agreements, whether oral or written, related to this subject +matter. Customer is not relying on any representation concerning this subject +matter, oral or written, not included in this agreement. No representation, +promise or inducement not included in this agreement is binding. +b. Non-Assignment. Neither party may assign or transfer this agreement to a +third party, nor delegate any duty, except that the agreement and all orders +may be assigned, without the consent of the other party, as part of a merger, +or sale of all or substantially all of the business or assets, of a party. +c. Independent Contractors. The parties are independent contractors with +respect to each other. +d. Enforceability. If any term of this agreement is invalid or unenforceable, +the other terms remain in effect. +e. Survival of Terms and Force Majeure. All terms that by their nature survive +termination of this agreement for each party to receive the benefits and +protections of this agreement, will survive. Neither party is liable for events +beyond its reasonable control, including, without limitation force majeure +events. +f. Modification Only in Writing. No modification or waiver of any term of this +agreement is effective unless signed by both parties. +g. Export Compliance. Customer must comply with all applicable export control +laws of the United States, foreign jurisdictions and other applicable laws and +regulations. +h. US GOVERNMENT RESTRICTED RIGHTS. If Customer is a United States government +agency or acquired the license to the Software hereunder pursuant to a +government contract or with government funds, then as defined in FAR §2.101, +DFAR §252.227-7014(a)(1) and DFAR §252.227-7014(a)(5) or otherwise, all +Software provided in connection with this agreement are “commercial items,” +“commercial computer software” or “commercial computer software documentation.” +Consistent with DFAR §227.7202 and FAR §12.212, any use, modification, +reproduction, release, performance, display, disclosure or distribution by or +for the United States government is governed solely by the terms of this +agreement and is prohibited except to the extent permitted by the terms of this +agreement. +i. No PO Terms. Liquibase rejects conflicting terms of a Customer’s +form-purchasing document. +j. Order of Precedence. If there is an inconsistency between this agreement and +an order, the order prevails. diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt new file mode 100644 index 00000000000..76cff2883af --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/README.txt @@ -0,0 +1,22 @@ +Liquibase License Information (Used by Liquibase AWS Secrets Manager Extension) +Version: ${project.version} + +Liquibase ships with 3rd party components using the following licenses: +- Apache 2.0 License - https://www.apache.org/licenses/LICENSE-2.0.txt +- MIT License - http://www.opensource.org/licenses/mit-license.php +- Liquibase Pro EULA Software License Subscription and Support Agreement + +Libraries and their licenses: + +Apache 2.0 License +- org.liquibase:liquibase-core +- software.amazon.awssdk:secretsmanager +- software.amazon.awssdk:ssm +- com.google.code.gson:gjson + +MIT License +- org.slf4j:slf4j-api +- org.slf4j:slf4j-jdk14 + +Liquibase Pro EULA Software License Subscription and Support Agreement +- org.liquibase:liquibase-commercial diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt new file mode 100644 index 00000000000..8e77af12431 --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/apache-2.0.txt @@ -0,0 +1,65 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. diff --git a/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt new file mode 100644 index 00000000000..fe45399e37a --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/aws-secrets-manager-extension/mit.txt @@ -0,0 +1,6 @@ +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt new file mode 100644 index 00000000000..10adb95aea8 --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/Liquibase Pro EULA Software License Subscription and Support Agreement.txt @@ -0,0 +1,182 @@ +SOFTWARE LICENSE SUBSCRIPTION AND SUPPORT AGREEMENT + +PLEASE READ THIS AGREEMENT CAREFULLY BEFORE USING THIS SERVICE. + +BY USING THE SOFTWARE OR CLICKING AGREE, CUSTOMER IS AGREEING TO BE BOUND BY +THIS AGREEMENT. IF YOU ARE AGREEING TO THIS AGREEMENT ON BEHALF OF OR FOR THE +BENEFIT OF YOUR EMPLOYER OR A THIRD PARTY, THEN YOU REPRESENT AND WARRANT THAT +YOU HAVE THE NECESSARY AUTHORITY TO AGREE TO THIS AGREEMENT ON YOUR EMPLOYER'S +OR THAT THIRD PARTY'S BEHALF. + +This agreement is between Liquibase, Inc. a Delaware corporation (Liquibase) and +you, the customer entering into this agreement (Customer). The LiquibasePro +software, updates, documentation and license keys provided to Customer +(Software) are licensed and are not sold. + +SCOPE. This agreement describes the licensing of the Software and support +provided to Customer under an order. Third party contractors and majority owned +affiliates of Customer can use and access the Software under the terms of this +agreement, and Customer is responsible for each of their compliance with such +terms. + +1. LICENSE. Subject to the other terms of this agreement, Liquibase grants +Customer, under an order, a term based non-exclusive, non-transferable license +up to the license capacity purchased to use the Software only in Customer’s +internal business operations. Third party licenses delivered with the Software +may be subject to additional license rights and restrictions a set forth at +https://www.liquibase.com/licenses/liquibase_pro_tpl.html. + +2. RESTRICTIONS. Customer may not: +a. Transfer, assign, sublicense, rent the Software, create derivative works of +the Software, or use it in any type of service provider environment; +b. Reverse engineer, decompile, disassemble, or translate the Software; or +c. Evaluate the Software for the purpose of competing with Liquibase Pro or +operate the Software other than in accordance with its technical documentation. + +3. PROPRIETARY RIGHTS AND MUTUAL CONFIDENTIALITY. +a. Proprietary Rights. The Software, workflow processes, user interface, +designs and other technologies provided by Liquibase as part of the Software are +the proprietary property of Liquibase and its licensors, and all right, title and +interest in and to such items, including all associated intellectual property +rights, remain only with Liquibase and its licensors. The Software is protected +by copyright and other intellectual property laws. Customer may not remove any +product identification, copyright, trademark or other notice from the Software. +Liquibase reserves all rights not expressly granted. +b. Mutual Confidentiality. Recipient may not disclose Confidential Information +of Discloser to any third party or use the Confidential Information in +violation of this agreement. +Confidential Information means all information that is disclosed to the +recipient (Recipient) by the discloser (Discloser), and includes, among other +things: + * any and all information relating to products or services provided by a +Discloser, software code, flow charts, techniques, specifications, development +and marketing plans, strategies, and forecasts; + * as to Liquibase, the Software and the terms of this agreement, including +without limitation, all pricing information. +Confidential Information excludes information that: + * was rightfully in Recipient's possession without any obligation of +confidentiality before receipt from the Discloser; + * is or becomes a matter of public knowledge through no fault of Recipient; + * is rightfully received by Recipient from a third party without violation of +a duty of confidentiality; or + * is independently developed by or for Recipient without use or access to the +Confidential Information. + +Recipient may disclose Confidential Information if required by law, but it will +attempt to provide notice to the Discloser in advance so it may seek a +protective order. Each party acknowledges that any misuse of the other party’s +Confidential Information may cause irreparable harm for which there is no +adequate remedy at law. Either party may seek immediate injunctive relief in +such event. + +4. WARRANTY, REMEDY and DISCLAIMER. For new license purchases, Liquibase warrants +that the Software will perform in substantial accordance with its accompanying +technical documentation for a period of 60 days from the date of the order. +This warranty will not apply to any problems caused by software not licensed to +Customer by Liquibase, use other than in accordance with the technical +documentation, or misuse of the Software. The warranty only covers problems +reported to Liquibase during the warranty period or 30 days after. Customer will +cooperate with Liquibase in resolving any warranty claim. +A. EXCLUSIVE REMEDY AND SOLE LIABILITY. Liquibase will use commercially +reasonable efforts to remedy covered warranty claims within a reasonable period +of time or replace the Software, or if Liquibase cannot do so it will refund to +Customer the license fee paid. THIS REMEDY IS CUSTOMER’S EXCLUSIVE REMEDY, AND +LIQUIBASE’S SOLE LIABILITY FOR THESE WARRANTY CLAIMS. +B. DISCLAIMER OF WARRANTIES. LIQUIBASE DISCLAIMS ALL OTHER EXPRESS AND IMPLIED +WARRANTIES, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTY OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. CUSTOMER UNDERSTANDS THAT +THE SOFTWARE MAY NOT BE ERROR FREE, AND USE MAY BE INTERRUPTED. + +5. TERMINATION. This agreement expires at the end of the license period +specified. Either party may terminate this agreement upon a material breach of +the other party after a 30 days’ notice/cure period, if the breach is not cured +during such time period. Upon terminationof this agreement or a license, +Customer must discontinue using the Software, de-install and destroy or return +the Software and all copies, within 5 days. Upon Liquibase's request, Customer +will provide written certification of such compliance. + +6. SUPPORT. Liquibase’s technical support and maintenance services (Support) is +included with the license fees. Customer will receive best efforts e-mail +response for support within two business days from receipt of issue. Liquibase +may change its Support terms, but Support will not materially degrade during +any Support term. + +7. LIMIT ON LIABILITY. There may be situations in which (as a result of +material breach or other liability) Customer is entitled to make a claim +against Liquibase. In each situation (regardless of the form of the legal action +(e.g. contract or tort claims)), Liquibase is not responsible for any damage and +does not have any liability beyond the greater of the amount paid or payable by +Customer to Liquibase within the 12 months prior to the event that gave rise to +the claim and in no event is Liquibase responsible for any: loss of data or +information; lost profits, revenue, or productivity; or other special, +consequential, incidental or indirect damages. + +8. INTELLECTUAL PROPERTY INDEMNITY +a. Defense of Third Party Claims. Liquibase will defend or settle any third party +claim against Customer to the extent that such claim alleges that the Software +violates a copyright, patent, trademark or other intellectual property right, +if Customer, promptly notifies Liquibase of the claim in writing, cooperates with +Liquibase in the defense, and allows Liquibase to solely control the defense or +settlement of the claim. Costs. Liquibase will pay infringement claim defense +costs incurred as part of its obligations above, and Liquibase negotiated +settlement amounts, and court awarded damages. Process. If such a claim appears +likely, then Liquibase may modify the Software, procure the necessary rights, or +replace it with the functional equivalent. If Liquibase determines that none of +these are reasonably available, then Liquibase may terminate the Software and +refund any prepaid and unused fees. Exclusions. Liquibase has no obligation for +any claim arising from: Liquibase’s compliance with Customer’s specifications; A +combination of the Software with other technology where the infringement would +not occur but for the combination; or Technology not provided by Liquibase. THIS +SECTION CONTAINS CUSTOMER’S EXCLUSIVE REMEDIES AND LIQUIBASE’S SOLE LIABILITY FOR +INTELLECTUAL PROPERTY INFRINGEMENT CLAIMS. + +9. GOVERNING LAW AND EXCLUSIVE FORUM. This agreement is governed by the laws of +the State of Delaware (without regard to conflicts of law principles) for any +dispute between the parties or relating in any way to the subject matter of +this agreement. Any suit or legal proceeding must be exclusively brought in the +federal or state courts for Travis County, Texas, and Customer submits to this +personal jurisdiction and venue. Nothing in this agreement prevents either +party from seeking injunctive relief in a court of competent jurisdiction. The +prevailing party in litigation is entitled to recover its attorneys’ fees and +costs from the other party. + +10. OTHER TERMS. +a. Entire Agreement. This agreement and the order constitute the entire +agreement between the parties and supersede any prior or contemporaneous +negotiations or agreements, whether oral or written, related to this subject +matter. Customer is not relying on any representation concerning this subject +matter, oral or written, not included in this agreement. No representation, +promise or inducement not included in this agreement is binding. +b. Non-Assignment. Neither party may assign or transfer this agreement to a +third party, nor delegate any duty, except that the agreement and all orders +may be assigned, without the consent of the other party, as part of a merger, +or sale of all or substantially all of the business or assets, of a party. +c. Independent Contractors. The parties are independent contractors with +respect to each other. +d. Enforceability. If any term of this agreement is invalid or unenforceable, +the other terms remain in effect. +e. Survival of Terms and Force Majeure. All terms that by their nature survive +termination of this agreement for each party to receive the benefits and +protections of this agreement, will survive. Neither party is liable for events +beyond its reasonable control, including, without limitation force majeure +events. +f. Modification Only in Writing. No modification or waiver of any term of this +agreement is effective unless signed by both parties. +g. Export Compliance. Customer must comply with all applicable export control +laws of the United States, foreign jurisdictions and other applicable laws and +regulations. +h. US GOVERNMENT RESTRICTED RIGHTS. If Customer is a United States government +agency or acquired the license to the Software hereunder pursuant to a +government contract or with government funds, then as defined in FAR §2.101, +DFAR §252.227-7014(a)(1) and DFAR §252.227-7014(a)(5) or otherwise, all +Software provided in connection with this agreement are “commercial items,” +“commercial computer software” or “commercial computer software documentation.” +Consistent with DFAR §227.7202 and FAR §12.212, any use, modification, +reproduction, release, performance, display, disclosure or distribution by or +for the United States government is governed solely by the terms of this +agreement and is prohibited except to the extent permitted by the terms of this +agreement. +i. No PO Terms. Liquibase rejects conflicting terms of a Customer’s +form-purchasing document. +j. Order of Precedence. If there is an inconsistency between this agreement and +an order, the order prevails. diff --git a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt new file mode 100644 index 00000000000..255dcf61cff --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/README.txt @@ -0,0 +1,16 @@ +Liquibase License Information (Used by Liquibase Hashicorp Vault Extension) +Version: ${project.version} + +Liquibase ships with 3rd party components using the following licenses: +- Apache 2.0 License - https://www.apache.org/licenses/LICENSE-2.0.txt +- Liquibase Pro EULA Software License Subscription and Support Agreement + +Libraries and their licenses: + +Apache 2.0 License +- org.liquibase:liquibase-core +- org.apache.httpcomponents:httpclient +- com.google.code.gson:gjson + +Liquibase Pro EULA Software License Subscription and Support Agreement +- org.liquibase:liquibase-commercial diff --git a/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt new file mode 100644 index 00000000000..8e77af12431 --- /dev/null +++ b/liquibase-dist/src/main/archive/licenses/extensions/hashicorp-vault-extension/apache-2.0.txt @@ -0,0 +1,65 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. diff --git a/liquibase-dist/src/main/install4j/liquibase.install4j b/liquibase-dist/src/main/install4j/liquibase.install4j index b7751d6c10e..2c75a356bf1 100644 --- a/liquibase-dist/src/main/install4j/liquibase.install4j +++ b/liquibase-dist/src/main/install4j/liquibase.install4j @@ -16,7 +16,7 @@ sqlite-* - + diff --git a/liquibase-extension-testing/pom.xml b/liquibase-extension-testing/pom.xml index 4967b860617..1069d1bee25 100644 --- a/liquibase-extension-testing/pom.xml +++ b/liquibase-extension-testing/pom.xml @@ -67,7 +67,7 @@ org.slf4j slf4j-jdk14 - 2.0.4 + 2.0.6 diff --git a/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy b/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy index d00ccfda2dc..f4c1b1d4f43 100644 --- a/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy +++ b/liquibase-extension-testing/src/main/groovy/liquibase/extension/testing/command/CommandTests.groovy @@ -257,7 +257,6 @@ Long Description: ${commandDefinition.getLongDescription() ?: "NOT SET"} outputStream = new FileOutputStream(testDef.outputFile) } - commandScope.addArgumentValue("database", database) commandScope.setOutput(outputStream) if (testDef.setup != null) { diff --git a/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy b/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy index 8d518db1670..07836192e8c 100644 --- a/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy +++ b/liquibase-integration-tests/src/test/resources/liquibase/extension/testing/command/tag.test.groovy @@ -34,10 +34,6 @@ Optional Args: password: { it.password }, tag: "version_2.0" ] - - expectedResults = [ - statusCode : 0 - ] } run "Run without a tag should throw an exception", { diff --git a/liquibase-maven-plugin/pom.xml b/liquibase-maven-plugin/pom.xml index df52feead2a..e7c817126cc 100644 --- a/liquibase-maven-plugin/pom.xml +++ b/liquibase-maven-plugin/pom.xml @@ -14,7 +14,7 @@ A Maven plugin wraps up some of the functionality of Liquibase - 3.8.5 + 3.8.7 diff --git a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java index c55027db438..837cc473486 100644 --- a/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java +++ b/liquibase-maven-plugin/src/main/java/org/liquibase/maven/plugins/LiquibaseChangeLogSyncToTagSQLMojo.java @@ -84,8 +84,8 @@ protected Liquibase createLiquibase(Database db) + migrationSqlOutputFile.getAbsolutePath()); } } - outputWriter = getOutputWriter(migrationSqlOutputFile);; - } catch (IOException e) { + outputWriter = getOutputWriter(migrationSqlOutputFile); + } catch (IOException e) { getLog().error(e); throw new MojoExecutionException( "Failed to create SQL output writer", e); diff --git a/pom.xml b/pom.xml index b8aaf95dca6..1060da385ad 100644 --- a/pom.xml +++ b/pom.xml @@ -126,7 +126,7 @@ org.mockito mockito-inline - 4.8.1 + 4.10.0 test @@ -215,7 +215,7 @@ com.oracle.database.jdbc ojdbc8 - 21.7.0.0 + 21.8.0.0 test @@ -229,13 +229,13 @@ net.snowflake snowflake-jdbc - 3.13.25 + 3.13.26 org.firebirdsql.jdbc jaybird - 4.0.6.java8 + 4.0.8.java8 test From 459428e45d2e3a34af2905ce82407fb831f75b8e Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 13:23:09 -0500 Subject: [PATCH 23/28] Revert "Revert "Merge remote-tracking branch 'origin/DAT-12727' into DAT-12602"" This reverts commit 12f65395db094819833d035af8606ff4e36e62f1. --- .../command/CommandArgumentDefinition.java | 3 ++- .../LiquibaseCommandLineConfiguration.java | 21 ++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java index 7b979811452..ff3baa3d7e3 100644 --- a/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java +++ b/liquibase-core/src/main/java/liquibase/command/CommandArgumentDefinition.java @@ -7,6 +7,7 @@ import liquibase.exception.MissingRequiredArgumentException; import liquibase.integration.commandline.LiquibaseCommandLineConfiguration; import liquibase.util.ObjectUtil; +import liquibase.util.StringUtil; import java.util.Collections; import java.util.Objects; @@ -296,7 +297,7 @@ public CommandArgumentDefinition build() throws IllegalArgumentExcepti Scope.getCurrentScope().getSingleton(CommandFactory.class).register(commandName, newCommandArgument); } catch (IllegalArgumentException iae) { Scope.getCurrentScope().getLog(CommandArgumentDefinition.class).warning( - "Unable to register command '" + commandName + "' argument '" + newCommandArgument.getName() + "': " + iae.getMessage()); + "Unable to register command '" + StringUtil.join(commandName, " ") + "' argument '" + newCommandArgument.getName() + "': " + iae.getMessage()); throw iae; } } diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java index 2efa34d1191..f0f8e921fa1 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java @@ -4,7 +4,9 @@ import liquibase.configuration.ConfigurationDefinition; import liquibase.configuration.ConfigurationValueConverter; import liquibase.logging.LogFormat; +import liquibase.util.StringUtil; +import java.util.Arrays; import java.util.logging.Level; /** @@ -82,10 +84,23 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio .build(); LOG_FORMAT = builder.define("logFormat", LogFormat.class) - .setDescription("Set the format of log output to console or log files\n" + - "[OSS] Defaults to \"TEXT\" logs to the console or output log files\n" + - "[PRO] Can be set to \"JSON\" to enable json-structured log files to the console or output log files") + .setDescription("Sets the format of log output to console or log files. " + + "Open Source users default to unstructured \"TEXT\" logs to the console or output log files." + + "Pro users have option to set value as \"JSON\" to enable json-structured log files to the console or output log files.") .setDefaultValue(LogFormat.TEXT) + .setValueHandler((logFormat) -> { + if (logFormat == null) { + return null; + } + + String logFormatString = (String) logFormat; + + if (Arrays.stream(LogFormat.values()).noneMatch(lf -> lf.toString().equalsIgnoreCase(logFormatString))) { + throw new IllegalArgumentException("WARNING: The log format value '"+logFormatString+"' is not valid. Valid values include: '" + StringUtil.join(LogFormat.values(), "', '", Object::toString) + "'"); + } + + return Enum.valueOf(LogFormat.class, logFormatString.toUpperCase()); + }) .build(); } From 4c6a74061303cffadd8f40901131c2f5e1e9e8f6 Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 13:46:41 -0500 Subject: [PATCH 24/28] [DAT-12602] Fix liquibase system information mdc. --- .../commandline/LiquibaseCommandLine.java | 12 +++++++++++- .../src/main/java/liquibase/Liquibase.java | 4 ++-- .../java/liquibase/integration/commandline/Main.java | 8 -------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java index d318cd3db6b..2952a0b33c7 100644 --- a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java +++ b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java @@ -18,6 +18,8 @@ import liquibase.license.LicenseServiceFactory; import liquibase.logging.LogService; import liquibase.logging.core.JavaLogService; +import liquibase.logging.mdc.MdcKey; +import liquibase.logging.mdc.MdcManager; import liquibase.resource.*; import liquibase.ui.ConsoleUIService; import liquibase.ui.UIService; @@ -25,6 +27,7 @@ import picocli.CommandLine; import java.io.*; +import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -349,7 +352,14 @@ public int execute(String[] args) { } enableMonitoring(); - + MdcManager mdcManager = Scope.getCurrentScope().getMdcManager(); + mdcManager.put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildNumber()); + mdcManager.put(MdcKey.LIQUIBASE_SYSTEM_USER, System.getProperty("user.name")); + mdcManager.put(MdcKey.LIQUIBASE_SYSTEM_NAME, InetAddress.getLocalHost().getHostName()); + Scope.getCurrentScope().getLog(getClass()).info("Starting command execution."); + mdcManager.remove(MdcKey.LIQUIBASE_VERSION); + mdcManager.remove(MdcKey.LIQUIBASE_SYSTEM_NAME); + mdcManager.remove(MdcKey.LIQUIBASE_SYSTEM_USER); int response = commandLine.execute(finalArgs); if (!wasHelpOrVersionRequested()) { diff --git a/liquibase-core/src/main/java/liquibase/Liquibase.java b/liquibase-core/src/main/java/liquibase/Liquibase.java index dea8a3b749e..4eb22eb6ff2 100644 --- a/liquibase-core/src/main/java/liquibase/Liquibase.java +++ b/liquibase-core/src/main/java/liquibase/Liquibase.java @@ -302,11 +302,11 @@ public void update(Contexts contexts, LabelExpression labelExpression, boolean c // hubUpdater.postUpdateHub(updateOperation, bufferLog); Scope.getCurrentScope().getMdcManager().put(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_SUCCESSFUL); - Scope.getCurrentScope().getLog(getClass()).info("Command completed successfully."); + Scope.getCurrentScope().getLog(getClass()).info("Update command completed successfully."); Scope.getCurrentScope().getMdcManager().remove(MdcKey.DEPLOYMENT_OUTCOME); } catch (Throwable e) { Scope.getCurrentScope().addMdcValue(MdcKey.DEPLOYMENT_OUTCOME, MdcValue.COMMAND_FAILED); - Scope.getCurrentScope().getLog(getClass()).info("Command encountered an exception."); + Scope.getCurrentScope().getLog(getClass()).info("Update command encountered an exception."); Scope.getCurrentScope().getMdcManager().remove(MdcKey.DEPLOYMENT_OUTCOME); if (hubUpdater != null) { hubUpdater.postUpdateHubExceptionHandling(updateOperation, bufferLog, e.getMessage()); diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java index 89a4a67e6a4..0b537c85d7d 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/Main.java @@ -27,14 +27,12 @@ import liquibase.logging.Logger; import liquibase.logging.core.JavaLogService; import liquibase.logging.mdc.MdcKey; -import liquibase.logging.mdc.MdcValue; import liquibase.resource.*; import liquibase.ui.ConsoleUIService; import liquibase.util.*; import java.io.*; import java.lang.reflect.Field; -import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -327,9 +325,6 @@ public Integer run() throws Exception { } } - Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildNumber()); - Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_SYSTEM_USER, System.getProperty("user.name")); - Scope.getCurrentScope().getMdcManager().put(MdcKey.LIQUIBASE_SYSTEM_NAME, InetAddress.getLocalHost().getHostName()); LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService(); if (licenseService != null) { @@ -400,9 +395,6 @@ public Integer run() throws Exception { if (!Main.runningFromNewCli) { innerScopeObjects.put(Scope.Attr.resourceAccessor.name(), new ClassLoaderResourceAccessor(main.configureClassLoader())); } - Scope.getCurrentScope().getMdcManager().remove(MdcKey.LIQUIBASE_VERSION); - Scope.getCurrentScope().getMdcManager().remove(MdcKey.LIQUIBASE_SYSTEM_NAME); - Scope.getCurrentScope().getMdcManager().remove(MdcKey.LIQUIBASE_SYSTEM_USER); Scope.child(innerScopeObjects, () -> { main.doMigration(); From d7dea0ca941e3f40c973f8b5eb3cbee2e2d3afba Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 15:15:42 -0500 Subject: [PATCH 25/28] [DAT-12602] Fix logged liquibase version. --- .../liquibase/integration/commandline/LiquibaseCommandLine.java | 2 +- liquibase-core/src/main/resources/liquibase.build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java index 2952a0b33c7..6dc3392ada7 100644 --- a/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java +++ b/liquibase-cli/src/main/java/liquibase/integration/commandline/LiquibaseCommandLine.java @@ -353,7 +353,7 @@ public int execute(String[] args) { enableMonitoring(); MdcManager mdcManager = Scope.getCurrentScope().getMdcManager(); - mdcManager.put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildNumber()); + mdcManager.put(MdcKey.LIQUIBASE_VERSION, LiquibaseUtil.getBuildVersion()); mdcManager.put(MdcKey.LIQUIBASE_SYSTEM_USER, System.getProperty("user.name")); mdcManager.put(MdcKey.LIQUIBASE_SYSTEM_NAME, InetAddress.getLocalHost().getHostName()); Scope.getCurrentScope().getLog(getClass()).info("Starting command execution."); diff --git a/liquibase-core/src/main/resources/liquibase.build.properties b/liquibase-core/src/main/resources/liquibase.build.properties index a0435f716ca..510a3a45778 100644 --- a/liquibase-core/src/main/resources/liquibase.build.properties +++ b/liquibase-core/src/main/resources/liquibase.build.properties @@ -4,4 +4,4 @@ build.repository.owner=${build.repository.owner} build.repository.name=${build.repository.name} build.branch=${build.branch} build.commit=${build.commit} -build.version=DEV +build.version=0.0.0 From af19e9787033cfa3977278a84b5ff23e4356d1df Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Wed, 11 Jan 2023 15:39:33 -0500 Subject: [PATCH 26/28] Revert change to build.properties --- liquibase-core/src/main/resources/liquibase.build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liquibase-core/src/main/resources/liquibase.build.properties b/liquibase-core/src/main/resources/liquibase.build.properties index 510a3a45778..a0435f716ca 100644 --- a/liquibase-core/src/main/resources/liquibase.build.properties +++ b/liquibase-core/src/main/resources/liquibase.build.properties @@ -4,4 +4,4 @@ build.repository.owner=${build.repository.owner} build.repository.name=${build.repository.name} build.branch=${build.branch} build.commit=${build.commit} -build.version=0.0.0 +build.version=DEV From cdf7898643754f94802db436aa08e0b7f91fdd73 Mon Sep 17 00:00:00 2001 From: Steven Massaro Date: Thu, 12 Jan 2023 07:49:31 -0600 Subject: [PATCH 27/28] safely cast logformat - fixes using the default value --- .../LiquibaseCommandLineConfiguration.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java index f0f8e921fa1..13917243866 100644 --- a/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java +++ b/liquibase-core/src/main/java/liquibase/integration/commandline/LiquibaseCommandLineConfiguration.java @@ -93,13 +93,19 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio return null; } - String logFormatString = (String) logFormat; + if (logFormat instanceof String) { + String logFormatString = (String) logFormat; - if (Arrays.stream(LogFormat.values()).noneMatch(lf -> lf.toString().equalsIgnoreCase(logFormatString))) { - throw new IllegalArgumentException("WARNING: The log format value '"+logFormatString+"' is not valid. Valid values include: '" + StringUtil.join(LogFormat.values(), "', '", Object::toString) + "'"); - } + if (Arrays.stream(LogFormat.values()).noneMatch(lf -> lf.toString().equalsIgnoreCase(logFormatString))) { + throw new IllegalArgumentException("WARNING: The log format value '"+logFormatString+"' is not valid. Valid values include: '" + StringUtil.join(LogFormat.values(), "', '", Object::toString) + "'"); + } - return Enum.valueOf(LogFormat.class, logFormatString.toUpperCase()); + return Enum.valueOf(LogFormat.class, logFormatString.toUpperCase()); + } else if (logFormat instanceof LogFormat) { + return (LogFormat) logFormat; + } else { + return null; + } }) .build(); From 039c58e6823ef59d9f8ac57f68d380979648a53f Mon Sep 17 00:00:00 2001 From: Alex Brackx Date: Thu, 12 Jan 2023 09:08:48 -0500 Subject: [PATCH 28/28] [DAT-12602] Adds mdc for failed changeset outcome. --- .../src/main/java/liquibase/changelog/ChangeSet.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java index a65af9a9e59..0a9610fe5f4 100644 --- a/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java +++ b/liquibase-core/src/main/java/liquibase/changelog/ChangeSet.java @@ -712,6 +712,10 @@ public ExecType execute(DatabaseChangeLog databaseChangeLog, ChangeExecListener } } catch (Exception e) { + if (getFailOnError() == null || getFailOnError()) { + Scope.getCurrentScope().addMdcValue(MdcKey.CHANGESET_OUTCOME, ExecType.FAILED.value.toLowerCase()); + } + log.info(String.format("ChangeSet %s encountered an exception.", toString(false))); try { database.rollback(); } catch (Exception e1) {