Skip to content

Commit

Permalink
Revert "Revert Use PathHandler for writing log files (#3420)"
Browse files Browse the repository at this point in the history
This reverts commit 9949ca0.
  • Loading branch information
abrackx committed Nov 3, 2022
1 parent 347c33d commit efa4da6
Show file tree
Hide file tree
Showing 18 changed files with 148 additions and 46 deletions.
Expand Up @@ -6,6 +6,7 @@
import liquibase.command.CommonArgumentNames;
import liquibase.exception.CommandValidationException;
import liquibase.exception.MissingRequiredArgumentException;
import liquibase.resource.OpenOptions;
import liquibase.resource.PathHandlerFactory;
import liquibase.util.StringUtil;
import picocli.CommandLine;
Expand Down Expand Up @@ -47,7 +48,7 @@ public CommandResults call() throws Exception {
try {
if (outputFile != null) {
final PathHandlerFactory pathHandlerFactory = Scope.getCurrentScope().getSingleton(PathHandlerFactory.class);
outputStream = pathHandlerFactory.openResourceOutputStream(outputFile, true);
outputStream = pathHandlerFactory.openResourceOutputStream(outputFile, new OpenOptions());
commandScope.setOutput(outputStream);
}

Expand Down
Expand Up @@ -60,7 +60,7 @@ public class LiquibaseCommandLine {
private Level configuredLogLevel;

private final CommandLine commandLine;
private FileHandler fileHandler;
private Handler fileHandler;

private final ResourceBundle coreBundle = getBundle("liquibase/i18n/liquibase-core");

Expand Down Expand Up @@ -89,7 +89,6 @@ public static void main(String[] args) {
private void cleanup() {
if (fileHandler != null) {
fileHandler.flush();
fileHandler.close();
}
}

Expand Down Expand Up @@ -353,9 +352,9 @@ public int execute(String[] args) {
int response = commandLine.execute(finalArgs);

if (!wasHelpOrVersionRequested()) {
final ConfiguredValue<File> logFile = LiquibaseCommandLineConfiguration.LOG_FILE.getCurrentConfiguredValue();
final ConfiguredValue<String> logFile = LiquibaseCommandLineConfiguration.LOG_FILE.getCurrentConfiguredValue();
if (logFile.found()) {
Scope.getCurrentScope().getUI().sendMessage("Logs saved to " + logFile.getValue().getAbsolutePath());
Scope.getCurrentScope().getUI().sendMessage("Logs saved to " + logFile.getValue());
}

final ConfiguredValue<String> outputFile = LiquibaseCommandLineConfiguration.OUTPUT_FILE.getCurrentConfiguredValue();
Expand Down Expand Up @@ -611,7 +610,7 @@ private void configureVersionInfo() {
protected Map<String, Object> configureLogging() throws IOException {
Map<String, Object> returnMap = new HashMap<>();
final ConfiguredValue<Level> currentConfiguredValue = LiquibaseCommandLineConfiguration.LOG_LEVEL.getCurrentConfiguredValue();
final File logFile = LiquibaseCommandLineConfiguration.LOG_FILE.getCurrentValue();
final String logFile = LiquibaseCommandLineConfiguration.LOG_FILE.getCurrentValue();

Level logLevel = Level.OFF;
if (!currentConfiguredValue.wasDefaultValueUsed()) {
Expand All @@ -630,7 +629,7 @@ protected Map<String, Object> configureLogging() throws IOException {
return returnMap;
}

private void configureLogging(Level logLevel, File logFile) throws IOException {
private void configureLogging(Level logLevel, String logFile) throws IOException {
configuredLogLevel = logLevel;

final JavaLogService logService = (JavaLogService) Scope.getCurrentScope().get(Scope.Attr.logService, LogService.class);
Expand All @@ -644,8 +643,9 @@ private void configureLogging(Level logLevel, File logFile) throws IOException {

if (logFile != null) {
if (fileHandler == null) {
fileHandler = new FileHandler(logFile.getAbsolutePath(), true);
fileHandler.setFormatter(new SimpleFormatter());
final PathHandlerFactory pathHandlerFactory = Scope.getCurrentScope().getSingleton(PathHandlerFactory.class);
OutputStream outputStream = pathHandlerFactory.openResourceOutputStream(logFile, new OpenOptions().setAppend(true));
fileHandler = new StreamHandler(outputStream, new SimpleFormatter());
rootLogger.addHandler(fileHandler);
}

Expand Down
@@ -1,15 +1,16 @@
package liquibase.changelog;

import liquibase.Scope;
import liquibase.GlobalConfiguration;
import liquibase.Scope;
import liquibase.parser.core.xml.XMLChangeLogSAXParser;
import liquibase.resource.PathHandlerFactory;
import liquibase.resource.OpenOptions;
import liquibase.resource.Resource;
import liquibase.resource.ResourceAccessor;
import liquibase.util.StreamUtil;

import java.io.*;
import java.util.SortedSet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -73,7 +74,7 @@ public static ChangeLogRewriterResult removeChangeLogId(String changeLogFile, St
}
}

try (OutputStream outputStream = resource.openOutputStream(true)) {
try (OutputStream outputStream = resource.openOutputStream(new OpenOptions())) {
outputStream.write(changeLogString.getBytes(encoding));
}

Expand Down Expand Up @@ -170,7 +171,7 @@ public static ChangeLogRewriterResult addChangeLogId(String changeLogFile, Strin
//
// Write out the file again
//
try (OutputStream outputStream = resource.openOutputStream(true)) {
try (OutputStream outputStream = resource.openOutputStream(new OpenOptions())) {
outputStream.write(changeLogString.getBytes(encoding));
}

Expand Down
Expand Up @@ -7,6 +7,7 @@
import liquibase.database.Database;
import liquibase.dbdoc.*;
import liquibase.exception.LiquibaseException;
import liquibase.resource.OpenOptions;
import liquibase.resource.Resource;
import liquibase.resource.ResourceAccessor;
import liquibase.snapshot.DatabaseSnapshot;
Expand Down Expand Up @@ -176,7 +177,7 @@ private void copyFile(String fileToCopy, Resource rootOutputDir) throws IOExcept
if (inputStream == null) {
throw new IOException("Can not find " + fileToCopy);
}
outputStream = rootOutputDir.resolve(fileToCopy.replaceFirst(".*\\/", "")).openOutputStream(true);
outputStream = rootOutputDir.resolve(fileToCopy.replaceFirst(".*\\/", "")).openOutputStream(new OpenOptions());
StreamUtil.copy(inputStream, outputStream);
} finally {
if (outputStream != null) {
Expand Down
@@ -1,6 +1,7 @@
package liquibase.dbdoc;

import liquibase.GlobalConfiguration;
import liquibase.resource.OpenOptions;
import liquibase.resource.Resource;
import liquibase.resource.ResourceAccessor;
import liquibase.util.StreamUtil;
Expand All @@ -20,7 +21,7 @@ public void writeChangeLog(String changeLog, String physicalFilePath) throws IOE
String changeLogOutFile = changeLog.replace(":", "_");
Resource xmlFile = outputDir.resolve(changeLogOutFile.toLowerCase() + ".html");

try (BufferedWriter changeLogStream = new BufferedWriter(new OutputStreamWriter(xmlFile.openOutputStream(true),
try (BufferedWriter changeLogStream = new BufferedWriter(new OutputStreamWriter(xmlFile.openOutputStream(new OpenOptions()),
GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue()))) {
Resource stylesheet = resourceAccessor.get(physicalFilePath);
if (stylesheet == null) {
Expand Down
@@ -1,6 +1,7 @@
package liquibase.dbdoc;

import liquibase.GlobalConfiguration;
import liquibase.resource.OpenOptions;
import liquibase.resource.Resource;
import liquibase.util.StringUtil;

Expand All @@ -21,7 +22,7 @@ public HTMLListWriter(String title, String filename, String subdir, Resource out
}

public void writeHTML(SortedSet objects) throws IOException {
Writer fileWriter = new OutputStreamWriter(outputDir.resolve(filename).openOutputStream(true), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue());
Writer fileWriter = new OutputStreamWriter(outputDir.resolve(filename).openOutputStream(new OpenOptions()), GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue());

try {
fileWriter.append("<HTML>\n" + "<HEAD><meta charset=\"utf-8\"/>\n" + "<TITLE>\n");
Expand Down
8 changes: 5 additions & 3 deletions liquibase-core/src/main/java/liquibase/dbdoc/HTMLWriter.java
Expand Up @@ -2,15 +2,17 @@

import liquibase.change.Change;
import liquibase.changelog.ChangeSet;
import liquibase.GlobalConfiguration;
import liquibase.database.Database;
import liquibase.exception.DatabaseException;
import liquibase.exception.DatabaseHistoryException;
import liquibase.resource.OpenOptions;
import liquibase.resource.Resource;
import liquibase.util.LiquibaseUtil;
import liquibase.util.StringUtil;

import java.io.*;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
Expand All @@ -27,7 +29,7 @@ public HTMLWriter(Resource outputDir, Database database) {
protected abstract void writeCustomHTML(Writer fileWriter, Object object, List<Change> changes, Database database) throws IOException;

private Writer createFileWriter(Object object) throws IOException {
return new OutputStreamWriter(outputDir.resolve(DBDocUtil.toFileName(object.toString().toLowerCase()) + ".html").openOutputStream(true));
return new OutputStreamWriter(outputDir.resolve(DBDocUtil.toFileName(object.toString().toLowerCase()) + ".html").openOutputStream(new OpenOptions()));
}

public void writeHTML(Object object, List<Change> ranChanges, List<Change> changesToRun, String changeLog) throws IOException, DatabaseHistoryException, DatabaseException {
Expand Down
Expand Up @@ -16,6 +16,7 @@
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.executor.Executor;
import liquibase.executor.ExecutorService;
import liquibase.resource.OpenOptions;
import liquibase.resource.PathHandlerFactory;
import liquibase.resource.Resource;
import liquibase.serializer.ChangeLogSerializer;
Expand Down Expand Up @@ -157,7 +158,7 @@ public void run() {
String toInsert = " " + innerXml + lineSeparator;
fileContents.insert(endTagIndex, toInsert);
}
try (OutputStream outputStream = file.openOutputStream(true)) {
try (OutputStream outputStream = file.openOutputStream(new OpenOptions())) {
outputStream.write(fileContents.toString().getBytes());
}
}
Expand Down Expand Up @@ -211,7 +212,7 @@ public void printNew(ChangeLogSerializer changeLogSerializer, Resource file) thr
Scope.getCurrentScope().getLog(getClass()).info(file + " does not exist, creating and adding " + changeSets.size() + " changesets.");
}

try (OutputStream stream = file.openOutputStream(true);
try (OutputStream stream = file.openOutputStream(new OpenOptions());
PrintStream out = new PrintStream(stream, true, GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue())) {
changeLogSerializer.write(changeSets, out);
}
Expand Down
Expand Up @@ -10,6 +10,7 @@
import liquibase.diff.output.DiffOutputControl;
import liquibase.diff.output.changelog.ChangeGeneratorChain;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.resource.OpenOptions;
import liquibase.resource.PathHandlerFactory;
import liquibase.resource.Resource;
import liquibase.servicelocator.LiquibaseService;
Expand Down Expand Up @@ -84,7 +85,7 @@ public Change[] fixMissing(DatabaseObject missingObject, DiffOutputControl outpu

String[] dataTypes = new String[0];
try (
OutputStream fileOutputStream = externalFileResource.openOutputStream(true);
OutputStream fileOutputStream = externalFileResource.openOutputStream(new OpenOptions());
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
fileOutputStream, GlobalConfiguration.OUTPUT_FILE_ENCODING.getCurrentValue());
CSVWriter outputFile = new CSVWriter(new BufferedWriter(outputStreamWriter));
Expand Down
Expand Up @@ -22,7 +22,7 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio
public static final ConfigurationDefinition<String> DEFAULTS_FILE;
public static final ConfigurationDefinition<Level> LOG_LEVEL;
public static final ConfigurationDefinition<String> LOG_CHANNELS;
public static final ConfigurationDefinition<File> LOG_FILE;
public static final ConfigurationDefinition<String> LOG_FILE;
public static final ConfigurationDefinition<String> OUTPUT_FILE;
public static final ConfigurationDefinition<Boolean> SHOULD_RUN;
public static final ConfigurationDefinition<ArgumentConverter> ARGUMENT_CONVERTER;
Expand Down Expand Up @@ -66,7 +66,7 @@ public class LiquibaseCommandLineConfiguration implements AutoloadedConfiguratio
.setDefaultValue("liquibase", "Controls which log channels have their level set by the liquibase.logLevel setting. Comma separate multiple values. To set the level of all channels, use 'all'. Example: liquibase,org.mariadb.jdbc")
.build();

LOG_FILE = builder.define("logFile", File.class).build();
LOG_FILE = builder.define("logFile", String.class).build();
OUTPUT_FILE = builder.define("outputFile", String.class).build();

MONITOR_PERFORMANCE = builder.define("monitorPerformance", String.class)
Expand Down
@@ -1,6 +1,7 @@
package liquibase.integration.spring;

import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.resource.OpenOptions;
import org.springframework.core.io.Resource;
import org.springframework.core.io.WritableResource;

Expand Down Expand Up @@ -59,10 +60,13 @@ public InputStream openInputStream() throws IOException {
}

@Override
public OutputStream openOutputStream(boolean createIfNeeded) throws IOException {
if (!resource.exists() && !createIfNeeded) {
public OutputStream openOutputStream(OpenOptions openOptions) throws IOException {
if (!resource.exists() && !openOptions.isCreateIfNeeded()) {
throw new IOException("Resource "+getUri()+" does not exist");
}
if (openOptions != null && openOptions.isAppend() && exists()) {
throw new IOException("Spring only supports truncating the existing resources.");
}
if (resource instanceof WritableResource) {
return ((WritableResource) resource).getOutputStream();
}
Expand Down
@@ -1,7 +1,5 @@
package liquibase.resource;

import liquibase.util.StringUtil;

import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
Expand Down Expand Up @@ -40,7 +38,7 @@ public boolean isWritable() {
}

@Override
public OutputStream openOutputStream(boolean createIfNeeded) throws IOException {
public OutputStream openOutputStream(OpenOptions openOptions) throws IOException {
if (!isWritable()) {
throw new IOException("Read only");
}
Expand Down
55 changes: 55 additions & 0 deletions liquibase-core/src/main/java/liquibase/resource/OpenOptions.java
@@ -0,0 +1,55 @@
package liquibase.resource;

/**
* Defines the options for opening {@link Resource}s in Liquibase.
*/
public class OpenOptions {
private boolean truncate;
private boolean createIfNeeded;

/**
* Use default options of truncate = true, createIfNeeded = true;
*/
public OpenOptions() {
this.truncate = true;
this.createIfNeeded = true;
}

/**
* Should an existing file be truncated when opened. Both this and {@link #isAppend()}
* are automatically kept in sync with each other.
*/
public boolean isTruncate() {
return truncate;
}

public OpenOptions setTruncate(boolean truncate) {
this.truncate = truncate;
return this;
}

/**
* Should an existing file be appended to when opened. Both this and {@link #isTruncate()}
* are automatically kept in sync with each other.
*/
public boolean isAppend() {
return !isTruncate();
}

public OpenOptions setAppend(boolean append) {
this.truncate = !append;
return this;
}

/**
* If true, create the resource if it does not exist. If false, do not create the resource.
*/
public boolean isCreateIfNeeded() {
return createIfNeeded;
}

public OpenOptions setCreateIfNeeded(boolean createIfNeeded) {
this.createIfNeeded = createIfNeeded;
return this;
}
}
@@ -1,6 +1,5 @@
package liquibase.resource;

import liquibase.Scope;
import liquibase.exception.UnexpectedLiquibaseException;
import liquibase.plugin.AbstractPluginFactory;

Expand Down Expand Up @@ -75,17 +74,30 @@ public Resource getResource(String resourcePath) throws IOException {
*
* @return null if resourcePath does not exist and createIfNotExists is false
* @throws IOException if there is an error opening the stream
*
* @deprecated use {@link #openResourceOutputStream(String, OpenOptions)}
*/
@Deprecated
public OutputStream openResourceOutputStream(String resourcePath, boolean createIfNotExists) throws IOException {
return openResourceOutputStream(resourcePath, new OpenOptions().setCreateIfNeeded(createIfNotExists));
}

/**
* Returns the outputStream from {@link #getResource(String)}, using settings from the passed {@link OpenOptions}.
*
* @return null if resourcePath does not exist and {@link OpenOptions#isCreateIfNeeded()} is false
* @throws IOException if there is an error opening the stream
*/
public OutputStream openResourceOutputStream(String resourcePath, OpenOptions openOptions) throws IOException {
Resource resource = getResource(resourcePath);
if (!resource.exists()) {
if (createIfNotExists) {
if (openOptions.isCreateIfNeeded()) {
return createResource(resourcePath);
} else {
return null;
}
}
return resource.openOutputStream(createIfNotExists);
return resource.openOutputStream(openOptions);
}

/**
Expand Down

0 comments on commit efa4da6

Please sign in to comment.