Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MSSQL core #1770

Merged
merged 3 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/github-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ jobs:
- oauth2app
- mysqlapp
- mariadbapp
- mssqlapp
- flywayapp
- undertowapp
- eurekaapp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ public enum DatabaseType {
MYSQL("mysql"),
MARIADB("mariadb"),
ORACLE("oracle"),
MSSQL("mssql"),
MSSQL("mssqlserver"),
MONGODB("mongodb"),
CASSANDRA("cassandra"),
COUCHBASE("couchbase"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ private GeneratorAction() {}

public static final String MYSQL = "mysql";

public static final String MSSQL = "mssql";

public static final String FLYWAY = "flyway";
public static final String FLYWAY_USER_AND_AUTHORITY_CHANGELOGS = "flyway-user-and-authority-changelogs";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package tech.jhipster.lite.generator.server.springboot.database.mssql.application;

import org.springframework.stereotype.Service;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.server.springboot.database.mssql.domain.MssqlService;

@Service
public class MssqlApplicationService {

private final MssqlService mssqlService;

public MssqlApplicationService(MssqlService mssqlService) {
this.mssqlService = mssqlService;
}

public void init(Project project) {
mssqlService.init(project);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package tech.jhipster.lite.generator.server.springboot.database.mssql.domain;

import java.util.Map;
import java.util.TreeMap;
import tech.jhipster.lite.generator.buildtool.generic.domain.Dependency;

public class Mssql {

public static final String MSSQL_DOCKER_IMAGE_NAME = "mcr.microsoft.com/mssql/server";
public static final String MSSQL_TEST_CONTAINER_EXTENSION_FILE = "MssqlTestContainerExtension.java";
public static final String LICENSE_TEST_CONTAINER_FILE = "container-license-acceptance.txt";

private Mssql() {}

public static String getDockerImageName() {
return MSSQL_DOCKER_IMAGE_NAME;
}

public static Dependency driver() {
return Dependency.builder().groupId("com.microsoft.sqlserver").artifactId("mssql-jdbc").build();
}

public static Map<String, Object> springProperties(String baseName) {
TreeMap<String, Object> result = new TreeMap<>();
result.put("spring.datasource.url", "jdbc:sqlserver://localhost:1433;database=" + baseName + ";trustServerCertificate=true");
result.put("spring.datasource.driver-class-name", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
result.put("spring.datasource.username", "SA");
result.put("spring.datasource.password", "yourStrong(!)Password");

result.put("spring.jpa.hibernate.ddl-auto", "update");
result.put("spring.jpa.properties.hibernate.format_sql", true);
result.put("spring.jpa.properties.hibernate.dialect", "org.hibernate.dialect.SQLServer2012Dialect");
return result;
}

public static Map<String, Object> springPropertiesForTest(String baseName) {
TreeMap<String, Object> result = new TreeMap<>();
result.put("spring.datasource.driver-class-name", "org.testcontainers.jdbc.ContainerDatabaseDriver");
result.put(
"spring.datasource.url",
"jdbc:tc:sqlserver:latest://;database=" + baseName + ";trustServerCertificate=true?TC_TMPFS=/testtmpfs:rw"
);
result.put("spring.datasource.username", "SA");
result.put("spring.datasource.password", "yourStrong(!)Password");
result.put("spring.datasource.hikari.maximum-pool-size", 2);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package tech.jhipster.lite.generator.server.springboot.database.mssql.domain;

import static tech.jhipster.lite.common.domain.FileUtils.*;
import static tech.jhipster.lite.generator.project.domain.Constants.*;
import static tech.jhipster.lite.generator.project.domain.DefaultConfig.*;

import tech.jhipster.lite.error.domain.Assert;
import tech.jhipster.lite.generator.buildtool.generic.domain.BuildToolService;
import tech.jhipster.lite.generator.docker.domain.DockerImages;
import tech.jhipster.lite.generator.project.domain.DatabaseType;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.domain.ProjectFile;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;
import tech.jhipster.lite.generator.server.springboot.common.domain.Level;
import tech.jhipster.lite.generator.server.springboot.common.domain.SpringBootCommonService;
import tech.jhipster.lite.generator.server.springboot.database.sqlcommon.domain.SQLCommonService;

public class MssqlDomainService implements MssqlService {

public static final String SOURCE = "server/sql";
public static final String EXTENSION_TEST_CONTAINER = "server/springboot/core";
public static final String EXTENSION_INTEGRATION_TEST_CLASS = "MssqlTestContainerExtension";

private final BuildToolService buildToolService;
private final SpringBootCommonService springBootCommonService;
private final SQLCommonService sqlCommonService;
private final DockerImages dockerImages;
private final ProjectRepository projectRepository;

public MssqlDomainService(
BuildToolService buildToolService,
SpringBootCommonService springBootCommonService,
SQLCommonService sqlCommonService,
DockerImages dockerImages,
ProjectRepository projectRepository
) {
this.buildToolService = buildToolService;
this.springBootCommonService = springBootCommonService;
this.sqlCommonService = sqlCommonService;
this.dockerImages = dockerImages;
this.projectRepository = projectRepository;
}

@Override
public void init(Project project) {
Assert.notNull("project", project);

addSpringData(project);
addDriver(project);
addDockerCompose(project);
addJavaFiles(project);
addHikari(project);
addProperties(project);
addHibernateCore(project);
addTestcontainers(project);
addLoggerInConfiguration(project);
}

private void addSpringData(Project project) {
sqlCommonService.addSpringDataJpa(project);
}

private void addDriver(Project project) {
buildToolService.addDependency(project, Mssql.driver());
}

private void addDockerCompose(Project project) {
project.addDefaultConfig(BASE_NAME);

String dockerImage = dockerImages.get(Mssql.getDockerImageName()).fullName();
project.addConfig("dockerImageName", dockerImage);

sqlCommonService.addDockerComposeTemplate(project, DatabaseType.MSSQL.id());
}

private void addHikari(Project project) {
sqlCommonService.addHikari(project);
}

private void addJavaFiles(Project project) {
sqlCommonService.addJavaFiles(project, DatabaseType.MSSQL.id());
}

private void addProperties(Project project) {
springBootCommonService.addPropertiesComment(project, "Database Configuration");

Mssql
.springProperties(project.getBaseName().orElse("jhipster"))
.forEach((k, v) -> springBootCommonService.addProperties(project, k, v));
springBootCommonService.addPropertiesNewLine(project);
}

private void addTestcontainers(Project project) {
String packageNamePath = project.getPackageNamePath().orElse(getPath(PACKAGE_PATH));
String integrationTestPath = getPath(TEST_JAVA, packageNamePath);
sqlCommonService.addTestcontainers(
project,
DatabaseType.MSSQL.id(),
Mssql.springPropertiesForTest(project.getBaseName().orElse("jhipster"))
);
projectRepository.add(
ProjectFile.forProject(project).withSource(SOURCE, Mssql.LICENSE_TEST_CONTAINER_FILE).withDestinationFolder(TEST_RESOURCES)
);
projectRepository.template(
ProjectFile
.forProject(project)
.withSource(EXTENSION_TEST_CONTAINER, Mssql.MSSQL_TEST_CONTAINER_EXTENSION_FILE)
.withDestinationFolder(getPath(integrationTestPath))
);
springBootCommonService.updateIntegrationTestAnnotation(project, EXTENSION_INTEGRATION_TEST_CLASS);
}

private void addHibernateCore(Project project) {
sqlCommonService.addHibernateCore(project);
}

private void addLoggerInConfiguration(Project project) {
sqlCommonService.addLoggers(project);
addLogger(project, "org.reflections", Level.WARN);
addLogger(project, Mssql.driver().getGroupId(), Level.WARN);

springBootCommonService.addLoggerTest(project, "com.github.dockerjava", Level.WARN);
springBootCommonService.addLoggerTest(project, "org.testcontainers", Level.WARN);
}

private void addLogger(Project project, String packageName, Level level) {
springBootCommonService.addLogger(project, packageName, level);
springBootCommonService.addLoggerTest(project, packageName, level);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tech.jhipster.lite.generator.server.springboot.database.mssql.domain;

import tech.jhipster.lite.generator.project.domain.Project;

public interface MssqlService {
void init(Project project);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package tech.jhipster.lite.generator.server.springboot.database.mssql.infrastructure.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.jhipster.lite.generator.buildtool.generic.domain.BuildToolService;
import tech.jhipster.lite.generator.docker.domain.DockerImages;
import tech.jhipster.lite.generator.project.domain.ProjectRepository;
import tech.jhipster.lite.generator.server.springboot.common.domain.SpringBootCommonService;
import tech.jhipster.lite.generator.server.springboot.database.mssql.domain.MssqlDomainService;
import tech.jhipster.lite.generator.server.springboot.database.mssql.domain.MssqlService;
import tech.jhipster.lite.generator.server.springboot.database.sqlcommon.domain.SQLCommonService;

@Configuration
public class MssqlBeanConfiguration {

private final BuildToolService buildToolService;
private final SpringBootCommonService springBootCommonService;
private final SQLCommonService sqlCommonService;
private final DockerImages dockerImages;
private final ProjectRepository projectRepository;

public MssqlBeanConfiguration(
BuildToolService buildToolService,
SpringBootCommonService springBootCommonService,
SQLCommonService sqlCommonService,
DockerImages dockerImages,
ProjectRepository projectRepository
) {
this.buildToolService = buildToolService;
this.springBootCommonService = springBootCommonService;
this.sqlCommonService = sqlCommonService;
this.dockerImages = dockerImages;
this.projectRepository = projectRepository;
}

@Bean
public MssqlService mssqlService() {
return new MssqlDomainService(buildToolService, springBootCommonService, sqlCommonService, dockerImages, projectRepository);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tech.jhipster.lite.generator.server.springboot.database.mssql.infrastructure.primary.rest;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.jhipster.lite.generator.project.domain.GeneratorAction;
import tech.jhipster.lite.generator.project.domain.Project;
import tech.jhipster.lite.generator.project.infrastructure.primary.dto.ProjectDTO;
import tech.jhipster.lite.generator.server.springboot.database.mssql.application.MssqlApplicationService;
import tech.jhipster.lite.technical.infrastructure.primary.annotation.GeneratorStep;

@RestController
@RequestMapping("/api/servers/spring-boot/databases/mssql")
@Tag(name = "Spring Boot - Database")
class MssqlResource {

private final MssqlApplicationService mongodbApplicationService;

public MssqlResource(MssqlApplicationService mongodbApplicationService) {
this.mongodbApplicationService = mongodbApplicationService;
}

@Operation(summary = "Add MSSQL drivers and dependencies, with testcontainers")
@ApiResponse(responseCode = "500", description = "An error occurred while adding MSSQL")
@PostMapping
@GeneratorStep(id = GeneratorAction.MSSQL)
public void init(@RequestBody ProjectDTO projectDTO) {
Project project = ProjectDTO.toProject(projectDTO);
mongodbApplicationService.init(project);
}
}
1 change: 1 addition & 0 deletions src/main/resources/generator/dependencies/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ FROM jboss/keycloak:16.1.1
FROM mariadb:10.8.3
FROM mongo:5.0.9
FROM mysql:8.0.29
FROM mcr.microsoft.com/mssql/server:2019-CU15-ubuntu-20.04
FROM postgres:14.3
FROM confluentinc/cp-zookeeper:7.1.1
FROM confluentinc/cp-kafka:7.1.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package {{packageName}};

import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.utility.DockerImageName;

import java.util.concurrent.atomic.AtomicBoolean;

public class MssqlTestContainerExtension implements BeforeAllCallback {

private static AtomicBoolean started = new AtomicBoolean(false);

private static MSSQLServerContainer<?> container = new MSSQLServerContainer<>(DockerImageName.parse("mcr.microsoft.com/mssql/server:latest").asCompatibleSubstituteFor("mcr.microsoft.com/mssql/server"))
.withUrlParam("trustServerCertificate","true")
.acceptLicense();

@Override
public void beforeAll(ExtensionContext extensionContext) throws Exception {
if (!started.get()) {
container.start();
System.setProperty("spring.datasource.url", container.getJdbcUrl());
System.setProperty("spring.datasource.password", container.getPassword());
System.setProperty("spring.datasource.username", container.getUsername());
System.setProperty("spring.datasource.driver-class-name","com.microsoft.sqlserver.jdbc.SQLServerDriver");
started.set(true);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package {{packageName}}.technical.infrastructure.secondary.mssqlserver;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories({ "{{packageName}}" })
@EnableTransactionManagement
public class DatabaseConfiguration {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This configuration is intended for development purpose, it's **your** responsibility to harden it for production
version: '2'
services:
msmssql-mssql:
image: {{dockerImageName}}
# volumes:
# - ~/volumes/jhipster/{{baseName}}/mssql/:/var/lib/mssql/
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=yourStrong(!)Password
- MSSQL_DATABASE={{baseName}}
- MSSQL_PID=Express
- MSSQL_SLEEP=60
# If you want to expose these ports outside your dev PC,
# remove the "127.0.0.1:" prefix
ports:
- 127.0.0.1:1433:1433
command: /bin/bash -c '/opt/mssql/bin/sqlservr & echo "wait $$MSSQL_SLEEP sec for DB to start "; sleep $$MSSQL_SLEEP; /opt/mssql-tools/bin/sqlcmd -U sa -P $$SA_PASSWORD -d tempdb -q "EXIT(CREATE DATABASE $$MSSQL_DATABASE)"; wait;'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mcr.microsoft.com/mssql/server:latest
Loading