From bf6232befeae0dbf8be8063b48635693db4867bb Mon Sep 17 00:00:00 2001 From: "Gunther C. Wenda" Date: Fri, 26 Jul 2024 12:10:06 +0200 Subject: [PATCH] fix include_all in native image --- .../quarkus/liquibase/LiquibaseFactory.java | 35 +++++++---- .../runtime/NativeImageResourceAccessor.java | 63 +++++++++++++++++++ .../src/main/resources/db/xml/changeLog.xml | 4 +- .../LiquibaseFunctionalityNativeIT.java | 7 --- .../liquibase/LiquibaseFunctionalityPMT.java | 2 +- .../liquibase/LiquibaseFunctionalityTest.java | 10 +-- 6 files changed, 92 insertions(+), 29 deletions(-) create mode 100644 extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/NativeImageResourceAccessor.java diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseFactory.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseFactory.java index 1616bdb3262af..6bc2900e1f288 100644 --- a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseFactory.java +++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/LiquibaseFactory.java @@ -10,6 +10,8 @@ import io.agroal.api.AgroalDataSource; import io.quarkus.liquibase.runtime.LiquibaseConfig; +import io.quarkus.liquibase.runtime.NativeImageResourceAccessor; +import io.quarkus.runtime.ImageMode; import io.quarkus.runtime.ResettableSystemProperties; import io.quarkus.runtime.util.StringUtil; import liquibase.Contexts; @@ -38,33 +40,44 @@ public LiquibaseFactory(LiquibaseConfig config, DataSource datasource, String da } private ResourceAccessor resolveResourceAccessor() throws FileNotFoundException { + var rootAccessor = new CompositeResourceAccessor(); + return ImageMode.current().isNativeImage() + ? nativeImageResourceAccessor(rootAccessor) + : defaultResourceAccessor(rootAccessor); + } + + private ResourceAccessor defaultResourceAccessor(CompositeResourceAccessor rootAccessor) + throws FileNotFoundException { - CompositeResourceAccessor compositeResourceAccessor = new CompositeResourceAccessor(); - compositeResourceAccessor - .addResourceAccessor(new ClassLoaderResourceAccessor(Thread.currentThread().getContextClassLoader())); + rootAccessor.addResourceAccessor( + new ClassLoaderResourceAccessor(Thread.currentThread().getContextClassLoader())); if (!config.changeLog.startsWith("filesystem:") && config.searchPath.isEmpty()) { - return compositeResourceAccessor; + return rootAccessor; } if (config.searchPath.isEmpty()) { - compositeResourceAccessor.addResourceAccessor( + return rootAccessor.addResourceAccessor( new DirectoryResourceAccessor( - Paths.get(StringUtil.changePrefix(config.changeLog, "filesystem:", "")).getParent())); - return compositeResourceAccessor; + Paths.get(StringUtil + .changePrefix(config.changeLog, "filesystem:", "")) + .getParent())); } for (String searchPath : config.searchPath.get()) { - compositeResourceAccessor.addResourceAccessor(new DirectoryResourceAccessor(Paths.get(searchPath))); + rootAccessor.addResourceAccessor(new DirectoryResourceAccessor(Paths.get(searchPath))); } + return rootAccessor; + } - return compositeResourceAccessor; + private ResourceAccessor nativeImageResourceAccessor(CompositeResourceAccessor rootAccessor) { + return rootAccessor.addResourceAccessor(new NativeImageResourceAccessor()); } private String parseChangeLog(String changeLog) { - if (changeLog.startsWith("filesystem:") && config.searchPath.isEmpty()) { - return Paths.get(StringUtil.changePrefix(changeLog, "filesystem:", "")).getFileName().toString(); + return Paths.get(StringUtil.changePrefix(changeLog, "filesystem:", "")) + .getFileName().toString(); } if (changeLog.startsWith("filesystem:")) { diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/NativeImageResourceAccessor.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/NativeImageResourceAccessor.java new file mode 100644 index 0000000000000..5a9d1e0fa15bd --- /dev/null +++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/NativeImageResourceAccessor.java @@ -0,0 +1,63 @@ +package io.quarkus.liquibase.runtime; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystemAlreadyExistsException; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; + +import org.jboss.logging.Logger; + +import liquibase.resource.AbstractPathResourceAccessor; +import liquibase.resource.PathResource; +import liquibase.resource.Resource; + +public class NativeImageResourceAccessor extends AbstractPathResourceAccessor { + private static final URI NATIVE_IMAGE_FILESYSTEM_URI = URI.create("resource:/"); + private static final Logger log = Logger.getLogger(NativeImageResourceAccessor.class); + + private final FileSystem fileSystem; + + public NativeImageResourceAccessor() { + FileSystem fs; + try { + fs = FileSystems.newFileSystem( + NATIVE_IMAGE_FILESYSTEM_URI, + Collections.singletonMap("create", "true")); + log.debug("Creating new filesystem for native image"); + } catch (FileSystemAlreadyExistsException ex) { + fs = FileSystems.getFileSystem(NATIVE_IMAGE_FILESYSTEM_URI); + log.debug("Native image file system already exists", ex); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + fileSystem = fs; + } + + @Override + protected Path getRootPath() { + return fileSystem.getPath("/"); + } + + @Override + protected Resource createResource(Path file, String pathToAdd) { + return new PathResource(pathToAdd, file); + } + + @Override + public void close() { + } + + @Override + public List describeLocations() { + return Collections.singletonList(fileSystem.toString()); + } + + @Override + public String toString() { + return getClass().getName() + " (" + getRootPath() + ") (" + fileSystem.toString() + ")"; + } +} diff --git a/integration-tests/liquibase/src/main/resources/db/xml/changeLog.xml b/integration-tests/liquibase/src/main/resources/db/xml/changeLog.xml index a0276c45aea2e..15f0c8ffa6301 100644 --- a/integration-tests/liquibase/src/main/resources/db/xml/changeLog.xml +++ b/integration-tests/liquibase/src/main/resources/db/xml/changeLog.xml @@ -10,7 +10,5 @@ - - + diff --git a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityNativeIT.java b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityNativeIT.java index f252e73b1d8d5..b23072fa20724 100644 --- a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityNativeIT.java +++ b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityNativeIT.java @@ -4,11 +4,4 @@ @QuarkusIntegrationTest public class LiquibaseFunctionalityNativeIT extends LiquibaseFunctionalityTest { - - // see: https://github.com/quarkusio/quarkus/issues/16292 - // if this is ever resolved, make sure to remove errorIfMissingOrEmpty="false" from includeAll in changeLog.xml - @Override - protected boolean isIncludeAllExpectedToWork() { - return false; - } } diff --git a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java index 1bcb6cb604d16..5a55dba9f8c82 100644 --- a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java +++ b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityPMT.java @@ -28,7 +28,7 @@ public class LiquibaseFunctionalityPMT { @Test public void test() { - LiquibaseFunctionalityTest.doTestLiquibaseQuarkusFunctionality(true); + LiquibaseFunctionalityTest.doTestLiquibaseQuarkusFunctionality(); } @AfterEach diff --git a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java index 447537cdef628..4a2fa97094fcb 100644 --- a/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java +++ b/integration-tests/liquibase/src/test/java/io/quarkus/it/liquibase/LiquibaseFunctionalityTest.java @@ -15,7 +15,7 @@ public class LiquibaseFunctionalityTest { @Test @DisplayName("Migrates a schema correctly using integrated instance") public void testLiquibaseQuarkusFunctionality() { - doTestLiquibaseQuarkusFunctionality(isIncludeAllExpectedToWork()); + doTestLiquibaseQuarkusFunctionality(); } @Test @@ -25,21 +25,17 @@ public void testLiquibaseUsingDedicatedUsernameAndPassword() { "ADMIN")); } - static void doTestLiquibaseQuarkusFunctionality(boolean isIncludeAllExpectedToWork) { + static void doTestLiquibaseQuarkusFunctionality() { when() .get("/liquibase/update") .then() .body(is( "create-tables-1,test-1,create-view-inline,create-view-file-abs,create-view-file-rel," - + (isIncludeAllExpectedToWork ? "includeAll-1,includeAll-2," : "") + + ("includeAll-1,includeAll-2,") + "json-create-tables-1,json-test-1," + "sql-create-tables-1,sql-test-1," + "yaml-create-tables-1,yaml-test-1," + "00000000000000,00000000000001,00000000000002," + "1613578374533-1,1613578374533-2,1613578374533-3")); } - - protected boolean isIncludeAllExpectedToWork() { - return true; - } }