Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix liquibase issue with resource path #41530

Merged
merged 1 commit into from
Jul 3, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT;
import static java.util.function.Predicate.not;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
Expand Down Expand Up @@ -61,8 +62,10 @@
import io.quarkus.liquibase.LiquibaseDataSource;
import io.quarkus.liquibase.LiquibaseFactory;
import io.quarkus.liquibase.runtime.LiquibaseBuildTimeConfig;
import io.quarkus.liquibase.runtime.LiquibaseDataSourceBuildTimeConfig;
import io.quarkus.liquibase.runtime.LiquibaseFactoryProducer;
import io.quarkus.liquibase.runtime.LiquibaseRecorder;
import io.quarkus.runtime.util.StringUtil;
import liquibase.change.Change;
import liquibase.change.DatabaseChangeProperty;
import liquibase.change.core.CreateProcedureChange;
Expand All @@ -77,6 +80,9 @@
import liquibase.parser.ChangeLogParserFactory;
import liquibase.plugin.AbstractPluginFactory;
import liquibase.resource.ClassLoaderResourceAccessor;
import liquibase.resource.CompositeResourceAccessor;
import liquibase.resource.DirectoryResourceAccessor;
import liquibase.resource.ResourceAccessor;

class LiquibaseProcessor {

Expand Down Expand Up @@ -360,57 +366,89 @@ private List<String> getChangeLogs(Collection<String> dataSourceNames, Liquibase
return Collections.emptyList();
}

ChangeLogParameters changeLogParameters = new ChangeLogParameters();
List<LiquibaseDataSourceBuildTimeConfig> liquibaseDataSources = new ArrayList<>();

ChangeLogParserFactory changeLogParserFactory = ChangeLogParserFactory.getInstance();
if (DataSourceUtil.hasDefault(dataSourceNames)) {
liquibaseDataSources.add(liquibaseBuildConfig.defaultDataSource);
}

for (String dataSourceName : dataSourceNames) {
if (!DataSourceUtil.isDefault(dataSourceName)) {
liquibaseDataSources.add(liquibaseBuildConfig.getConfigForDataSourceName(dataSourceName));
}
}

ChangeLogParameters changeLogParameters = new ChangeLogParameters();
ChangeLogParserFactory changeLogParserFactory = ChangeLogParserFactory.getInstance();
Set<String> resources = new LinkedHashSet<>();
for (LiquibaseDataSourceBuildTimeConfig liquibaseDataSourceConfig : liquibaseDataSources) {

ClassLoaderResourceAccessor classLoaderResourceAccessor = new ClassLoaderResourceAccessor(
Thread.currentThread().getContextClassLoader());
Optional<List<String>> oSearchPaths = liquibaseDataSourceConfig.searchPath;
String changeLog = liquibaseDataSourceConfig.changeLog;
String parsedChangeLog = parseChangeLog(oSearchPaths, changeLog);

try {
// default datasource
if (DataSourceUtil.hasDefault(dataSourceNames)) {
resources.addAll(findAllChangeLogFiles(liquibaseBuildConfig.defaultDataSource.changeLog, changeLogParserFactory,
classLoaderResourceAccessor, changeLogParameters));
try (ResourceAccessor resourceAccessor = resolveResourceAccessor(oSearchPaths, changeLog)) {
resources.addAll(findAllChangeLogFiles(parsedChangeLog, changeLogParserFactory,
resourceAccessor, changeLogParameters));
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}

// named datasources
Collection<String> namedDataSourceChangeLogs = dataSourceNames.stream()
.filter(n -> !DataSourceUtil.isDefault(n))
.map(liquibaseBuildConfig::getConfigForDataSourceName)
.map(c -> c.changeLog)
.collect(Collectors.toCollection(LinkedHashSet::new));

for (String namedDataSourceChangeLog : namedDataSourceChangeLogs) {
resources.addAll(
findAllChangeLogFiles(namedDataSourceChangeLog, changeLogParserFactory, classLoaderResourceAccessor,
changeLogParameters));
}
LOGGER.debugf("Liquibase changeLogs: %s", resources);
return new ArrayList<>(resources);
}

LOGGER.debugf("Liquibase changeLogs: %s", resources);
private ResourceAccessor resolveResourceAccessor(Optional<List<String>> oSearchPaths, String changeLog)
throws FileNotFoundException {

return new ArrayList<>(resources);
CompositeResourceAccessor compositeResourceAccessor = new CompositeResourceAccessor();
compositeResourceAccessor
.addResourceAccessor(new ClassLoaderResourceAccessor(Thread.currentThread().getContextClassLoader()));

} finally {
try {
classLoaderResourceAccessor.close();
} catch (Exception ignored) {
// close() really shouldn't declare that exception, see also https://github.com/liquibase/liquibase/pull/2576
}
if (!changeLog.startsWith("filesystem:") && oSearchPaths.isEmpty()) {
return compositeResourceAccessor;
}

if (oSearchPaths.isEmpty()) {
compositeResourceAccessor.addResourceAccessor(
new DirectoryResourceAccessor(
Paths.get(StringUtil.changePrefix(changeLog, "filesystem:", "")).getParent()));
return compositeResourceAccessor;
}

for (String searchPath : oSearchPaths.get()) {
compositeResourceAccessor.addResourceAccessor(new DirectoryResourceAccessor(Paths.get(searchPath)));
}

return compositeResourceAccessor;
}

private String parseChangeLog(Optional<List<String>> oSearchPaths, String changeLog) {

if (changeLog.startsWith("filesystem:") && oSearchPaths.isEmpty()) {
return Paths.get(StringUtil.changePrefix(changeLog, "filesystem:", "")).getFileName().toString();
}

if (changeLog.startsWith("filesystem:")) {
return StringUtil.changePrefix(changeLog, "filesystem:", "");
}

if (changeLog.startsWith("classpath:")) {
return StringUtil.changePrefix(changeLog, "classpath:", "");
}

return changeLog;
}

/**
* Finds all resource files for the given change log file
*/
private Set<String> findAllChangeLogFiles(String file, ChangeLogParserFactory changeLogParserFactory,
ClassLoaderResourceAccessor classLoaderResourceAccessor,
ChangeLogParameters changeLogParameters) {
ResourceAccessor resourceAccessor, ChangeLogParameters changeLogParameters) {
try {
ChangeLogParser parser = changeLogParserFactory.getParser(file, classLoaderResourceAccessor);
DatabaseChangeLog changelog = parser.parse(file, changeLogParameters, classLoaderResourceAccessor);
ChangeLogParser parser = changeLogParserFactory.getParser(file, resourceAccessor);
DatabaseChangeLog changelog = parser.parse(file, changeLogParameters, resourceAccessor);

if (changelog != null) {
Set<String> result = new LinkedHashSet<>();
Expand Down