Update postgres-json to Add ShadowJar compatibility

Add .env for redis and ES
change group name of project
This commit is contained in:
2020-05-11 01:50:40 +02:00
parent b4be28ddc8
commit 8640d9146d
15 changed files with 135 additions and 51 deletions

7
.env
View File

@@ -4,10 +4,11 @@ DATABASE_URL=jdbc:postgresql:dc-project
APP_PORT=8080 APP_PORT=8080
OPENAPI_PORT=8181 OPENAPI_PORT=8181
SONARQUBE_PORT=9000 SONARQUBE_PORT=9002
ELASTIC_REST=9200 ELASTIC_REST=9200
ELASTIC_NODES=9300 ELASTIC_NODES=9300
ELASTICSEARCH_CONNECTION=http://elasticsearch:9200
POSTGRESQL_PORT=5432 POSTGRESQL_PORT=5432
DB_HOST=db DB_HOST=db
@@ -17,9 +18,9 @@ DB_USER=dc-project
DB_PWD=dc-project DB_PWD=dc-project
REDIS_PORT=6379 REDIS_PORT=6379
REDIS_CONNECTION=redis://localhost:6379 REDIS_CONNECTION=redis://redis:6379
REDIS_COMMANDER_PORT=8081 REDIS_COMMANDER_PORT=8081
RABBITMQ_PORT=5672 RABBITMQ_PORT=5672
RABBITMQ_CONNECTION=amqp://localhost:5672 RABBITMQ_CONNECTION=amqp://rabbitmq:5672
RABBITMQ_MANAGEMENT_PORT=15672 RABBITMQ_MANAGEMENT_PORT=15672

31
.idea/runConfigurations/Build.xml generated Normal file
View File

@@ -0,0 +1,31 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="build" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<extension name="net.ashald.envfile">
<option name="IS_ENABLED" value="false" />
<option name="IS_SUBST" value="false" />
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
<option name="IS_IGNORE_MISSING_FILES" value="false" />
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
<ENTRIES>
<ENTRY IS_ENABLED="true" PARSER="runconfig" />
</ENTRIES>
</extension>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<method v="2" />
</configuration>
</component>

View File

@@ -0,0 +1,31 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Build without test" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-x test -x ktlintKotlinScriptCheck -x ktlintTestSourceSetCheck -x ktlintMainSourceSetCheck" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="build" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<extension name="net.ashald.envfile">
<option name="IS_ENABLED" value="false" />
<option name="IS_SUBST" value="false" />
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
<option name="IS_IGNORE_MISSING_FILES" value="false" />
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
<ENTRIES>
<ENTRY IS_ENABLED="true" PARSER="runconfig" />
</ENTRIES>
</extension>
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
<method v="2" />
</configuration>
</component>

13
.idea/runConfigurations/SQL_Fixtures.xml generated Normal file
View File

@@ -0,0 +1,13 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="SQL Fixtures" type="ShConfigurationType">
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/src/main/resources/sql/fixtures/fixtures.sh" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/src/main/resources/sql/fixtures/" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="false" />
<option name="INTERPRETER_PATH" value="C:/Program Files/Git/bin/bash.exe" />
<option name="INTERPRETER_OPTIONS" value="" />
<method v="2" />
</configuration>
</component>

View File

@@ -1,12 +1,12 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="SQL Tests" type="ShConfigurationType"> <configuration default="false" name="SQL Tests" type="ShConfigurationType">
<option name="INDEPENDENT_SCRIPT_PATH" value="false" /> <option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/src/test/test.sh" /> <option name="SCRIPT_PATH" value="$PROJECT_DIR$/src/test/test.sh" />
<option name="SCRIPT_OPTIONS" value="" /> <option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" /> <option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/src/test" /> <option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/src/test" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="false" /> <option name="INDEPENDENT_INTERPRETER_PATH" value="false" />
<option name="INTERPRETER_PATH" value="C:/Program Files/Git/git-bash.exe" /> <option name="INTERPRETER_PATH" value="C:/Program Files/Git/bin/bash.exe" />
<option name="INTERPRETER_OPTIONS" value="" /> <option name="INTERPRETER_OPTIONS" value="" />
<method v="2" /> <method v="2" />
</configuration> </configuration>

View File

