From c63bb4cc2e3996cfa75e130291fce9492b49ad2d Mon Sep 17 00:00:00 2001 From: fabienpuissant Date: Sat, 12 Oct 2024 23:23:15 +0200 Subject: [PATCH 1/2] WIP working but need to be reworked, add feature test, ci test, cannot test on mssql --- .../application/JooqApplicationService.java | 33 ++ .../jooq/domain/CommonModuleBuilder.java | 89 +++++ .../database/jooq/domain/DatabaseType.java | 18 + .../jooq/domain/JooqModuleFactory.java | 264 ++++++++++++++ .../primary/JooqModuleConfiguration.java | 82 +++++ .../database/jooq/package-info.java | 2 + .../database/jpa/domain/JpaModuleFactory.java | 2 +- .../jpa/domain/SQLCommonModuleBuilder.java | 9 +- .../primary/JpaModuleConfiguration.java | 8 +- .../shared/slug/domain/JHLiteFeatureSlug.java | 1 + .../shared/slug/domain/JHLiteModuleSlug.java | 4 + .../resources/generator/dependencies/pom.xml | 6 + .../MsSQLTestContainerExtension.java.mustache | 0 .../{jpa => common}/databaseType.md.mustache | 0 .../container-license-acceptance.txt.mustache | 0 .../docker/mariadb.yml.mustache | 0 .../{jpa => common}/docker/mssql.yml.mustache | 0 .../{jpa => common}/docker/mysql.yml.mustache | 0 .../docker/postgresql.yml.mustache | 0 .../springboot/database/jooq-mariadb.feature | 41 +++ .../springboot/database/jooq-mssql.feature | 30 ++ .../springboot/database/jooq-mysql.feature | 41 +++ .../database/jooq-postgresql.feature | 41 +++ .../jooq/domain/JooqModuleFactoryTest.java | 323 ++++++++++++++++++ 24 files changed, 985 insertions(+), 9 deletions(-) create mode 100644 src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/application/JooqApplicationService.java create mode 100644 src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/CommonModuleBuilder.java create mode 100644 src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/DatabaseType.java create mode 100644 src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java create mode 100644 src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/infrastructure/primary/JooqModuleConfiguration.java create mode 100644 src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/package-info.java rename src/main/resources/generator/server/springboot/database/{jpa => common}/MsSQLTestContainerExtension.java.mustache (100%) rename src/main/resources/generator/server/springboot/database/{jpa => common}/databaseType.md.mustache (100%) rename src/main/resources/generator/server/springboot/database/{jpa => common}/docker/container-license-acceptance.txt.mustache (100%) rename src/main/resources/generator/server/springboot/database/{jpa => common}/docker/mariadb.yml.mustache (100%) rename src/main/resources/generator/server/springboot/database/{jpa => common}/docker/mssql.yml.mustache (100%) rename src/main/resources/generator/server/springboot/database/{jpa => common}/docker/mysql.yml.mustache (100%) rename src/main/resources/generator/server/springboot/database/{jpa => common}/docker/postgresql.yml.mustache (100%) create mode 100644 src/test/features/server/springboot/database/jooq-mariadb.feature create mode 100644 src/test/features/server/springboot/database/jooq-mssql.feature create mode 100644 src/test/features/server/springboot/database/jooq-mysql.feature create mode 100644 src/test/features/server/springboot/database/jooq-postgresql.feature create mode 100644 src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/application/JooqApplicationService.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/application/JooqApplicationService.java new file mode 100644 index 00000000000..05c7455ad5d --- /dev/null +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/application/JooqApplicationService.java @@ -0,0 +1,33 @@ +package tech.jhipster.lite.generator.server.springboot.database.jooq.application; + +import org.springframework.stereotype.Service; +import tech.jhipster.lite.generator.server.springboot.database.jooq.domain.JooqModuleFactory; +import tech.jhipster.lite.module.domain.JHipsterModule; +import tech.jhipster.lite.module.domain.docker.DockerImages; +import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; + +@Service +public class JooqApplicationService { + + private final JooqModuleFactory factory; + + public JooqApplicationService(DockerImages dockerImages) { + factory = new JooqModuleFactory(dockerImages); + } + + public JHipsterModule buildPostgresql(JHipsterModuleProperties properties) { + return factory.buildPostgresql(properties); + } + + public JHipsterModule buildMariaDB(JHipsterModuleProperties properties) { + return factory.buildMariaDB(properties); + } + + public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { + return factory.buildMsSQL(properties); + } + + public JHipsterModule buildMySQL(JHipsterModuleProperties properties) { + return factory.buildMySQL(properties); + } +} diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/CommonModuleBuilder.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/CommonModuleBuilder.java new file mode 100644 index 00000000000..a6fbf7f825c --- /dev/null +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/CommonModuleBuilder.java @@ -0,0 +1,89 @@ +package tech.jhipster.lite.generator.server.springboot.database.jooq.domain; + +import static tech.jhipster.lite.module.domain.JHipsterModule.*; + +import tech.jhipster.lite.module.domain.DocumentationTitle; +import tech.jhipster.lite.module.domain.JHipsterModule; +import tech.jhipster.lite.module.domain.docker.DockerImageVersion; +import tech.jhipster.lite.module.domain.file.JHipsterSource; +import tech.jhipster.lite.module.domain.javabuild.ArtifactId; +import tech.jhipster.lite.module.domain.javadependency.JavaDependency; +import tech.jhipster.lite.module.domain.javadependency.JavaDependencyScope; +import tech.jhipster.lite.module.domain.javaproperties.PropertyValue; +import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; +import tech.jhipster.lite.shared.error.domain.Assert; + +final class CommonModuleBuilder { + + private static final PropertyValue FALSE = propertyValue(false); + + private CommonModuleBuilder() {} + + public static JHipsterModule.JHipsterModuleBuilder commonModuleBuilder( + JHipsterModuleProperties properties, + DatabaseType databaseType, + DockerImageVersion dockerImage, + DocumentationTitle documentationTitle, + ArtifactId testContainerArtifactId + ) { + Assert.notNull("properties", properties); + Assert.notNull("databaseType", databaseType); + Assert.notNull("dockerImage", dockerImage); + Assert.notNull("documentationTitle", documentationTitle); + Assert.notNull("testContainerArtifactId", testContainerArtifactId); + + String databaseId = databaseType.id(); + JHipsterSource source = from("server/springboot/database/common"); + + //@formatter:off + return moduleBuilder(properties) + .context() + .put("srcMainDocker", "src/main/docker") // To be used in >.md file + .put("databaseType", databaseId) + .put(databaseId + "DockerImageWithVersion", dockerImage.fullName()) // To be used in .yml docker-compose file + .and() + .documentation(documentationTitle, source.template("databaseType.md")) + .startupCommands() + .dockerCompose(startupCommand(databaseId)) + .and() + .files() + .add(source.append("docker").template(databaseId + ".yml"), toSrcMainDocker().append(databaseId + ".yml")) + .and() + .javaDependencies() + .addDependency(groupId("org.springframework.boot"), artifactId("spring-boot-starter-jooq")) + .addDependency(groupId("com.zaxxer"), artifactId("HikariCP")) + .addDependency(testContainer(testContainerArtifactId)) + .and() + .springMainProperties() + .set(propertyKey("spring.datasource.password"), propertyValue("")) + .set(propertyKey("spring.datasource.type"), propertyValue("com.zaxxer.hikari.HikariDataSource")) + .set(propertyKey("spring.datasource.hikari.poolName"), propertyValue("Hikari")) + .set(propertyKey("spring.datasource.hikari.auto-commit"), FALSE) + .and() + .springTestProperties() + .set( + propertyKey("spring.datasource.url"), + propertyValue("jdbc:tc:" + dockerImage.fullName() + ":///" + properties.projectBaseName().name()) + ) + .set(propertyKey("spring.datasource.username"), propertyValue(properties.projectBaseName().name())) + .set(propertyKey("spring.datasource.password"), propertyValue("")) + .set(propertyKey("spring.datasource.driver-class-name"), propertyValue("org.testcontainers.jdbc.ContainerDatabaseDriver")) + .set(propertyKey("spring.datasource.hikari.maximum-pool-size"), propertyValue(2)) + .and(); + //@formatter:on + } + + private static String startupCommand(String databaseId) { + return "src/main/docker/" + databaseId + ".yml"; + } + + private static JavaDependency testContainer(ArtifactId testContainerArtifactId) { + return javaDependency() + .groupId("org.testcontainers") + .artifactId(testContainerArtifactId) + .dependencySlug("%s-%s".formatted("testcontainers", testContainerArtifactId)) + .versionSlug("testcontainers") + .scope(JavaDependencyScope.TEST) + .build(); + } +} diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/DatabaseType.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/DatabaseType.java new file mode 100644 index 00000000000..8feebc291a6 --- /dev/null +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/DatabaseType.java @@ -0,0 +1,18 @@ +package tech.jhipster.lite.generator.server.springboot.database.jooq.domain; + +enum DatabaseType { + POSTGRESQL("postgresql"), + MYSQL("mysql"), + MARIADB("mariadb"), + MSSQL("mssql"); + + private final String id; + + DatabaseType(String id) { + this.id = id; + } + + public String id() { + return id; + } +} diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java new file mode 100644 index 00000000000..777d2989b6b --- /dev/null +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java @@ -0,0 +1,264 @@ +package tech.jhipster.lite.generator.server.springboot.database.jooq.domain; + +import static tech.jhipster.lite.generator.server.springboot.database.jooq.domain.CommonModuleBuilder.commonModuleBuilder; +import static tech.jhipster.lite.module.domain.JHipsterModule.*; +import static tech.jhipster.lite.module.domain.JHipsterModule.lineBeforeText; + +import tech.jhipster.lite.module.domain.JHipsterModule; +import tech.jhipster.lite.module.domain.LogLevel; +import tech.jhipster.lite.module.domain.docker.DockerImageVersion; +import tech.jhipster.lite.module.domain.docker.DockerImages; +import tech.jhipster.lite.module.domain.file.JHipsterSource; +import tech.jhipster.lite.module.domain.javadependency.JavaDependency; +import tech.jhipster.lite.module.domain.javadependency.JavaDependencyScope; +import tech.jhipster.lite.module.domain.mavenplugin.MavenBuildPhase; +import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; + +public class JooqModuleFactory { + + public static final String ORG_POSTGRESQL = "org.postgresql"; + private static final String MYSQL = "mysql"; + private static final String MYSQL_GROUP_ID = "com.mysql"; + private static final String MYSQL_ARTIFACT_ID = "mysql-connector-j"; + + private static final String SPRING_DATASOURCE_URL = "spring.datasource.url"; + private static final String SPRING_DATASOURCE_USERNAME = "spring.datasource.username"; + private static final String SPRING_DATASOURCE_DRIVER_CLASS_NAME = "spring.datasource.driver-class-name"; + + private final DockerImages dockerImages; + + public JooqModuleFactory(DockerImages dockerImages) { + this.dockerImages = dockerImages; + } + + public JHipsterModule buildPostgresql(JHipsterModuleProperties properties) { + DockerImageVersion dockerImage = dockerImages.get("postgres"); + + //@formatter:off + return commonModuleBuilder( + properties, + DatabaseType.POSTGRESQL, + dockerImage, + documentationTitle("Postgresql"), + artifactId("postgresql") + ) + .javaDependencies() + .addDependency( + JavaDependency.builder() + .groupId(groupId(ORG_POSTGRESQL)) + .artifactId(artifactId("postgresql")) + .scope(JavaDependencyScope.RUNTIME) + .build() + ) + .and() + .mavenPlugins() + .plugin(mavenPlugin() + .groupId("org.jooq") + .artifactId("jooq-codegen-maven") + .versionSlug("jooq") + .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqCodegenPluginConfiguration("jdbc:postgresql://localhost:5432/" + properties.projectBaseName().name(), DatabaseType.POSTGRESQL, properties.projectBaseName().name(), "", "public")) + .build()) + .and() + .springMainProperties() + .set(propertyKey(SPRING_DATASOURCE_URL), propertyValue("jdbc:postgresql://localhost:5432/" + properties.projectBaseName().name())) + .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue(properties.projectBaseName().name())) + .set(propertyKey(SPRING_DATASOURCE_DRIVER_CLASS_NAME), propertyValue("org.postgresql.Driver")) + .and() + .springTestProperties() + .set( + propertyKey(SPRING_DATASOURCE_URL), + propertyValue( + "jdbc:tc:postgresql:" + dockerImage.version().get() + ":///" + properties.projectBaseName().name() + "?TC_TMPFS=/testtmpfs:rw" + ) + ) + .and() + .springMainLogger(ORG_POSTGRESQL, LogLevel.WARN) + .springTestLogger(ORG_POSTGRESQL, LogLevel.WARN) + .springTestLogger("org.jboss.logging", LogLevel.WARN) + .build(); + //@formatter:on + } + + public JHipsterModule buildMariaDB(JHipsterModuleProperties properties) { + //@formatter:off + return commonModuleBuilder( + properties, + DatabaseType.MARIADB, + dockerImages.get("mariadb"), + documentationTitle("MariaDB"), + artifactId("mariadb") + ) + .javaDependencies() + .addDependency( + javaDependency().groupId("org.mariadb.jdbc").artifactId("mariadb-java-client").scope(JavaDependencyScope.RUNTIME).build() + ) + .and() + .mavenPlugins() + .plugin(mavenPlugin() + .groupId("org.jooq") + .artifactId("jooq-codegen-maven") + .versionSlug("jooq") + .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqCodegenPluginConfiguration("jdbc:mariadb://localhost:3306/" + properties.projectBaseName().name(), DatabaseType.MARIADB, "root", "", properties.projectBaseName().name())) + .build()) + .and() + .springMainProperties() + .set(propertyKey(SPRING_DATASOURCE_URL), propertyValue("jdbc:mariadb://localhost:3306/" + properties.projectBaseName().name())) + .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue("root")) + .set(propertyKey(SPRING_DATASOURCE_DRIVER_CLASS_NAME), propertyValue("org.mariadb.jdbc.Driver")) + .and() + .build(); + //@formatter:on + } + + public JHipsterModule buildMySQL(JHipsterModuleProperties properties) { + //@formatter:off + return commonModuleBuilder( + properties, + DatabaseType.MYSQL, + dockerImages.get(MYSQL), + documentationTitle("MySQL"), + artifactId(MYSQL) + ) + .javaDependencies() + .addDependency(javaDependency().groupId(MYSQL_GROUP_ID).artifactId(MYSQL_ARTIFACT_ID).scope(JavaDependencyScope.RUNTIME).build()) + .and() + .mavenPlugins() + .plugin(mavenPlugin() + .groupId("org.jooq") + .artifactId("jooq-codegen-maven") + .versionSlug("jooq") + .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqCodegenPluginConfiguration("jdbc:mysql://localhost:3306/" + properties.projectBaseName().name(), DatabaseType.MYSQL, "root", "", properties.projectBaseName().name())) + .build()) + .and() + .springMainProperties() + .set(propertyKey(SPRING_DATASOURCE_URL), propertyValue("jdbc:mysql://localhost:3306/" + properties.projectBaseName().name())) + .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue("root")) + .set(propertyKey(SPRING_DATASOURCE_DRIVER_CLASS_NAME), propertyValue("com.mysql.cj.jdbc.Driver")) + .and() + .build(); + //@formatter:on + } + + public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { + DockerImageVersion dockerImage = dockerImages.get("mcr.microsoft.com/mssql/server"); + JHipsterSource source = from("server/springboot/database/common"); + + //@formatter:off + return commonModuleBuilder( + properties, + DatabaseType.MSSQL, + dockerImage, + documentationTitle("MsSQL"), + artifactId("mssqlserver") + ) + .files() + .add(source.append("docker").template("container-license-acceptance.txt"), to("src/test/resources/container-license-acceptance.txt")) + .add( + source.template("MsSQLTestContainerExtension.java"), + toSrcTestJava().append(properties.basePackage().path()).append("MsSQLTestContainerExtension.java") + ) + .and() + .javaDependencies() + .addDependency(javaDependency().groupId("com.microsoft.sqlserver").artifactId("mssql-jdbc").scope(JavaDependencyScope.RUNTIME).build()) + .and() + .mavenPlugins() + .plugin(mavenPlugin() + .groupId("org.jooq") + .artifactId("jooq-codegen-maven") + .versionSlug("jooq") + .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqCodegenPluginConfiguration("jdbc:sqlserver://localhost:1433;database=" + properties.projectBaseName().name() + ";trustServerCertificate=true", DatabaseType.MSSQL, "SA", "yourStrong(!)Password", "model")) + .build()) + .and() + .springMainProperties() + .set( + propertyKey(SPRING_DATASOURCE_URL), + propertyValue("jdbc:sqlserver://localhost:1433;database=" + properties.projectBaseName().name() + ";trustServerCertificate=true") + ) + .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue("SA")) + .set(propertyKey("spring.datasource.password"), propertyValue("yourStrong(!)Password")) + .set(propertyKey(SPRING_DATASOURCE_DRIVER_CLASS_NAME), propertyValue("com.microsoft.sqlserver.jdbc.SQLServerDriver")) + .and() + .springTestProperties() + .set( + propertyKey(SPRING_DATASOURCE_URL), + propertyValue( + "jdbc:tc:sqlserver:///;database=" + properties.projectBaseName().name() + ";trustServerCertificate=true?TC_TMPFS=/testtmpfs:rw" + ) + ) + .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue("SA")) + .set(propertyKey("spring.datasource.password"), propertyValue("yourStrong(!)Password")) + .and() + .mandatoryReplacements() + .in(path("src/test/java").append(properties.basePackage().path()).append("IntegrationTest.java")) + .add( + lineBeforeText("import org.springframework.boot.test.context.SpringBootTest;"), + "import org.junit.jupiter.api.extension.ExtendWith;" + ) + .add(lineBeforeText("public @interface"), "@ExtendWith(MsSQLTestContainerExtension.class)") + .and() + .and() + .springMainLogger("com.microsoft.sqlserver", LogLevel.WARN) + .springMainLogger("org.reflections", LogLevel.WARN) + .build(); + //@formatter:on + } + + //TODO Create an API for MavenPluginConfiguration with a builder + private String jooqCodegenPluginConfiguration( + String databaseUrl, + DatabaseType databaseType, + String user, + String password, + String inputSchema + ) { + return String.format( + """ + + %s + %s + %s + %s + + + + %s + .* + %s + + + org.jooq.codegen + target/generated-sources/jooq + + + """, + databaseDriver(databaseType), + databaseUrl, + user, + password, + databaseJooqName(databaseType), + inputSchema + ); + } + + private static String databaseJooqName(DatabaseType databaseType) { + return switch (databaseType) { + case POSTGRESQL -> "org.jooq.meta.postgres.PostgresDatabase"; + case MYSQL -> "org.jooq.meta.mysql.MySQLDatabase"; + case MARIADB -> "org.jooq.meta.mariadb.MariaDBDatabase"; + case MSSQL -> "org.jooq.meta.sqlserver.SQLServerDatabase"; + }; + } + + private static String databaseDriver(DatabaseType databaseType) { + return switch (databaseType) { + case POSTGRESQL -> "org.postgresql.Driver"; + case MARIADB -> "org.mariadb.jdbc.Driver"; + case MYSQL -> "com.mysql.jdbc.Driver"; + case MSSQL -> "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + }; + } +} diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/infrastructure/primary/JooqModuleConfiguration.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/infrastructure/primary/JooqModuleConfiguration.java new file mode 100644 index 00000000000..b21ddcec1ca --- /dev/null +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/infrastructure/primary/JooqModuleConfiguration.java @@ -0,0 +1,82 @@ +package tech.jhipster.lite.generator.server.springboot.database.jooq.infrastructure.primary; + +import static tech.jhipster.lite.shared.slug.domain.JHLiteFeatureSlug.JOOQ; +import static tech.jhipster.lite.shared.slug.domain.JHLiteModuleSlug.JOOQ_MARIADB; +import static tech.jhipster.lite.shared.slug.domain.JHLiteModuleSlug.JOOQ_MSSQL; +import static tech.jhipster.lite.shared.slug.domain.JHLiteModuleSlug.JOOQ_MYSQL; +import static tech.jhipster.lite.shared.slug.domain.JHLiteModuleSlug.JOOQ_POSTGRESQL; +import static tech.jhipster.lite.shared.slug.domain.JHLiteModuleSlug.SPRING_BOOT; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import tech.jhipster.lite.generator.server.springboot.database.jooq.application.JooqApplicationService; +import tech.jhipster.lite.module.domain.resource.JHipsterModuleOrganization; +import tech.jhipster.lite.module.domain.resource.JHipsterModulePropertiesDefinition; +import tech.jhipster.lite.module.domain.resource.JHipsterModuleResource; + +@Configuration +class JooqModuleConfiguration { + + private static final String API_DOC_GROUP = "Spring Boot - Database"; + + @Bean + JHipsterModuleResource jooqPostgresqlModule(JooqApplicationService postgresql) { + return JHipsterModuleResource.builder() + .slug(JOOQ_POSTGRESQL) + .propertiesDefinition(properties()) + .apiDoc(API_DOC_GROUP, "Add Jooq with Postgresql to project") + .organization(organization()) + .tags(tags()) + .factory(postgresql::buildPostgresql); + } + + @Bean + JHipsterModuleResource jooqMariaDBModule(JooqApplicationService applicationService) { + return JHipsterModuleResource.builder() + .slug(JOOQ_MARIADB) + .propertiesDefinition(properties()) + .apiDoc(API_DOC_GROUP, "Add Jooq with MariaDB to project") + .organization(organization()) + .tags(tags()) + .factory(applicationService::buildMariaDB); + } + + @Bean + JHipsterModuleResource jooqMySQLModule(JooqApplicationService applicationService) { + return JHipsterModuleResource.builder() + .slug(JOOQ_MYSQL) + .propertiesDefinition(properties()) + .apiDoc(API_DOC_GROUP, "Add Jooq with MySQL to project") + .organization(organization()) + .tags(tags()) + .factory(applicationService::buildMySQL); + } + + @Bean + JHipsterModuleResource jooqMsSQLModule(JooqApplicationService applicationService) { + return JHipsterModuleResource.builder() + .slug(JOOQ_MSSQL) + .propertiesDefinition(properties()) + .apiDoc(API_DOC_GROUP, "Add Jooq with MsSQL to project") + .organization(organization()) + .tags(tags()) + .factory(applicationService::buildMsSQL); + } + + private static JHipsterModulePropertiesDefinition properties() { + return JHipsterModulePropertiesDefinition.builder() + .addBasePackage() + .addIndentation() + .addProjectBaseName() + .addSpringConfigurationFormat() + .build(); + } + + private static JHipsterModuleOrganization organization() { + return JHipsterModuleOrganization.builder().feature(JOOQ).addDependency(SPRING_BOOT).build(); + } + + private static String[] tags() { + return new String[] { "server", "spring", "spring-boot", "database" }; + } +} diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/package-info.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/package-info.java new file mode 100644 index 00000000000..c8ee34bf344 --- /dev/null +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/package-info.java @@ -0,0 +1,2 @@ +@tech.jhipster.lite.BusinessContext +package tech.jhipster.lite.generator.server.springboot.database.jooq; diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/JpaModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/JpaModuleFactory.java index edd00c21f48..ced259dbc53 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/JpaModuleFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/JpaModuleFactory.java @@ -119,7 +119,7 @@ public JHipsterModule buildMySQL(JHipsterModuleProperties properties) { public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { DockerImageVersion dockerImage = dockerImages.get("mcr.microsoft.com/mssql/server"); - JHipsterSource source = from("server/springboot/database/jpa"); + JHipsterSource source = from("server/springboot/database/common"); //@formatter:off return sqlCommonModuleBuilder(properties, DatabaseType.MSSQL, dockerImage, documentationTitle("MsSQL"), artifactId("mssqlserver")) diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/SQLCommonModuleBuilder.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/SQLCommonModuleBuilder.java index 32abfa23617..057f43a319b 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/SQLCommonModuleBuilder.java +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/domain/SQLCommonModuleBuilder.java @@ -45,7 +45,8 @@ public static JHipsterModuleBuilder sqlCommonModuleBuilder( Assert.notNull("testContainerArtifactId", testContainerArtifactId); String databaseId = databaseType.id(); - JHipsterSource source = from("server/springboot/database/jpa"); + JHipsterSource commonSource = from("server/springboot/database/common"); + JHipsterSource jpaSource = from("server/springboot/database/jpa"); JHipsterDestination mainDestination = toSrcMainJava() .append(properties.packagePath()) .append("wire") @@ -59,13 +60,13 @@ public static JHipsterModuleBuilder sqlCommonModuleBuilder( .put("databaseType", databaseId) .put(databaseId + "DockerImageWithVersion", dockerImage.fullName()) // To be used in .yml docker-compose file .and() - .documentation(documentationTitle, source.template("databaseType.md")) + .documentation(documentationTitle, commonSource.template("databaseType.md")) .startupCommands() .dockerCompose(startupCommand(databaseId)) .and() .files() - .add(source.template("DatabaseConfiguration.java"), mainDestination.append("DatabaseConfiguration.java")) - .add(source.append("docker").template(databaseId + ".yml"), toSrcMainDocker().append(databaseId + ".yml")) + .add(jpaSource.template("DatabaseConfiguration.java"), mainDestination.append("DatabaseConfiguration.java")) + .add(commonSource.append("docker").template(databaseId + ".yml"), toSrcMainDocker().append(databaseId + ".yml")) .and() .javaDependencies() .addDependency(groupId("org.springframework.boot"), artifactId("spring-boot-starter-data-jpa")) diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/infrastructure/primary/JpaModuleConfiguration.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/infrastructure/primary/JpaModuleConfiguration.java index d0ed49b5ceb..ebaf035fd82 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/infrastructure/primary/JpaModuleConfiguration.java +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jpa/infrastructure/primary/JpaModuleConfiguration.java @@ -20,7 +20,7 @@ class JpaModuleConfiguration { private static final String API_DOC_GROUP = "Spring Boot - Database"; @Bean - JHipsterModuleResource postgresqlModule(JpaApplicationService postgresql) { + JHipsterModuleResource jpaPostgresqlModule(JpaApplicationService postgresql) { return JHipsterModuleResource.builder() .slug(JPA_POSTGRESQL) .propertiesDefinition(properties()) @@ -31,7 +31,7 @@ JHipsterModuleResource postgresqlModule(JpaApplicationService postgresql) { } @Bean - JHipsterModuleResource mariaDBModule(JpaApplicationService applicationService) { + JHipsterModuleResource jpaMariaDBModule(JpaApplicationService applicationService) { return JHipsterModuleResource.builder() .slug(JPA_MARIADB) .propertiesDefinition(properties()) @@ -42,7 +42,7 @@ JHipsterModuleResource mariaDBModule(JpaApplicationService applicationService) { } @Bean - JHipsterModuleResource mySQLModule(JpaApplicationService applicationService) { + JHipsterModuleResource jpaMmySQLModule(JpaApplicationService applicationService) { return JHipsterModuleResource.builder() .slug(JPA_MYSQL) .propertiesDefinition(properties()) @@ -53,7 +53,7 @@ JHipsterModuleResource mySQLModule(JpaApplicationService applicationService) { } @Bean - JHipsterModuleResource msSQLModule(JpaApplicationService applicationService) { + JHipsterModuleResource jpaMsSQLModule(JpaApplicationService applicationService) { return JHipsterModuleResource.builder() .slug(JPA_MSSQL) .propertiesDefinition(properties()) diff --git a/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteFeatureSlug.java b/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteFeatureSlug.java index cca8f6c2a05..0eb9a7a86cb 100644 --- a/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteFeatureSlug.java +++ b/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteFeatureSlug.java @@ -21,6 +21,7 @@ public enum JHLiteFeatureSlug implements JHipsterFeatureSlugFactory { CODE_COVERAGE_JAVA("code-coverage-java"), JAVA_BUILD_TOOL("java-build-tool"), JAVA_BUILD_TOOL_WRAPPER("java-build-tool-wrapper"), + JOOQ("jooq"), JPA_PERSISTENCE("jpa-persistence"), LICENSE("license"), OAUTH_PROVIDER("oauth-provider"), diff --git a/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteModuleSlug.java b/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteModuleSlug.java index 66dd0ef692b..d2d75d25665 100644 --- a/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteModuleSlug.java +++ b/src/main/java/tech/jhipster/lite/shared/slug/domain/JHLiteModuleSlug.java @@ -59,6 +59,10 @@ public enum JHLiteModuleSlug implements JHipsterModuleSlugFactory { JAVA_MEMOIZERS("java-memoizers"), JIB("jib"), JMOLECULES("jmolecules"), + JOOQ_MARIADB("jooq-mariadb"), + JOOQ_MSSQL("jooq-mssql"), + JOOQ_MYSQL("jooq-mysql"), + JOOQ_POSTGRESQL("jooq-postgresql"), JPA_PAGINATION("jpa-pagination"), JPA_MARIADB("jpa-mariadb"), JPA_MSSQL("jpa-mssql"), diff --git a/src/main/resources/generator/dependencies/pom.xml b/src/main/resources/generator/dependencies/pom.xml index 4b84384691b..924e064780f 100644 --- a/src/main/resources/generator/dependencies/pom.xml +++ b/src/main/resources/generator/dependencies/pom.xml @@ -71,10 +71,16 @@ 0.0.21 1.0.3 0.36.0 + 3.19.13 + + org.jooq + jooq-codegen + ${jooq.version} + kr.motd.maven os-maven-plugin diff --git a/src/main/resources/generator/server/springboot/database/jpa/MsSQLTestContainerExtension.java.mustache b/src/main/resources/generator/server/springboot/database/common/MsSQLTestContainerExtension.java.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/MsSQLTestContainerExtension.java.mustache rename to src/main/resources/generator/server/springboot/database/common/MsSQLTestContainerExtension.java.mustache diff --git a/src/main/resources/generator/server/springboot/database/jpa/databaseType.md.mustache b/src/main/resources/generator/server/springboot/database/common/databaseType.md.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/databaseType.md.mustache rename to src/main/resources/generator/server/springboot/database/common/databaseType.md.mustache diff --git a/src/main/resources/generator/server/springboot/database/jpa/docker/container-license-acceptance.txt.mustache b/src/main/resources/generator/server/springboot/database/common/docker/container-license-acceptance.txt.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/docker/container-license-acceptance.txt.mustache rename to src/main/resources/generator/server/springboot/database/common/docker/container-license-acceptance.txt.mustache diff --git a/src/main/resources/generator/server/springboot/database/jpa/docker/mariadb.yml.mustache b/src/main/resources/generator/server/springboot/database/common/docker/mariadb.yml.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/docker/mariadb.yml.mustache rename to src/main/resources/generator/server/springboot/database/common/docker/mariadb.yml.mustache diff --git a/src/main/resources/generator/server/springboot/database/jpa/docker/mssql.yml.mustache b/src/main/resources/generator/server/springboot/database/common/docker/mssql.yml.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/docker/mssql.yml.mustache rename to src/main/resources/generator/server/springboot/database/common/docker/mssql.yml.mustache diff --git a/src/main/resources/generator/server/springboot/database/jpa/docker/mysql.yml.mustache b/src/main/resources/generator/server/springboot/database/common/docker/mysql.yml.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/docker/mysql.yml.mustache rename to src/main/resources/generator/server/springboot/database/common/docker/mysql.yml.mustache diff --git a/src/main/resources/generator/server/springboot/database/jpa/docker/postgresql.yml.mustache b/src/main/resources/generator/server/springboot/database/common/docker/postgresql.yml.mustache similarity index 100% rename from src/main/resources/generator/server/springboot/database/jpa/docker/postgresql.yml.mustache rename to src/main/resources/generator/server/springboot/database/common/docker/postgresql.yml.mustache diff --git a/src/test/features/server/springboot/database/jooq-mariadb.feature b/src/test/features/server/springboot/database/jooq-mariadb.feature new file mode 100644 index 00000000000..7fcf3cc0f4d --- /dev/null +++ b/src/test/features/server/springboot/database/jooq-mariadb.feature @@ -0,0 +1,41 @@ +Feature: Jooq MariaDB module + + Scenario: Should add MariaDB elements using legacy url + When I apply modules to default project + | maven-java | + | spring-boot | + | jooq-mariadb | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | mariadb.md | + And I should have files in "src/main/docker" + | mariadb.yml | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | + + Scenario: Should get MariaDB module properties definition + When I get module "jooq-mariadb" properties definition + Then I should have properties definitions + | Key | Type | Mandatory | + | packageName | STRING | true | + | baseName | STRING | true | + | indentSize | INTEGER | false | + | springConfigurationFormat | STRING | false | + + Scenario: Should add MariaDB elements using module url + When I apply "jooq-mariadb" module to default project with maven file + | packageName | tech.jhipster.chips | + | baseName | jhipster | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | mariadb.md | + And I should have files in "src/main/docker" + | mariadb.yml | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | diff --git a/src/test/features/server/springboot/database/jooq-mssql.feature b/src/test/features/server/springboot/database/jooq-mssql.feature new file mode 100644 index 00000000000..5c430b284fc --- /dev/null +++ b/src/test/features/server/springboot/database/jooq-mssql.feature @@ -0,0 +1,30 @@ +Feature: Jooq MsSql module + + Scenario: Should add MsSQL elements using legacy url + When I apply modules to default project + | maven-java | + | spring-boot | + | jooq-mssql | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | mssql.md | + And I should have files in "src/main/docker" + | mssql.yml | + And I should have files in "src/test/java/tech/jhipster/chips" + | MsSQLTestContainerExtension.java | + And I should have files in "src/test/resources" + | container-license-acceptance.txt | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | + + Scenario: Should get MsSQL module properties definition + When I get module "jooq-mssql" properties definition + Then I should have properties definitions + | Key | Type | Mandatory | + | packageName | STRING | true | + | baseName | STRING | true | + | indentSize | INTEGER | false | + | springConfigurationFormat | STRING | false | diff --git a/src/test/features/server/springboot/database/jooq-mysql.feature b/src/test/features/server/springboot/database/jooq-mysql.feature new file mode 100644 index 00000000000..3d597ef3eec --- /dev/null +++ b/src/test/features/server/springboot/database/jooq-mysql.feature @@ -0,0 +1,41 @@ +Feature: Jooq MySQL module + + Scenario: Should add MySQL elements using legacy url + When I apply modules to default project + | maven-java | + | spring-boot | + | jooq-mysql | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | mysql.md | + And I should have files in "src/main/docker" + | mysql.yml | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | + + Scenario: Should get MySQL module properties definition + When I get module "jooq-mysql" properties definition + Then I should have properties definitions + | Key | Type | Mandatory | + | packageName | STRING | true | + | baseName | STRING | true | + | indentSize | INTEGER | false | + | springConfigurationFormat | STRING | false | + + Scenario: Should add MySQL elements using module url + When I apply "jooq-mysql" module to default project with maven file + | packageName | tech.jhipster.chips | + | baseName | jhipster | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | mysql.md | + And I should have files in "src/main/docker" + | mysql.yml | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | diff --git a/src/test/features/server/springboot/database/jooq-postgresql.feature b/src/test/features/server/springboot/database/jooq-postgresql.feature new file mode 100644 index 00000000000..d4b6c46fdb8 --- /dev/null +++ b/src/test/features/server/springboot/database/jooq-postgresql.feature @@ -0,0 +1,41 @@ +Feature: Jooq PostgreSQL module + + Scenario: Should add postgreSQL elements using legacy url + When I apply modules to default project + | maven-java | + | spring-boot | + | jooq-postgresql | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | postgresql.md | + And I should have files in "src/main/docker" + | postgresql.yml | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | + + Scenario: Should get postgreSQL module properties definition + When I get module "jooq-postgresql" properties definition + Then I should have properties definitions + | Key | Type | Mandatory | + | packageName | STRING | true | + | baseName | STRING | true | + | indentSize | INTEGER | false | + | springConfigurationFormat | STRING | false | + + Scenario: Should add postgreSQL elements using module url + When I apply "jooq-postgresql" module to default project with maven file + | packageName | tech.jhipster.chips | + | baseName | jhipster | + Then I should have files in "" + | pom.xml | + And I should have files in "documentation" + | postgresql.md | + And I should have files in "src/main/docker" + | postgresql.yml | + And I should have files in "src/main/resources/config" + | application.yml | + And I should have files in "src/test/resources/config" + | application-test.yml | diff --git a/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java new file mode 100644 index 00000000000..258ea11b624 --- /dev/null +++ b/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java @@ -0,0 +1,323 @@ +package tech.jhipster.lite.generator.server.springboot.database.jooq.domain; + +import static org.mockito.Mockito.when; +import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import tech.jhipster.lite.TestFileUtils; +import tech.jhipster.lite.UnitTest; +import tech.jhipster.lite.module.domain.JHipsterModule; +import tech.jhipster.lite.module.domain.JHipsterModulesFixture; +import tech.jhipster.lite.module.domain.docker.DockerImageVersion; +import tech.jhipster.lite.module.domain.docker.DockerImages; +import tech.jhipster.lite.module.domain.properties.JHipsterModuleProperties; +import tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions; + +@UnitTest +@ExtendWith(MockitoExtension.class) +public class JooqModuleFactoryTest { + + @Mock + private DockerImages dockerImages; + + @InjectMocks + private JooqModuleFactory factory; + + @Test + void shouldCreatePostgresqlModule() { + JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(TestFileUtils.tmpDirForTest()) + .basePackage("tech.jhipster.jhlitest") + .projectBaseName("myapp") + .build(); + + when(dockerImages.get("postgres")).thenReturn(new DockerImageVersion("postgres", "0.0.0")); + + JHipsterModule module = factory.buildPostgresql(properties); + + assertThatModuleWithFiles(module, pomFile()) + .hasFile("documentation/postgresql.md") + .containing("docker compose -f src/main/docker/postgresql.yml up -d") + .and() + .hasFile("pom.xml") + .containing( + """ + + org.postgresql + postgresql + runtime + + """ + ) + .containing("com.zaxxer") + .containing("HikariCP") + .containing( + """ + + org.springframework.boot + spring-boot-starter-jooq + + """ + ) + .containing("org.testcontainers") + .containing("postgresql") + .containing("jooq-codegen-maven") + .and() + .hasFile("src/main/resources/config/application.yml") + .containing( + """ + spring: + datasource: + driver-class-name: org.postgresql.Driver + hikari: + auto-commit: false + poolName: Hikari + password: '' + type: com.zaxxer.hikari.HikariDataSource + url: jdbc:postgresql://localhost:5432/myapp + username: myapp + """ + ) + .and() + .hasFile("src/test/resources/config/application-test.yml") + .containing( + """ + spring: + datasource: + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + hikari: + maximum-pool-size: 2 + password: '' + url: jdbc:tc:postgresql:0.0.0:///myapp?TC_TMPFS=/testtmpfs:rw + username: myapp + """ + ); + } + + @Test + void shouldCreateMariadbModule() { + JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(TestFileUtils.tmpDirForTest()) + .basePackage("tech.jhipster.jhlitest") + .projectBaseName("myapp") + .build(); + + when(dockerImages.get("mariadb")).thenReturn(new DockerImageVersion("mariadb", "0.0.0")); + + JHipsterModule module = factory.buildMariaDB(properties); + + assertThatModuleWithFiles(module, pomFile()) + .hasFile("documentation/mariadb.md") + .containing("docker compose -f src/main/docker/mariadb.yml up -d") + .and() + .hasPrefixedFiles("src/main/docker", "mariadb.yml") + .hasFile("pom.xml") + .containing( + """ + + org.mariadb.jdbc + mariadb-java-client + runtime + + """ + ) + .containing("com.zaxxer") + .containing("HikariCP") + .containing( + """ + + org.springframework.boot + spring-boot-starter-jooq + + """ + ) + .containing("org.testcontainers") + .containing("mariadb") + .containing("jooq-codegen-maven") + .and() + .hasFile("src/main/resources/config/application.yml") + .containing( + """ + spring: + datasource: + driver-class-name: org.mariadb.jdbc.Driver + hikari: + auto-commit: false + poolName: Hikari + password: '' + type: com.zaxxer.hikari.HikariDataSource + url: jdbc:mariadb://localhost:3306/myapp + username: root + """ + ) + .and() + .hasFile("src/test/resources/config/application-test.yml") + .containing( + """ + spring: + datasource: + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + hikari: + maximum-pool-size: 2 + password: '' + url: jdbc:tc:mariadb:0.0.0:///myapp + username: myapp + """ + ); + } + + @Test + void shouldCreateMysqlModule() { + JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(TestFileUtils.tmpDirForTest()) + .basePackage("tech.jhipster.jhlitest") + .projectBaseName("myapp") + .build(); + + when(dockerImages.get("mysql")).thenReturn(new DockerImageVersion("mysql", "0.0.0")); + + JHipsterModule module = factory.buildMySQL(properties); + + assertThatModuleWithFiles(module, pomFile()) + .hasFile("documentation/mysql.md") + .containing("docker compose -f src/main/docker/mysql.yml up -d") + .and() + .hasPrefixedFiles("src/main/docker", "mysql.yml") + .hasFile("pom.xml") + .containing( + """ + + com.mysql + mysql-connector-j + runtime + + """ + ) + .containing("com.zaxxer") + .containing("HikariCP") + .containing( + """ + + org.springframework.boot + spring-boot-starter-jooq + + """ + ) + .containing("org.testcontainers") + .containing("mysql") + .containing("jooq-codegen-maven") + .and() + .hasFile("src/main/resources/config/application.yml") + .containing( + // language=yaml + """ + spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + hikari: + auto-commit: false + poolName: Hikari + password: '' + type: com.zaxxer.hikari.HikariDataSource + url: jdbc:mysql://localhost:3306/myapp + username: root + """ + ) + .and() + .hasFile("src/test/resources/config/application-test.yml") + .containing( + // language=yaml + """ + spring: + datasource: + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + hikari: + maximum-pool-size: 2 + password: '' + url: jdbc:tc:mysql:0.0.0:///myapp + username: myapp + """ + ); + } + + @Test + void shouldCreateMssqlModule() { + JHipsterModuleProperties properties = JHipsterModulesFixture.propertiesBuilder(TestFileUtils.tmpDirForTest()) + .basePackage("tech.jhipster.jhlitest") + .projectBaseName("myapp") + .build(); + + when(dockerImages.get("mcr.microsoft.com/mssql/server")).thenReturn(new DockerImageVersion("mcr.microsoft.com/mssql/server", "0.0.0")); + + JHipsterModule module = factory.buildMsSQL(properties); + + assertThatModuleWithFiles(module, pomFile(), integrationTestAnnotation()) + .hasFile("documentation/mssql.md") + .containing("docker compose -f src/main/docker/mssql.yml up -d") + .and() + .hasFile("src/test/java/tech/jhipster/jhlitest/MsSQLTestContainerExtension.java") + .and() + .hasFile("src/test/resources/container-license-acceptance.txt") + .and() + .hasFile("pom.xml") + .containing( + """ + + com.microsoft.sqlserver + mssql-jdbc + runtime + + """ + ) + .containing("com.zaxxer") + .containing("HikariCP") + .containing( + """ + + org.springframework.boot + spring-boot-starter-jooq + + """ + ) + .containing("org.testcontainers") + .containing("mssqlserver") + .containing("jooq-codegen-maven") + .and() + .hasFile("src/main/resources/config/application.yml") + .containing( + // language=yaml + """ + spring: + datasource: + driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver + hikari: + auto-commit: false + poolName: Hikari + password: yourStrong(!)Password + type: com.zaxxer.hikari.HikariDataSource + url: jdbc:sqlserver://localhost:1433;database=myapp;trustServerCertificate=true + username: SA + """ + ) + .and() + .hasFile("src/test/resources/config/application-test.yml") + .containing( + // language=yaml + """ + spring: + datasource: + driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver + hikari: + maximum-pool-size: 2 + password: yourStrong(!)Password + url: jdbc:tc:sqlserver:///;database=myapp;trustServerCertificate=true?TC_TMPFS=/testtmpfs:rw + username: SA + """ + ); + } + + private JHipsterModulesAssertions.ModuleFile integrationTestAnnotation() { + return file("src/test/resources/projects/files/IntegrationTest.java", "src/test/java/tech/jhipster/jhlitest/IntegrationTest.java"); + } +} From 42678fa19c1298083f758affb53443f0999913e3 Mon Sep 17 00:00:00 2001 From: fabienpuissant Date: Sun, 20 Oct 2024 21:39:46 +0200 Subject: [PATCH 2/2] add jooq module with default maven codegen --- .../jooq/domain/JooqModuleFactory.java | 120 ++++++--------- .../lite/module/domain/JHipsterModule.java | 5 + .../domain/jooqplugin/DatabaseType.java | 10 ++ .../JooqModuleCodegenConfiguration.java | 140 ++++++++++++++++++ .../jooq/domain/JooqModuleFactoryTest.java | 2 +- 5 files changed, 203 insertions(+), 74 deletions(-) create mode 100644 src/main/java/tech/jhipster/lite/module/domain/jooqplugin/DatabaseType.java create mode 100644 src/main/java/tech/jhipster/lite/module/domain/jooqplugin/JooqModuleCodegenConfiguration.java diff --git a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java index 777d2989b6b..e5c4cd550de 100644 --- a/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java +++ b/src/main/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactory.java @@ -16,6 +16,11 @@ public class JooqModuleFactory { + public static final String GENERATE = "generate"; + public static final String JOOQ_CODEGEN = "jooq-codegen"; + public static final String JOOQ_CODEGEN_MAVEN = "jooq-codegen-maven"; + public static final String ORG_JOOQ = "org.jooq"; + public static final String MSSQL_PASSWORD = "yourStrong(!)Password"; public static final String ORG_POSTGRESQL = "org.postgresql"; private static final String MYSQL = "mysql"; private static final String MYSQL_GROUP_ID = "com.mysql"; @@ -53,11 +58,17 @@ public JHipsterModule buildPostgresql(JHipsterModuleProperties properties) { .and() .mavenPlugins() .plugin(mavenPlugin() - .groupId("org.jooq") - .artifactId("jooq-codegen-maven") + .groupId(ORG_JOOQ) + .artifactId(JOOQ_CODEGEN_MAVEN) .versionSlug("jooq") - .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) - .configuration(jooqCodegenPluginConfiguration("jdbc:postgresql://localhost:5432/" + properties.projectBaseName().name(), DatabaseType.POSTGRESQL, properties.projectBaseName().name(), "", "public")) + .addExecution(pluginExecution().goals(GENERATE).id(JOOQ_CODEGEN).phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqModuleCodegenConfiguration() + .database(tech.jhipster.lite.module.domain.jooqplugin.DatabaseType.POSTGRESQL) + .databaseUrl("jdbc:postgresql://localhost:5432/" + properties.projectBaseName().name()) + .user(properties.projectBaseName().name()) + .inputSchema("public") + .build() + .getConfiguration()) .build()) .and() .springMainProperties() @@ -96,11 +107,17 @@ public JHipsterModule buildMariaDB(JHipsterModuleProperties properties) { .and() .mavenPlugins() .plugin(mavenPlugin() - .groupId("org.jooq") - .artifactId("jooq-codegen-maven") + .groupId(ORG_JOOQ) + .artifactId(JOOQ_CODEGEN_MAVEN) .versionSlug("jooq") - .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) - .configuration(jooqCodegenPluginConfiguration("jdbc:mariadb://localhost:3306/" + properties.projectBaseName().name(), DatabaseType.MARIADB, "root", "", properties.projectBaseName().name())) + .addExecution(pluginExecution().goals(GENERATE).id(JOOQ_CODEGEN).phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqModuleCodegenConfiguration() + .database(tech.jhipster.lite.module.domain.jooqplugin.DatabaseType.MARIADB) + .databaseUrl("jdbc:mariadb://localhost:3306/" + properties.projectBaseName().name()) + .user("root") + .inputSchema("properties.projectBaseName().name()") + .build() + .getConfiguration()) .build()) .and() .springMainProperties() @@ -126,11 +143,17 @@ public JHipsterModule buildMySQL(JHipsterModuleProperties properties) { .and() .mavenPlugins() .plugin(mavenPlugin() - .groupId("org.jooq") - .artifactId("jooq-codegen-maven") + .groupId(ORG_JOOQ) + .artifactId(JOOQ_CODEGEN_MAVEN) .versionSlug("jooq") - .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) - .configuration(jooqCodegenPluginConfiguration("jdbc:mysql://localhost:3306/" + properties.projectBaseName().name(), DatabaseType.MYSQL, "root", "", properties.projectBaseName().name())) + .addExecution(pluginExecution().goals(GENERATE).id(JOOQ_CODEGEN).phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqModuleCodegenConfiguration() + .database(tech.jhipster.lite.module.domain.jooqplugin.DatabaseType.MYSQL) + .databaseUrl("jdbc:mysql://localhost:3306/" + properties.projectBaseName().name()) + .user("root") + .inputSchema("properties.projectBaseName().name()") + .build() + .getConfiguration()) .build()) .and() .springMainProperties() @@ -166,11 +189,17 @@ public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { .and() .mavenPlugins() .plugin(mavenPlugin() - .groupId("org.jooq") - .artifactId("jooq-codegen-maven") + .groupId(ORG_JOOQ) + .artifactId(JOOQ_CODEGEN_MAVEN) .versionSlug("jooq") - .addExecution(pluginExecution().goals("generate").id("jooq-codegen").phase(MavenBuildPhase.GENERATE_RESOURCES)) - .configuration(jooqCodegenPluginConfiguration("jdbc:sqlserver://localhost:1433;database=" + properties.projectBaseName().name() + ";trustServerCertificate=true", DatabaseType.MSSQL, "SA", "yourStrong(!)Password", "model")) + .addExecution(pluginExecution().goals(GENERATE).id(JOOQ_CODEGEN).phase(MavenBuildPhase.GENERATE_RESOURCES)) + .configuration(jooqModuleCodegenConfiguration() + .database(tech.jhipster.lite.module.domain.jooqplugin.DatabaseType.MSSQL) + .databaseUrl("jdbc:sqlserver://localhost:1433;database=" + properties.projectBaseName().name() + ";trustServerCertificate=true") + .user("SA") + .inputSchema("model") + .password(MSSQL_PASSWORD) + .getConfiguration()) .build()) .and() .springMainProperties() @@ -179,7 +208,7 @@ public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { propertyValue("jdbc:sqlserver://localhost:1433;database=" + properties.projectBaseName().name() + ";trustServerCertificate=true") ) .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue("SA")) - .set(propertyKey("spring.datasource.password"), propertyValue("yourStrong(!)Password")) + .set(propertyKey("spring.datasource.password"), propertyValue(MSSQL_PASSWORD)) .set(propertyKey(SPRING_DATASOURCE_DRIVER_CLASS_NAME), propertyValue("com.microsoft.sqlserver.jdbc.SQLServerDriver")) .and() .springTestProperties() @@ -190,7 +219,7 @@ public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { ) ) .set(propertyKey(SPRING_DATASOURCE_USERNAME), propertyValue("SA")) - .set(propertyKey("spring.datasource.password"), propertyValue("yourStrong(!)Password")) + .set(propertyKey("spring.datasource.password"), propertyValue(MSSQL_PASSWORD)) .and() .mandatoryReplacements() .in(path("src/test/java").append(properties.basePackage().path()).append("IntegrationTest.java")) @@ -206,59 +235,4 @@ public JHipsterModule buildMsSQL(JHipsterModuleProperties properties) { .build(); //@formatter:on } - - //TODO Create an API for MavenPluginConfiguration with a builder - private String jooqCodegenPluginConfiguration( - String databaseUrl, - DatabaseType databaseType, - String user, - String password, - String inputSchema - ) { - return String.format( - """ - - %s - %s - %s - %s - - - - %s - .* - %s - - - org.jooq.codegen - target/generated-sources/jooq - - - """, - databaseDriver(databaseType), - databaseUrl, - user, - password, - databaseJooqName(databaseType), - inputSchema - ); - } - - private static String databaseJooqName(DatabaseType databaseType) { - return switch (databaseType) { - case POSTGRESQL -> "org.jooq.meta.postgres.PostgresDatabase"; - case MYSQL -> "org.jooq.meta.mysql.MySQLDatabase"; - case MARIADB -> "org.jooq.meta.mariadb.MariaDBDatabase"; - case MSSQL -> "org.jooq.meta.sqlserver.SQLServerDatabase"; - }; - } - - private static String databaseDriver(DatabaseType databaseType) { - return switch (databaseType) { - case POSTGRESQL -> "org.postgresql.Driver"; - case MARIADB -> "org.mariadb.jdbc.Driver"; - case MYSQL -> "com.mysql.jdbc.Driver"; - case MSSQL -> "com.microsoft.sqlserver.jdbc.SQLServerDriver"; - }; - } } diff --git a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java index 868add69bfb..0d4f881c663 100644 --- a/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java +++ b/src/main/java/tech/jhipster/lite/module/domain/JHipsterModule.java @@ -37,6 +37,7 @@ import tech.jhipster.lite.module.domain.javaproperties.*; import tech.jhipster.lite.module.domain.javaproperties.JHipsterModuleSpringFactories.JHipsterModuleSpringFactoriesBuilder; import tech.jhipster.lite.module.domain.javaproperties.JHipsterModuleSpringProperties.JHipsterModuleSpringPropertiesBuilder; +import tech.jhipster.lite.module.domain.jooqplugin.JooqModuleCodegenConfiguration; import tech.jhipster.lite.module.domain.mavenplugin.*; import tech.jhipster.lite.module.domain.mavenplugin.JHipsterModuleMavenPlugins.JHipsterModuleMavenPluginsBuilder; import tech.jhipster.lite.module.domain.mavenplugin.MavenPlugin.MavenPluginGroupIdBuilder; @@ -190,6 +191,10 @@ public static JavaDependencyGroupIdBuilder javaDependency() { return JavaDependency.builder(); } + public static JooqModuleCodegenConfiguration.JooqModuleCodegenConfigurationBuilder jooqModuleCodegenConfiguration() { + return JooqModuleCodegenConfiguration.builder(); + } + public static MavenBuildExtensionGroupIdBuilder mavenBuildExtension() { return MavenBuildExtension.builder(); } diff --git a/src/main/java/tech/jhipster/lite/module/domain/jooqplugin/DatabaseType.java b/src/main/java/tech/jhipster/lite/module/domain/jooqplugin/DatabaseType.java new file mode 100644 index 00000000000..1484212f297 --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/domain/jooqplugin/DatabaseType.java @@ -0,0 +1,10 @@ +package tech.jhipster.lite.module.domain.jooqplugin; + +//shared enum ?? + +public enum DatabaseType { + POSTGRESQL, + MYSQL, + MARIADB, + MSSQL, +} diff --git a/src/main/java/tech/jhipster/lite/module/domain/jooqplugin/JooqModuleCodegenConfiguration.java b/src/main/java/tech/jhipster/lite/module/domain/jooqplugin/JooqModuleCodegenConfiguration.java new file mode 100644 index 00000000000..bc18291c9dc --- /dev/null +++ b/src/main/java/tech/jhipster/lite/module/domain/jooqplugin/JooqModuleCodegenConfiguration.java @@ -0,0 +1,140 @@ +package tech.jhipster.lite.module.domain.jooqplugin; + +import tech.jhipster.lite.shared.error.domain.Assert; + +public final class JooqModuleCodegenConfiguration { + + private final DatabaseType database; + private final String databaseUrl; + private final String user; + private final String inputSchema; + private final String password; + + private JooqModuleCodegenConfiguration(JooqModuleCodegenConfigurationBuilder builder) { + Assert.notNull("database", builder.database); + Assert.notNull("databaseUrl", builder.databaseUrl); + Assert.notNull("user", builder.user); + Assert.notNull("inputSchema", builder.inputSchema); + + this.database = builder.database; + this.databaseUrl = builder.databaseUrl; + this.user = builder.user; + this.inputSchema = builder.inputSchema; + this.password = builder.password == null ? "" : builder.password; + } + + public String getConfiguration() { + return String.format( + """ + + %s + %s + %s + + + + %s + .* + %s + + + org.jooq.codegen + target/generated-sources/jooq + + + """, + databaseUrl, + user, + password, + databaseJooqName(), + inputSchema + ); + } + + private String databaseJooqName() { + return switch (database) { + case POSTGRESQL -> "org.jooq.meta.postgres.PostgresDatabase"; + case MYSQL -> "org.jooq.meta.mysql.MySQLDatabase"; + case MARIADB -> "org.jooq.meta.mariadb.MariaDBDatabase"; + case MSSQL -> "org.jooq.meta.sqlserver.SQLServerDatabase"; + }; + } + + public static JooqModuleCodegenConfigurationBuilder builder() { + return new JooqModuleCodegenConfigurationBuilder(); + } + + public interface JooqModuleCodegenConfigurationDatabaseBuilder { + JooqModuleCodegenConfigurationDatabaseUrlBuilder database(DatabaseType database); + } + + public interface JooqModuleCodegenConfigurationDatabaseUrlBuilder { + JooqModuleCodegenConfigurationUserBuilder databaseUrl(String databaseUrl); + } + + public interface JooqModuleCodegenConfigurationUserBuilder { + JooqModuleCodegenConfigurationInputSchemaBuilder user(String user); + } + + public interface JooqModuleCodegenConfigurationInputSchemaBuilder { + JooqModuleCodegenConfigurationBuilder inputSchema(String inputSchema); + } + + public interface JooqModuleCodegenConfigurationPasswordBuilder { + JooqModuleCodegenConfiguration password(String password); + } + + public static final class JooqModuleCodegenConfigurationBuilder + implements + JooqModuleCodegenConfigurationDatabaseBuilder, + JooqModuleCodegenConfigurationDatabaseUrlBuilder, + JooqModuleCodegenConfigurationUserBuilder, + JooqModuleCodegenConfigurationInputSchemaBuilder, + JooqModuleCodegenConfigurationPasswordBuilder { + + private DatabaseType database; + private String databaseUrl; + private String user; + private String inputSchema; + private String password; + + @Override + public JooqModuleCodegenConfigurationDatabaseUrlBuilder database(DatabaseType database) { + this.database = database; + + return this; + } + + @Override + public JooqModuleCodegenConfigurationUserBuilder databaseUrl(String databaseUrl) { + this.databaseUrl = databaseUrl; + + return this; + } + + @Override + public JooqModuleCodegenConfigurationInputSchemaBuilder user(String user) { + this.user = user; + + return this; + } + + @Override + public JooqModuleCodegenConfigurationBuilder inputSchema(String inputSchema) { + this.inputSchema = inputSchema; + + return this; + } + + @Override + public JooqModuleCodegenConfiguration password(String password) { + this.password = password; + + return build(); + } + + public JooqModuleCodegenConfiguration build() { + return new JooqModuleCodegenConfiguration(this); + } + } +} diff --git a/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java index 258ea11b624..0773df34c68 100644 --- a/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java +++ b/src/test/java/tech/jhipster/lite/generator/server/springboot/database/jooq/domain/JooqModuleFactoryTest.java @@ -19,7 +19,7 @@ @UnitTest @ExtendWith(MockitoExtension.class) -public class JooqModuleFactoryTest { +class JooqModuleFactoryTest { @Mock private DockerImages dockerImages;