From 29a134f49c339f1453ff248e21ad2b408a5911e8 Mon Sep 17 00:00:00 2001 From: Jose <josecarvajalhilario@gmail.com> Date: Thu, 4 May 2023 06:07:39 +0200 Subject: [PATCH] Don't generate the init task for db migration if migrate at start is off The `quarkus.[flyway or liquibase or liquibase-mongodb].enabled` and `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start` properties are runtime properties, so I have to create the following build time properties to read these values and allow users configurating it: - `quarkus.[flyway or liquibase or liquibase-mongodb].generate-init-task` with default value `quarkus.[flyway or liquibase or liquibase-mongodb].enabled` - `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-with-init-task` with default value `quarkus.[flyway or liquibase or liquibase-mongodb].migrate-at-start` Plus, I've extended the coverage of these extensions with the K8s tests. Fix https://github.com/quarkusio/quarkus/issues/33097 --- .../io/quarkus/flyway/FlywayProcessor.java | 16 +-- .../flyway/runtime/FlywayBuildTimeConfig.java | 9 ++ .../FlywayDataSourceBuildTimeConfig.java | 9 ++ .../deployment/LiquibaseMongodbProcessor.java | 18 +-- .../LiquibaseMongodbBuildTimeConfig.java | 18 +++ .../deployment/LiquibaseProcessor.java | 16 +-- .../runtime/LiquibaseBuildTimeConfig.java | 9 ++ .../LiquibaseDataSourceBuildTimeConfig.java | 9 ++ ...esWithFlywayInitMigrationDisabledTest.java | 89 ++++++++++++++ .../KubernetesWithFlywayInitTest.java | 11 +- ...ithLiquibaseInitMigrationDisabledTest.java | 89 ++++++++++++++ .../KubernetesWithLiquibaseInitTest.java | 109 +++++++++++++++++ ...ibaseMongoDbInitMigrationDisabledTest.java | 90 ++++++++++++++ ...ubernetesWithLiquibaseMongoDbInitTest.java | 111 ++++++++++++++++++ 14 files changed, 577 insertions(+), 26 deletions(-) create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java create mode 100644 integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java diff --git a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java index ce3fa9db00e21..01cd379b1e9e5 100644 --- a/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java +++ b/extensions/flyway/deployment/src/main/java/io/quarkus/flyway/FlywayProcessor.java @@ -221,13 +221,15 @@ public ServiceStartBuildItem startActions(FlywayRecorder recorder, } @BuildStep - public InitTaskBuildItem configureInitTask() { - return InitTaskBuildItem.create() - .withName("flyway-init") - .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_FLYWAY_ENABLED", "true")) - .withAppEnvVars(Map.of("QUARKUS_FLYWAY_ENABLED", "false")) - .withSharedEnvironment(true) - .withSharedFilesystem(true); + public void configureInitTask(FlywayBuildTimeConfig config, BuildProducer<InitTaskBuildItem> initTasks) { + if (config.generateInitTask && config.defaultDataSource.migrateWithInitTask) { + initTasks.produce(InitTaskBuildItem.create() + .withName("flyway-init") + .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_FLYWAY_ENABLED", "true")) + .withAppEnvVars(Map.of("QUARKUS_FLYWAY_ENABLED", "false")) + .withSharedEnvironment(true) + .withSharedFilesystem(true)); + } } private Set<String> getDataSourceNames(List<JdbcDataSourceBuildItem> jdbcDataSourceBuildItems) { diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java index 47e7a4878c7f4..fb89b198ef227 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayBuildTimeConfig.java @@ -21,6 +21,15 @@ public FlywayDataSourceBuildTimeConfig getConfigForDataSourceName(String dataSou return namedDataSources.getOrDefault(dataSourceName, FlywayDataSourceBuildTimeConfig.defaultConfig()); } + /** + * Flag to enable / disable the generation of the init task Kubernetes resources. + * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present. + * + * The default value is `quarkus.flyway.enabled`. + */ + @ConfigItem(defaultValue = "${quarkus.flyway.enabled:true}") + public boolean generateInitTask; + /** * Flyway configuration for the default datasource. */ diff --git a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java index 7668f4ca191ea..c58c527656d99 100644 --- a/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java +++ b/extensions/flyway/runtime/src/main/java/io/quarkus/flyway/runtime/FlywayDataSourceBuildTimeConfig.java @@ -36,6 +36,15 @@ public final class FlywayDataSourceBuildTimeConfig { @ConfigItem public Optional<List<String>> callbacks = Optional.empty(); + /** + * Flag to enable / disable the migration using the generated init task Kubernetes resources. + * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present. + * + * The default value is `quarkus.flyway.migrate-at-start`. + */ + @ConfigItem(defaultValue = "${quarkus.flyway.migrate-at-start:false}") + public boolean migrateWithInitTask; + /** * Creates a {@link FlywayDataSourceBuildTimeConfig} with default settings. * diff --git a/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java b/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java index 462e0d5f6d61d..dfbaeb81c64aa 100644 --- a/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java +++ b/extensions/liquibase-mongodb/deployment/src/main/java/io/quarkus/liquibase/mongodb/deployment/LiquibaseMongodbProcessor.java @@ -254,14 +254,16 @@ ServiceStartBuildItem startLiquibase(LiquibaseMongodbRecorder recorder, } @BuildStep - public InitTaskBuildItem configureInitTask() { - return InitTaskBuildItem.create() - .withName("liquibase-mongodb-init") - .withTaskEnvVars( - Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_MONGODB_ENABLED", "true")) - .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_MONGODB_ENABLED", "false")) - .withSharedEnvironment(true) - .withSharedFilesystem(true); + public void configureInitTask(LiquibaseMongodbBuildTimeConfig config, BuildProducer<InitTaskBuildItem> initTasks) { + if (config.generateInitTask && config.migrateWithInitTask) { + initTasks.produce(InitTaskBuildItem.create() + .withName("liquibase-mongodb-init") + .withTaskEnvVars( + Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_MONGODB_ENABLED", "true")) + .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_MONGODB_ENABLED", "false")) + .withSharedEnvironment(true) + .withSharedFilesystem(true)); + } } /** diff --git a/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java b/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java index 08bdc6b5363bb..141b5cbb256f4 100644 --- a/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java +++ b/extensions/liquibase-mongodb/runtime/src/main/java/io/quarkus/liquibase/mongodb/runtime/LiquibaseMongodbBuildTimeConfig.java @@ -15,4 +15,22 @@ public class LiquibaseMongodbBuildTimeConfig { */ @ConfigItem(defaultValue = "db/changeLog.xml") public String changeLog; + + /** + * Flag to enable / disable the generation of the init task Kubernetes resources. + * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present. + * + * The default value is `quarkus.liquibase-mongodb.enabled`. + */ + @ConfigItem(defaultValue = "${quarkus.liquibase-mongodb.enabled:true}") + public boolean generateInitTask; + + /** + * Flag to enable / disable the migration using the generated init task Kubernetes resources. + * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present. + * + * The default value is `quarkus.liquibase-mongodb.migrate-at-start`. + */ + @ConfigItem(defaultValue = "${quarkus.liquibase-mongodb.migrate-at-start:false}") + public boolean migrateWithInitTask; } 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 cd935d27f0e65..56a4cd875b3e7 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 @@ -314,13 +314,15 @@ ServiceStartBuildItem startLiquibase(LiquibaseRecorder recorder, } @BuildStep - public InitTaskBuildItem configureInitTask() { - return InitTaskBuildItem.create() - .withName("liquibase-init") - .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_ENABLED", "true")) - .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_ENABLED", "false")) - .withSharedEnvironment(true) - .withSharedFilesystem(true); + public void configureInitTask(LiquibaseBuildTimeConfig config, BuildProducer<InitTaskBuildItem> initTasks) { + if (config.generateInitTask && config.defaultDataSource.migrateWithInitTask) { + initTasks.produce(InitTaskBuildItem.create() + .withName("liquibase-init") + .withTaskEnvVars(Map.of("QUARKUS_INIT_AND_EXIT", "true", "QUARKUS_LIQUIBASE_ENABLED", "true")) + .withAppEnvVars(Map.of("QUARKUS_LIQUIBASE_ENABLED", "false")) + .withSharedEnvironment(true) + .withSharedFilesystem(true)); + } } private Set<String> getDataSourceNames(List<JdbcDataSourceBuildItem> jdbcDataSourceBuildItems) { diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java index 1055e3bbc7b57..8e498ecad3cac 100644 --- a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java +++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseBuildTimeConfig.java @@ -31,6 +31,15 @@ public LiquibaseDataSourceBuildTimeConfig getConfigForDataSourceName(String data return namedDataSources.getOrDefault(dataSourceName, LiquibaseDataSourceBuildTimeConfig.defaultConfig()); } + /** + * Flag to enable / disable the generation of the init task Kubernetes resources. + * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present. + * + * The default value is `quarkus.liquibase.enabled`. + */ + @ConfigItem(defaultValue = "${quarkus.liquibase.enabled:true}") + public boolean generateInitTask; + /** * Liquibase configuration for the default datasource. */ diff --git a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java index 02be6092e80cc..1d3d5dd4134a6 100644 --- a/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java +++ b/extensions/liquibase/runtime/src/main/java/io/quarkus/liquibase/runtime/LiquibaseDataSourceBuildTimeConfig.java @@ -28,4 +28,13 @@ public static final LiquibaseDataSourceBuildTimeConfig defaultConfig() { @ConfigItem(defaultValue = DEFAULT_CHANGE_LOG) public String changeLog; + /** + * Flag to enable / disable the migration using the generated init task Kubernetes resources. + * This property is only relevant if the Quarkus Kubernetes/OpenShift extensions are present. + * + * The default value is `quarkus.liquibase.migrate-at-start`. + */ + @ConfigItem(defaultValue = "${quarkus.liquibase.migrate-at-start:false}") + public boolean migrateWithInitTask; + } diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java new file mode 100644 index 0000000000000..835ce44239537 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitMigrationDisabledTest.java @@ -0,0 +1,89 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.batch.v1.Job; +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithFlywayInitMigrationDisabledTest { + + private static final String NAME = "kubernetes-with-flyway-init-migration-disabled"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName(NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .setLogFileName("k8s.log") + .overrideConfigKey("quarkus.flyway.migrate-at-start", "false") + .setForcedDependencies(Arrays.asList( + new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-flyway", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List<HasMetadata> kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + Optional<Deployment> deployment = kubernetesList.stream() + .filter(d -> "Deployment".equals(d.getKind()) + && NAME.equals(d.getMetadata().getName())) + .map(d -> (Deployment) d).findAny(); + + assertTrue(deployment.isPresent()); + assertThat(deployment).satisfies(j -> j.isPresent()); + assertThat(deployment.get()).satisfies(d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(NAME); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getInitContainers()).noneSatisfy(container -> { + assertThat(container.getName()).isEqualTo("init"); + }); + + }); + }); + }); + }); + + Optional<Job> job = kubernetesList.stream() + .filter(j -> "Job".equals(j.getKind()) && "flyway-init".equals(j.getMetadata().getName())).map(j -> (Job) j) + .findAny(); + assertFalse(job.isPresent()); + + Optional<RoleBinding> roleBinding = kubernetesList.stream().filter( + r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName())) + .map(r -> (RoleBinding) r).findFirst(); + assertFalse(roleBinding.isPresent()); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java index 827c7b3c0c7f6..c6bc3daac8e25 100644 --- a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithFlywayInitTest.java @@ -26,12 +26,15 @@ public class KubernetesWithFlywayInitTest { + private static final String NAME = "kubernetes-with-flyway-init"; + @RegisterExtension static final QuarkusProdModeTest config = new QuarkusProdModeTest() .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) - .setApplicationName("kubernetes-with-flyway-init") + .setApplicationName(NAME) .setApplicationVersion("0.1-SNAPSHOT") .setLogFileName("k8s.log") + .overrideConfigKey("quarkus.flyway.migrate-at-start", "true") .setForcedDependencies(Arrays.asList( new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()), new AppArtifact("io.quarkus", "quarkus-flyway", Version.getVersion()))); @@ -50,14 +53,14 @@ public void assertGeneratedResources() throws IOException { Optional<Deployment> deployment = kubernetesList.stream() .filter(d -> "Deployment".equals(d.getKind()) - && "kubernetes-with-flyway-init".equals(d.getMetadata().getName())) + && NAME.equals(d.getMetadata().getName())) .map(d -> (Deployment) d).findAny(); assertTrue(deployment.isPresent()); assertThat(deployment).satisfies(j -> j.isPresent()); assertThat(deployment.get()).satisfies(d -> { assertThat(d.getMetadata()).satisfies(m -> { - assertThat(m.getName()).isEqualTo("kubernetes-with-flyway-init"); + assertThat(m.getName()).isEqualTo(NAME); }); assertThat(d.getSpec()).satisfies(deploymentSpec -> { @@ -99,7 +102,7 @@ public void assertGeneratedResources() throws IOException { }); Optional<RoleBinding> roleBinding = kubernetesList.stream().filter( - r -> r instanceof RoleBinding && "kubernetes-with-flyway-init-view-jobs".equals(r.getMetadata().getName())) + r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName())) .map(r -> (RoleBinding) r).findFirst(); assertTrue(roleBinding.isPresent()); } diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java new file mode 100644 index 0000000000000..9bdd79963271a --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitMigrationDisabledTest.java @@ -0,0 +1,89 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.batch.v1.Job; +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithLiquibaseInitMigrationDisabledTest { + + private static final String NAME = "kubernetes-with-liquibase-init-migration-disabled"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName(NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .setLogFileName("k8s.log") + .overrideConfigKey("quarkus.liquibase.migrate-at-start", "false") + .setForcedDependencies(Arrays.asList( + new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-liquibase", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List<HasMetadata> kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + Optional<Deployment> deployment = kubernetesList.stream() + .filter(d -> "Deployment".equals(d.getKind()) + && NAME.equals(d.getMetadata().getName())) + .map(d -> (Deployment) d).findAny(); + + assertTrue(deployment.isPresent()); + assertThat(deployment).satisfies(j -> j.isPresent()); + assertThat(deployment.get()).satisfies(d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(NAME); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getInitContainers()).noneSatisfy(container -> { + assertThat(container.getName()).isEqualTo("init"); + }); + + }); + }); + }); + }); + + Optional<Job> job = kubernetesList.stream() + .filter(j -> "Job".equals(j.getKind()) && "liquibase-init".equals(j.getMetadata().getName())).map(j -> (Job) j) + .findAny(); + assertFalse(job.isPresent()); + + Optional<RoleBinding> roleBinding = kubernetesList.stream().filter( + r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName())) + .map(r -> (RoleBinding) r).findFirst(); + assertFalse(roleBinding.isPresent()); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java new file mode 100644 index 0000000000000..578b8c25e1531 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseInitTest.java @@ -0,0 +1,109 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.batch.v1.Job; +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithLiquibaseInitTest { + + private static final String NAME = "kubernetes-with-liquibase-init"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName(NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .setLogFileName("k8s.log") + .overrideConfigKey("quarkus.liquibase.migrate-at-start", "true") + .setForcedDependencies(Arrays.asList( + new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-liquibase", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List<HasMetadata> kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + Optional<Deployment> deployment = kubernetesList.stream() + .filter(d -> "Deployment".equals(d.getKind()) + && NAME.equals(d.getMetadata().getName())) + .map(d -> (Deployment) d).findAny(); + + assertTrue(deployment.isPresent()); + assertThat(deployment).satisfies(j -> j.isPresent()); + assertThat(deployment.get()).satisfies(d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(NAME); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getInitContainers()).singleElement().satisfies(container -> { + assertThat(container.getName()).isEqualTo("init"); + }); + + }); + }); + }); + }); + + Optional<Job> job = kubernetesList.stream() + .filter(j -> "Job".equals(j.getKind()) && "liquibase-init".equals(j.getMetadata().getName())).map(j -> (Job) j) + .findAny(); + assertTrue(job.isPresent()); + + assertThat(job.get()).satisfies(j -> { + assertThat(j.getSpec()).satisfies(jobSpec -> { + assertThat(jobSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getName()).isEqualTo("liquibase-init"); + assertThat(container.getEnv()).filteredOn(env -> "QUARKUS_LIQUIBASE_ENABLED".equals(env.getName())) + .singleElement().satisfies(env -> { + assertThat(env.getValue()).isEqualTo("true"); + }); + assertThat(container.getEnv()) + .filteredOn(env -> "QUARKUS_INIT_AND_EXIT".equals(env.getName())).singleElement() + .satisfies(env -> { + assertThat(env.getValue()).isEqualTo("true"); + }); + }); + }); + }); + }); + }); + + Optional<RoleBinding> roleBinding = kubernetesList.stream().filter( + r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName())) + .map(r -> (RoleBinding) r).findFirst(); + assertTrue(roleBinding.isPresent()); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java new file mode 100644 index 0000000000000..f54702922f00b --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest.java @@ -0,0 +1,90 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.batch.v1.Job; +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithLiquibaseMongoDbInitMigrationDisabledTest { + + private static final String NAME = "kubernetes-with-liquibase-mongodb-init-migration-disabled"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName(NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .setLogFileName("k8s.log") + .overrideConfigKey("quarkus.liquibase-mongodb.migrate-at-start", "false") + .setForcedDependencies(Arrays.asList( + new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-liquibase-mongodb", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List<HasMetadata> kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + Optional<Deployment> deployment = kubernetesList.stream() + .filter(d -> "Deployment".equals(d.getKind()) + && NAME.equals(d.getMetadata().getName())) + .map(d -> (Deployment) d).findAny(); + + assertTrue(deployment.isPresent()); + assertThat(deployment).satisfies(j -> j.isPresent()); + assertThat(deployment.get()).satisfies(d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(NAME); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getInitContainers()).noneSatisfy(container -> { + assertThat(container.getName()).isEqualTo("init"); + }); + + }); + }); + }); + }); + + Optional<Job> job = kubernetesList.stream() + .filter(j -> "Job".equals(j.getKind()) && "liquibase-mongodb-init".equals(j.getMetadata().getName())) + .map(j -> (Job) j) + .findAny(); + assertFalse(job.isPresent()); + + Optional<RoleBinding> roleBinding = kubernetesList.stream().filter( + r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName())) + .map(r -> (RoleBinding) r).findFirst(); + assertFalse(roleBinding.isPresent()); + } +} diff --git a/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java new file mode 100644 index 0000000000000..f91925218cf33 --- /dev/null +++ b/integration-tests/kubernetes/quarkus-standard-way/src/test/java/io/quarkus/it/kubernetes/KubernetesWithLiquibaseMongoDbInitTest.java @@ -0,0 +1,111 @@ +package io.quarkus.it.kubernetes; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.fabric8.kubernetes.api.model.HasMetadata; +import io.fabric8.kubernetes.api.model.apps.Deployment; +import io.fabric8.kubernetes.api.model.batch.v1.Job; +import io.fabric8.kubernetes.api.model.rbac.RoleBinding; +import io.quarkus.bootstrap.model.AppArtifact; +import io.quarkus.builder.Version; +import io.quarkus.test.ProdBuildResults; +import io.quarkus.test.ProdModeTestResults; +import io.quarkus.test.QuarkusProdModeTest; + +public class KubernetesWithLiquibaseMongoDbInitTest { + + private static final String NAME = "kubernetes-with-liquibase-mongodb-init"; + + @RegisterExtension + static final QuarkusProdModeTest config = new QuarkusProdModeTest() + .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClasses(GreetingResource.class)) + .setApplicationName(NAME) + .setApplicationVersion("0.1-SNAPSHOT") + .setLogFileName("k8s.log") + .overrideConfigKey("quarkus.liquibase-mongodb.migrate-at-start", "true") + .setForcedDependencies(Arrays.asList( + new AppArtifact("io.quarkus", "quarkus-kubernetes", Version.getVersion()), + new AppArtifact("io.quarkus", "quarkus-liquibase-mongodb", Version.getVersion()))); + + @ProdBuildResults + private ProdModeTestResults prodModeTestResults; + + @Test + public void assertGeneratedResources() throws IOException { + final Path kubernetesDir = prodModeTestResults.getBuildDir().resolve("kubernetes"); + assertThat(kubernetesDir) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.json")) + .isDirectoryContaining(p -> p.getFileName().endsWith("kubernetes.yml")); + List<HasMetadata> kubernetesList = DeserializationUtil + .deserializeAsList(kubernetesDir.resolve("kubernetes.yml")); + + Optional<Deployment> deployment = kubernetesList.stream() + .filter(d -> "Deployment".equals(d.getKind()) + && NAME.equals(d.getMetadata().getName())) + .map(d -> (Deployment) d).findAny(); + + assertTrue(deployment.isPresent()); + assertThat(deployment).satisfies(j -> j.isPresent()); + assertThat(deployment.get()).satisfies(d -> { + assertThat(d.getMetadata()).satisfies(m -> { + assertThat(m.getName()).isEqualTo(NAME); + }); + + assertThat(d.getSpec()).satisfies(deploymentSpec -> { + assertThat(deploymentSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getInitContainers()).singleElement().satisfies(container -> { + assertThat(container.getName()).isEqualTo("init"); + }); + + }); + }); + }); + }); + + Optional<Job> job = kubernetesList.stream() + .filter(j -> "Job".equals(j.getKind()) && "liquibase-mongodb-init".equals(j.getMetadata().getName())) + .map(j -> (Job) j) + .findAny(); + assertTrue(job.isPresent()); + + assertThat(job.get()).satisfies(j -> { + assertThat(j.getSpec()).satisfies(jobSpec -> { + assertThat(jobSpec.getTemplate()).satisfies(t -> { + assertThat(t.getSpec()).satisfies(podSpec -> { + assertThat(podSpec.getContainers()).singleElement().satisfies(container -> { + assertThat(container.getName()).isEqualTo("liquibase-mongodb-init"); + assertThat(container.getEnv()) + .filteredOn(env -> "QUARKUS_LIQUIBASE_MONGODB_ENABLED".equals(env.getName())) + .singleElement().satisfies(env -> { + assertThat(env.getValue()).isEqualTo("true"); + }); + assertThat(container.getEnv()) + .filteredOn(env -> "QUARKUS_INIT_AND_EXIT".equals(env.getName())).singleElement() + .satisfies(env -> { + assertThat(env.getValue()).isEqualTo("true"); + }); + }); + }); + }); + }); + }); + + Optional<RoleBinding> roleBinding = kubernetesList.stream().filter( + r -> r instanceof RoleBinding && (NAME + "-view-jobs").equals(r.getMetadata().getName())) + .map(r -> (RoleBinding) r).findFirst(); + assertTrue(roleBinding.isPresent()); + } +}