@@ -1,5 +1,6 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.owasp.dependencycheck.reporting.ReportGenerator import org.owasp.dependencycheck.reporting.ReportGenerator
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
val ktor_version: String by project val ktor_version: String by project
val kotlin_version: String by project val kotlin_version: String by project
@@ -9,7 +10,7 @@ val koinVersion: String by project
val jackson_version: String by project val jackson_version: String by project
val cucumber_version: String by project val cucumber_version: String by project
group = "fr.dcproject" group = "com.github.flecomte"
version = "0.0.1" version = "0.0.1"
plugins { plugins {
@@ -19,7 +20,7 @@ plugins {
id("maven-publish") id("maven-publish")
id("org.jetbrains.kotlin.jvm") version "1.3.50" id("org.jetbrains.kotlin.jvm") version "1.3.50"
id("com.github.johnrengelman.shadow") version "5.0.0" id("com.github.johnrengelman.shadow") version "5.2.0"
id("org.jlleitschuh.gradle.ktlint") version "8.2.0" id("org.jlleitschuh.gradle.ktlint") version "8.2.0"
id("org.owasp.dependencycheck") version "5.1.0" id("org.owasp.dependencycheck") version "5.1.0"
id("org.sonarqube") version "2.7" id("org.sonarqube") version "2.7"
@@ -44,6 +45,12 @@ tasks.withType<Jar> {
} }
} }
tasks {
named<ShadowJar>("shadowJar") {
mergeServiceFiles("META-INF/services")
}
}
jacoco { jacoco {
toolVersion = "0.8.3" toolVersion = "0.8.3"
} }
@@ -86,7 +93,7 @@ dependencies {
implementation("net.pearx.kasechange:kasechange-jvm:1.1.0") implementation("net.pearx.kasechange:kasechange-jvm:1.1.0")
implementation("com.auth0:java-jwt:3.8.2") implementation("com.auth0:java-jwt:3.8.2")
implementation("com.github.jasync-sql:jasync-postgresql:1.0.7") implementation("com.github.jasync-sql:jasync-postgresql:1.0.7")
implementation("com.github.flecomte:postgres-json:1.0.4") implementation("com.github.flecomte:postgres-json:1.1.1")
implementation("com.github.flecomte:ktor-voter:1.0.1") implementation("com.github.flecomte:ktor-voter:1.0.1")
implementation("com.sendgrid:sendgrid-java:4.4.1") implementation("com.sendgrid:sendgrid-java:4.4.1")
implementation("io.lettuce:lettuce-core:5.2.2.RELEASE") implementation("io.lettuce:lettuce-core:5.2.2.RELEASE")

View File

@@ -42,10 +42,11 @@ services:
ports: ports:
- ${APP_PORT}:8080 - ${APP_PORT}:8080
environment: environment:
DB_HOST: db DB_HOST: ${DB_HOST}
SEND_GRID_KEY: ${SEND_GRID_KEY} SEND_GRID_KEY: ${SEND_GRID_KEY}
REDIS_CONNECTION: redis://redis:6379 REDIS_CONNECTION: ${REDIS_CONNECTION}
RABBITMQ_CONNECTION: amqp://rabbitmq:5671 RABBITMQ_CONNECTION: ${RABBITMQ_CONNECTION}
ELASTICSEARCH_CONNECTION: ${ELASTICSEARCH_CONNECTION}
depends_on: depends_on:
- elasticsearch - elasticsearch
- db - db

View File

@@ -9,7 +9,6 @@ RUN chown -R $APPLICATION_USER /app
USER $APPLICATION_USER USER $APPLICATION_USER
COPY ./libs/dcproject-0.0.1-all.jar /app/dcproject.jar COPY ./libs/dcproject-0.0.1-all.jar /app/dcproject.jar
COPY ./resources /app/resources
WORKDIR /app WORKDIR /app
CMD ["java", "-server", "-XX:+UnlockExperimentalVMOptions", "-XX:InitialRAMFraction=2", "-XX:MinRAMFraction=2", "-XX:MaxRAMFraction=2", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "dcproject.jar"] CMD ["java", "-server", "-XX:+UnlockExperimentalVMOptions", "-XX:InitialRAMFraction=2", "-XX:MinRAMFraction=2", "-XX:MaxRAMFraction=2", "-XX:+UseG1GC", "-XX:MaxGCPauseMillis=100", "-XX:+UseStringDeduplication", "-jar", "dcproject.jar"]

View File

@@ -73,7 +73,6 @@ fun Application.module(env: Env = PROD) {
} }
install(DataConversion) { install(DataConversion) {
// TODO move to postgresJson lib
convert<UUID> { convert<UUID> {
decode { values, _ -> decode { values, _ ->
values.singleOrNull()?.let { UUID.fromString(it) } values.singleOrNull()?.let { UUID.fromString(it) }
@@ -359,7 +358,6 @@ fun Application.module(env: Env = PROD) {
maxAge = Duration.ofDays(1) maxAge = Duration.ofDays(1)
} }
// TODO move to postgresJson lib
if (env == PROD) { if (env == PROD) {
get<Migrations>().run() get<Migrations>().run()
} }

View File

@@ -5,17 +5,16 @@ import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm import com.auth0.jwt.algorithms.Algorithm
import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigFactory
import fr.dcproject.entity.UserI import fr.dcproject.entity.UserI
import org.eclipse.jetty.util.resource.JarResource
import java.io.File
import java.util.* import java.util.*
import java.net.URI
class Config { object Config {
private var config = ConfigFactory.load() private var config = ConfigFactory.load()
val sqlFiles: File = try { object Sql {
File(this::class.java.getResource("/sql").toURI()) val migrationFiles: URI = this::class.java.getResource("/sql/migrations").toURI()
} catch (e: IllegalArgumentException) { val functionFiles: URI = this::class.java.getResource("/sql/functions").toURI()
JarResource.newResource("./resources/sql").file val fixtureFiles: URI = this::class.java.getResource("/sql/fixtures").toURI()
} }
val envName: String = config.getString("app.envName") val envName: String = config.getString("app.envName")
@@ -27,6 +26,7 @@ class Config {
var password: String = config.getString("db.password") var password: String = config.getString("db.password")
val port: Int = config.getInt("db.port") val port: Int = config.getInt("db.port")
val redis: String = config.getString("redis.connection") val redis: String = config.getString("redis.connection")
val elasticsearch: String = config.getString("elasticsearch.connection")
val rabbitmq: String = config.getString("rabbitmq.connection") val rabbitmq: String = config.getString("rabbitmq.connection")
val exchangeNotificationName = "notification" val exchangeNotificationName = "notification"
val sendGridKey: String = config.getString("mail.sendGrid.key") val sendGridKey: String = config.getString("mail.sendGrid.key")

View File

@@ -39,35 +39,33 @@ import fr.dcproject.repository.VoteComment as VoteCommentRepository
import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository
import fr.dcproject.repository.Workgroup as WorkgroupRepository import fr.dcproject.repository.Workgroup as WorkgroupRepository
val config = Config()
@KtorExperimentalAPI @KtorExperimentalAPI
val Module = module { val Module = module {
single { config } single { Config }
// SQL connection // SQL connection
single { single {
Connection( Connection(
host = config.host, host = Config.host,
port = config.port, port = Config.port,
database = config.database, database = Config.database,
username = config.username, username = Config.username,
password = config.password password = Config.password
) )
} }
// Launch Database migration // Launch Database migration
single { Migrations(connection = get(), directory = config.sqlFiles) } single { Migrations(get(), Config.Sql.migrationFiles, Config.Sql.functionFiles) }
// Redis client // Redis client
single<RedisAsyncCommands<String, String>> { single<RedisAsyncCommands<String, String>> {
RedisClient.create(config.redis).connect()?.async() ?: error("Unable to connect to redis") RedisClient.create(Config.redis).connect()?.async() ?: error("Unable to connect to redis")
} }
// RabbitMQ // RabbitMQ
single<ConnectionFactory> { single<ConnectionFactory> {
ConnectionFactory().apply { setUri(config.rabbitmq) } ConnectionFactory().apply { setUri(Config.rabbitmq) }
} }
// JsonSerializer // JsonSerializer
@@ -93,7 +91,7 @@ val Module = module {
single { single {
Requester.RequesterFactory( Requester.RequesterFactory(
connection = get(), connection = get(),
functionsDirectory = config.sqlFiles.resolve("functions") functionsDirectory = Config.Sql.functionFiles
).createRequester() ).createRequester()
} }
@@ -117,15 +115,15 @@ val Module = module {
// Elasticsearch Client // Elasticsearch Client
single<RestClient> { single<RestClient> {
RestClient.builder( RestClient.builder(
HttpHost("localhost", 9200, "http") HttpHost.create(Config.elasticsearch)
).build() ).build()
} }
single { ArticleViewManager(get()) } single { ArticleViewManager(get()) }
// Mailler // Mailler
single { Mailer(config.sendGridKey) } single { Mailer(Config.sendGridKey) }
// SSO Manager for connection // SSO Manager for connection
single { SsoManager(get<Mailer>(), config.domain, get()) } single { SsoManager(get<Mailer>(), Config.domain, get()) }
} }

View File

@@ -3,7 +3,7 @@ package fr.dcproject.event
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.rabbitmq.client.* import com.rabbitmq.client.*
import com.rabbitmq.client.BuiltinExchangeType.DIRECT import com.rabbitmq.client.BuiltinExchangeType.DIRECT
import fr.dcproject.config import fr.dcproject.Config
import fr.dcproject.entity.Article import fr.dcproject.entity.Article
import fr.dcproject.event.publisher.Publisher import fr.dcproject.event.publisher.Publisher
import fr.dcproject.repository.Follow import fr.dcproject.repository.Follow
@@ -32,7 +32,7 @@ fun EventSubscriber.Configuration.configEvent(
serialiser: ObjectMapper serialiser: ObjectMapper
) { ) {
/* Config Rabbit */ /* Config Rabbit */
val exchangeName = config.exchangeNotificationName val exchangeName = Config.exchangeNotificationName
rabbitFactory.newConnection().use { connection -> rabbitFactory.newConnection().use { connection ->
connection.createChannel().use { channel -> connection.createChannel().use { channel ->
channel.queueDeclare("push", true, false, false, null) channel.queueDeclare("push", true, false, false, null)

View File

@@ -2,7 +2,7 @@ package fr.dcproject.event.publisher
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.rabbitmq.client.ConnectionFactory import com.rabbitmq.client.ConnectionFactory
import fr.dcproject.config import fr.dcproject.Config
import fr.dcproject.event.EntityEvent import fr.dcproject.event.EntityEvent
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
@@ -19,7 +19,7 @@ class Publisher(
return GlobalScope.launch { return GlobalScope.launch {
factory.newConnection().use { connection -> factory.newConnection().use { connection ->
connection.createChannel().use { channel -> connection.createChannel().use { channel ->
channel.basicPublish(config.exchangeNotificationName, "", null, it.serialize().toByteArray()) channel.basicPublish(Config.exchangeNotificationName, "", null, it.serialize().toByteArray())
logger.debug("Publish message ${it.target.id}") logger.debug("Publish message ${it.target.id}")
} }
} }

View File

@@ -32,6 +32,11 @@ rabbitmq {
connection = ${?RABBITMQ_CONNECTION} connection = ${?RABBITMQ_CONNECTION}
} }
elasticsearch {
connection = "http://localhost:9200"
connection = ${?ELASTICSEARCH_CONNECTION}
}
mail { mail {
sendGrid { sendGrid {
key = ${?SEND_GRID_KEY} key = ${?SEND_GRID_KEY}

View File

@@ -1,6 +1,6 @@
import feature.KtorServerContext import feature.KtorServerContext
import fr.dcproject.Config
import fr.dcproject.Env.CUCUMBER import fr.dcproject.Env.CUCUMBER
import fr.dcproject.config
import fr.dcproject.module import fr.dcproject.module
import fr.dcproject.utils.LoggerDelegate import fr.dcproject.utils.LoggerDelegate
import fr.postgresjson.connexion.Connection import fr.postgresjson.connexion.Connection
@@ -36,9 +36,9 @@ class RunCucumberTest : En, KoinTest {
init { init {
if (!unitialized) { if (!unitialized) {
config.database = "test" Config.database = "test"
config.username = "test" Config.username = "test"
config.password = "test" Config.password = "test"
withTestApplication({ module(CUCUMBER) }) { withTestApplication({ module(CUCUMBER) }) {
migrations() migrations()
@@ -47,9 +47,9 @@ class RunCucumberTest : En, KoinTest {
} }
Before(-1) { _: Scenario -> Before(-1) { _: Scenario ->
config.database = "test" Config.database = "test"
config.username = "test" Config.username = "test"
config.password = "test" Config.password = "test"
ktorContext.start() ktorContext.start()
//language=PostgreSQL //language=PostgreSQL
get<Connection>().sendQuery("start transaction;", listOf()) get<Connection>().sendQuery("start transaction;", listOf())
@@ -63,9 +63,9 @@ class RunCucumberTest : En, KoinTest {
} }
private fun migrations() { private fun migrations() {
config.database = "test" Config.database = "test"
config.username = "test" Config.username = "test"
config.password = "test" Config.password = "test"
val migrations: Migrations = get() val migrations: Migrations = get()
migrations.forceAllDown() migrations.forceAllDown()
migrations.run() migrations.run()
@@ -89,7 +89,7 @@ class RunCucumberTest : En, KoinTest {
private fun getFixturesRequester(): Requester { private fun getFixturesRequester(): Requester {
return Requester.RequesterFactory( return Requester.RequesterFactory(
connection = get(), connection = get(),
queriesDirectory = config.sqlFiles.resolve("fixtures") queriesDirectory = Config.Sql.fixtureFiles
).createRequester() ).createRequester()
} }
} }