Skip to content

Commit

Permalink
refactor: Set up test, dev, and production environments
Browse files Browse the repository at this point in the history
  • Loading branch information
shorinami committed Jan 10, 2024
1 parent 7d441f7 commit ca66036
Show file tree
Hide file tree
Showing 19 changed files with 273 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
/build/

# Etc
/.env
/test
logs/
24 changes: 24 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ repositories {
mavenCentral()
}

sourceSets {
val dev by creating {
compileClasspath += main.get().output
runtimeClasspath += main.get().output
}
}

val devImplementation: Configuration by configurations.getting {
extendsFrom(configurations.implementation.get())
}

dependencies {
// Spring
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
Expand Down Expand Up @@ -50,9 +61,14 @@ dependencies {
implementation("io.sentry", "sentry-spring-boot-starter", "7.1.0")
// Testing
testImplementation("org.springframework.boot", "spring-boot-starter-test")
testImplementation("org.springframework.boot", "spring-boot-testcontainers")
testImplementation("org.testcontainers", "postgresql", "1.19.3")
testImplementation("org.testcontainers", "junit-jupiter", "1.19.3")
testImplementation("org.junit.jupiter", "junit-jupiter-api", "5.10.1")
testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.10.1")
testImplementation("org.mockito", "mockito-junit-jupiter", "5.8.0")
// Development
devImplementation("org.testcontainers", "postgresql", "1.19.3")
}

tasks {
Expand All @@ -69,7 +85,15 @@ tasks {
dependsOn("bootJar")
}

create<org.springframework.boot.gradle.tasks.run.BootRun>("bootDevRun") {
group = "application"
mainClass.set("com.sellbycar.marketplace.DevelopmentLauncher")
classpath(sourceSets["dev"].runtimeClasspath)
jvmArgs("-Dspring.profiles.active=development")
}

test {
useJUnitPlatform()
jvmArgs("-Dspring.profiles.active=testing")
}
}
8 changes: 8 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
pluginManagement {
plugins {
kotlin("jvm") version "1.9.21"
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
}
rootProject.name = "backend"
22 changes: 22 additions & 0 deletions src/dev/java/com/sellbycar/marketplace/DevelopmentLauncher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.sellbycar.marketplace;

import lombok.extern.slf4j.Slf4j;

import java.io.File;

@Slf4j
public class DevelopmentLauncher {

public static void main(String[] args) {
checkDocker();
MarketplaceApplication.main(args);
}

private static void checkDocker() {
File dockerSocket = new File("/var/run/docker.sock");
if (!dockerSocket.exists()) {
log.error("Install and run Docker to boot the development environment.");
Runtime.getRuntime().exit(1);
}
}
}
28 changes: 28 additions & 0 deletions src/dev/java/com/sellbycar/marketplace/config/DatabaseConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.sellbycar.marketplace.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.testcontainers.containers.PostgreSQLContainer;

import javax.sql.DataSource;

@Configuration
public class DatabaseConfig {

@SuppressWarnings({"rawtypes"})
private final PostgreSQLContainer<?> container = new PostgreSQLContainer("postgres:latest")
.withUsername("development")
.withPassword("development")
.withDatabaseName("development");

@Bean
public DataSource dataSource() {
container.start();
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setUrl(container.getJdbcUrl());
dataSource.setUsername(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
}
}
29 changes: 29 additions & 0 deletions src/dev/java/com/sellbycar/marketplace/config/MailConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.sellbycar.marketplace.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.testcontainers.containers.GenericContainer;

import java.util.Properties;

@Configuration
public class MailConfig {

@SuppressWarnings({"resource"})
private final GenericContainer<?> container = new GenericContainer<>("oryd/mailslurper:latest-smtps")
.withExposedPorts(1025);

@Bean
public JavaMailSender javaMailSender() {
container.start();
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost(container.getHost());
mailSender.setPort(container.getMappedPort(1025));
Properties properties = mailSender.getJavaMailProperties();
properties.put("mail.smtp.auth", "false");
properties.put("mail.smtp.starttls.enable", "false");
return mailSender;
}
}
10 changes: 10 additions & 0 deletions src/dev/resources/application-development.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Jwt
jwt.secret.access=xEyI5DO1025mQmmyHuKefeZ/Fm4q5p7oXCIRa2D3eioxBjJB4F4p3ea88PRpXj3jx9q6sdoeAJfOfyFXtS6/MQ==
jwt.secret.refresh=x4zh8N0eX0T5GHORFFuuU2hC0gdBrFrPE15DpCBoznkNE55kqUK1N6m0x3gvg5bgqecAoWn0rOpYJN+md3owXQ==

# Log
logging.level.org.springframework.web=INFO
spring.output.ansi.enabled=always

# Mail
spring.mail.username=
2 changes: 1 addition & 1 deletion src/main/java/com/sellbycar/marketplace/auth/JwtUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class JwtUtils {
private static final Logger logger = LoggerFactory.getLogger(AuthEntryPointJwt.class);

@Value(("${jwt.secret.access.expirationMs}"))
private int jwtAccessExpirationMs;
private long jwtAccessExpirationMs;

@Value(("${jwt.secret.refresh.expirationMs}"))
private long jwtRefreshExpirationMs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@
@Configuration
public class SwaggerConfig {

@Value("${SERVER_SOURCE}")
@Value("${server.url}")
private String serverURL;
@Value("${server.description}")
private String serverDescription;

@Bean
OpenAPI customOpenApi() {
return new OpenAPI()
.info(new Info().
title("REST API marketplace")
title("REST API eTachka Marketplace")
.version("v1")
.description("REST API for user database")
.termsOfService("s"))
.description("Documentation for accessing the eTachka Marketplace resources via REST API.")
.termsOfService("https://etachka-marketplace.space/tos"))
.addServersItem(new Server()
.url(serverURL)
.description("Future Server for Marketplace"));
.description(serverDescription));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {
@Value(("${front.host}"))
@Value(("${server.frontend.host}"))
private String host;
private final UserRepository userRepository;
private final UserDetailsServiceImpl userDetailsServiceImpl;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"properties": [
{
"name": "server.url",
"type": "java.lang.String",
"description": "URL of the server."
},
{
"name": "jwt.secret.access.expirationMs",
"type": "java.lang.Long",
"description": "JWT secret access expiration in milliseconds."
},
{
"name": "jwt.secret.refresh.expirationMs",
"type": "java.lang.Long",
"description": "JWT secret refresh expiration in milliseconds."
},
{
"name": "jwt.secret.access",
"type": "java.lang.String",
"description": "JWT secret access."
},
{
"name": "jwt.secret.refresh",
"type": "java.lang.String",
"description": "JWT secret refresh."
},
{
"name": "server.frontend.host",
"type": "java.lang.String",
"description": "Frontend server host."
}
]
}
31 changes: 31 additions & 0 deletions src/main/resources/application-production.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Database
spring.datasource.url=${DB_SOURCE}
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}

# Mail
spring.mail.host=${EMAIL_HOST}
spring.mail.port=587
spring.mail.username=${YOUR_EMAIL}
spring.mail.password=${EMAIL_PASSWORD}
spring.mail.protocol=smtp
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

# Server
server.url=https://api.etachka-marketplace.space
server.description=REST API eTachka Marketplace
server.frontend.host=https://etachka-marketplace.space

# Jwt
jwt.secret.access=${JWT_TOKEN_SECRET_ACCESS}
jwt.secret.refresh=${JWT_TOKEN_SECRET_REFRESH}

# Log
logging.level.org.springframework.web=INFO
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
logging.file.name=logs/LogFile.log

# Sentry
sentry.dsn=${SENTRY_DSN}
sentry.traces-sample-rate=1.0
47 changes: 10 additions & 37 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,52 +1,25 @@
# Database settings
# Database
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=${DB_SOURCE}
spring.datasource.username=${DB_USER:root}
spring.datasource.password=${DB_PASSWORD:root}
spring.jpa.database=postgresql
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=validate

# Migrations
spring.flyway.baselineOnMigrate=true

#Swagger Settings
# Swagger
springdoc.swagger-ui.use-root-path=true
springdoc.paths-to-match=/**/v1/**, /api/**

# Front source
front.host=${FRONT_HOST}

#HTTPS
# Server
server.ssl.enabled=false
server.port=${PORT:8080}
server.url=http://localhost:${PORT:8080}
server.description=
server.frontend.host=localhost

# Mail sender settings
spring.mail.host=${EMAIL_HOST}
spring.mail.port=587
spring.mail.username=${YOUR_EMAIL}
spring.mail.password=${EMAIL_PASSWORD}
spring.mail.protocol=smtp
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

# Jwt Settings
jwt.secret.access.expirationMs=9000000
jwt.secret.refresh.expirationMs=540000000
jwt.secret.access=${JWT_TOKEN_SECRET_ACCESS}
jwt.secret.refresh=${JWT_TOKEN_SECRET_REFRESH}

# Image settings
# Servlet
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

# log pattern
logging.level.org.springframework.web=INFO
logging.pattern.file= "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
logging.file.name=logs/LogFile.log
spring.output.ansi.enabled=detect

# Sentry
sentry.dsn=${SENTRY_DSN:}
sentry.traces-sample-rate=1.0
# JWT
jwt.secret.access.expirationMs=9000000
jwt.secret.refresh.expirationMs=540000000
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.sellbycar.marketplace;

import com.sellbycar.marketplace.util.ContainerUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

@SpringBootTest
@Testcontainers
class MarketplaceApplicationTest {

@Container
public static PostgreSQLContainer<?> postgres = ContainerUtil.createPostgres();
@Container
public static GenericContainer<?> mailslurper = ContainerUtil.createMailslurper();

@DynamicPropertySource
static void configureProperties(DynamicPropertyRegistry registry) {
// Database
registry.add("spring.datasource.url", postgres::getJdbcUrl);
registry.add("spring.datasource.username", postgres::getUsername);
registry.add("spring.datasource.password", postgres::getPassword);
// Mail
registry.add("spring.mail.host", mailslurper::getHost);
registry.add("spring.mail.port", () -> mailslurper.getMappedPort(1025));
registry.add("spring.mail.username", () -> "");
registry.add("spring.mail.protocol", () -> "smtp");
registry.add("spring.mail.smtp.auth", () -> false);
registry.add("spring.mail.smtp.starttls.enable", () -> false);
}

@Test
void contextLoads() {
}
}

This file was deleted.

Loading

0 comments on commit ca66036

Please sign in to comment.