Repository: jhipster/jhipster-lite
Pull request #9748 (2024-05-06 21:08:28)

Move the ability to start liquibase asynchronously to its own module
The async liquibase feature is not often used in my experience, so I think it could be useful to move it to its own module so we can pick exactly what we need


Patch:
diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/application/LiquibaseApplicationService.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/application/LiquibaseApplicationService.java
index 374942fca..94d52cad2 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/application/LiquibaseApplicationService.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/application/LiquibaseApplicationService.java
@@ -17,4 +17,8 @@ public class LiquibaseApplicationService {
   public JHipsterModule buildModule(JHipsterModuleProperties properties) {
     return factory.buildModule(properties);
   }
+
+  public JHipsterModule buildAsyncModule(JHipsterModuleProperties properties) {
+    return factory.buildAsyncModule(properties);
+  }
 }
diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactory.java
index 3522f9ff8..7e3f6f6cf 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactory.java
@@ -21,14 +21,8 @@ public class LiquibaseModuleFactory {
   public JHipsterModule buildModule(JHipsterModuleProperties properties) {
     Assert.notNull("properties", properties);
 
-    String packagePath = properties.packagePath();
-
     //@formatter:off
     return moduleBuilder(properties)
-      .context()
-        .put("yamlSpringConfigurationFormat", properties.springConfigurationFormat() == YAML)
-        .put("propertiesSpringConfigurationFormat", properties.springConfigurationFormat() == PROPERTIES)
-      .and()
       .javaDependencies()
         .addDependency(groupId("org.liquibase"), artifactId("liquibase-core"), versionSlug(LIQUIBASE))
         .and()
@@ -38,6 +32,27 @@ public class LiquibaseModuleFactory {
       .files()
         .add(SOURCE.file("resources/master.xml"), to("src/main/resources/config/liquibase/master.xml"))
         .add(SOURCE.file("resources/0000000000_example.xml"), to("src/main/resources/config/liquibase/changelog/0000000000_example.xml"))
+        .and()
+      .springMainLogger(LIQUIBASE, LogLevel.WARN)
+      .springMainLogger("LiquibaseSchemaResolver", LogLevel.INFO)
+      .springMainLogger("com.zaxxer.hikari", LogLevel.WARN)
+      .springTestLogger(LIQUIBASE, LogLevel.WARN)
+      .springTestLogger("LiquibaseSchemaResolver", LogLevel.INFO)
+      .springTestLogger("com.zaxxer.hikari", LogLevel.WARN)
+      .build();
+    //@formatter:on
+  }
+
+  public JHipsterModule buildAsyncModule(JHipsterModuleProperties properties) {
+    String packagePath = properties.packagePath();
+
+    //@formatter:off
+    return moduleBuilder(properties)
+      .context()
+        .put("yamlSpringConfigurationFormat", properties.springConfigurationFormat() == YAML)
+        .put("propertiesSpringConfigurationFormat", properties.springConfigurationFormat() == PROPERTIES)
+        .and()
+      .files()
         .batch(SOURCE.append("main"), toSrcMainJava().append(packagePath).append(LIQUIBASE_SECONDARY))
           .addTemplate("AsyncSpringLiquibase.java")
           .addTemplate("LiquibaseConfiguration.java")
@@ -49,12 +64,6 @@ public class LiquibaseModuleFactory {
           .addTemplate("SpringLiquibaseUtilTest.java")
           .and()
         .and()
-      .springMainLogger(LIQUIBASE, LogLevel.WARN)
-      .springMainLogger("LiquibaseSchemaResolver", LogLevel.INFO)
-      .springMainLogger("com.zaxxer.hikari", LogLevel.WARN)
-      .springTestLogger(LIQUIBASE, LogLevel.WARN)
-      .springTestLogger("LiquibaseSchemaResolver", LogLevel.INFO)
-      .springTestLogger("com.zaxxer.hikari", LogLevel.WARN)
       .build();
     //@formatter:on
   }
diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/infrastructure/primary/LiquibaseModuleConfiguration.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/infrastructure/primary/LiquibaseModuleConfiguration.java
index 109a89054..71ca50bca 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/infrastructure/primary/LiquibaseModuleConfiguration.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/infrastructure/primary/LiquibaseModuleConfiguration.java
@@ -1,9 +1,7 @@
 package tech.jhipster.lite.generator.server.springboot.dbmigration.liquibase.infrastructure.primary;
 
-import static tech.jhipster.lite.generator.slug.domain.JHLiteFeatureSlug.DATABASE_MIGRATION;
-import static tech.jhipster.lite.generator.slug.domain.JHLiteFeatureSlug.JPA_PERSISTENCE;
-import static tech.jhipster.lite.generator.slug.domain.JHLiteModuleSlug.LIQUIBASE;
-import static tech.jhipster.lite.generator.slug.domain.JHLiteModuleSlug.LOGS_SPY;
+import static tech.jhipster.lite.generator.slug.domain.JHLiteFeatureSlug.*;
+import static tech.jhipster.lite.generator.slug.domain.JHLiteModuleSlug.*;
 
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -19,9 +17,7 @@ class LiquibaseModuleConfiguration {
   JHipsterModuleResource liquibaseModule(LiquibaseApplicationService liquibase) {
     return JHipsterModuleResource.builder()
       .slug(LIQUIBASE)
-      .propertiesDefinition(
-        JHipsterModulePropertiesDefinition.builder().addIndentation().addBasePackage().addSpringConfigurationFormat().build()
-      )
+      .propertiesDefinition(JHipsterModulePropertiesDefinition.builder().addIndentation().addSpringConfigurationFormat().build())
       .apiDoc("Spring Boot - Database Migration", "Add Liquibase")
       .organization(
         JHipsterModuleOrganization.builder().feature(DATABASE_MIGRATION).addDependency(JPA_PERSISTENCE).addDependency(LOGS_SPY).build()
@@ -29,4 +25,17 @@ class LiquibaseModuleConfiguration {
       .tags("server", "spring", "spring-boot", "database", "migration", "liquibase")
       .factory(liquibase::buildModule);
   }
+
+  @Bean
+  JHipsterModuleResource liquibaseAsyncModule(LiquibaseApplicationService liquibase) {
+    return JHipsterModuleResource.builder()
+      .slug(LIQUIBASE_ASYNC)
+      .propertiesDefinition(
+        JHipsterModulePropertiesDefinition.builder().addIndentation().addBasePackage().addSpringConfigurationFormat().build()
+      )
+      .apiDoc("Spring Boot - Database Migration", "Support updating the database asynchronously with Liquibase")
+      .organization(JHipsterModuleOrganization.builder().addDependency(LIQUIBASE).build())
+      .tags("server", "spring", "spring-boot", "database", "migration", "liquibase")
+      .factory(liquibase::buildAsyncModule);
+  }
 }
diff --git a/src/main/java/tech/jhipster/lite/generator/slug/domain/JHLiteModuleSlug.java b/src/main/java/tech/jhipster/lite/generator/slug/domain/JHLiteModuleSlug.java
index bcef8b0d0..e8574e6a1 100644
--- a/src/main/java/tech/jhipster/lite/generator/slug/domain/JHLiteModuleSlug.java
+++ b/src/main/java/tech/jhipster/lite/generator/slug/domain/JHLiteModuleSlug.java
@@ -63,6 +63,7 @@ public enum JHLiteModuleSlug implements JHipsterModuleSlugFactory {
   LICENSE_APACHE("license-apache"),
   LICENSE_MIT("license-mit"),
   LIQUIBASE("liquibase"),
+  LIQUIBASE_ASYNC("liquibase-async"),
   LOGSTASH("logstash"),
   LOGS_SPY("logs-spy"),
   MARIADB("mariadb"),


Test patch:
diff --git a/src/test/features/server/springboot/dbmigration/liquibase.feature b/src/test/features/server/springboot/dbmigration/liquibase.feature
index fefd8845b..1b306506d 100644
--- a/src/test/features/server/springboot/dbmigration/liquibase.feature
+++ b/src/test/features/server/springboot/dbmigration/liquibase.feature
@@ -3,5 +3,11 @@ Feature: Liquibase module
   Scenario: Should apply liquibase module
     When I apply "liquibase" module to default project with maven file
       | packageName | tech.jhipster.chips |
+    Then I should have files in "src/main/resources/config/liquibase"
+      | master.xml |
+
+  Scenario: Should apply liquibase-async module
+    When I apply "liquibase-async" module to default project with maven file
+      | packageName | tech.jhipster.chips |
     Then I should have files in "src/main/java/tech/jhipster/chips/wire/liquibase/infrastructure/secondary"
       | AsyncSpringLiquibase.java |
diff --git a/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactoryTest.java
index ebea19f04..744c28b97 100644
--- a/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/server/springboot/dbmigration/liquibase/domain/LiquibaseModuleFactoryTest.java
@@ -4,6 +4,7 @@ import static tech.jhipster.lite.TestFileUtils.*;
 import static tech.jhipster.lite.module.domain.properties.SpringConfigurationFormat.*;
 import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*;
 
+import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import tech.jhipster.lite.UnitTest;
 import tech.jhipster.lite.module.domain.JHipsterModule;
@@ -15,86 +16,105 @@ class LiquibaseModuleFactoryTest {
 
   private static final LiquibaseModuleFactory factory = new LiquibaseModuleFactory();
 
-  @Test
-  void shouldBuildModule() {
-    JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
-      .basePackage("com.jhipster.test")
-      .build();
-
-    JHipsterModule module = factory.buildModule(properties);
-
-    assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
-      .hasFile("pom.xml")
-      .containing(
-        """
-            <dependency>
-              <groupId>org.liquibase</groupId>
-              <artifactId>liquibase-core</artifactId>
-              <version>${liquibase.version}</version>
-            </dependency>
-        """
-      )
-      .and()
-      .hasPrefixedFiles("src/main/resources/config/liquibase", "master.xml", "changelog/0000000000_example.xml")
-      .hasPrefixedFiles(
-        "src/main/java/com/jhipster/test/wire/liquibase/infrastructure/secondary",
-        "AsyncSpringLiquibase.java",
-        "LiquibaseConfiguration.java",
-        "SpringLiquibaseUtil.java"
-      )
-      .hasPrefixedFiles(
-        "src/test/java/com/jhipster/test/wire/liquibase/infrastructure/secondary",
-        "AsyncSpringLiquibaseTest.java",
-        "LiquibaseConfigurationIT.java",
-        "SpringLiquibaseUtilTest.java"
-      )
-      .hasFile("src/test/resources/logback.xml")
-      .containing("<logger name=\"liquibase\" level=\"WARN\" />")
-      .containing("<logger name=\"LiquibaseSchemaResolver\" level=\"INFO\" />")
-      .containing("<logger name=\"com.zaxxer.hikari\" level=\"WARN\" />")
-      .and()
-      .hasFile("src/main/resources/logback-spring.xml")
-      .containing("<logger name=\"liquibase\" level=\"WARN\" />")
-      .containing("<logger name=\"LiquibaseSchemaResolver\" level=\"INFO\" />")
-      .containing("<logger name=\"com.zaxxer.hikari\" level=\"WARN\" />")
-      .and()
-      .hasFile("src/main/resources/config/application.yml")
-      .containing(
-        """
-        spring:
-          liquibase:
-            change-log: classpath:config/liquibase/master.xml
-        """
-      );
-  }
+  @Nested
+  class LiquibaseModule {
 
-  @Test
-  void shouldBuildModuleWithYamlSpringConfigurationFormat() {
-    JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
-      .basePackage("com.jhipster.test")
-      .springConfigurationFormat(YAML)
-      .build();
+    @Test
+    void shouldBuildModule() {
+      JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
+        .basePackage("com.jhipster.test")
+        .build();
 
-    JHipsterModule module = factory.buildModule(properties);
+      JHipsterModule module = factory.buildModule(properties);
 
-    assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
-      .hasFile("src/test/java/com/jhipster/test/wire/liquibase/infrastructure/secondary/SpringLiquibaseUtilTest.java")
-      .containing("YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();")
-      .notContaining("Properties properties = new Properties();");
+      assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
+        .hasFile("pom.xml")
+        .containing(
+          """
+              <dependency>
+                <groupId>org.liquibase</groupId>
+                <artifactId>liquibase-core</artifactId>
+                <version>${liquibase.version}</version>
+              </dependency>
+          """
+        )
+        .and()
+        .hasPrefixedFiles("src/main/resources/config/liquibase", "master.xml", "changelog/0000000000_example.xml")
+        .hasFile("src/test/resources/logback.xml")
+        .containing("<logger name=\"liquibase\" level=\"WARN\" />")
+        .containing("<logger name=\"LiquibaseSchemaResolver\" level=\"INFO\" />")
+        .containing("<logger name=\"com.zaxxer.hikari\" level=\"WARN\" />")
+        .and()
+        .hasFile("src/main/resources/logback-spring.xml")
+        .containing("<logger name=\"liquibase\" level=\"WARN\" />")
+        .containing("<logger name=\"LiquibaseSchemaResolver\" level=\"INFO\" />")
+        .containing("<logger name=\"com.zaxxer.hikari\" level=\"WARN\" />")
+        .and()
+        .hasFile("src/main/resources/config/application.yml")
+        .containing(
+          """
+          spring:
+            liquibase:
+              change-log: classpath:config/liquibase/master.xml
+          """
+        );
+    }
   }
 
-  @Test
-  void shouldBuildModuleWithPropertiesSpringConfigurationFormat() {
-    JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
-      .basePackage("com.jhipster.test")
-      .springConfigurationFormat(PROPERTIES)
-      .build();
+  @Nested
+  class AsyncLiquibaseModule {
+
+    @Test
+    void shouldBuildAsyncModule() {
+      JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
+        .basePackage("com.jhipster.test")
+        .build();
+
+      JHipsterModule module = factory.buildAsyncModule(properties);
+
+      assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
+        .hasPrefixedFiles(
+          "src/main/java/com/jhipster/test/wire/liquibase/infrastructure/secondary",
+          "AsyncSpringLiquibase.java",
+          "LiquibaseConfiguration.java",
+          "SpringLiquibaseUtil.java"
+        )
+        .hasPrefixedFiles(
+          "src/test/java/com/jhipster/test/wire/liquibase/infrastructure/secondary",
+          "AsyncSpringLiquibaseTest.java",
+          "LiquibaseConfigurationIT.java",
+          "SpringLiquibaseUtilTest.java"
+        );
+    }
+
+    @Test
+    void shouldBuildModuleWithYamlSpringConfigurationFormat() {
+      JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
+        .basePackage("com.jhipster.test")
+        .springConfigurationFormat(YAML)
+        .build();
+
+      JHipsterModule module = factory.buildAsyncModule(properties);
+
+      assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
+        .hasFile("src/test/java/com/jhipster/test/wire/liquibase/infrastructure/secondary/SpringLiquibaseUtilTest.java")
+        .containing("YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();")
+        .notContaining("Properties properties = new Properties();");
+    }
+
+    @Test
+    void shouldBuildModuleWithPropertiesSpringConfigurationFormat() {
+      JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(tmpDirForTest())
+        .basePackage("com.jhipster.test")
+        .springConfigurationFormat(PROPERTIES)
+        .build();
 
-    JHipsterModule module = factory.buildModule(properties);
+      JHipsterModule module = factory.buildAsyncModule(properties);
 
-    assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
-      .hasFile("src/test/java/com/jhipster/test/wire/liquibase/infrastructure/secondary/SpringLiquibaseUtilTest.java")
-      .containing("Properties properties = new Properties();")
-      .notContaining("YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();");
+      assertThatModuleWithFiles(module, pomFile(), logbackFile(), testLogbackFile())
+        .hasFile("src/test/java/com/jhipster/test/wire/liquibase/infrastructure/secondary/SpringLiquibaseUtilTest.java")
+        .containing("Properties properties = new Properties();")
+        .notContaining("YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();");
+    }
   }
 }
diff --git a/tests-ci/generate.sh b/tests-ci/generate.sh
index 8cbfb8b41..453032bb4 100755
--- a/tests-ci/generate.sh
+++ b/tests-ci/generate.sh
@@ -181,7 +181,7 @@ elif [[ $application == 'fullapp' ]]; then
   applyModules "spring-boot-cucumber-jpa-reset"
   applyModules "application-service-hexagonal-architecture-documentation"
 
-  applyModules "postgresql" "liquibase"
+  applyModules "postgresql" "liquibase" "liquibase-async"
 
   applyModules \
   "kipe-expression" \