From 3f8105712784d055f9e0e6d36f4feec699ed6b66 Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Date: Thu, 27 Jun 2024 16:34:53 -0500 Subject: [PATCH] fixing bug described in issue #41236 --- .../deployment/LiquibaseProcessor.java | 104 ++++++++++++------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java index 66e45af582ff9..8b415d41106e4 100644 --- a/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java +++ b/extensions/liquibase/deployment/src/main/java/io/quarkus/liquibase/deployment/LiquibaseProcessor.java @@ -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; @@ -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; @@ -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 { @@ -360,57 +366,89 @@ private List getChangeLogs(Collection dataSourceNames, Liquibase return Collections.emptyList(); } - ChangeLogParameters changeLogParameters = new ChangeLogParameters(); + List 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 resources = new LinkedHashSet<>(); + for (LiquibaseDataSourceBuildTimeConfig liquibaseDataSourceConfig : liquibaseDataSources) { - ClassLoaderResourceAccessor classLoaderResourceAccessor = new ClassLoaderResourceAccessor( - Thread.currentThread().getContextClassLoader()); + Optional> 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 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> 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> 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 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 result = new LinkedHashSet<>();