Compare commits
308 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1c013e3e15 | |||
| 003aa9ff05 | |||
| 44c5f1b15b | |||
| 2f3a2f9b8e | |||
| 1a62c5ec9a | |||
| 55674cbef1 | |||
| ac5dbbc384 | |||
| 9460992f37 | |||
| 8013cfb266 | |||
| f577ea70b3 | |||
| 2673cf527a | |||
| 371483ccde | |||
| 76e4033a22 | |||
| fee5e5784b | |||
| 1c33c026f0 | |||
| 4871e7d780 | |||
| 359450ad8f | |||
| 11903a4cda | |||
| 1a8b544cdb | |||
| e2c1f15ab8 | |||
| dc87c95bb4 | |||
| d4cc3f21da | |||
| 59c050d14d | |||
| cb9bd0c14b | |||
| 1ce3a18d8e | |||
| be6fb8dc12 | |||
| cd9fd569d7 | |||
| 2920186352 | |||
| cccabb2cc9 | |||
| 620cd73fec | |||
| e474a40068 | |||
| 242bf9c9b3 | |||
| 543f3fb9bb | |||
| 994e266b52 | |||
| 3f392eece6 | |||
| 518b59e9aa | |||
| 596b7ff0c9 | |||
| 87175eb8ea | |||
| 1118866856 | |||
| 367f59ee18 | |||
| 0588f88f9a | |||
| 496cf50d88 | |||
| 13253e4af1 | |||
| 39c665b7a9 | |||
| 50b4cf1816 | |||
| 6a5e00bb4d | |||
| 0c8bcbd634 | |||
| 8223dd21bb | |||
| 27e405c585 | |||
| 34513e25b6 | |||
| f5c1aa29e8 | |||
| 875d0bfffa | |||
| fb7b07340a | |||
| a07b19a3cb | |||
| 13cdaaf01a | |||
| e473e62068 | |||
| 9d3eeeb04b | |||
| eb399392c9 | |||
| 1ec1c59c8c | |||
| 9511331cd2 | |||
| 33a8cdb169 | |||
| 6aa3ddb28d | |||
| 708d241a26 | |||
| e4745e71c2 | |||
| e26710898e | |||
| fe11384ad2 | |||
| 61a7091736 | |||
| 2ef9f65f2c | |||
| b5fc3d25bb | |||
| 3faf2e5f0d | |||
| ab418ae300 | |||
| 395d64a44a | |||
| a300e275d4 | |||
| 3a18ef0554 | |||
| 921a545877 | |||
| ef942b956e | |||
| ff74ad7e47 | |||
| 2bb90ced03 | |||
| a48cd52652 | |||
| dd4c2dadab | |||
| c81b63aef2 | |||
| cb762a446a | |||
| db810ab0c6 | |||
| 01c5b78325 | |||
| 1bc7293660 | |||
| 55c890aca5 | |||
| c0e364637a | |||
| 0a1ed9ba82 | |||
| 620085fda8 | |||
| 3b5c1cf68a | |||
| a0d07e88a1 | |||
| f17277c0e9 | |||
| 9f13213a35 | |||
| 5f0b8de159 | |||
| 6b66130ddc | |||
| 7f93ec5044 | |||
| 1be608e6b2 | |||
| b13cd5544c | |||
| 104f0fb3fc | |||
| b2f40ff421 | |||
| 09e81620a1 | |||
| 7e16c7bb74 | |||
| fe953fc967 | |||
| 453fd2225c | |||
| 70fd54d831 | |||
| dcf7a2bc06 | |||
| 118af0170a | |||
| 0aa8089a9a | |||
| fef5f3b396 | |||
| 1838b90ac9 | |||
| 73fa2be91f | |||
| 52183abd08 | |||
| e19266d4cc | |||
| f458d7b674 | |||
| 29d4d6ec25 | |||
| 03f68213e8 | |||
| 66fa1ba840 | |||
| 89b2abc10e | |||
| b04408219d | |||
| 5ef2345ea6 | |||
| 50b5ca03c6 | |||
| 9862e112eb | |||
| 5dc1518cfc | |||
| fbd18e4c2e | |||
| 0e5943864d | |||
| 46cc61fc25 | |||
| 786b0bc949 | |||
| 8aa809c37e | |||
| fdd69a687b | |||
| 4c1ab796e4 | |||
| c1a3590b2b | |||
| c9ce2a9dc7 | |||
| 8701815288 | |||
| d03b585372 | |||
| c9879be72c | |||
| ec8abf44b8 | |||
| 776e0257fb | |||
| 8f1f1f10d9 | |||
| cba3f1f4bc | |||
| 316b1e8318 | |||
| 78a6cc417c | |||
| 564d612e9a | |||
| 65bf9a75f0 | |||
| 33ceb13cde | |||
| 7765e6d27a | |||
| ca402dbea7 | |||
| 07ae50c40a | |||
| 42dbd940a0 | |||
| 0f768f3e4c | |||
| 5fce37f269 | |||
| 52bdcd0990 | |||
| 1655f47044 | |||
| c07a57a591 | |||
| 0cf1aea9bf | |||
| 235de4e5ff | |||
| 869093ab25 | |||
| 189aa8d549 | |||
| 97b07fb424 | |||
| 9c88adbabd | |||
| ed0873837b | |||
| 6988365473 | |||
| 4762275b5b | |||
| 97c1e47db2 | |||
| bb637dd96a | |||
| 9fc21f5459 | |||
| d9deb4836e | |||
| 79feed54dd | |||
| 2e8215eafc | |||
| 4c00095118 | |||
| bc772f168f | |||
| 8d93fc8b3c | |||
| 66dcff8f46 | |||
| c61b31cc58 | |||
| 78604301c3 | |||
| d382a89905 | |||
| 7446bd506a | |||
| c25cf64f4b | |||
| c1af949204 | |||
| 7985ea67e5 | |||
| 9a3a308841 | |||
| d83ba2d54d | |||
| 7b4066b928 | |||
| 9fb2262107 | |||
| a27099177d | |||
| b0aec9bea0 | |||
| a17bd11e9e | |||
| 8cf79a791e | |||
| bf4e01e318 | |||
| d29bb4467a | |||
| 0ecf0c205f | |||
| 55aa512aa5 | |||
| addb3cddff | |||
| f7b6cc4eb3 | |||
| 28b9ac4e54 | |||
| 02879291e8 | |||
| 066b01e86f | |||
| c85401aa86 | |||
| 34a7310944 | |||
| e8716a1e7f | |||
| f8ecd69582 | |||
| 99438b1ff9 | |||
| ec0115d613 | |||
| 55bfbb619d | |||
| edf0c00cf1 | |||
| dcf35eaccd | |||
| 905330a722 | |||
| 5979337bc3 | |||
| 8c228f666f | |||
| 678bdf7087 | |||
| 507698c7ea | |||
| fdd4742b28 | |||
| 0bbe37c6d5 | |||
| 192411a69a | |||
| 929d248841 | |||
| 8ead83941f | |||
| aeaab860b2 | |||
| 16eadc0921 | |||
| f2445f3b25 | |||
| bb212f9c6c | |||
| 89c15eb1cf | |||
| a05b5edc86 | |||
| 5704eb9e07 | |||
| 3580c33891 | |||
| 3b3a71f6eb | |||
| d479cf6bca | |||
| b54a40cef4 | |||
| 1c644768e6 | |||
| aa95de7a6a | |||
| dd6433306d | |||
| bfc0b7e796 | |||
| 81e14f1a84 | |||
| d9f19a9c23 | |||
| 1e5598cb91 | |||
| f34407962b | |||
| 49a03a57cb | |||
| c1b8b508ac | |||
| c92d0b5640 | |||
| 73e96c0c46 | |||
| fac27d0725 | |||
| 97ccb6ee51 | |||
| 93aa47c6cc | |||
| 667339979b | |||
| 3ba4a195ba | |||
| 6a32895571 | |||
| 6cdc526335 | |||
| a79e1ec086 | |||
| 4b435b925e | |||
| 78e01ba981 | |||
| 56818189ae | |||
| fbea05218b | |||
| c78dfc0f7f | |||
| 425d01c0df | |||
| 64fa0912b8 | |||
| ba673943d8 | |||
| c196bfadbc | |||
| e9f56412c5 | |||
| d12c9c2166 | |||
| 55cd97078a | |||
| d6840e8064 | |||
| 308a284280 | |||
| 1b6549eae3 | |||
| b028ff05b9 | |||
| c380ba47a5 | |||
| ecda29abe5 | |||
| bec73561e7 | |||
| 299495a03c | |||
| d87b433398 | |||
| b61fc3c7d1 | |||
| b421b03575 | |||
| 128510fe88 | |||
| ce90884758 | |||
| 42440c0041 | |||
| 459397f8e7 | |||
| 7c106f7cf8 | |||
| caadc2a969 | |||
| 91ab800272 | |||
| 64f74d0449 | |||
| 6a8c5bf717 | |||
| a1c1accc87 | |||
| 03401f711e | |||
| 74923891d0 | |||
| 317e029f79 | |||
| 46ee98c97f | |||
| 269bf09c66 | |||
| 9d6ad08834 | |||
| 06b1296192 | |||
| 5def84282d | |||
| 24d8f1d58b | |||
| a3b44588a9 | |||
| 16feab9655 | |||
| 01c3d85a17 | |||
| 3d319605de | |||
| 63c4568aeb | |||
| e2d1b697b7 | |||
| 70092efaf5 | |||
| 9c10a88a36 | |||
| 2ee8b80596 | |||
| ee60f5b4e7 | |||
| 10928251e6 | |||
| 9b79301662 | |||
| 32510652d1 | |||
| a6c36c542e | |||
| 7874f5cec4 | |||
| 8ff6fcc970 | |||
| bd123d03e9 | |||
| ac852baaf6 | |||
| 159b9de19a | |||
| e4a85722f1 |
13
.dockerignore
Normal file
13
.dockerignore
Normal file
@@ -0,0 +1,13 @@
|
||||
build
|
||||
out
|
||||
GH_TOKEN.txt
|
||||
Makefile
|
||||
var
|
||||
gradle
|
||||
.idea
|
||||
.gradle
|
||||
docker
|
||||
gradlew
|
||||
gradlew.bat
|
||||
docker-compose.yml
|
||||
src/test
|
||||
7
.env
7
.env
@@ -1,10 +1,11 @@
|
||||
NAME=dc-project
|
||||
APP_NAME=dc-project
|
||||
|
||||
DATABASE_URL=jdbc:postgresql:dc-project
|
||||
|
||||
APP_PORT=8080
|
||||
OPENAPI_PORT=8181
|
||||
SONARQUBE_PORT=9002
|
||||
SONARQUBE_DB_PORT=5434
|
||||
|
||||
ELASTIC_REST=9200
|
||||
ELASTIC_NODES=9300
|
||||
@@ -23,4 +24,6 @@ REDIS_COMMANDER_PORT=8081
|
||||
|
||||
RABBITMQ_PORT=5672
|
||||
RABBITMQ_CONNECTION=amqp://rabbitmq:5672
|
||||
RABBITMQ_MANAGEMENT_PORT=15672
|
||||
RABBITMQ_MANAGEMENT_PORT=15672
|
||||
|
||||
SEND_GRID_KEY=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
|
||||
160
.github/workflows/tests.yml
vendored
Normal file
160
.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
# This workflow will build a Java project with Gradle
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Setup Gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Build
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: build -x test -x ktlintKotlinScriptCheck -x ktlintTestSourceSetCheck -x ktlintMainSourceSetCheck -x detekt
|
||||
|
||||
- name: processResources
|
||||
run: gradle processResources
|
||||
- name: processTestResources
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: processResources
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Build
|
||||
path: build
|
||||
|
||||
testSql:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: Build
|
||||
path: build
|
||||
|
||||
- name: Composer Up
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: testSqlComposeUp
|
||||
|
||||
- name: TestSql
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: testSql
|
||||
|
||||
test:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: Build
|
||||
path: build
|
||||
|
||||
- name: Composer Up
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: testComposeUp
|
||||
|
||||
- name: Test
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: test
|
||||
|
||||
- name: Coverage
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: coveralls
|
||||
env:
|
||||
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
|
||||
|
||||
- name: Cache SonarCloud packages
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.sonar/cache
|
||||
key: ${{ runner.os }}-sonar
|
||||
restore-keys: ${{ runner.os }}-sonar
|
||||
|
||||
- name: Test
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: test
|
||||
|
||||
- name: Build and analyze
|
||||
uses: gradle/gradle-build-action@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: sonarqube --info
|
||||
|
||||
lint:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: Build
|
||||
path: build
|
||||
- name: Lint
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
gradle-version: '7.4'
|
||||
arguments: ktlintCheck
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,4 +6,6 @@
|
||||
*.ipr
|
||||
*.iws
|
||||
dcproject.iml
|
||||
/var
|
||||
/var
|
||||
GH_TOKEN.txt
|
||||
allSQL.sql
|
||||
64
.idea/codeStyles/Project.xml
generated
64
.idea/codeStyles/Project.xml
generated
@@ -1,17 +1,71 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<option name="LINE_SEPARATOR" value=" " />
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value />
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<PostgresCodeStyleSettings version="2">
|
||||
<option name="ALIAS_CASE" value="1" />
|
||||
<SqlCodeStyleSettings version="6">
|
||||
<option name="KEYWORD_CASE" value="1" />
|
||||
<option name="TYPE_CASE" value="1" />
|
||||
<option name="IDENTIFIER_CASE" value="1" />
|
||||
</PostgresCodeStyleSettings>
|
||||
<option name="TYPE_CASE" value="4" />
|
||||
<option name="ALIAS_CASE" value="4" />
|
||||
<option name="BUILT_IN_CASE" value="4" />
|
||||
<option name="QUOTE_IDENTIFIER" value="1" />
|
||||
<option name="QUERY_EL_LINE" value="0" />
|
||||
<option name="QUERY_IN_ONE_STRING" value="3" />
|
||||
<option name="SUBQUERY_CONTENT" value="2" />
|
||||
<option name="SUBQUERY_CLOSING" value="2" />
|
||||
<option name="INSERT_OPENING" value="4" />
|
||||
<option name="INSERT_CLOSING" value="0" />
|
||||
<option name="INSERT_VALUES_EL_LINE" value="101" />
|
||||
<option name="INSERT_COLLAPSE_MULTI_ROW_VALUES" value="true" />
|
||||
<option name="SET_EL_LINE" value="1" />
|
||||
<option name="SET_EL_WRAP" value="0" />
|
||||
<option name="WITH_EL_LINE" value="101" />
|
||||
<option name="WITH_EL_WRAP" value="2" />
|
||||
<option name="SELECT_EL_LINE" value="101" />
|
||||
<option name="SELECT_EL_COMMA" value="2" />
|
||||
<option name="SELECT_NEW_LINE_AFTER_ALL_DISTINCT" value="true" />
|
||||
<option name="SELECT_KEEP_N_ITEMS_IN_LINE" value="4" />
|
||||
<option name="SELECT_USE_AS_WORD" value="1" />
|
||||
<option name="FROM_EL_LINE" value="1" />
|
||||
<option name="FROM_EL_COMMA" value="2" />
|
||||
<option name="FROM_ALIGN_JOIN_TABLES" value="true" />
|
||||
<option name="FROM_INDENT_JOIN" value="false" />
|
||||
<option name="FROM_PLACE_ON" value="10" />
|
||||
<option name="WHERE_EL_LINE" value="1" />
|
||||
<option name="WHERE_EL_WRAP" value="3" />
|
||||
<option name="ORDER_EL_LINE" value="101" />
|
||||
<option name="ORDER_EL_WRAP" value="1" />
|
||||
<option name="ORDER_EL_COMMA" value="2" />
|
||||
</SqlCodeStyleSettings>
|
||||
<codeStyleSettings language="SQL">
|
||||
<option name="KEEP_LINE_BREAKS" value="false" />
|
||||
<option name="KEEP_FIRST_COLUMN_COMMENT" value="false" />
|
||||
<indentOptions>
|
||||
<option name="SMART_TABS" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
|
||||
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
|
||||
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
2
.idea/codeStyles/codeStyleConfig.xml
generated
2
.idea/codeStyles/codeStyleConfig.xml
generated
@@ -2,4 +2,4 @@
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
</component>
|
||||
|
||||
9
.idea/dataSources.xml
generated
9
.idea/dataSources.xml
generated
@@ -11,7 +11,14 @@
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://localhost:5432/test</jdbc-url>
|
||||
<jdbc-url>jdbc:postgresql://localhost:15432/test</jdbc-url>
|
||||
</data-source>
|
||||
<data-source source="LOCAL" name="sonar@localhost" uuid="ee78beab-120d-4740-ad21-d4d9e2121d25">
|
||||
<driver-ref>postgresql</driver-ref>
|
||||
<synchronize>true</synchronize>
|
||||
<jdbc-driver>org.postgresql.Driver</jdbc-driver>
|
||||
<jdbc-url>jdbc:postgresql://localhost:5433/sonar</jdbc-url>
|
||||
<working-dir>$ProjectFileDir$</working-dir>
|
||||
</data-source>
|
||||
</component>
|
||||
</project>
|
||||
5
.idea/gradle.xml
generated
5
.idea/gradle.xml
generated
@@ -4,8 +4,8 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="delegatedBuild" value="false" />
|
||||
<option name="testRunner" value="PLATFORM" />
|
||||
<option name="delegatedBuild" value="true" />
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="modules">
|
||||
@@ -13,7 +13,6 @@
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -10,4 +10,7 @@
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="corretto-11" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
<component name="TaskProjectConfiguration">
|
||||
<server type="GitHub" url="https://github.com" />
|
||||
</component>
|
||||
</project>
|
||||
37
.idea/runConfigurations/All_Tests.xml
generated
Normal file
37
.idea/runConfigurations/All_Tests.xml
generated
Normal file
@@ -0,0 +1,37 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="All Tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
|
||||
<useClassPathOnly />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="fr.dcproject.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="pattern" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<patterns>
|
||||
<pattern testClass="unit..*" />
|
||||
<pattern testClass="functional..*" />
|
||||
<pattern testClass="integration..*" />
|
||||
</patterns>
|
||||
<tag value="!functional" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="SQL Fixtures on DEV" run_configuration_type="ShConfigurationType" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Lint Format" run_configuration_type="GradleRunConfiguration" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,25 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="All Tests + Lint (offline)" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="tags" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.options="--tags ~@online" -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Lint" run_configuration_type="GradleRunConfiguration" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Test All SQL" run_configuration_type="ShConfigurationType" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -2,6 +2,7 @@
|
||||
<configuration default="false" name="Build and start all Docker" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envFilePath" value="" />
|
||||
<option name="envVars">
|
||||
<list>
|
||||
<DockerEnvVarImpl>
|
||||
@@ -11,11 +12,24 @@
|
||||
</list>
|
||||
</option>
|
||||
<option name="commandLineOptions" value="--build" />
|
||||
<option name="secondarySourceFiles">
|
||||
<list>
|
||||
<option value="docker-compose-sonar.yml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="app" />
|
||||
<option value="db" />
|
||||
<option value="elasticsearch" />
|
||||
<option value="openapi" />
|
||||
<option value="rabbitmq" />
|
||||
<option value="redis" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="docker-compose.yml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2">
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="build" externalProjectPath="$PROJECT_DIR$" vmOptions="" scriptParameters="" />
|
||||
</method>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
2
.idea/runConfigurations/Build_without_test.xml
generated
2
.idea/runConfigurations/Build_without_test.xml
generated
@@ -4,7 +4,7 @@
|
||||
<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="scriptParameters" value="-x test -x ktlintKotlinScriptCheck -x ktlintTestSourceSetCheck -x ktlintMainSourceSetCheck -x detekt" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
|
||||
24
.idea/runConfigurations/Citizen_Tests.xml
generated
24
.idea/runConfigurations/Citizen_Tests.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Citizen Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@citizen"" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Comment_Tests.xml
generated
24
.idea/runConfigurations/Comment_Tests.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Comment Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@comment"" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Constitution_Tests.xml
generated
24
.idea/runConfigurations/Constitution_Tests.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Constitution Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@constitution"" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
23
.idea/runConfigurations/Create_lock_dependencies.xml
generated
Normal file
23
.idea/runConfigurations/Create_lock_dependencies.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Create lock dependencies" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="--write-locks" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="dependencies" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
19
.idea/runConfigurations/Cucumber_Tests.xml
generated
19
.idea/runConfigurations/Cucumber_Tests.xml
generated
@@ -1,19 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Cucumber Tests" type="JUnit" factoryName="JUnit">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/cucumber.out.log" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
30
.idea/runConfigurations/Cucumber_Tests__offline_.xml
generated
30
.idea/runConfigurations/Cucumber_Tests__offline_.xml
generated
@@ -1,30 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Cucumber Tests (offline)" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="fr.dcproject.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags=" not @online" -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
23
.idea/runConfigurations/Down_Docker.xml
generated
Normal file
23
.idea/runConfigurations/Down_Docker.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Down Docker" 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="testComposeDownForced" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Follow_Tests.xml
generated
24
.idea/runConfigurations/Follow_Tests.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Follow Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@follow"" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +1,7 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Voter Tests" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<configuration default="false" name="Functional Tests" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<useClassPathOnly />
|
||||
<extension name="coverage">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="fr.dcproject.security.voter.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
@@ -21,7 +15,7 @@
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="voter" />
|
||||
<tag value="functional" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
@@ -1,11 +1,11 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="All Tests + Lint" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<configuration default="false" name="Functional Tests (offline)" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="package" />
|
||||
<option name="TEST_OBJECT" value="tags" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
@@ -15,10 +15,9 @@
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="functional&!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Lint" run_configuration_type="GradleRunConfiguration" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Test All SQL" run_configuration_type="ShConfigurationType" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +1,13 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Article Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<configuration default="false" name="Integration Tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@article" -Dstrict" />
|
||||
<option name="TEST_OBJECT" value="pattern" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
@@ -16,7 +16,10 @@
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<patterns>
|
||||
<pattern testClass="integration..*" />
|
||||
</patterns>
|
||||
<tag value="!functional" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
31
.idea/runConfigurations/Lint.xml
generated
31
.idea/runConfigurations/Lint.xml
generated
@@ -1,31 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Lint" 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="ktlintCheck" />
|
||||
</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>
|
||||
23
.idea/runConfigurations/Lint_Format.xml
generated
Normal file
23
.idea/runConfigurations/Lint_Format.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Lint Format" type="GradleRunConfiguration" factoryName="Gradle" singleton="true">
|
||||
<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="ktlintFormat" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
39
.idea/runConfigurations/Lint_Test_Sonar___Run.xml
generated
39
.idea/runConfigurations/Lint_Test_Sonar___Run.xml
generated
@@ -1,39 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Lint+Test+Sonar & Run" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="env">
|
||||
<map>
|
||||
<entry key="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</map>
|
||||
</option>
|
||||
<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="run" />
|
||||
</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">
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All Tests + Lint" run_configuration_type="JUnit" />
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="Sonarqube" run_configuration_type="GradleRunConfiguration" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
38
.idea/runConfigurations/Lint__Test___Run.xml
generated
38
.idea/runConfigurations/Lint__Test___Run.xml
generated
@@ -1,38 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Lint, Test & Run" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="env">
|
||||
<map>
|
||||
<entry key="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</map>
|
||||
</option>
|
||||
<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="run" />
|
||||
</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">
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="All Tests + Lint" run_configuration_type="JUnit" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Mark_as__error.xml
generated
24
.idea/runConfigurations/Mark_as__error.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Mark as @error" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@error" -Dstrict" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
23
.idea/runConfigurations/Migration.xml
generated
Normal file
23
.idea/runConfigurations/Migration.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Migration" 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="migration" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Opinion_Tests.xml
generated
24
.idea/runConfigurations/Opinion_Tests.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Opinion Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@opinion"" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
4
.idea/runConfigurations/Reset_DB_on_DEV.xml
generated
4
.idea/runConfigurations/Reset_DB_on_DEV.xml
generated
@@ -6,8 +6,10 @@
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/src/main/resources/sql" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="false" />
|
||||
<option name="INTERPRETER_PATH" value="C:/Program Files/Git/bin/bash.exe" />
|
||||
<option name="INTERPRETER_PATH" value="$PROJECT_DIR$/../../../../Program Files/Git/bin/bash.exe" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
7
.idea/runConfigurations/Run_dependencies.xml
generated
7
.idea/runConfigurations/Run_dependencies.xml
generated
@@ -2,6 +2,7 @@
|
||||
<configuration default="false" name="Run dependencies" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envFilePath" value="" />
|
||||
<option name="envVars">
|
||||
<list>
|
||||
<DockerEnvVarImpl>
|
||||
@@ -11,12 +12,18 @@
|
||||
</list>
|
||||
</option>
|
||||
<option name="commandLineOptions" value="--build" />
|
||||
<option name="secondarySourceFiles">
|
||||
<list>
|
||||
<option value="docker-compose-sonar.yml" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="db" />
|
||||
<option value="elasticsearch" />
|
||||
<option value="rabbitmq" />
|
||||
<option value="redis" />
|
||||
<option value="openapi" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="docker-compose.yml" />
|
||||
|
||||
4
.idea/runConfigurations/SQL_Fixtures_on_DEV.xml
generated
4
.idea/runConfigurations/SQL_Fixtures_on_DEV.xml
generated
@@ -6,8 +6,10 @@
|
||||
<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_PATH" value="$PROJECT_DIR$/../../../../Program Files/Git/bin/bash.exe" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
11
.idea/runConfigurations/Sonarqube.xml
generated
11
.idea/runConfigurations/Sonarqube.xml
generated
@@ -1,10 +1,15 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Sonarqube" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="env">
|
||||
<map>
|
||||
<entry key="SONAR_TOKEN" value="15ad34f46763706727d884ced12c48d5222fe639" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="-x test" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
@@ -15,7 +20,9 @@
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<GradleScriptDebugEnabled>true</GradleScriptDebugEnabled>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
23
.idea/runConfigurations/Sonarqube__Send_without_run_test_.xml
generated
Normal file
23
.idea/runConfigurations/Sonarqube__Send_without_run_test_.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Sonarqube (Send without run 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="sonarqube" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Start_Db.xml
generated
24
.idea/runConfigurations/Start_Db.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Start Db" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envVars">
|
||||
<list>
|
||||
<DockerEnvVarImpl>
|
||||
<option name="name" value="SEND_GRID_KEY" />
|
||||
<option name="value" value="$SEND_GRID_KEY$" />
|
||||
</DockerEnvVarImpl>
|
||||
</list>
|
||||
</option>
|
||||
<option name="commandLineOptions" value="--build" />
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="db" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="docker-compose.yml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
16
.idea/runConfigurations/Start_Elasticsearch.xml
generated
16
.idea/runConfigurations/Start_Elasticsearch.xml
generated
@@ -1,16 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Start Elasticsearch" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="commandLineOptions" value="--build" />
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="elasticsearch" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="docker-compose.yml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Start_RabbitMQ.xml
generated
24
.idea/runConfigurations/Start_RabbitMQ.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Start RabbitMQ" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envVars">
|
||||
<list>
|
||||
<DockerEnvVarImpl>
|
||||
<option name="name" value="SEND_GRID_KEY" />
|
||||
<option name="value" value="$SEND_GRID_KEY$" />
|
||||
</DockerEnvVarImpl>
|
||||
</list>
|
||||
</option>
|
||||
<option name="commandLineOptions" value="--build" />
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="rabbitmq" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="docker-compose.yml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
24
.idea/runConfigurations/Start_Redis.xml
generated
24
.idea/runConfigurations/Start_Redis.xml
generated
@@ -1,24 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Start Redis" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
|
||||
<deployment type="docker-compose.yml">
|
||||
<settings>
|
||||
<option name="envVars">
|
||||
<list>
|
||||
<DockerEnvVarImpl>
|
||||
<option name="name" value="SEND_GRID_KEY" />
|
||||
<option name="value" value="$SEND_GRID_KEY$" />
|
||||
</DockerEnvVarImpl>
|
||||
</list>
|
||||
</option>
|
||||
<option name="commandLineOptions" value="--build" />
|
||||
<option name="services">
|
||||
<list>
|
||||
<option value="redis" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="docker-compose.yml" />
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
28
.idea/runConfigurations/Test.xml
generated
Normal file
28
.idea/runConfigurations/Test.xml
generated
Normal file
@@ -0,0 +1,28 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="env">
|
||||
<map>
|
||||
<entry key="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</map>
|
||||
</option>
|
||||
<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="test" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
23
.idea/runConfigurations/TestSql.xml
generated
Normal file
23
.idea/runConfigurations/TestSql.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="TestSql" 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="testSql" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
8
.idea/runConfigurations/Test_All_SQL.xml
generated
8
.idea/runConfigurations/Test_All_SQL.xml
generated
@@ -1,13 +1,17 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test All SQL" type="ShConfigurationType">
|
||||
<configuration default="false" name="Test All SQL" type="ShConfigurationType" singleton="false">
|
||||
<option name="SCRIPT_TEXT" value="" />
|
||||
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
|
||||
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/src/test/sql/test.sh" />
|
||||
<option name="SCRIPT_OPTIONS" value="1" />
|
||||
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
|
||||
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$/src/test/sql" />
|
||||
<option name="INDEPENDENT_INTERPRETER_PATH" value="false" />
|
||||
<option name="INTERPRETER_PATH" value="C:/Program Files/Git/bin/bash.exe" />
|
||||
<option name="INTERPRETER_PATH" value="$PROJECT_DIR$/../../../../Program Files/Git/bin/bash.exe" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="EXECUTE_IN_TERMINAL" value="false" />
|
||||
<option name="EXECUTE_SCRIPT_FILE" value="true" />
|
||||
<envs />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
23
.idea/runConfigurations/Test_With_Dependencies.xml
generated
Normal file
23
.idea/runConfigurations/Test_With_Dependencies.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Test With Dependencies" 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="testWithDependencies" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +1,12 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Vote Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<configuration default="false" name="Unit Tests" type="JUnit" factoryName="JUnit" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="PACKAGE_NAME" value="fr.dcproject" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@vote"" />
|
||||
<option name="TEST_OBJECT" value="tags" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
@@ -16,7 +15,7 @@
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<tag value="unit" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
30
.idea/runConfigurations/Unit__functional_and_integration_tests.xml
generated
Normal file
30
.idea/runConfigurations/Unit__functional_and_integration_tests.xml
generated
Normal file
@@ -0,0 +1,30 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Unit, functional and integration tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<useClassPathOnly />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="pattern" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<patterns>
|
||||
<pattern testClass="unit..*" />
|
||||
<pattern testClass="functional..*" />
|
||||
<pattern testClass="integration..*" />
|
||||
</patterns>
|
||||
<tag value="!functional" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +1,13 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Auth Tests" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<configuration default="false" name="Unit and functional tests" type="JUnit" factoryName="JUnit" singleton="false" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="corretto-11" />
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="MAIN_CLASS_NAME" value="" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@auth"" />
|
||||
<option name="TEST_OBJECT" value="pattern" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Djdk.attach.allowAttachSelf=true" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
@@ -16,7 +16,11 @@
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<patterns>
|
||||
<pattern testClass="unit..*" />
|
||||
<pattern testClass="functional..*" />
|
||||
</patterns>
|
||||
<tag value="!functional" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
23
.idea/runConfigurations/Update_Dependency.xml
generated
Normal file
23
.idea/runConfigurations/Update_Dependency.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Update Dependency" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="--update-locks *:*" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="classes" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value="" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
30
.idea/runConfigurations/Workgroup_test.xml
generated
30
.idea/runConfigurations/Workgroup_test.xml
generated
@@ -1,30 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Workgroup test" type="JUnit" factoryName="JUnit" folderName="Cucumber" show_console_on_std_err="true">
|
||||
<output_file path="$PROJECT_DIR$/var/log/test/out.log" is_save="true" />
|
||||
<module name="dcproject.test" />
|
||||
<useClassPathOnly />
|
||||
<extension name="coverage" sample_coverage="false">
|
||||
<pattern>
|
||||
<option name="PATTERN" value="fr.dcproject.*" />
|
||||
<option name="ENABLED" value="true" />
|
||||
</pattern>
|
||||
</extension>
|
||||
<option name="PACKAGE_NAME" value="" />
|
||||
<option name="MAIN_CLASS_NAME" value="RunCucumberTest" />
|
||||
<option name="METHOD_NAME" value="" />
|
||||
<option name="TEST_OBJECT" value="class" />
|
||||
<option name="VM_PARAMETERS" value="-ea -Dcucumber.filter.tags="@workgroup"" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="TEST_SEARCH_SCOPE">
|
||||
<value defaultName="wholeProject" />
|
||||
</option>
|
||||
<envs>
|
||||
<env name="SEND_GRID_KEY" value="$SEND_GRID_KEY$" />
|
||||
</envs>
|
||||
<dir value="$PROJECT_DIR$" />
|
||||
<tag value="!online" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
59
Makefile
Normal file
59
Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
.EXPORT_ALL_VARIABLES:
|
||||
VERSION=$(shell ./hook/version.sh)
|
||||
GITHUB_USERNAME=$(shell git config user.email)
|
||||
GITHUB_TOKEN=$(shell cat ./GH_TOKEN.txt)
|
||||
|
||||
# HELP
|
||||
# This will output the help for each task
|
||||
# thanks to https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
||||
.PHONY: help
|
||||
|
||||
help: ## This help.
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
bd: build-docker
|
||||
|
||||
build-docker: ## Build the docker image of application (alias: bd)
|
||||
docker build -t dc-project -f docker/app/Dockerfile .
|
||||
|
||||
pd: publish-docker
|
||||
|
||||
publish-docker: build-docker ## Publish docker image of application to Github (alias: pd)
|
||||
@git diff --quiet --exit-code || (echo "The git is DIRTY !!! You cannot publish this crap!" && exit 1)
|
||||
@cat ./GH_TOKEN.txt | docker login docker.pkg.github.com -u ${GITHUB_USERNAME} --password-stdin
|
||||
@docker tag dc-project docker.pkg.github.com/flecomte/dc-project/dc-project:${VERSION}
|
||||
docker push docker.pkg.github.com/flecomte/dc-project/dc-project:${VERSION}
|
||||
|
||||
rd: run-docker
|
||||
|
||||
run-docker: ## Build and Run all docker services (alias: rd)
|
||||
docker-compose up -d --build
|
||||
|
||||
rdd: run-docker-dependencies
|
||||
|
||||
run-docker-dependencies: ## Build and Run dependencies docker services (alias: rdd)
|
||||
docker-compose up -d --build openapi rabbitmq redis elasticsearch db sonarqube_db sonarqube
|
||||
|
||||
pm: publish-maven
|
||||
|
||||
publish-maven: ## Publish JAR file to Github (alias: pm)
|
||||
@git diff --quiet --exit-code || (echo "The git is DIRTY !!! You cannot publish this crap!" && exit 1)
|
||||
gradlew publish
|
||||
|
||||
f: fixtures
|
||||
|
||||
fixtures: ## Import fixtures (alias: f)
|
||||
bash src/main/resources/sql/fixtures/fixtures.sh
|
||||
|
||||
reset-database: ## Reset database !!!
|
||||
cd src/main/resources/sql/ ; bash resetDB.sh
|
||||
|
||||
test-sql: ## Test sql
|
||||
cd src/test/sql/ ; bash test.sh 1
|
||||
|
||||
v: version
|
||||
|
||||
version: ## Show current version (alias: v)
|
||||
@echo ${VERSION}
|
||||
35
README.md
Normal file
35
README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# DC Project
|
||||
|
||||
[](https://sonarcloud.io/dashboard?id=dc-project)
|
||||
|
||||
[](https://github.com/flecomte/dc-project/actions/workflows/tests.yml)
|
||||
[](https://coveralls.io/github/flecomte/dc-project?branch=master)
|
||||
[](https://sonarcloud.io/dashboard?id=dc-project)
|
||||
|
||||
[](https://sonarcloud.io/dashboard?id=dc-project)
|
||||
|
||||
[Installation](./doc/installation/Installation.md)
|
||||
|
||||
### Run dockers
|
||||
```bash
|
||||
$ make run-docker
|
||||
```
|
||||
|
||||
### Add fixtures
|
||||
```bash
|
||||
$ make fixtures
|
||||
```
|
||||
|
||||
## Publish package
|
||||
1. Got to [https://github.com](https://github.com/settings/tokens/new) and create a new token with packages scopes
|
||||
2. Create a file `GH_TOKEN.txt` and put it the github token
|
||||
|
||||
### Maven
|
||||
```bash
|
||||
$ make publish-maven
|
||||
```
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
$ make publish-docker
|
||||
```
|
||||
431
build.gradle.kts
431
build.gradle.kts
@@ -1,40 +1,166 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import fr.postgresjson.connexion.Connection
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.gitlab.arturbosch.detekt.Detekt
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.owasp.dependencycheck.reporting.ReportGenerator
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
val ktor_version: String by project
|
||||
val kotlin_version: String by project
|
||||
val coroutinesVersion: String by project
|
||||
val logback_version: String by project
|
||||
val koinVersion: String by project
|
||||
val jackson_version: String by project
|
||||
val cucumber_version: String by project
|
||||
val ktorVersion = "1.5.4"
|
||||
val kotlinVersion = "1.5.31"
|
||||
val coroutinesVersion = "1.5.2"
|
||||
val logbackVersion = "1.2.3"
|
||||
val koinVersion = "3.1.5"
|
||||
val jacksonVersion = "2.13.1"
|
||||
|
||||
group = "com.github.flecomte"
|
||||
version = "0.0.1"
|
||||
version = versioning.info.run {
|
||||
if (dirty) {
|
||||
versioning.info.full
|
||||
} else {
|
||||
versioning.info.lastTag
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
jacoco
|
||||
application
|
||||
`maven-publish`
|
||||
|
||||
id("maven-publish")
|
||||
id("org.jetbrains.kotlin.jvm") version "1.3.50"
|
||||
kotlin("jvm") version "1.5.31"
|
||||
kotlin("plugin.serialization") version "1.5.31"
|
||||
|
||||
id("com.github.johnrengelman.shadow") version "5.2.0"
|
||||
id("org.jlleitschuh.gradle.ktlint") version "8.2.0"
|
||||
id("org.owasp.dependencycheck") version "5.1.0"
|
||||
id("org.sonarqube") version "2.7"
|
||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||
id("org.jlleitschuh.gradle.ktlint") version "10.2.1"
|
||||
id("org.owasp.dependencycheck") version "6.1.5"
|
||||
id("org.sonarqube") version "3.3"
|
||||
id("net.nemerosa.versioning") version "2.15.1"
|
||||
id("io.gitlab.arturbosch.detekt") version "1.19.0"
|
||||
id("com.avast.gradle.docker-compose") version "0.15.1"
|
||||
id("com.github.kt3k.coveralls") version "2.12.0"
|
||||
}
|
||||
|
||||
dependencyLocking {
|
||||
lockAllConfigurations()
|
||||
// lockMode.set(LockMode.STRICT)
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "io.ktor.server.jetty.EngineMain"
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.typesafe:config:1.4.2")
|
||||
classpath("com.github.flecomte:postgres-json:2.1.2")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.distZip.configure { enabled = false }
|
||||
tasks.distTar.configure { enabled = false }
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
}
|
||||
}
|
||||
|
||||
val migration by tasks.registering {
|
||||
group = "application"
|
||||
dependsOn(tasks.named("composeUp"))
|
||||
|
||||
doLast {
|
||||
val config = ConfigFactory.parseFile(file("$buildDir/resources/main/application.conf")).resolve()
|
||||
val connection = Connection(
|
||||
host = config.getString("db.host"),
|
||||
port = config.getInt("db.port"),
|
||||
database = config.getString("db.database"),
|
||||
username = config.getString("db.username"),
|
||||
password = config.getString("db.password")
|
||||
)
|
||||
Migrations(
|
||||
connection,
|
||||
file("$buildDir/resources/main/sql/migrations").toURI(),
|
||||
file("$buildDir/resources/main/sql/functions").toURI()
|
||||
).run {
|
||||
run()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val migrationTest by tasks.registering {
|
||||
group = "tests"
|
||||
dependsOn(tasks.named("testComposeUp"))
|
||||
finalizedBy(tasks.named("testComposeDown"))
|
||||
doLast {
|
||||
val config = ConfigFactory.parseFile(file("$buildDir/resources/test/application-test.conf")).resolve()
|
||||
val connection = Connection(
|
||||
host = config.getString("db.host"),
|
||||
port = config.getInt("db.port"),
|
||||
database = config.getString("db.database"),
|
||||
username = config.getString("db.username"),
|
||||
password = config.getString("db.password")
|
||||
)
|
||||
Migrations(
|
||||
connection,
|
||||
file("$buildDir/resources/main/sql/migrations").toURI(),
|
||||
file("$buildDir/resources/main/sql/functions").toURI()
|
||||
).run {
|
||||
run()
|
||||
connection.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val testSql by tasks.registering {
|
||||
group = "tests"
|
||||
dependsOn(tasks.named("processResources"))
|
||||
dependsOn(tasks.named("processTestResources"))
|
||||
|
||||
doLast {
|
||||
val config = ConfigFactory.parseFile(file("$buildDir/resources/test/application-test.conf")).resolve()
|
||||
|
||||
val connection = Connection(
|
||||
host = config.getString("db.host"),
|
||||
port = config.getInt("db.port"),
|
||||
database = config.getString("db.database"),
|
||||
username = config.getString("db.username"),
|
||||
password = config.getString("db.password")
|
||||
)
|
||||
|
||||
Migrations(
|
||||
connection,
|
||||
file("$buildDir/resources/main/sql/migrations").toURI(),
|
||||
file("$buildDir/resources/main/sql/functions").toURI(),
|
||||
file("$buildDir/resources/test/sql/fixtures").toURI()
|
||||
).run()
|
||||
|
||||
Requester.RequesterFactory(
|
||||
connection = connection,
|
||||
queriesDirectory = file("$buildDir/resources/test/sql").toURI()
|
||||
).createRequester().run {
|
||||
getQueries().map {
|
||||
try {
|
||||
it.sendQuery() == 0
|
||||
} catch (e: Exception) {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connection.disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Jar> {
|
||||
manifest {
|
||||
attributes(
|
||||
@@ -43,21 +169,215 @@ tasks.withType<Jar> {
|
||||
)
|
||||
)
|
||||
}
|
||||
isZip64 = true
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<ShadowJar>("shadowJar") {
|
||||
mergeServiceFiles("META-INF/services")
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions {
|
||||
jvmTarget = "11"
|
||||
sourceCompatibility = "11"
|
||||
targetCompatibility = "11"
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named<ShadowJar>("shadowJar") {
|
||||
mergeServiceFiles("META-INF/services")
|
||||
archiveFileName.set("${archiveBaseName.get()}-latest-all.${archiveExtension.get()}")
|
||||
isZip64 = true
|
||||
}
|
||||
|
||||
tasks.sonarqube.configure {
|
||||
dependsOn(tasks.jacocoTestReport)
|
||||
}
|
||||
|
||||
val sourcesJar by tasks.registering(Jar::class) {
|
||||
group = "build"
|
||||
archiveClassifier.set("sources")
|
||||
from(sourceSets.getByName("main").allSource)
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnit()
|
||||
useJUnitPlatform()
|
||||
systemProperty("junit.jupiter.execution.parallel.enabled", true)
|
||||
finalizedBy(tasks.jacocoTestReport) // report is always generated after tests run
|
||||
}
|
||||
|
||||
coveralls {
|
||||
sourceDirs.add("src/main/kotlin")
|
||||
}
|
||||
|
||||
apply(plugin = "docker-compose")
|
||||
dockerCompose {
|
||||
projectName = "dc-project"
|
||||
useComposeFiles = listOf("docker-compose.yml")
|
||||
startedServices = listOf("db", "elasticsearch", "rabbitmq", "redis")
|
||||
stopContainers = false
|
||||
removeVolumes = false
|
||||
removeContainers = false
|
||||
isRequiredBy(project.tasks.run)
|
||||
|
||||
createNested("testSql").apply {
|
||||
projectName = "dc-project_test"
|
||||
useComposeFiles = listOf("docker-compose-test.yml")
|
||||
startedServices = listOf("db", "elasticsearch")
|
||||
stopContainers = false
|
||||
}
|
||||
|
||||
createNested("test").apply {
|
||||
projectName = "dc-project_test"
|
||||
useComposeFiles = listOf("docker-compose-test.yml")
|
||||
stopContainers = false
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
if (versioning.info.dirty == false) {
|
||||
repositories {
|
||||
maven {
|
||||
name = "dc-project"
|
||||
group = "com.github.flecomte"
|
||||
url = uri("https://maven.pkg.github.com/flecomte/dc-project")
|
||||
credentials {
|
||||
username = System.getenv("GITHUB_USERNAME")
|
||||
password = System.getenv("GITHUB_TOKEN")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
publications {
|
||||
create<MavenPublication>("dc-project") {
|
||||
from(components["java"])
|
||||
artifact(sourcesJar)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoggerFactory.getLogger("gradle")
|
||||
.warn("The git is DIRTY (${versioning.info.full})")
|
||||
}
|
||||
}
|
||||
|
||||
jacoco {
|
||||
toolVersion = "0.8.3"
|
||||
toolVersion = "0.8.7"
|
||||
applyTo(tasks.run.get())
|
||||
}
|
||||
|
||||
tasks.register<JacocoReport>("applicationCodeCoverageReport") {
|
||||
executionData(tasks.run.get())
|
||||
sourceSets(sourceSets.main.get())
|
||||
}
|
||||
|
||||
tasks.jacocoTestReport {
|
||||
dependsOn(tasks.test)
|
||||
reports {
|
||||
xml.isEnabled = true
|
||||
html.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
detekt {
|
||||
buildUponDefaultConfig = true // preconfigure defaults
|
||||
ignoreFailures = true
|
||||
// config = files("$projectDir/config/detekt.yml") // point to your custom config defining rules to run, overwriting default behavior
|
||||
// baseline = file("$projectDir/config/baseline.xml") // a way of suppressing issues before introducing detekt
|
||||
|
||||
reports {
|
||||
html.enabled = true // observe findings in your browser with structure and code snippets
|
||||
xml.enabled = true // checkstyle like format mainly for integrations like Jenkins
|
||||
txt.enabled = true // similar to the console output, contains issue signature to manually edit baseline files
|
||||
sarif.enabled = true // standardized SARIF format (https://sarifweb.azurewebsites.net/) to support integrations with Github Code Scanning
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Detekt> {
|
||||
// Target version of the generated JVM bytecode. It is used for type resolution.
|
||||
this.jvmTarget = "11"
|
||||
ignoreFailures = true
|
||||
}
|
||||
|
||||
val setMaxMapCount = tasks.create<Exec>("setMaxMapCount") {
|
||||
group = "docker"
|
||||
doFirst {
|
||||
if (OperatingSystem.current().isWindows) {
|
||||
commandLine("cmd", "/c", "Powershell -ExecutionPolicy Bypass; wsl -d docker-desktop sysctl -w vm.max_map_count=262144")
|
||||
} else if (OperatingSystem.current().isLinux) {
|
||||
commandLine("sysctl -w vm.max_map_count=262144")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("testComposeUp").configure {
|
||||
if (OperatingSystem.current().isWindows) {
|
||||
dependsOn(setMaxMapCount)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("testWithDependencies", Test::class) {
|
||||
group = "tests"
|
||||
dependsOn(tasks.named("testComposeUp"))
|
||||
dependsOn(tasks.ktlintCheck)
|
||||
dependsOn(testSql)
|
||||
dependsOn(tasks.jacocoTestReport)
|
||||
finalizedBy(tasks.sonarqube) // report is always generated after tests run
|
||||
}
|
||||
tasks.register("testArticles", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("article")
|
||||
}
|
||||
}
|
||||
tasks.register("testCitizens", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("citizen")
|
||||
}
|
||||
}
|
||||
tasks.register("testComments", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("comment")
|
||||
}
|
||||
}
|
||||
tasks.register("testConstitutions", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("constitution")
|
||||
}
|
||||
}
|
||||
tasks.register("testFollows", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("follow")
|
||||
}
|
||||
}
|
||||
tasks.register("testNotifications", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("notification")
|
||||
}
|
||||
}
|
||||
tasks.register("testOpinions", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("opinion")
|
||||
}
|
||||
}
|
||||
tasks.register("testVotes", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("vote")
|
||||
}
|
||||
}
|
||||
tasks.register("testWorkgroups", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("workgroup")
|
||||
}
|
||||
}
|
||||
tasks.register("testViews", Test::class) {
|
||||
group = "tests"
|
||||
useJUnitPlatform {
|
||||
includeTags("view")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,46 +388,51 @@ dependencyCheck {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven { url = uri("https://kotlin.bintray.com/ktor") }
|
||||
maven { url = uri("https://jitpack.io") }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version")
|
||||
implementation(gradleApi())
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlinVersion")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:$coroutinesVersion")
|
||||
implementation("io.ktor:ktor-server-jetty:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-jetty:$ktor_version")
|
||||
implementation("ch.qos.logback:logback-classic:$logback_version")
|
||||
implementation("io.ktor:ktor-server-core:$ktor_version")
|
||||
implementation("io.ktor:ktor-locations:$ktor_version")
|
||||
implementation("io.ktor:ktor-auth:$ktor_version")
|
||||
implementation("io.ktor:ktor-auth-jwt:$ktor_version")
|
||||
implementation("io.ktor:ktor-gson:$ktor_version")
|
||||
implementation("io.ktor:ktor-auth-jwt:$ktor_version")
|
||||
implementation("io.ktor:ktor-websockets:$ktor_version")
|
||||
implementation("org.koin:koin-ktor:$koinVersion")
|
||||
implementation("io.ktor:ktor-jackson:$ktor_version")
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version")
|
||||
implementation("com.fasterxml.jackson.datatype:jackson-datatype-joda:$jackson_version")
|
||||
implementation("net.pearx.kasechange:kasechange-jvm:1.1.0")
|
||||
implementation("com.auth0:java-jwt:3.8.2")
|
||||
implementation("com.github.jasync-sql:jasync-postgresql:1.0.7")
|
||||
implementation("com.github.flecomte:postgres-json:1.1.1")
|
||||
implementation("com.github.flecomte:ktor-voter:1.0.1")
|
||||
implementation("com.sendgrid:sendgrid-java:4.4.1")
|
||||
implementation("io.lettuce:lettuce-core:5.2.2.RELEASE")
|
||||
implementation("com.rabbitmq:amqp-client:5.8.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
|
||||
implementation("io.ktor:ktor-server-jetty:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-jetty:$ktorVersion")
|
||||
implementation("ch.qos.logback:logback-classic:$logbackVersion")
|
||||
implementation("io.ktor:ktor-server-core:$ktorVersion")
|
||||
implementation("io.ktor:ktor-locations:$ktorVersion")
|
||||
implementation("io.ktor:ktor-auth:$ktorVersion")
|
||||
implementation("io.ktor:ktor-auth-jwt:$ktorVersion")
|
||||
implementation("io.ktor:ktor-websockets:$ktorVersion")
|
||||
implementation("io.insert-koin:koin-ktor:$koinVersion")
|
||||
implementation("io.ktor:ktor-jackson:$ktorVersion")
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion")
|
||||
implementation("com.fasterxml.jackson.datatype:jackson-datatype-joda:$jacksonVersion")
|
||||
implementation("net.pearx.kasechange:kasechange-jvm:1.3.0")
|
||||
implementation("com.auth0:java-jwt:3.12.0")
|
||||
implementation("com.github.jasync-sql:jasync-postgresql:1.1.6")
|
||||
implementation("com.github.flecomte:postgres-json:2.1.2")
|
||||
implementation("com.sendgrid:sendgrid-java:4.7.1")
|
||||
implementation("io.lettuce:lettuce-core:5.3.6.RELEASE") // TODO update to 6.0.2
|
||||
implementation("com.rabbitmq:amqp-client:5.10.0")
|
||||
implementation("org.elasticsearch.client:elasticsearch-rest-client:6.7.1")
|
||||
implementation("com.jayway.jsonpath:json-path:2.4.0")
|
||||
implementation("com.jayway.jsonpath:json-path:2.5.0")
|
||||
implementation("com.avast.gradle:gradle-docker-compose-plugin:0.14.0")
|
||||
implementation("io.konform:konform:0.3.0")
|
||||
|
||||
testImplementation("io.ktor:ktor-server-tests:$ktor_version")
|
||||
testImplementation("io.ktor:ktor-client-mock:$ktor_version")
|
||||
testImplementation("io.ktor:ktor-client-mock-jvm:$ktor_version")
|
||||
testImplementation("org.koin:koin-test:$koinVersion")
|
||||
testImplementation("io.mockk:mockk:1.9.3")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.5.0")
|
||||
testImplementation("org.amshove.kluent:kluent:1.4")
|
||||
testImplementation("io.cucumber:cucumber-java8:$cucumber_version")
|
||||
testImplementation("io.cucumber:cucumber-junit:$cucumber_version")
|
||||
testImplementation("io.ktor:ktor-server-tests:$ktorVersion")
|
||||
testImplementation("io.ktor:ktor-client-mock:$ktorVersion")
|
||||
testImplementation("io.ktor:ktor-client-mock-jvm:$ktorVersion")
|
||||
testImplementation("io.insert-koin:koin-test:$koinVersion")
|
||||
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:5.8.2")
|
||||
testImplementation("org.amshove.kluent:kluent:1.68")
|
||||
testImplementation("io.mockk:mockk:1.12.2")
|
||||
testImplementation("io.mockk:mockk-agent-api:1.12.2")
|
||||
testImplementation("io.mockk:mockk-agent-jvm:1.12.2")
|
||||
testImplementation("org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion")
|
||||
testImplementation("com.thedeanda:lorem:2.1")
|
||||
testImplementation("org.openapi4j:openapi-operation-validator:1.0.6")
|
||||
testImplementation("org.openapi4j:openapi-parser:1.0.6")
|
||||
}
|
||||
|
||||
20
doc/installation/Installation-linux.md
Normal file
20
doc/installation/Installation-linux.md
Normal file
@@ -0,0 +1,20 @@
|
||||
Installation on Linux (debian)
|
||||
=====================
|
||||
|
||||
## Prerequisites
|
||||
```bash
|
||||
apt-get update
|
||||
```
|
||||
|
||||
### Install docker
|
||||
See: [docs.docker.com/get-docker](https://docs.docker.com/get-docker/)
|
||||
```bash
|
||||
apt-get install docker
|
||||
apt-get install docker-compose
|
||||
```
|
||||
|
||||
### Install Git
|
||||
See: [git-scm.com/downloads](https://git-scm.com/downloads)
|
||||
```powershell
|
||||
apt-get install git
|
||||
```
|
||||
50
doc/installation/Installation-windows.md
Normal file
50
doc/installation/Installation-windows.md
Normal file
@@ -0,0 +1,50 @@
|
||||
Installation on Windows
|
||||
============
|
||||
|
||||
## Prerequisites
|
||||
### Install chocolaty (optional)
|
||||
First install Chocolaty => [https://chocolatey.org/install](https://chocolatey.org/install)
|
||||
```powershell
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
```
|
||||
|
||||
### Install make (optional)
|
||||
Install make with chocolaty
|
||||
```powershell
|
||||
chocolatey install make
|
||||
```
|
||||
Install make for gitbash
|
||||
[https://gist.github.com/evanwill/0207876c3243bbb6863e65ec5dc3f058#make]()
|
||||
|
||||
### Install awk (optional)
|
||||
Install awk with chocolaty
|
||||
```powershell
|
||||
chocolatey install awk
|
||||
```
|
||||
|
||||
### Install docker
|
||||
See: [docs.docker.com/get-docker](https://docs.docker.com/get-docker/)
|
||||
```powershell
|
||||
choco install docker-desktop
|
||||
```
|
||||
|
||||
If you use docker with WSL2, you need to change config for elasticsearch:
|
||||
```powershell
|
||||
wsl -d docker-desktop
|
||||
sysctl -w vm.max_map_count=262144
|
||||
echo "vm.max_map_count = 262144" > /etc/sysctl.d/99-docker-desktop.conf
|
||||
```
|
||||
then restart docker-desktop
|
||||
|
||||
### Install Git
|
||||
See: [git-scm.com/downloads](https://git-scm.com/downloads)
|
||||
```powershell
|
||||
choco install git
|
||||
```
|
||||
|
||||
### Add JAVA_HOME path
|
||||
In CMD (Not Powershell)
|
||||
```cmd
|
||||
$ setx -m JAVA_HOME "C:\Users\%USERNAME%\.jdks\corretto-11.0.7"
|
||||
$ setx -m PATH "%PATH%;%JAVA_HOME%\bin";
|
||||
```
|
||||
7
doc/installation/Installation.md
Normal file
7
doc/installation/Installation.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
1. [Installation on Windows](Installation-windows.md)
|
||||
2. [Installation on Linux](Installation-linux.md)
|
||||
3. [Problems in installations](Problems.md)
|
||||
|
||||
29
doc/installation/Problems.md
Normal file
29
doc/installation/Problems.md
Normal file
@@ -0,0 +1,29 @@
|
||||
Problems
|
||||
========
|
||||
|
||||
1. [max_map_count](#max_map_count)
|
||||
|
||||
max_map_count
|
||||
-------------
|
||||
|
||||
**Context**:
|
||||
|
||||
Elasticsearch in Docker on WSL2
|
||||
|
||||
**Error**:
|
||||
```
|
||||
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
|
||||
```
|
||||
|
||||
**Resolution**:
|
||||
|
||||
[Stackoverflow](https://stackoverflow.com/questions/42111566/elasticsearch-in-windows-docker-image-vm-max-map-count)
|
||||
|
||||
In Powershell:
|
||||
```powershell
|
||||
wsl -d docker-desktop
|
||||
sysctl -w vm.max_map_count=262144
|
||||
echo "vm.max_map_count = 262144" > /etc/sysctl.d/99-docker-desktop.conf
|
||||
```
|
||||
|
||||
restart docker-desktop
|
||||
98
doc/schema/Article.puml
Normal file
98
doc/schema/Article.puml
Normal file
@@ -0,0 +1,98 @@
|
||||
@startuml
|
||||
|
||||
title Search / Get articles
|
||||
|
||||
actor Front
|
||||
box Article API
|
||||
control Controller
|
||||
control Repository
|
||||
entity Article
|
||||
database Postgres
|
||||
endbox
|
||||
box View System
|
||||
control ArticleViewManager
|
||||
database Elasticsearch
|
||||
endbox
|
||||
box Notification System
|
||||
control EventNotification
|
||||
database RabbitMQ
|
||||
database Redis
|
||||
endbox
|
||||
|
||||
Front -> Controller++: GET /articles?page=1
|
||||
Controller -> Repository++: find
|
||||
Repository -> Postgres++: find_articles()
|
||||
return
|
||||
return
|
||||
return: 200, Articles
|
||||
|
||||
newpage Create / Update Article
|
||||
|
||||
Front -> Controller: POST /article
|
||||
activate Controller
|
||||
Controller -> Controller: Convert dto to Entity
|
||||
Controller -> Controller: Check Authorization
|
||||
alt Authorize
|
||||
Controller -> Repository++: upsert(entity)
|
||||
Repository -> Postgres++: upsert_article
|
||||
return
|
||||
return
|
||||
Controller -> Controller: Convert to dto
|
||||
Front <-- Controller: 200, New Article
|
||||
else not authorize
|
||||
Front <-- Controller: 403, "Forbidden"
|
||||
end
|
||||
Controller -> EventNotification: raiseEvent(ArticleUpdate)
|
||||
deactivate Controller
|
||||
activate EventNotification
|
||||
EventNotification ->> RabbitMQ
|
||||
deactivate EventNotification
|
||||
...
|
||||
RabbitMQ -->> EventNotification++
|
||||
EventNotification ->> : Send Email
|
||||
EventNotification ->> Redis : Push Event Notification
|
||||
return <<ACK>>
|
||||
|
||||
newpage get one article by id
|
||||
|
||||
Front -> Controller: GET /article/{article}
|
||||
activate Controller
|
||||
Controller -> Repository++: findById()
|
||||
Repository -> Postgres++: find_article_by_id()
|
||||
return
|
||||
return
|
||||
Controller -> Controller: Check Authorization
|
||||
|
||||
alt Authorize
|
||||
Controller -> ArticleViewManager++: getViewsCount(Article)
|
||||
ArticleViewManager -> Elasticsearch++
|
||||
return
|
||||
return
|
||||
Controller -> Controller: Convert Article and Views to dto
|
||||
Front <<-- Controller: 200, Article
|
||||
else not authorize
|
||||
Front <<-- Controller: 403, "Forbidden"
|
||||
end
|
||||
Controller -> ArticleViewManager++: increment the view counter
|
||||
ArticleViewManager -> Elasticsearch++
|
||||
return
|
||||
return
|
||||
deactivate Controller
|
||||
|
||||
newpage get article versions by id
|
||||
|
||||
Front -> Controller: GET /articles/{article}/versions
|
||||
activate Controller
|
||||
Controller -> Controller: Check Authorization
|
||||
alt Authorize
|
||||
Controller -> Repository++: findVersionsByVersionId
|
||||
Repository -> Postgres++: find_articles_versions_by_version_id
|
||||
return
|
||||
return
|
||||
Controller -> Controller: Convert to dto
|
||||
Front <-- Controller: 200, Articles versions
|
||||
else not authorize
|
||||
Front <-- Controller: 403, "Forbidden"
|
||||
end
|
||||
deactivate Controller
|
||||
@enduml
|
||||
66
doc/schema/Notification.puml
Normal file
66
doc/schema/Notification.puml
Normal file
@@ -0,0 +1,66 @@
|
||||
@startuml
|
||||
title Notification
|
||||
|Server|
|
||||
partition Event {
|
||||
start
|
||||
:Article is modified;
|
||||
:Send message to "notification" exchange (RabbitMQ);
|
||||
:RabbitMQ send message to "push" and "email" queue;
|
||||
stop
|
||||
}
|
||||
split
|
||||
partition Email {
|
||||
-[hidden]->
|
||||
:Consume "email" queue<
|
||||
repeat :get next notification;
|
||||
:Get followers of article from DB;
|
||||
while (loop on followers)
|
||||
:Send email to the citizen>
|
||||
endwhile
|
||||
:ACK>
|
||||
repeat while()
|
||||
detach
|
||||
}
|
||||
splitagain
|
||||
partition Push {
|
||||
-[hidden]->
|
||||
:Consume "email" queue<
|
||||
repeat :get next notification;
|
||||
:Get followers of article from DB;
|
||||
while (loop on followers)
|
||||
:Send notification message to redis>
|
||||
endwhile
|
||||
:ACK>
|
||||
repeat while()
|
||||
detach
|
||||
}
|
||||
splitagain
|
||||
partition "Notification direct" {
|
||||
-[hidden]->
|
||||
|Client|
|
||||
start
|
||||
:Client arrive on the web site;
|
||||
:Connect to the websocket;
|
||||
|Server|
|
||||
:Get citizen notification
|
||||
from redis;
|
||||
while (on each notifications)
|
||||
:Send notification to websocket>
|
||||
endwhile(no notification left)
|
||||
|Client|
|
||||
:show notification;
|
||||
|Server|
|
||||
:Subscribe to redis event;
|
||||
repeat :On new notification;
|
||||
:Get new notification from redis;
|
||||
:Send notification to websocket>
|
||||
|Client|
|
||||
:show notification;
|
||||
|Server|
|
||||
repeat while (wait notification)
|
||||
detach
|
||||
}
|
||||
endsplit
|
||||
|
||||
|
||||
@enduml
|
||||
44
docker-compose-test.yml
Normal file
44
docker-compose-test.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
version: '3.3'
|
||||
services:
|
||||
rabbitmq:
|
||||
container_name: ${APP_NAME}_rabbitmq_test
|
||||
image: rabbitmq:management-alpine
|
||||
ports:
|
||||
- 5673:5672
|
||||
- 15673:15672
|
||||
|
||||
redis:
|
||||
container_name: ${APP_NAME}_redis_test
|
||||
image: redis:6-alpine
|
||||
ports:
|
||||
- 6380:6379
|
||||
|
||||
elasticsearch:
|
||||
container_name: ${APP_NAME}_elasticsearch_test
|
||||
image: elasticsearch:6.7.1
|
||||
ports:
|
||||
- 9201:9200
|
||||
- 9301:9300
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://elasticsearch:9200"]
|
||||
interval: 3s
|
||||
timeout: 2s
|
||||
retries: 20
|
||||
|
||||
db:
|
||||
container_name: ${APP_NAME}_postgresql_test
|
||||
build:
|
||||
context: docker/postgresql
|
||||
ports:
|
||||
- 15432:5432
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${DB_NAME}
|
||||
POSTGRES_USER: ${DB_USER}
|
||||
POSTGRES_DB: ${DB_PWD}
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
healthcheck:
|
||||
test: [ "CMD", "pg_isready", "-q", "-d", "${DB_NAME}", "-U", "${DB_USER}" ]
|
||||
interval: 3s
|
||||
timeout: 2s
|
||||
retries: 20
|
||||
@@ -1,44 +1,35 @@
|
||||
# To execute this docker-compose yml file use docker-compose -f <file_name> up
|
||||
# Add the "-d" flag at the end for detached execution
|
||||
version: '3.7'
|
||||
version: '3.8'
|
||||
services:
|
||||
sonarqube:
|
||||
container_name: sonarqube_${NAME}
|
||||
image: sonarqube
|
||||
restart: always
|
||||
ports:
|
||||
- ${SONARQUBE_PORT}:9000
|
||||
|
||||
openapi:
|
||||
container_name: openapi_${NAME}
|
||||
container_name: ${APP_NAME}_openapi
|
||||
image: swaggerapi/swagger-ui
|
||||
restart: always
|
||||
ports:
|
||||
- ${OPENAPI_PORT}:8080
|
||||
environment:
|
||||
URL: "http://localhost:8080"
|
||||
|
||||
rabbitmq:
|
||||
container_name: rabbitmq_${NAME}
|
||||
container_name: ${APP_NAME}_rabbitmq
|
||||
image: rabbitmq:management-alpine
|
||||
restart: always
|
||||
ports:
|
||||
- ${RABBITMQ_PORT}:5672
|
||||
- ${RABBITMQ_MANAGEMENT_PORT}:15672
|
||||
|
||||
redis:
|
||||
container_name: redis_${NAME}
|
||||
image: redis:6.0-rc-alpine
|
||||
restart: always
|
||||
container_name: ${APP_NAME}_redis
|
||||
image: redis:6-alpine
|
||||
ports:
|
||||
- ${REDIS_PORT}:6379
|
||||
volumes:
|
||||
- redis-data:/var/lib/redis:rw
|
||||
|
||||
app:
|
||||
container_name: app_${NAME}
|
||||
container_name: ${APP_NAME}_app
|
||||
build:
|
||||
context: ./build
|
||||
dockerfile: ../docker/app/Dockerfile
|
||||
restart: always
|
||||
context: .
|
||||
dockerfile: docker/app/Dockerfile
|
||||
ports:
|
||||
- ${APP_PORT}:8080
|
||||
environment:
|
||||
@@ -47,6 +38,9 @@ services:
|
||||
REDIS_CONNECTION: ${REDIS_CONNECTION}
|
||||
RABBITMQ_CONNECTION: ${RABBITMQ_CONNECTION}
|
||||
ELASTICSEARCH_CONNECTION: ${ELASTICSEARCH_CONNECTION}
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
JWT_ISSUER: ${JWT_ISSUER}
|
||||
JWT_VALIDITY: ${JWT_VALIDITY}
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
- db
|
||||
@@ -54,19 +48,21 @@ services:
|
||||
- rabbitmq
|
||||
|
||||
elasticsearch:
|
||||
container_name: elasticsearch_${NAME}
|
||||
container_name: ${APP_NAME}_elasticsearch
|
||||
image: elasticsearch:6.7.1
|
||||
restart: always
|
||||
ports:
|
||||
- ${ELASTIC_REST}:9200
|
||||
- ${ELASTIC_NODES}:9300
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://elasticsearch:9200"]
|
||||
interval: 3s
|
||||
timeout: 2s
|
||||
retries: 20
|
||||
|
||||
# Database
|
||||
db:
|
||||
container_name: postgresql_${NAME}
|
||||
container_name: ${APP_NAME}_postgresql
|
||||
build:
|
||||
context: docker/postgresql
|
||||
restart: always
|
||||
ports:
|
||||
- ${POSTGRESQL_PORT}:5432
|
||||
environment:
|
||||
@@ -75,11 +71,15 @@ services:
|
||||
POSTGRES_DB: ${DB_PWD}
|
||||
volumes:
|
||||
- ./var/log/postgresql:/var/log/postgresql:rw
|
||||
- ./var/postgresql/data:/var/lib/postgresql/data:rw
|
||||
- db-data:/var/lib/postgresql/data:rw
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://elasticsearch:9200/"]
|
||||
test: [ "CMD", "pg_isready", "-q", "-d", "${DB_NAME}", "-U", "${DB_USER}" ]
|
||||
interval: 3s
|
||||
timeout: 2s
|
||||
retries: 20
|
||||
|
||||
volumes:
|
||||
db-data:
|
||||
redis-data:
|
||||
@@ -1,5 +1,13 @@
|
||||
FROM adoptopenjdk/openjdk11:jre-11.0.4_11-alpine
|
||||
#### BUILD ####
|
||||
FROM gradle:6.8-jdk11 AS build
|
||||
COPY --chown=gradle:gradle . /home/gradle/src
|
||||
|
||||
WORKDIR /home/gradle/src
|
||||
RUN gradle build -x test -x ktlintKotlinScriptCheck -x ktlintTestSourceSetCheck -x ktlintMainSourceSetCheck --no-daemon
|
||||
RUN gradle shadowJar
|
||||
|
||||
#### RUN ####
|
||||
FROM amazoncorretto:11-alpine as run
|
||||
ENV APPLICATION_USER ktor
|
||||
RUN adduser -D -g '' $APPLICATION_USER
|
||||
|
||||
@@ -8,7 +16,7 @@ RUN chown -R $APPLICATION_USER /app
|
||||
|
||||
USER $APPLICATION_USER
|
||||
|
||||
COPY ./libs/dcproject-0.0.1-all.jar /app/dcproject.jar
|
||||
COPY --from=build /home/gradle/src/build/libs/dcproject-latest-all.jar /app/dcproject.jar
|
||||
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"]
|
||||
|
||||
275
gradle.lockfile
Normal file
275
gradle.lockfile
Normal file
@@ -0,0 +1,275 @@
|
||||
# This is a Gradle generated file for dependency locking.
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
ch.qos.logback:logback-classic:1.2.3=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
ch.qos.logback:logback-core:1.2.3=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.auth0:java-jwt:3.12.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.auth0:jwks-rsa:0.9.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.avast.gradle:gradle-docker-compose-plugin:0.14.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.beust:jcommander:1.81=detekt
|
||||
com.fasterxml.jackson.core:jackson-annotations:2.13.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-core:2.13.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.core:jackson-databind:2.13.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.datatype:jackson-datatype-joda:2.13.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.fasterxml.jackson:jackson-bom:2.13.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.flecomte:postgres-json:2.1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.github.jasync-sql:jasync-common:1.1.6=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata
|
||||
com.github.jasync-sql:jasync-common:1.1.7=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.jasync-sql:jasync-pool:1.1.6=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata
|
||||
com.github.jasync-sql:jasync-pool:1.1.7=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.jasync-sql:jasync-postgresql:1.1.6=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata
|
||||
com.github.jasync-sql:jasync-postgresql:1.1.7=runtimeClasspath,testRuntimeClasspath
|
||||
com.github.shyiko.klob:klob:0.2.1=ktlint
|
||||
com.google.code.findbugs:jsr305:3.0.2=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.errorprone:error_prone_annotations:2.2.0=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.guava:failureaccess:1.0.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.guava:guava:27.1-jre=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=runtimeClasspath,testRuntimeClasspath
|
||||
com.google.j2objc:j2objc-annotations:1.1=runtimeClasspath,testRuntimeClasspath
|
||||
com.googlecode.json-simple:json-simple:1.1.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
com.jayway.jsonpath:json-path:2.5.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.ongres.scram:client:2.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.ongres.scram:common:2.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.ongres.stringprep:saslprep:1.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.ongres.stringprep:stringprep:1.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.pinterest.ktlint:ktlint-core:0.42.1=ktlint,ktlintBaselineReporter
|
||||
com.pinterest.ktlint:ktlint-reporter-baseline:0.42.1=ktlint,ktlintBaselineReporter
|
||||
com.pinterest.ktlint:ktlint-reporter-checkstyle:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-reporter-html:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-reporter-json:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-reporter-plain:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-reporter-sarif:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-ruleset-experimental:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-ruleset-standard:0.42.1=ktlint
|
||||
com.pinterest.ktlint:ktlint-ruleset-test:0.42.1=ktlint
|
||||
com.pinterest:ktlint:0.42.1=ktlint
|
||||
com.rabbitmq:amqp-client:5.10.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.sendgrid:java-http-client:4.3.6=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.sendgrid:sendgrid-java:4.7.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.thedeanda:lorem:2.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
com.typesafe:config:1.3.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
commons-codec:commons-codec:1.11=compileClasspath,implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata
|
||||
commons-codec:commons-codec:1.14=runtimeClasspath,testRuntimeClasspath
|
||||
commons-io:commons-io:2.6=runtimeClasspath,testRuntimeClasspath
|
||||
commons-logging:commons-logging:1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
info.picocli:picocli:3.9.6=ktlint
|
||||
io.github.detekt.sarif4k:sarif4k:0.0.1=detekt,ktlint
|
||||
io.github.microutils:kotlin-logging:1.7.6=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.gitlab.arturbosch.detekt:detekt-api:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-cli:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-core:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-metrics:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-parser:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-psi-utils:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-report-html:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-report-sarif:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-report-txt:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-report-xml:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-complexity:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-coroutines:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-documentation:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-empty:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-errorprone:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-exceptions:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-naming:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-performance:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules-style:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-rules:1.19.0=detekt
|
||||
io.gitlab.arturbosch.detekt:detekt-tooling:1.19.0=detekt
|
||||
io.insert-koin:koin-core-jvm:3.1.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.insert-koin:koin-core:3.1.5=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.insert-koin:koin-ktor:3.1.5=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.insert-koin:koin-test-jvm:3.1.5=testCompileClasspath,testRuntimeClasspath
|
||||
io.insert-koin:koin-test:3.1.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.konform:konform-jvm:0.3.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.konform:konform:0.3.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-auth-jwt-kotlinMultiplatform:1.5.4=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
io.ktor:ktor-auth-jwt:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-auth-kotlinMultiplatform:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-auth:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-client-cio-jvm:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-client-cio:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-client-core-jvm:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-client-core:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-client-jetty-kotlinMultiplatform:1.5.4=implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-client-jetty:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-client-mock-jvm:1.5.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-client-mock:1.5.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-http-cio-jvm:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-http-cio:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-http-jvm:1.6.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-http:1.6.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-io-jvm:1.6.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-io:1.6.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-jackson-kotlinMultiplatform:1.5.4=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
io.ktor:ktor-jackson:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-locations-kotlinMultiplatform:1.5.4=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
io.ktor:ktor-locations:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-network-jvm:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-network-tls-certificates-kotlinMultiplatform:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-network-tls-certificates:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-network-tls-jvm:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-network-tls:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-network:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-core-kotlinMultiplatform:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-server-core:1.6.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-server-host-common-kotlinMultiplatform:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-host-common:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-jetty-kotlinMultiplatform:1.5.4=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
io.ktor:ktor-server-jetty:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-server-servlet-kotlinMultiplatform:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-servlet:1.5.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-test-host-kotlinMultiplatform:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-test-host:1.5.4=testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-server-tests-kotlinMultiplatform:1.5.4=testImplementationDependenciesMetadata
|
||||
io.ktor:ktor-server-tests:1.5.4=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-utils-jvm:1.6.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
io.ktor:ktor-utils:1.6.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-websockets-kotlinMultiplatform:1.5.4=implementationDependenciesMetadata,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.ktor:ktor-websockets:1.5.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.lettuce:lettuce-core:5.3.6.RELEASE=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk-agent-api:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk-agent-common:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk-agent-jvm:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk-common:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk-dsl-jvm:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk-dsl:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.mockk:mockk:1.12.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.netty:netty-buffer:4.1.56.Final=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.netty:netty-codec:4.1.56.Final=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.netty:netty-common:4.1.56.Final=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.netty:netty-handler:4.1.56.Final=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.netty:netty-resolver:4.1.56.Final=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.netty:netty-transport:4.1.56.Final=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
io.projectreactor:reactor-core:3.4.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
javax.servlet:javax.servlet-api:3.1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
joda-time:joda-time:2.10.8=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
junit:junit:4.12=testCompileClasspath,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy-agent:1.12.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.bytebuddy:byte-buddy:1.12.5=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.java.dev.jna:jna-platform:5.5.0=testRuntimeClasspath
|
||||
net.java.dev.jna:jna:5.5.0=testRuntimeClasspath
|
||||
net.minidev:accessors-smart:1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.minidev:json-smart:2.3=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.pearx.kasechange:kasechange-jvm:1.3.0=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
net.pearx.kasechange:kasechange-metadata:1.3.0=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
org.amshove.kluent:kluent-common:1.68=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.amshove.kluent:kluent:1.68=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpasyncclient:4.1.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpclient:4.5.12=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpcore-nio:4.4.5=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apache.httpcomponents:httpcore:4.4.13=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath,testImplementationDependenciesMetadata
|
||||
org.bouncycastle:bcprov-jdk15on:1.67=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.checkerframework:checker-qual:2.5.2=runtimeClasspath,testRuntimeClasspath
|
||||
org.codehaus.mojo:animal-sniffer-annotations:1.17=runtimeClasspath,testRuntimeClasspath
|
||||
org.ec4j.core:ec4j-core:0.3.0=ktlint,ktlintBaselineReporter
|
||||
org.eclipse.jetty.http2:http2-client:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-common:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-hpack:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-http-client-transport:9.4.31.v20200723=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty.http2:http2-server:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-client:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-java-client:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-java-server:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-openjdk8-client:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-openjdk8-server:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-alpn-server:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-client:9.4.31.v20200723=testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-continuation:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-http:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-io:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-server:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-servlets:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.eclipse.jetty:jetty-util:9.4.31.v20200723=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.elasticsearch.client:elasticsearch-rest-client:6.7.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.fusesource.jansi:jansi:2.3.4=runtimeClasspath,testRuntimeClasspath
|
||||
org.hamcrest:hamcrest-core:1.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.jacoco:org.jacoco.agent:0.8.7=jacocoAgent,jacocoAnt
|
||||
org.jacoco:org.jacoco.ant:0.8.7=jacocoAnt
|
||||
org.jacoco:org.jacoco.core:0.8.7=jacocoAnt
|
||||
org.jacoco:org.jacoco.report:0.8.7=jacocoAnt
|
||||
org.jetbrains.intellij.deps:trove4j:1.0.20181211=detekt,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.31=detekt,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.5.31=detekt,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.5.31=kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-native-utils:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-project-model:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.5.30=compileClasspath,implementationDependenciesMetadata,runtimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-reflect:1.5.31=detekt,kotlinCompilerClasspath,kotlinKlibCommonizerClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-script-runtime:1.5.31=detekt,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath
|
||||
org.jetbrains.kotlin:kotlin-scripting-common:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-scripting-jvm:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-serialization:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-common:1.5.31=compileClasspath,detekt,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.0=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.31=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.0=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.31=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.5.20=ktlint,ktlintBaselineReporter
|
||||
org.jetbrains.kotlin:kotlin-stdlib:1.5.31=compileClasspath,detekt,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-test-annotations-common:1.5.31=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-test-common:1.5.31=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-test-junit:1.5.31=testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-test:1.5.31=testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlin:kotlin-util-io:1.5.31=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.4.2=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core-metadata:1.4.2=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0=kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-debug:1.5.2=testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.5.1-native-mt=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-reactive:1.5.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.5.2=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-html-jvm:0.7.3=detekt
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.1.0=detekt,ktlint
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-core-metadata:1.0.1=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-core:1.1.0=detekt,ktlint
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.1.0=detekt,ktlint
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-json-metadata:1.0.1=implementationDependenciesMetadata,testImplementationDependenciesMetadata
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0=detekt,ktlint
|
||||
org.jetbrains:annotations:13.0=compileClasspath,detekt,implementationDependenciesMetadata,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinKlibCommonizerClasspath,ktlint,ktlintBaselineReporter,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.joda:joda-convert:1.8.1=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-api:5.8.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-engine:5.8.2=testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:5.8.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter:5.8.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-commons:1.8.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.junit.platform:junit-platform-engine:1.8.2=testRuntimeClasspath
|
||||
org.junit:junit-bom:5.8.2=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.objenesis:objenesis:3.1=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.openapi4j:openapi-core:1.0.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.openapi4j:openapi-operation-validator:1.0.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.openapi4j:openapi-parser:1.0.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.openapi4j:openapi-schema-validator:1.0.6=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.ow2.asm:asm-analysis:9.1=jacocoAnt
|
||||
org.ow2.asm:asm-commons:9.1=jacocoAnt
|
||||
org.ow2.asm:asm-tree:9.1=jacocoAnt
|
||||
org.ow2.asm:asm:5.0.4=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.ow2.asm:asm:9.1=jacocoAnt
|
||||
org.reactivestreams:reactive-streams:1.0.3=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.slf4j:slf4j-api:1.7.30=compileClasspath,implementationDependenciesMetadata,runtimeClasspath,testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.yaml:snakeyaml:1.27=runtimeClasspath
|
||||
org.yaml:snakeyaml:1.28=testCompileClasspath,testImplementationDependenciesMetadata,testRuntimeClasspath
|
||||
org.yaml:snakeyaml:1.29=detekt
|
||||
empty=annotationProcessor,apiDependenciesMetadata,compileOnly,compileOnlyDependenciesMetadata,detektPlugins,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDef,kotlinScriptDefExtensions,ktlintReporter,ktlintRuleset,runtimeOnlyDependenciesMetadata,shadow,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnly,testCompileOnlyDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDef,testKotlinScriptDefExtensions,testRuntimeOnlyDependenciesMetadata
|
||||
@@ -1,10 +1,7 @@
|
||||
ktor_version=1.2.2
|
||||
kotlin.code.style=official
|
||||
kotlin_version=1.3.40
|
||||
coroutinesVersion=1.3.3
|
||||
logback_version=1.2.1
|
||||
koinVersion=2.0.1
|
||||
jackson_version=2.9.9
|
||||
cucumber_version=5.1.3
|
||||
systemProp.sonar.host.url=http://localhost:9000
|
||||
systemProp.sonar.login=1196e8015c20035f1aa91e881b95ce9d6e879c8a
|
||||
systemProp.sonar.host.url=https://sonarcloud.io
|
||||
systemProp.sonar.projectKey=dc-project
|
||||
systemProp.sonar.projectName=DC Project
|
||||
systemProp.sonar.organization=flecomte
|
||||
systemProp.sonar.java.coveragePlugin=jacoco
|
||||
systemProp.sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
31
gradlew
vendored
31
gradlew
vendored
@@ -82,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -129,6 +130,7 @@ fi
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -154,19 +156,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
25
gradlew.bat
vendored
25
gradlew.bat
vendored
@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -51,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -61,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
12
hook/version.sh
Normal file
12
hook/version.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [[ $(git describe --tags --dirty) =~ ^V?([0-9][0-9.]*(-dirty)?)$ ]]; then
|
||||
VERSION="${BASH_REMATCH[1]}"
|
||||
elif [[ $(git describe --tags --dirty) =~ ^V?([0-9][0-9.]*)-([0-9]+)-g(.+(-dirty)?)$ ]]; then
|
||||
VERSION="${BASH_REMATCH[1]}-${BASH_REMATCH[3]}"
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo $VERSION
|
||||
@@ -1,364 +0,0 @@
|
||||
package fr.dcproject
|
||||
|
||||
import com.fasterxml.jackson.core.util.DefaultIndenter
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule
|
||||
import com.github.jasync.sql.db.postgresql.exceptions.GenericDatabaseException
|
||||
import fr.dcproject.Env.PROD
|
||||
import fr.dcproject.entity.*
|
||||
import fr.dcproject.event.EventNotification
|
||||
import fr.dcproject.event.EventSubscriber
|
||||
import fr.dcproject.routes.*
|
||||
import fr.dcproject.security.voter.*
|
||||
import fr.ktorVoter.AuthorizationVoter
|
||||
import fr.ktorVoter.ForbiddenException
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.application.Application
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.application.call
|
||||
import io.ktor.application.install
|
||||
import io.ktor.auth.Authentication
|
||||
import io.ktor.auth.authenticate
|
||||
import io.ktor.auth.jwt.jwt
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.jetty.Jetty
|
||||
import io.ktor.features.*
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.auth.HttpAuthHeader
|
||||
import io.ktor.jackson.jackson
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Locations
|
||||
import io.ktor.response.respond
|
||||
import io.ktor.routing.Routing
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import io.ktor.websocket.WebSockets
|
||||
import org.eclipse.jetty.util.log.Slf4jLog
|
||||
import org.elasticsearch.client.Request
|
||||
import org.elasticsearch.client.RestClient
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.ktor.ext.Koin
|
||||
import org.koin.ktor.ext.get
|
||||
import org.slf4j.event.Level
|
||||
import java.time.Duration
|
||||
import java.util.*
|
||||
import java.util.concurrent.CompletionException
|
||||
import fr.dcproject.entity.Workgroup as WorkgroupEntity
|
||||
import fr.dcproject.repository.Article as RepositoryArticle
|
||||
import fr.dcproject.repository.Citizen as RepositoryCitizen
|
||||
import fr.dcproject.repository.Constitution as RepositoryConstitution
|
||||
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
|
||||
import fr.dcproject.repository.User as UserRepository
|
||||
import fr.dcproject.repository.Workgroup as WorkgroupRepository
|
||||
|
||||
fun main(args: Array<String>): Unit = io.ktor.server.jetty.EngineMain.main(args)
|
||||
|
||||
enum class Env { PROD, TEST, CUCUMBER }
|
||||
|
||||
@KtorExperimentalAPI
|
||||
@KtorExperimentalLocationsAPI
|
||||
@Suppress("unused") // Referenced in application.conf
|
||||
fun Application.module(env: Env = PROD) {
|
||||
install(Koin) {
|
||||
Slf4jLog()
|
||||
modules(Module)
|
||||
}
|
||||
|
||||
install(CallLogging) {
|
||||
level = Level.INFO
|
||||
}
|
||||
|
||||
install(DataConversion) {
|
||||
convert<UUID> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
}
|
||||
|
||||
encode { value ->
|
||||
when (value) {
|
||||
null -> listOf()
|
||||
is UUID -> listOf(value.toString())
|
||||
else -> throw InternalError("Cannot convert $value as UUID")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: create generic convert for entityI
|
||||
convert<Article> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
get<RepositoryArticle>().findById(UUID.fromString(it))
|
||||
?: throw NotFoundException("Article $values not found")
|
||||
} ?: throw NotFoundException("Article $values not found")
|
||||
}
|
||||
}
|
||||
convert<ArticleRef> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
ArticleRef(UUID.fromString(it))
|
||||
} ?: throw NotFoundException("""UUID "$values" is not valid for Article""")
|
||||
}
|
||||
}
|
||||
|
||||
convert<CommentRef> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
CommentRef(UUID.fromString(it))
|
||||
} ?: throw NotFoundException("""UUID "$values" is not valid for Comment""")
|
||||
}
|
||||
}
|
||||
convert<ConstitutionRef> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
ConstitutionRef(UUID.fromString(it))
|
||||
} ?: throw NotFoundException("""UUID "$values" is not valid for Constitution""")
|
||||
}
|
||||
}
|
||||
|
||||
convert<Constitution> {
|
||||
decode { values, _ ->
|
||||
val id = values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
?: throw InternalError("Cannot convert $values to UUID")
|
||||
get<RepositoryConstitution>().findById(id) ?: throw NotFoundException("Constitution $values not found")
|
||||
}
|
||||
}
|
||||
|
||||
convert<Citizen> {
|
||||
decode { values, _ ->
|
||||
val id = values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
?: throw InternalError("Cannot convert $values to UUID")
|
||||
get<RepositoryCitizen>().findById(id, true) ?: throw NotFoundException("Citizen $values not found")
|
||||
}
|
||||
}
|
||||
|
||||
convert<CitizenRef> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
CitizenRef(UUID.fromString(it))
|
||||
} ?: throw NotFoundException("""UUID "$values" is not valid for Citizen""")
|
||||
}
|
||||
}
|
||||
|
||||
convert<OpinionChoice> {
|
||||
decode { values, _ ->
|
||||
val id = values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
?: throw InternalError("Cannot convert $values to UUID")
|
||||
get<OpinionChoiceRepository>().findOpinionChoiceById(id)
|
||||
?: throw NotFoundException("OpinionChoice $values not found")
|
||||
}
|
||||
}
|
||||
|
||||
convert<WorkgroupRef> {
|
||||
decode { values, _ ->
|
||||
values.singleOrNull()?.let {
|
||||
WorkgroupRef(UUID.fromString(it))
|
||||
} ?: throw NotFoundException("""UUID "$values" is not valid for Workgroup""")
|
||||
}
|
||||
}
|
||||
|
||||
convert<WorkgroupEntity> {
|
||||
decode { values, _ ->
|
||||
val id = values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
?: throw InternalError("Cannot convert $values to UUID")
|
||||
get<WorkgroupRepository>().findById(id)
|
||||
?: throw NotFoundException("Workgroup $values not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
install(Locations) {
|
||||
}
|
||||
|
||||
install(AuthorizationVoter) {
|
||||
voters = mutableListOf(
|
||||
ArticleVoter(),
|
||||
ConstitutionVoter(),
|
||||
CitizenVoter(),
|
||||
CommentVoter(),
|
||||
VoteVoter(),
|
||||
FollowVoter(),
|
||||
OpinionVoter(),
|
||||
OpinionChoiceVoter(),
|
||||
WorkgroupVoter()
|
||||
)
|
||||
}
|
||||
|
||||
HttpClient(Jetty) {
|
||||
engine {
|
||||
}
|
||||
}
|
||||
|
||||
/* Create index if not exist */
|
||||
get<RestClient>().run {
|
||||
if (performRequest(Request("HEAD", "/views?include_type_name=false")).statusLine.statusCode == 404) {
|
||||
Request(
|
||||
"PUT",
|
||||
"/views?include_type_name=false"
|
||||
).apply {
|
||||
//language=JSON
|
||||
setJsonEntity(
|
||||
"""
|
||||
{
|
||||
"settings": {
|
||||
"number_of_shards": 5
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"logged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"user_ref": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"version_id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"ip": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"citizen_id": {
|
||||
"type": "keyword"
|
||||
},
|
||||
"view_at": {
|
||||
"type": "date"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
}.let {
|
||||
performRequest(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
install(WebSockets) {
|
||||
pingPeriod = Duration.ofSeconds(60) // Disabled (null) by default
|
||||
timeout = Duration.ofSeconds(15)
|
||||
maxFrameSize = Long.MAX_VALUE // Disabled (max value). The connection will be closed if surpassed this length.
|
||||
masking = false
|
||||
}
|
||||
|
||||
install(EventSubscriber) {
|
||||
EventNotification(this, get(), get(), get(), get(), get()).config()
|
||||
}
|
||||
|
||||
install(Authentication) {
|
||||
/**
|
||||
* Setup the JWT authentication to be used in [Routing].
|
||||
* If the token is valid, the corresponding [User] is fetched from the database.
|
||||
* The [User] can then be accessed in each [ApplicationCall].
|
||||
*/
|
||||
jwt {
|
||||
verifier(JwtConfig.verifier)
|
||||
realm = "dc-project.fr"
|
||||
validate {
|
||||
it.payload.getClaim("id").asString()?.let { id ->
|
||||
get<UserRepository>().findById(UUID.fromString(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jwt("url") {
|
||||
verifier(JwtConfig.verifier)
|
||||
realm = "dc-project.fr"
|
||||
authHeader { call ->
|
||||
call.request.queryParameters.get("token")?.let {
|
||||
HttpAuthHeader.Single("Bearer", it)
|
||||
}
|
||||
}
|
||||
validate {
|
||||
it.payload.getClaim("id").asString()?.let { id ->
|
||||
get<UserRepository>().findById(UUID.fromString(id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
install(AutoHeadResponse)
|
||||
|
||||
install(ContentNegotiation) {
|
||||
jackson {
|
||||
propertyNamingStrategy = PropertyNamingStrategy.SNAKE_CASE
|
||||
|
||||
registerModule(JodaModule())
|
||||
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||
setDefaultPrettyPrinter(DefaultPrettyPrinter().apply {
|
||||
indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
|
||||
indentObjectsWith(DefaultIndenter(" ", "\n"))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
install(Routing) {
|
||||
// trace { application.log.trace(it.buildText()) }
|
||||
authenticate(optional = true) {
|
||||
article(get(), get())
|
||||
auth(get(), get(), get())
|
||||
citizen(get(), get())
|
||||
constitution(get())
|
||||
followArticle(get())
|
||||
followConstitution(get())
|
||||
comment(get())
|
||||
commentArticle(get())
|
||||
commentConstitution(get())
|
||||
voteArticle(get(), get(), get())
|
||||
voteConstitution(get())
|
||||
opinionArticle(get())
|
||||
opinionChoice(get())
|
||||
workgroup(get())
|
||||
definition()
|
||||
}
|
||||
|
||||
authenticate("url") {
|
||||
notificationArticle(get(), get(named("ws")))
|
||||
}
|
||||
}
|
||||
|
||||
install(StatusPages) {
|
||||
// TODO move to postgresJson lib
|
||||
exception<CompletionException> { e ->
|
||||
val parent = e.cause?.cause
|
||||
if (parent is GenericDatabaseException) {
|
||||
call.respond(HttpStatusCode.BadRequest, parent.errorMessage.message!!)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
exception<NotFoundException> { e ->
|
||||
call.respond(HttpStatusCode.NotFound, e.message!!)
|
||||
}
|
||||
exception<ForbiddenException> {
|
||||
call.respond(HttpStatusCode.Forbidden)
|
||||
}
|
||||
}
|
||||
|
||||
install(CORS) {
|
||||
method(HttpMethod.Options)
|
||||
method(HttpMethod.Put)
|
||||
method(HttpMethod.Delete)
|
||||
header(HttpHeaders.Authorization)
|
||||
anyHost()
|
||||
// host("localhost:4200", schemes = listOf("http", "https"))
|
||||
allowCredentials = true
|
||||
allowSameOrigin = true
|
||||
maxAge = Duration.ofDays(1)
|
||||
}
|
||||
|
||||
if (env == PROD) {
|
||||
get<Migrations>().run()
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package fr.dcproject
|
||||
|
||||
import fr.dcproject.entity.User
|
||||
import fr.dcproject.entity.UserI
|
||||
import fr.ktorVoter.ForbiddenException
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.auth.authentication
|
||||
import io.ktor.util.AttributeKey
|
||||
import io.ktor.util.pipeline.PipelineContext
|
||||
import org.koin.core.context.GlobalContext
|
||||
import fr.dcproject.entity.Citizen as CitizenEntity
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
|
||||
private val citizenAttributeKey = AttributeKey<CitizenEntity>("CitizenContext")
|
||||
|
||||
val ApplicationCall.citizen: CitizenEntity
|
||||
get() = attributes.computeIfAbsent(citizenAttributeKey) {
|
||||
val user = authentication.principal<UserI>() ?: throw ForbiddenException()
|
||||
GlobalContext.get().koin.get<CitizenRepository>().findByUser(user)
|
||||
?: throw ForbiddenException("Citizen not found for this user id \"${user.id}\"")
|
||||
}
|
||||
|
||||
val ApplicationCall.citizenOrNull: CitizenEntity?
|
||||
get() = authentication.principal<UserI>()?.let {
|
||||
GlobalContext.get().koin.get<CitizenRepository>().findByUser(it)
|
||||
}
|
||||
|
||||
val PipelineContext<Unit, ApplicationCall>.citizen get() = context.citizen
|
||||
val PipelineContext<Unit, ApplicationCall>.citizenOrNull get() = context.citizenOrNull
|
||||
|
||||
val ApplicationCall.user get() = authentication.principal<User>()
|
||||
@@ -1,62 +0,0 @@
|
||||
package fr.dcproject
|
||||
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.JWTVerifier
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import fr.dcproject.entity.UserI
|
||||
import java.util.*
|
||||
import java.net.URI
|
||||
|
||||
object Config {
|
||||
private var config = ConfigFactory.load()
|
||||
|
||||
object Sql {
|
||||
val migrationFiles: URI = this::class.java.getResource("/sql/migrations").toURI()
|
||||
val functionFiles: URI = this::class.java.getResource("/sql/functions").toURI()
|
||||
val fixtureFiles: URI = this::class.java.getResource("/sql/fixtures").toURI()
|
||||
}
|
||||
|
||||
val envName: String = config.getString("app.envName")
|
||||
val domain: String = config.getString("app.domain")
|
||||
|
||||
val host: String = config.getString("db.host")
|
||||
var database: String = config.getString("db.database")
|
||||
var username: String = config.getString("db.username")
|
||||
var password: String = config.getString("db.password")
|
||||
val port: Int = config.getInt("db.port")
|
||||
val redis: String = config.getString("redis.connection")
|
||||
val elasticsearch: String = config.getString("elasticsearch.connection")
|
||||
val rabbitmq: String = config.getString("rabbitmq.connection")
|
||||
val exchangeNotificationName = "notification"
|
||||
val sendGridKey: String = config.getString("mail.sendGrid.key")
|
||||
}
|
||||
|
||||
object JwtConfig {
|
||||
private const val secret = "zAP5MBA4B4Ijz0MZaS48"
|
||||
const val issuer = "dc-project.fr"
|
||||
private const val validityInMs = 3_600_000 * 10 // 10 hours
|
||||
|
||||
// TODO change to RSA512
|
||||
val algorithm = Algorithm.HMAC512(secret)
|
||||
|
||||
val verifier: JWTVerifier = JWT
|
||||
.require(algorithm)
|
||||
.withIssuer(issuer)
|
||||
.build()
|
||||
|
||||
/**
|
||||
* Produce a token for this combination of User and Account
|
||||
*/
|
||||
fun makeToken(user: UserI): String = JWT.create()
|
||||
.withSubject("Authentication")
|
||||
.withIssuer(issuer)
|
||||
.withClaim("id", user.id.toString())
|
||||
.withExpiresAt(getExpiration())
|
||||
.sign(algorithm)
|
||||
|
||||
/**
|
||||
* Calculate the expiration Date based on current time + the given validity
|
||||
*/
|
||||
private fun getExpiration() = Date(System.currentTimeMillis() + validityInMs)
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
package fr.dcproject
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.rabbitmq.client.ConnectionFactory
|
||||
import fr.dcproject.event.publisher.Publisher
|
||||
import fr.dcproject.messages.Mailer
|
||||
import fr.dcproject.messages.NotificationEmailSender
|
||||
import fr.dcproject.messages.SsoManager
|
||||
import fr.dcproject.views.ArticleViewManager
|
||||
import fr.postgresjson.connexion.Connection
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.features.websocket.WebSockets
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import io.lettuce.core.RedisClient
|
||||
import io.lettuce.core.api.async.RedisAsyncCommands
|
||||
import org.apache.http.HttpHost
|
||||
import org.elasticsearch.client.RestClient
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
import fr.dcproject.repository.Article as ArticleRepository
|
||||
import fr.dcproject.repository.Citizen as CitizenRepository
|
||||
import fr.dcproject.repository.CommentArticle as CommentArticleRepository
|
||||
import fr.dcproject.repository.CommentConstitution as CommentConstitutionRepository
|
||||
import fr.dcproject.repository.CommentGeneric as CommentGenericRepository
|
||||
import fr.dcproject.repository.Constitution as ConstitutionRepository
|
||||
import fr.dcproject.repository.FollowArticle as FollowArticleRepository
|
||||
import fr.dcproject.repository.FollowConstitution as FollowConstitutionRepository
|
||||
import fr.dcproject.repository.OpinionArticle as OpinionArticleRepository
|
||||
import fr.dcproject.repository.OpinionChoice as OpinionChoiceRepository
|
||||
import fr.dcproject.repository.User as UserRepository
|
||||
import fr.dcproject.repository.VoteArticle as VoteArticleRepository
|
||||
import fr.dcproject.repository.VoteComment as VoteCommentRepository
|
||||
import fr.dcproject.repository.VoteConstitution as VoteConstitutionRepository
|
||||
import fr.dcproject.repository.Workgroup as WorkgroupRepository
|
||||
|
||||
@KtorExperimentalAPI
|
||||
val Module = module {
|
||||
|
||||
single { Config }
|
||||
|
||||
// SQL connection
|
||||
single {
|
||||
Connection(
|
||||
host = Config.host,
|
||||
port = Config.port,
|
||||
database = Config.database,
|
||||
username = Config.username,
|
||||
password = Config.password
|
||||
)
|
||||
}
|
||||
|
||||
// Launch Database migration
|
||||
single { Migrations(get(), Config.Sql.migrationFiles, Config.Sql.functionFiles) }
|
||||
|
||||
// Redis client
|
||||
single<RedisAsyncCommands<String, String>> {
|
||||
RedisClient.create(Config.redis).connect()?.async() ?: error("Unable to connect to redis")
|
||||
}
|
||||
|
||||
// RabbitMQ
|
||||
single<ConnectionFactory> {
|
||||
ConnectionFactory().apply { setUri(Config.rabbitmq) }
|
||||
}
|
||||
|
||||
// JsonSerializer
|
||||
single<ObjectMapper> {
|
||||
jacksonObjectMapper().apply {
|
||||
registerModule(SimpleModule())
|
||||
propertyNamingStrategy = PropertyNamingStrategy.SNAKE_CASE
|
||||
|
||||
registerModule(JodaModule())
|
||||
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Client HTTP for WebSockets
|
||||
single(named("ws")) {
|
||||
HttpClient {
|
||||
install(WebSockets)
|
||||
}
|
||||
}
|
||||
|
||||
// SQL Requester (postgresJson)
|
||||
single {
|
||||
Requester.RequesterFactory(
|
||||
connection = get(),
|
||||
functionsDirectory = Config.Sql.functionFiles
|
||||
).createRequester()
|
||||
}
|
||||
|
||||
// Repositories
|
||||
single { UserRepository(get()) }
|
||||
single { ArticleRepository(get()) }
|
||||
single { CitizenRepository(get()) }
|
||||
single { ConstitutionRepository(get()) }
|
||||
single { FollowArticleRepository(get()) }
|
||||
single { FollowConstitutionRepository(get()) }
|
||||
single { CommentGenericRepository(get()) }
|
||||
single { CommentArticleRepository(get()) }
|
||||
single { CommentConstitutionRepository(get()) }
|
||||
single { VoteArticleRepository(get()) }
|
||||
single { VoteConstitutionRepository(get()) }
|
||||
single { VoteCommentRepository(get()) }
|
||||
single { OpinionChoiceRepository(get()) }
|
||||
single { OpinionArticleRepository(get()) }
|
||||
single { WorkgroupRepository(get()) }
|
||||
|
||||
// Elasticsearch Client
|
||||
single<RestClient> {
|
||||
RestClient.builder(
|
||||
HttpHost.create(Config.elasticsearch)
|
||||
).build()
|
||||
}
|
||||
|
||||
single { ArticleViewManager(get()) }
|
||||
|
||||
// Mailler
|
||||
single { Mailer(Config.sendGridKey) }
|
||||
|
||||
// SSO Manager for connection
|
||||
single { SsoManager(get<Mailer>(), Config.domain, get()) }
|
||||
|
||||
single { Publisher(get(), get()) }
|
||||
|
||||
single { NotificationEmailSender(get<Mailer>(), Config.domain, get(), get()) }
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
import fr.postgresjson.entity.mutable.EntityVersioning
|
||||
import fr.postgresjson.entity.mutable.UuidEntityVersioning
|
||||
import java.util.*
|
||||
|
||||
class Article(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
title: String,
|
||||
override var anonymous: Boolean = true,
|
||||
override var content: String,
|
||||
override var description: String,
|
||||
override var tags: List<String> = emptyList(),
|
||||
draft: Boolean = false,
|
||||
override var lastVersion: Boolean = false,
|
||||
override val createdBy: CitizenBasic
|
||||
) : ArticleFull,
|
||||
ArticleAuthI<CitizenBasicI>,
|
||||
ArticleSimple(id, title, createdBy, draft),
|
||||
Viewable by ViewableImp() {
|
||||
init {
|
||||
tags = tags.distinct()
|
||||
}
|
||||
}
|
||||
|
||||
open class ArticleSimple(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override var title: String,
|
||||
override val createdBy: CitizenBasic,
|
||||
override var draft: Boolean = false
|
||||
) : ArticleSimpleI,
|
||||
ArticleAuthI<CitizenBasicI>,
|
||||
ArticleRefVersioning(id),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityCreatedBy<CitizenBasicI> by EntityCreatedByImp(createdBy),
|
||||
EntityDeletedAt by EntityDeletedAtImp(),
|
||||
Votable by VotableImp(),
|
||||
Opinionable by OpinionableImp()
|
||||
|
||||
open class ArticleRefVersioning(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
versionNumber: Int? = null,
|
||||
versionId: UUID = UUID.randomUUID()
|
||||
) : ArticleRef(id),
|
||||
EntityVersioning<UUID, Int> by UuidEntityVersioning(versionNumber, versionId)
|
||||
|
||||
open class ArticleRef(
|
||||
id: UUID = UUID.randomUUID()
|
||||
) : ArticleI, TargetRef(id)
|
||||
|
||||
interface ArticleI : UuidEntityI, TargetI
|
||||
|
||||
interface ArticleSimpleI :
|
||||
ArticleI,
|
||||
EntityVersioning<UUID, Int>,
|
||||
EntityCreatedBy<CitizenBasicI>,
|
||||
EntityCreatedAt,
|
||||
EntityDeletedAt,
|
||||
Votable {
|
||||
var title: String
|
||||
}
|
||||
|
||||
interface ArticleBasicI :
|
||||
ArticleSimpleI {
|
||||
var anonymous: Boolean
|
||||
var content: String
|
||||
var description: String
|
||||
var tags: List<String>
|
||||
}
|
||||
|
||||
interface ArticleFull :
|
||||
ArticleBasicI {
|
||||
var draft: Boolean
|
||||
var lastVersion: Boolean
|
||||
}
|
||||
|
||||
interface ArticleAuthI<U : CitizenWithUserI> :
|
||||
ArticleI,
|
||||
EntityCreatedBy<U>,
|
||||
EntityDeletedAt {
|
||||
var draft: Boolean
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.dcproject.entity.CitizenI.Name
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedAt
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedAtImp
|
||||
import fr.postgresjson.entity.immutable.UuidEntity
|
||||
import fr.postgresjson.entity.immutable.UuidEntityI
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
import org.joda.time.DateTime
|
||||
import java.util.*
|
||||
|
||||
class Citizen(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
name: Name,
|
||||
email: String,
|
||||
birthday: DateTime,
|
||||
voteAnonymous: Boolean = true,
|
||||
followAnonymous: Boolean = true,
|
||||
override val user: User
|
||||
) : CitizenFull,
|
||||
CitizenBasic(id, name, email, birthday, voteAnonymous, followAnonymous, user),
|
||||
EntityCreatedAt by EntityCreatedAtImp() {
|
||||
var workgroups: List<WorkgroupSimple<CitizenRef>> = emptyList()
|
||||
}
|
||||
|
||||
open class CitizenBasic(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
name: Name,
|
||||
override var email: String,
|
||||
override var birthday: DateTime,
|
||||
override var voteAnonymous: Boolean = true,
|
||||
override var followAnonymous: Boolean = true,
|
||||
override val user: User
|
||||
) : CitizenBasicI,
|
||||
CitizenSimple(id, name, user)
|
||||
|
||||
open class CitizenSimple(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
var name: Name,
|
||||
user: UserRef
|
||||
) : CitizenRefWithUser(id, user)
|
||||
|
||||
open class CitizenRefWithUser(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val user: UserRef
|
||||
) : CitizenWithUserI,
|
||||
CitizenRef(id),
|
||||
EntityDeletedAt by EntityDeletedAtImp()
|
||||
|
||||
open class CitizenRef(
|
||||
id: UUID = UUID.randomUUID()
|
||||
) : UuidEntity(id),
|
||||
CitizenI
|
||||
|
||||
interface CitizenI : UuidEntityI {
|
||||
data class Name(
|
||||
var firstName: String,
|
||||
var lastName: String,
|
||||
var civility: String? = null
|
||||
) {
|
||||
fun getFullName(): String = "${civility ?: ""} $firstName $lastName".trim()
|
||||
}
|
||||
}
|
||||
|
||||
interface CitizenBasicI : CitizenWithUserI, EntityDeletedAt {
|
||||
var name: Name
|
||||
var email: String
|
||||
var birthday: DateTime
|
||||
var voteAnonymous: Boolean
|
||||
var followAnonymous: Boolean
|
||||
}
|
||||
|
||||
interface CitizenFull : CitizenBasicI {
|
||||
override val user: User
|
||||
}
|
||||
|
||||
interface CitizenWithUserI : CitizenI {
|
||||
val user: UserI
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
import java.util.*
|
||||
|
||||
open class Comment<T : TargetI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: CitizenBasic,
|
||||
override var target: T,
|
||||
var content: String,
|
||||
val responses: List<Comment<T>>? = null,
|
||||
var parent: Comment<T>? = null,
|
||||
val parentsIds: List<UUID>? = null,
|
||||
val childrenCount: Int? = null
|
||||
) : ExtraI<T, CitizenBasicI>,
|
||||
CommentRef(id),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityCreatedBy<CitizenBasicI> by EntityCreatedByImp(createdBy),
|
||||
EntityUpdatedAt by EntityUpdatedAtImp(),
|
||||
EntityDeletedAt by EntityDeletedAtImp(),
|
||||
Votable by VotableImp(),
|
||||
TargetI {
|
||||
constructor(
|
||||
createdBy: CitizenBasic,
|
||||
parent: Comment<T>,
|
||||
content: String
|
||||
) : this(
|
||||
createdBy = createdBy,
|
||||
parent = parent,
|
||||
target = parent.target,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
open class CommentRef(id: UUID = UUID.randomUUID()) : CommentS(id)
|
||||
|
||||
sealed class CommentS(id: UUID) : TargetRef(id)
|
||||
@@ -1,69 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
import java.util.*
|
||||
|
||||
class Constitution(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
title: String,
|
||||
anonymous: Boolean = true,
|
||||
titles: MutableList<TitleSimple<ArticleSimple>> = mutableListOf(),
|
||||
draft: Boolean = false,
|
||||
lastVersion: Boolean = false,
|
||||
override val createdBy: CitizenSimple
|
||||
) : ConstitutionSimple<CitizenSimple, ConstitutionSimple.TitleSimple<ArticleSimple>>(
|
||||
id,
|
||||
title = title,
|
||||
anonymous = anonymous,
|
||||
titles = titles,
|
||||
draft = draft,
|
||||
lastVersion = lastVersion,
|
||||
createdBy = createdBy
|
||||
) {
|
||||
|
||||
class Title(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
name: String,
|
||||
rank: Int? = null,
|
||||
override val articles: MutableList<ArticleSimple> = mutableListOf()
|
||||
) : ConstitutionSimple.TitleSimple<ArticleSimple>(id, name, rank)
|
||||
}
|
||||
|
||||
open class ConstitutionSimple<Cr : CitizenRefWithUser, T : ConstitutionSimple.TitleSimple<*>>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
var title: String,
|
||||
var anonymous: Boolean = true,
|
||||
open var titles: MutableList<T> = mutableListOf(),
|
||||
var draft: Boolean = false,
|
||||
var lastVersion: Boolean = false,
|
||||
override val createdBy: Cr,
|
||||
versionId: UUID = UUID.randomUUID()
|
||||
) : ConstitutionRef(id),
|
||||
EntityVersioning<UUID, Int?> by UuidEntityVersioning(versionId = versionId),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityCreatedBy<Cr> by EntityCreatedByImp(createdBy),
|
||||
EntityDeletedAt by EntityDeletedAtImp() {
|
||||
|
||||
init {
|
||||
titles.forEachIndexed { index, title ->
|
||||
title.rank = index
|
||||
}
|
||||
}
|
||||
|
||||
open class TitleSimple<A : ArticleI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
var name: String,
|
||||
var rank: Int? = null,
|
||||
open val articles: MutableList<A> = mutableListOf()
|
||||
) : TitleRef(id)
|
||||
}
|
||||
|
||||
open class ConstitutionRef(id: UUID = UUID.randomUUID()) : ConstitutionS(id) {
|
||||
open class TitleRef(
|
||||
id: UUID = UUID.randomUUID()
|
||||
) : UuidEntity(id)
|
||||
}
|
||||
|
||||
sealed class ConstitutionS(id: UUID = UUID.randomUUID()) : TargetRef(id), TargetI
|
||||
@@ -1,20 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import java.util.*
|
||||
|
||||
class Follow<T : TargetI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: CitizenBasic,
|
||||
override var target: T
|
||||
) : ExtraI<T, CitizenBasicI>,
|
||||
FollowSimple<T, CitizenBasicI>(id, createdBy, target)
|
||||
|
||||
open class FollowSimple<T : TargetI, C : CitizenI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: C,
|
||||
override var target: T
|
||||
) : ExtraI<T, C>,
|
||||
UuidEntity(id),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityCreatedBy<C> by EntityCreatedByImp(createdBy)
|
||||
@@ -1,27 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedAt
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedAtImp
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedBy
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedByImp
|
||||
import java.util.*
|
||||
|
||||
open class Opinion<T : TargetI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: CitizenBasic,
|
||||
override val target: T,
|
||||
val choice: OpinionChoice
|
||||
) : ExtraI<T, CitizenBasicI>,
|
||||
TargetRef(id),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityCreatedBy<CitizenBasicI> by EntityCreatedByImp(createdBy) {
|
||||
|
||||
fun getName(): String = choice.name
|
||||
}
|
||||
|
||||
class OpinionArticle(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
createdBy: CitizenBasic,
|
||||
target: ArticleRef,
|
||||
choice: OpinionChoice
|
||||
) : Opinion<ArticleRef>(id, createdBy, target, choice)
|
||||
@@ -1,20 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedAt
|
||||
import fr.postgresjson.entity.immutable.EntityCreatedAtImp
|
||||
import fr.postgresjson.entity.immutable.UuidEntity
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
import java.util.*
|
||||
|
||||
class OpinionChoice(
|
||||
id: UUID? = null,
|
||||
val name: String,
|
||||
val target: List<String>?
|
||||
) : OpinionChoiceRef(id),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityDeletedAt by EntityDeletedAtImp()
|
||||
|
||||
open class OpinionChoiceRef(
|
||||
id: UUID?
|
||||
) : UuidEntity(id ?: UUID.randomUUID())
|
||||
@@ -1,15 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.EntityI
|
||||
|
||||
class OpinionAggregation(
|
||||
private val underlying: MutableMap<String, Any> = mutableMapOf()
|
||||
) : MutableMap<String, Any> by underlying, EntityI
|
||||
|
||||
interface Opinionable {
|
||||
var opinions: MutableMap<String, Int>
|
||||
}
|
||||
|
||||
class OpinionableImp : Opinionable {
|
||||
override var opinions: MutableMap<String, Int> = mutableMapOf()
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.dcproject.entity.UserI.Roles
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import io.ktor.auth.Principal
|
||||
import org.joda.time.DateTime
|
||||
import java.util.*
|
||||
|
||||
class User(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
username: String,
|
||||
blockedAt: DateTime? = null,
|
||||
override var plainPassword: String? = null,
|
||||
override var roles: List<Roles> = emptyList()
|
||||
) : UserFull, UserBasic(id, username, blockedAt),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityUpdatedAt by EntityUpdatedAtImp()
|
||||
|
||||
open class UserBasic(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override var username: String,
|
||||
override var blockedAt: DateTime? = null
|
||||
) : UserBasicI, UserRef(id)
|
||||
|
||||
open class UserRef(
|
||||
id: UUID = UUID.randomUUID()
|
||||
) : UserI, UuidEntity(id)
|
||||
|
||||
interface UserI : UuidEntityI, Principal {
|
||||
enum class Roles { ROLE_USER, ROLE_ADMIN }
|
||||
}
|
||||
|
||||
interface UserBasicI : UserI {
|
||||
var username: String
|
||||
var blockedAt: DateTime?
|
||||
}
|
||||
|
||||
interface UserFull : UserBasicI, EntityCreatedAt, EntityUpdatedAt {
|
||||
var plainPassword: String?
|
||||
var roles: List<Roles>
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.EntityI
|
||||
import fr.postgresjson.entity.immutable.EntityUpdatedAt
|
||||
import fr.postgresjson.entity.immutable.EntityUpdatedAtImp
|
||||
|
||||
open class ViewAggregation(
|
||||
val total: Int,
|
||||
val unique: Int
|
||||
) : EntityI,
|
||||
EntityUpdatedAt by EntityUpdatedAtImp() {
|
||||
constructor() : this(0, 0)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
interface Viewable {
|
||||
var views: ViewAggregation
|
||||
}
|
||||
|
||||
class ViewableImp : Viewable {
|
||||
override var views: ViewAggregation = ViewAggregation()
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
interface Votable {
|
||||
var votes: VoteAggregation
|
||||
}
|
||||
|
||||
class VotableImp : Votable {
|
||||
override var votes: VoteAggregation = VoteAggregation()
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import java.util.*
|
||||
|
||||
open class Vote<T : TargetI>(
|
||||
id: UUID = UUID.randomUUID(),
|
||||
override val createdBy: CitizenBasic,
|
||||
override var target: T,
|
||||
var note: Int,
|
||||
var anonymous: Boolean = true
|
||||
) : ExtraI<T, CitizenBasicI>,
|
||||
UuidEntity(id),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityCreatedBy<CitizenBasicI> by EntityCreatedByImp(createdBy),
|
||||
EntityUpdatedAt by EntityUpdatedAtImp() {
|
||||
init {
|
||||
if (note > 1 && note < -1) {
|
||||
error("note must be 1, 0 or -1")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.EntityI
|
||||
import fr.postgresjson.entity.mutable.EntityUpdatedAt
|
||||
import fr.postgresjson.entity.mutable.EntityUpdatedAtImp
|
||||
|
||||
open class VoteAggregation(
|
||||
val up: Int,
|
||||
val neutral: Int,
|
||||
val down: Int,
|
||||
val total: Int,
|
||||
val score: Int
|
||||
) : EntityI,
|
||||
EntityUpdatedAt by EntityUpdatedAtImp() {
|
||||
constructor() : this(0, 0, 0, 0, 0)
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package fr.dcproject.entity
|
||||
|
||||
import fr.postgresjson.entity.immutable.*
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAt
|
||||
import fr.postgresjson.entity.mutable.EntityDeletedAtImp
|
||||
import java.util.*
|
||||
|
||||
class Workgroup(
|
||||
id: UUID? = null,
|
||||
name: String,
|
||||
description: String,
|
||||
logo: String? = null,
|
||||
anonymous: Boolean = true,
|
||||
owner: CitizenBasic,
|
||||
createdBy: CitizenBasic,
|
||||
override var members: List<CitizenBasic> = emptyList()
|
||||
) : WorkgroupWithAuthI<CitizenBasic>,
|
||||
WorkgroupSimple<CitizenBasic>(
|
||||
id,
|
||||
name,
|
||||
description,
|
||||
logo,
|
||||
anonymous,
|
||||
owner,
|
||||
createdBy
|
||||
),
|
||||
EntityCreatedAt by EntityCreatedAtImp(),
|
||||
EntityUpdatedAt by EntityUpdatedAtImp()
|
||||
|
||||
open class WorkgroupSimple<Z : CitizenRef>(
|
||||
id: UUID? = null,
|
||||
var name: String,
|
||||
var description: String,
|
||||
var logo: String? = null,
|
||||
var anonymous: Boolean = true,
|
||||
var owner: Z,
|
||||
createdBy: Z
|
||||
) : WorkgroupRef(id),
|
||||
EntityCreatedBy<Z> by EntityCreatedByImp(createdBy),
|
||||
EntityDeletedAt by EntityDeletedAtImp()
|
||||
|
||||
open class WorkgroupRef(
|
||||
id: UUID? = null
|
||||
) : UuidEntity(id ?: UUID.randomUUID()), WorkgroupI
|
||||
|
||||
interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, EntityCreatedBy<Z>, EntityDeletedAt {
|
||||
val anonymous: Boolean
|
||||
val owner: Z
|
||||
|
||||
fun isMember(user: UserI): Boolean =
|
||||
members.map { it.user.id }.contains(user.id) || owner.user.id == user.id
|
||||
|
||||
fun isMember(citizen: CitizenWithUserI): Boolean =
|
||||
isMember(citizen.user)
|
||||
}
|
||||
|
||||
interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI {
|
||||
var members: List<Z>
|
||||
}
|
||||
|
||||
fun List<CitizenI>.asCitizen(citizen: CitizenI): Boolean = this.map { it.id }.contains(citizen.id)
|
||||
|
||||
interface WorkgroupI : UuidEntityI
|
||||
@@ -1,133 +0,0 @@
|
||||
package fr.dcproject.event
|
||||
|
||||
import com.rabbitmq.client.*
|
||||
import com.rabbitmq.client.BuiltinExchangeType.DIRECT
|
||||
import fr.dcproject.Config
|
||||
import fr.dcproject.entity.Article
|
||||
import fr.dcproject.entity.CitizenRef
|
||||
import fr.dcproject.entity.FollowSimple
|
||||
import fr.dcproject.entity.TargetRef
|
||||
import fr.dcproject.event.publisher.Publisher
|
||||
import fr.dcproject.messages.NotificationEmailSender
|
||||
import fr.dcproject.repository.Follow
|
||||
import fr.postgresjson.serializer.deserialize
|
||||
import io.ktor.application.ApplicationCall
|
||||
import io.ktor.application.EventDefinition
|
||||
import io.ktor.application.application
|
||||
import io.ktor.util.pipeline.PipelineContext
|
||||
import io.lettuce.core.api.async.RedisAsyncCommands
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.io.errors.IOException
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import fr.dcproject.repository.FollowArticle as FollowArticleRepository
|
||||
|
||||
class ArticleUpdate(
|
||||
target: Article
|
||||
) : EntityEvent(target, "article", "update") {
|
||||
companion object {
|
||||
val event = EventDefinition<ArticleUpdate>()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Event> PipelineContext<Unit, ApplicationCall>.raiseEvent(definition: EventDefinition<T>, value: T) =
|
||||
application.environment.monitor.raise(definition, value)
|
||||
|
||||
class EventNotification(
|
||||
private val config: EventSubscriber.Configuration,
|
||||
private val rabbitFactory: ConnectionFactory,
|
||||
private val redis: RedisAsyncCommands<String, String>,
|
||||
private val followRepo: FollowArticleRepository,
|
||||
private val publisher: Publisher,
|
||||
private val notificationEmailSender: NotificationEmailSender
|
||||
) {
|
||||
private val logger: Logger = LoggerFactory.getLogger(Publisher::class.qualifiedName)
|
||||
|
||||
fun config() {
|
||||
/* Config Rabbit */
|
||||
val exchangeName = Config.exchangeNotificationName
|
||||
rabbitFactory.newConnection().use { connection ->
|
||||
connection.createChannel().use { channel ->
|
||||
channel.queueDeclare("push", true, false, false, null)
|
||||
channel.queueDeclare("email", true, false, false, null)
|
||||
channel.exchangeDeclare(exchangeName, DIRECT, true)
|
||||
channel.queueBind("push", exchangeName, "")
|
||||
channel.queueBind("email", exchangeName, "")
|
||||
}
|
||||
}
|
||||
|
||||
/* Declare publisher on event */
|
||||
config.subscribe(ArticleUpdate.event) {
|
||||
publisher.publish(it)
|
||||
}
|
||||
|
||||
/* Launch Consumer */
|
||||
GlobalScope.launch {
|
||||
val rabbitChannel = rabbitFactory.newConnection().createChannel()
|
||||
|
||||
val consumerPush: Consumer = object : DefaultConsumer(rabbitChannel) {
|
||||
@Throws(IOException::class)
|
||||
override fun handleDelivery(
|
||||
consumerTag: String,
|
||||
envelope: Envelope,
|
||||
properties: AMQP.BasicProperties,
|
||||
body: ByteArray
|
||||
) = runBlocking {
|
||||
decodeEvent(body) {
|
||||
redis.zadd(
|
||||
"notification:${follow.createdBy.id}",
|
||||
event.id,
|
||||
rawEvent
|
||||
)
|
||||
}
|
||||
|
||||
rabbitChannel.basicAck(envelope.deliveryTag, false)
|
||||
}
|
||||
}
|
||||
|
||||
val consumerEmail: Consumer = object : DefaultConsumer(rabbitChannel) {
|
||||
@Throws(IOException::class)
|
||||
override fun handleDelivery(
|
||||
consumerTag: String,
|
||||
envelope: Envelope,
|
||||
properties: AMQP.BasicProperties,
|
||||
body: ByteArray
|
||||
) {
|
||||
runBlocking {
|
||||
decodeEvent(body) {
|
||||
logger.debug("EmailSend to: ${follow.createdBy.id}")
|
||||
notificationEmailSender.sendEmail(follow)
|
||||
}
|
||||
}
|
||||
rabbitChannel.basicAck(envelope.deliveryTag, false)
|
||||
}
|
||||
}
|
||||
rabbitChannel.basicConsume("push", false, consumerPush) // The front consume the redis via Websocket
|
||||
rabbitChannel.basicConsume("email", false, consumerEmail)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun decodeEvent(body: ByteArray, action: suspend Msg.() -> Unit) {
|
||||
val rawEvent = body.toString(Charsets.UTF_8)
|
||||
val event = rawEvent.deserialize<EntityEvent>() ?: error("Unable to unserialise event message from rabbit")
|
||||
val repo = when (event.type) {
|
||||
"article" -> followRepo
|
||||
else -> error("event '${event.type}' not implemented")
|
||||
} as Follow<*, *>
|
||||
|
||||
repo
|
||||
.findFollowsByTarget(event.target)
|
||||
.collect {
|
||||
Msg(event, rawEvent, it).action()
|
||||
}
|
||||
}
|
||||
|
||||
private class Msg(
|
||||
val event: EntityEvent,
|
||||
val rawEvent: String,
|
||||
val follow: FollowSimple<out TargetRef, CitizenRef>
|
||||
)
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package fr.dcproject.event
|
||||
|
||||
import fr.postgresjson.entity.Serializable
|
||||
import fr.postgresjson.entity.immutable.UuidEntity
|
||||
import io.ktor.application.*
|
||||
import io.ktor.util.AttributeKey
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import kotlinx.coroutines.DisposableHandle
|
||||
import org.joda.time.DateTime
|
||||
import kotlin.random.Random.Default.nextInt
|
||||
|
||||
open class Event(
|
||||
val type: String,
|
||||
val createdAt: DateTime = DateTime.now()
|
||||
) : Serializable {
|
||||
val id: Double = randId(createdAt.millis)
|
||||
|
||||
private fun randId(time: Long): Double {
|
||||
return (time.toString() + nextInt(1000, 9999).toString()).toDouble()
|
||||
}
|
||||
}
|
||||
|
||||
open class EntityEvent(
|
||||
val target: UuidEntity,
|
||||
type: String,
|
||||
val action: String
|
||||
) : Event(type)
|
||||
|
||||
/**
|
||||
* Installation Class
|
||||
*/
|
||||
class EventSubscriber {
|
||||
class Configuration(private val monitor: ApplicationEvents) {
|
||||
private val subscribers = mutableListOf<DisposableHandle>()
|
||||
fun <T : Event> subscribe(definition: EventDefinition<T>, handler: EventHandler<T>): DisposableHandle {
|
||||
return monitor.subscribe(definition, handler).also {
|
||||
subscribers.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object Feature : ApplicationFeature<Application, Configuration, EventSubscriber> {
|
||||
override val key = AttributeKey<EventSubscriber>("EventSubscriber")
|
||||
|
||||
@KtorExperimentalAPI
|
||||
override fun install(
|
||||
pipeline: Application,
|
||||
configure: Configuration.() -> Unit
|
||||
): EventSubscriber {
|
||||
Configuration(pipeline.environment.monitor).apply(configure)
|
||||
return EventSubscriber()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package fr.dcproject.event.publisher
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.rabbitmq.client.ConnectionFactory
|
||||
import fr.dcproject.Config
|
||||
import fr.dcproject.event.EntityEvent
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class Publisher(
|
||||
private val mapper: ObjectMapper,
|
||||
private val factory: ConnectionFactory,
|
||||
private val logger: Logger = LoggerFactory.getLogger(Publisher::class.qualifiedName)
|
||||
) {
|
||||
fun <T : EntityEvent> publish(it: T): Job {
|
||||
return GlobalScope.launch {
|
||||
factory.newConnection().use { connection ->
|
||||
connection.createChannel().use { channel ->
|
||||
channel.basicPublish(Config.exchangeNotificationName, "", null, it.serialize().toByteArray())
|
||||
logger.debug("Publish message ${it.target.id}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun EntityEvent.serialize(): String {
|
||||
return mapper.writeValueAsString(this) ?: error("Unable tu serialize message")
|
||||
}
|
||||
}
|
||||
190
src/main/kotlin/fr/dcproject/application/Application.kt
Normal file
190
src/main/kotlin/fr/dcproject/application/Application.kt
Normal file
@@ -0,0 +1,190 @@
|
||||
package fr.dcproject.application
|
||||
|
||||
import com.fasterxml.jackson.core.util.DefaultIndenter
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule
|
||||
import fr.dcproject.application.Env.PROD
|
||||
import fr.dcproject.application.Env.TEST
|
||||
import fr.dcproject.application.http.statusPagesInstallation
|
||||
import fr.dcproject.common.utils.onApplicationStopped
|
||||
import fr.dcproject.component.article.articleKoinModule
|
||||
import fr.dcproject.component.article.routes.installArticleRoutes
|
||||
import fr.dcproject.component.auth.authKoinModule
|
||||
import fr.dcproject.component.auth.jwt.jwtInstallation
|
||||
import fr.dcproject.component.auth.routes.installAuthRoutes
|
||||
import fr.dcproject.component.citizen.citizenKoinModule
|
||||
import fr.dcproject.component.citizen.routes.installCitizenRoutes
|
||||
import fr.dcproject.component.comment.article.routes.installCommentArticleRoutes
|
||||
import fr.dcproject.component.comment.commentKoinModule
|
||||
import fr.dcproject.component.comment.constitution.routes.installCommentConstitutionRoutes
|
||||
import fr.dcproject.component.comment.generic.routes.installCommentRoutes
|
||||
import fr.dcproject.component.constitution.constitutionKoinModule
|
||||
import fr.dcproject.component.constitution.routes.installConstitutionRoutes
|
||||
import fr.dcproject.component.doc.routes.installDocRoutes
|
||||
import fr.dcproject.component.follow.followKoinModule
|
||||
import fr.dcproject.component.follow.routes.article.installFollowArticleRoutes
|
||||
import fr.dcproject.component.follow.routes.citizen.installFollowCitizenRoutes
|
||||
import fr.dcproject.component.follow.routes.constitution.installFollowConstitutionRoutes
|
||||
import fr.dcproject.component.notification.email.NotificationEmailConsumer
|
||||
import fr.dcproject.component.notification.push.NotificationPushConsumer
|
||||
import fr.dcproject.component.notification.routes.installNotificationsRoutes
|
||||
import fr.dcproject.component.opinion.opinionKoinModule
|
||||
import fr.dcproject.component.opinion.routes.installOpinionRoutes
|
||||
import fr.dcproject.component.views.viewKoinModule
|
||||
import fr.dcproject.component.vote.routes.installVoteRoutes
|
||||
import fr.dcproject.component.vote.voteKoinModule
|
||||
import fr.dcproject.component.workgroup.routes.installWorkgroupRoutes
|
||||
import fr.dcproject.component.workgroup.workgroupKoinModule
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.application.Application
|
||||
import io.ktor.application.install
|
||||
import io.ktor.auth.Authentication
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.engine.jetty.Jetty
|
||||
import io.ktor.features.AutoHeadResponse
|
||||
import io.ktor.features.CORS
|
||||
import io.ktor.features.CallLogging
|
||||
import io.ktor.features.ContentNegotiation
|
||||
import io.ktor.features.DataConversion
|
||||
import io.ktor.features.StatusPages
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpMethod
|
||||
import io.ktor.http.cio.websocket.pingPeriod
|
||||
import io.ktor.http.cio.websocket.timeout
|
||||
import io.ktor.jackson.jackson
|
||||
import io.ktor.locations.KtorExperimentalLocationsAPI
|
||||
import io.ktor.locations.Locations
|
||||
import io.ktor.routing.Routing
|
||||
import io.ktor.server.jetty.EngineMain
|
||||
import io.ktor.websocket.WebSockets
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import org.eclipse.jetty.util.log.Slf4jLog
|
||||
import org.koin.dsl.module
|
||||
import org.koin.ktor.ext.Koin
|
||||
import org.koin.ktor.ext.get
|
||||
import org.slf4j.event.Level
|
||||
import java.time.Duration
|
||||
|
||||
fun main(args: Array<String>): Unit = EngineMain.main(args)
|
||||
|
||||
enum class Env { PROD, TEST }
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@KtorExperimentalLocationsAPI
|
||||
@Suppress("unused") // Referenced in application.conf
|
||||
fun Application.module(env: Env = PROD) {
|
||||
install(Koin) {
|
||||
Slf4jLog()
|
||||
modules(
|
||||
listOf(
|
||||
if (env == TEST) module { single { Configuration("application-test.conf") } }
|
||||
else module { single { Configuration() } },
|
||||
KoinModule,
|
||||
articleKoinModule,
|
||||
authKoinModule,
|
||||
citizenKoinModule,
|
||||
commentKoinModule,
|
||||
constitutionKoinModule,
|
||||
followKoinModule,
|
||||
opinionKoinModule,
|
||||
viewKoinModule,
|
||||
voteKoinModule,
|
||||
workgroupKoinModule,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
install(CallLogging) {
|
||||
level = Level.INFO
|
||||
}
|
||||
|
||||
install(DataConversion, converters)
|
||||
|
||||
install(Locations)
|
||||
|
||||
HttpClient(Jetty) {
|
||||
engine {
|
||||
}
|
||||
}
|
||||
|
||||
install(WebSockets) {
|
||||
pingPeriod = Duration.ofSeconds(60) // Disabled (null) by default
|
||||
timeout = Duration.ofSeconds(15)
|
||||
maxFrameSize = Long.MAX_VALUE // Disabled (max value). The connection will be closed if surpassed this length.
|
||||
masking = false
|
||||
}
|
||||
|
||||
get<NotificationEmailConsumer>().run {
|
||||
start()
|
||||
onApplicationStopped { close() }
|
||||
}
|
||||
|
||||
get<NotificationPushConsumer>().run {
|
||||
start()
|
||||
onApplicationStopped { close() }
|
||||
}
|
||||
|
||||
install(Authentication, jwtInstallation(get(), get()))
|
||||
|
||||
install(AutoHeadResponse)
|
||||
|
||||
install(ContentNegotiation) {
|
||||
jackson {
|
||||
propertyNamingStrategy = PropertyNamingStrategies.LOWER_CAMEL_CASE
|
||||
|
||||
registerModule(JodaModule())
|
||||
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
|
||||
configure(SerializationFeature.INDENT_OUTPUT, true)
|
||||
setDefaultPrettyPrinter(
|
||||
DefaultPrettyPrinter().apply {
|
||||
indentArraysWith(DefaultPrettyPrinter.FixedSpaceIndenter.instance)
|
||||
indentObjectsWith(DefaultIndenter(" ", "\n"))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
install(Routing.Feature) {
|
||||
// trace { application.log.trace(it.buildText()) }
|
||||
installArticleRoutes()
|
||||
installAuthRoutes()
|
||||
installCitizenRoutes()
|
||||
installCommentArticleRoutes()
|
||||
installCommentRoutes()
|
||||
installFollowArticleRoutes()
|
||||
installFollowConstitutionRoutes()
|
||||
installFollowCitizenRoutes()
|
||||
installWorkgroupRoutes()
|
||||
installOpinionRoutes()
|
||||
installVoteRoutes()
|
||||
installConstitutionRoutes()
|
||||
installCommentConstitutionRoutes()
|
||||
installNotificationsRoutes()
|
||||
installDocRoutes()
|
||||
}
|
||||
|
||||
install(StatusPages, statusPagesInstallation())
|
||||
|
||||
install(CORS) {
|
||||
method(HttpMethod.Options)
|
||||
method(HttpMethod.Put)
|
||||
method(HttpMethod.Delete)
|
||||
header(HttpHeaders.Authorization)
|
||||
if (env == PROD) {
|
||||
host("localhost:4200", schemes = listOf("http", "https"))
|
||||
} else {
|
||||
anyHost()
|
||||
}
|
||||
allowCredentials = true
|
||||
allowSameOrigin = true
|
||||
maxAgeInSeconds = Duration.ofDays(1).seconds
|
||||
}
|
||||
|
||||
if (env == PROD) {
|
||||
get<Migrations>().run()
|
||||
}
|
||||
}
|
||||
57
src/main/kotlin/fr/dcproject/application/Configuration.kt
Normal file
57
src/main/kotlin/fr/dcproject/application/Configuration.kt
Normal file
@@ -0,0 +1,57 @@
|
||||
package fr.dcproject.application
|
||||
|
||||
import com.typesafe.config.Config
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import java.net.URI
|
||||
|
||||
class Configuration(val config: Config) {
|
||||
constructor(resourceBasename: String? = null) : this(if (resourceBasename == null) ConfigFactory.load() else ConfigFactory.load(resourceBasename))
|
||||
|
||||
interface Sql {
|
||||
val migrationFiles: URI
|
||||
val functionFiles: URI
|
||||
val fixtureFiles: URI
|
||||
}
|
||||
val sql
|
||||
get() = object : Sql {
|
||||
override val migrationFiles: URI = this::class.java.getResource("/sql/migrations")?.toURI() ?: error("No migrations found")
|
||||
override val functionFiles: URI = this::class.java.getResource("/sql/functions")?.toURI() ?: error("No sql function found")
|
||||
override val fixtureFiles: URI = this::class.java.getResource("/sql/fixtures")?.toURI() ?: error("No sql fixture found")
|
||||
}
|
||||
|
||||
interface Database {
|
||||
val host: String
|
||||
val port: Int
|
||||
var database: String
|
||||
var username: String
|
||||
var password: String
|
||||
}
|
||||
val database
|
||||
get() = object : Database {
|
||||
override val host: String = config.getString("db.host")
|
||||
override val port: Int = config.getInt("db.port")
|
||||
override var database: String = config.getString("db.database")
|
||||
override var username: String = config.getString("db.username")
|
||||
override var password: String = config.getString("db.password")
|
||||
}
|
||||
|
||||
val envName: String = config.getString("app.envName")
|
||||
val domain: String = config.getString("app.domain")
|
||||
|
||||
val redis: String = config.getString("redis.connection")
|
||||
val elasticsearch: String = config.getString("elasticsearch.connection")
|
||||
val rabbitmq: String = config.getString("rabbitmq.connection")
|
||||
val exchangeNotificationName = "notification"
|
||||
val sendGridKey: String = config.getString("mail.sendGrid.key")
|
||||
|
||||
interface Jwt {
|
||||
val secret: String
|
||||
val issuer: String
|
||||
val validityInMs: Int
|
||||
}
|
||||
val jwt = object : Jwt {
|
||||
override val secret = config.getString("jwt.secret")
|
||||
override val issuer = config.getString("jwt.issuer")
|
||||
override val validityInMs = config.getInt("jwt.validity")
|
||||
}
|
||||
}
|
||||
40
src/main/kotlin/fr/dcproject/application/Converters.kt
Normal file
40
src/main/kotlin/fr/dcproject/application/Converters.kt
Normal file
@@ -0,0 +1,40 @@
|
||||
package fr.dcproject.application
|
||||
|
||||
import fr.dcproject.application.http.BadRequestException
|
||||
import fr.dcproject.application.http.HttpErrorBadRequest
|
||||
import fr.dcproject.application.http.HttpErrorBadRequest.InvalidParam
|
||||
import io.ktor.features.DataConversion
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import java.util.UUID
|
||||
|
||||
private typealias ConverterDeclaration = DataConversion.Configuration.() -> Unit
|
||||
|
||||
val converters: ConverterDeclaration = {
|
||||
convert<UUID> {
|
||||
decode { values, _ ->
|
||||
try {
|
||||
values.singleOrNull()?.let { UUID.fromString(it) }
|
||||
} catch (e: Throwable) {
|
||||
throw BadRequestException(
|
||||
HttpErrorBadRequest(
|
||||
HttpStatusCode.BadRequest,
|
||||
invalidParams = listOf(
|
||||
InvalidParam(
|
||||
"ID",
|
||||
"must be UUID"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
encode { value ->
|
||||
when (value) {
|
||||
null -> listOf()
|
||||
is UUID -> listOf(value.toString())
|
||||
else -> throw InternalError("Cannot convert $value as UUID")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
127
src/main/kotlin/fr/dcproject/application/KoinModule.kt
Normal file
127
src/main/kotlin/fr/dcproject/application/KoinModule.kt
Normal file
@@ -0,0 +1,127 @@
|
||||
package fr.dcproject.application
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies
|
||||
import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.datatype.joda.JodaModule
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.rabbitmq.client.ConnectionFactory
|
||||
import fr.dcproject.common.email.Mailer
|
||||
import fr.dcproject.component.auth.jwt.JwtConfig
|
||||
import fr.dcproject.component.notification.NotificationPublisherAsync
|
||||
import fr.dcproject.component.notification.email.NotificationEmailConsumer
|
||||
import fr.dcproject.component.notification.email.NotificationEmailSender
|
||||
import fr.dcproject.component.notification.push.NotificationPushConsumer
|
||||
import fr.dcproject.component.notification.push.NotificationPushListener
|
||||
import fr.postgresjson.connexion.Connection
|
||||
import fr.postgresjson.connexion.Requester
|
||||
import fr.postgresjson.migration.Migrations
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.features.websocket.WebSockets
|
||||
import io.lettuce.core.RedisClient
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
|
||||
val KoinModule = module {
|
||||
// JWT
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
JwtConfig(
|
||||
config.jwt.secret,
|
||||
config.jwt.issuer,
|
||||
config.jwt.validityInMs,
|
||||
)
|
||||
}
|
||||
// JWT Verifier
|
||||
single {
|
||||
get<JwtConfig>().verifier
|
||||
}
|
||||
// SQL connection
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
Connection(
|
||||
host = config.database.host,
|
||||
port = config.database.port,
|
||||
database = config.database.database,
|
||||
username = config.database.username,
|
||||
password = config.database.password
|
||||
)
|
||||
}
|
||||
|
||||
// Launch Database migration
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
Migrations(get(), config.sql.migrationFiles, config.sql.functionFiles)
|
||||
}
|
||||
|
||||
// Redis client
|
||||
single<RedisClient> {
|
||||
val config: Configuration = get()
|
||||
RedisClient.create(config.redis).apply {
|
||||
connect().sync().configSet("notify-keyspace-events", "KEA")
|
||||
}
|
||||
}
|
||||
|
||||
single { NotificationPushListener.Builder(get()) }
|
||||
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
NotificationEmailConsumer(get(), get(), get(), get(), get(), config.exchangeNotificationName)
|
||||
}
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
NotificationPushConsumer(get(), get(), get(), get(), get(), config.exchangeNotificationName)
|
||||
}
|
||||
|
||||
// RabbitMQ
|
||||
single<ConnectionFactory> {
|
||||
val config: Configuration = get()
|
||||
ConnectionFactory().apply { setUri(config.rabbitmq) }
|
||||
}
|
||||
|
||||
// JsonSerializer
|
||||
single<ObjectMapper> {
|
||||
jacksonObjectMapper().apply {
|
||||
registerModule(SimpleModule())
|
||||
propertyNamingStrategy = PropertyNamingStrategies.LOWER_CAMEL_CASE
|
||||
|
||||
registerModule(JodaModule())
|
||||
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
|
||||
configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Client HTTP for WebSockets
|
||||
single(named("ws")) {
|
||||
HttpClient {
|
||||
install(WebSockets)
|
||||
}
|
||||
}
|
||||
|
||||
// SQL Requester (postgresJson)
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
Requester.RequesterFactory(
|
||||
connection = get(),
|
||||
functionsDirectory = config.sql.functionFiles
|
||||
).createRequester()
|
||||
}
|
||||
|
||||
// Mailer
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
Mailer(config.sendGridKey)
|
||||
}
|
||||
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
NotificationPublisherAsync(factory = get(), exchangeName = config.exchangeNotificationName)
|
||||
}
|
||||
|
||||
single {
|
||||
val config: Configuration = get()
|
||||
NotificationEmailSender(get<Mailer>(), config.domain, get(), get())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package fr.dcproject.application.http
|
||||
|
||||
import fr.dcproject.application.http.HttpErrorBadRequest.InvalidParam
|
||||
import io.konform.validation.ValidationResult
|
||||
import io.ktor.http.HttpStatusCode
|
||||
|
||||
class BadRequestException(val httpError: HttpErrorBadRequest) : Exception()
|
||||
|
||||
class HttpErrorBadRequest(
|
||||
statusCode: HttpStatusCode,
|
||||
val title: String = statusCode.description,
|
||||
val invalidParams: List<InvalidParam>,
|
||||
) {
|
||||
val statusCode: Int = statusCode.value
|
||||
data class InvalidParam(
|
||||
val name: String,
|
||||
val reason: String
|
||||
)
|
||||
}
|
||||
|
||||
fun ValidationResult<*>.toOutput() = HttpErrorBadRequest(
|
||||
HttpStatusCode.BadRequest,
|
||||
invalidParams = this.errors.map {
|
||||
InvalidParam(
|
||||
it.dataPath,
|
||||
it.message
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
fun ValidationResult<*>.badRequestIfNotValid() {
|
||||
if (errors.size > 0) {
|
||||
throw BadRequestException(toOutput())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package fr.dcproject.application.http
|
||||
|
||||
import com.github.jasync.sql.db.postgresql.exceptions.GenericDatabaseException
|
||||
import fr.dcproject.common.security.AccessDeniedException
|
||||
import fr.dcproject.component.auth.ForbiddenException
|
||||
import fr.dcproject.component.auth.user
|
||||
import io.ktor.application.call
|
||||
import io.ktor.features.NotFoundException
|
||||
import io.ktor.features.ParameterConversionException
|
||||
import io.ktor.features.StatusPages
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.response.respond
|
||||
import java.util.concurrent.CompletionException
|
||||
|
||||
class HttpError(
|
||||
statusCode: HttpStatusCode,
|
||||
cause: Throwable? = null,
|
||||
val title: String = cause?.message ?: statusCode.description,
|
||||
) {
|
||||
val statusCode: Int = statusCode.value
|
||||
}
|
||||
|
||||
fun statusPagesInstallation(): StatusPages.Configuration.() -> Unit = {
|
||||
exception<CompletionException> { e ->
|
||||
val parent = e.cause?.cause
|
||||
if (parent is GenericDatabaseException) {
|
||||
HttpError(
|
||||
HttpStatusCode.BadRequest,
|
||||
cause = parent
|
||||
).let {
|
||||
call.respond(HttpStatusCode.BadRequest, it)
|
||||
}
|
||||
} else {
|
||||
HttpError(
|
||||
HttpStatusCode.BadRequest,
|
||||
cause = e
|
||||
).let {
|
||||
call.respond(HttpStatusCode.InternalServerError, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
exception<NotFoundException> { e ->
|
||||
HttpError(
|
||||
HttpStatusCode.NotFound,
|
||||
cause = e
|
||||
).let {
|
||||
call.respond(HttpStatusCode.NotFound, it)
|
||||
}
|
||||
}
|
||||
exception<AccessDeniedException> { e ->
|
||||
if (call.user == null) {
|
||||
HttpError(
|
||||
HttpStatusCode.Unauthorized,
|
||||
cause = e
|
||||
).let {
|
||||
call.respond(HttpStatusCode.Unauthorized, it)
|
||||
}
|
||||
} else {
|
||||
HttpError(
|
||||
HttpStatusCode.Forbidden,
|
||||
cause = e
|
||||
).let {
|
||||
call.respond(HttpStatusCode.Forbidden, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
exception<ForbiddenException> { e ->
|
||||
HttpError(
|
||||
HttpStatusCode.Forbidden,
|
||||
cause = e
|
||||
).let {
|
||||
call.respond(HttpStatusCode.Forbidden, it)
|
||||
}
|
||||
}
|
||||
exception<BadRequestException> { e ->
|
||||
call.respond(HttpStatusCode.BadRequest, e.httpError)
|
||||
}
|
||||
exception<ParameterConversionException> { e ->
|
||||
val parent = e.cause
|
||||
if (parent is BadRequestException) {
|
||||
call.respond(HttpStatusCode.BadRequest, parent.httpError)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/main/kotlin/fr/dcproject/common/BitMaskEnum.kt
Normal file
11
src/main/kotlin/fr/dcproject/common/BitMaskEnum.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package fr.dcproject.common
|
||||
|
||||
interface BitMaskI {
|
||||
val bit: Long
|
||||
|
||||
infix operator fun contains(which: BitMaskI): Boolean = bit and which.bit == which.bit
|
||||
infix operator fun plus(mask: BitMaskI): BitMaskI = BitMask(mask.bit and this.bit)
|
||||
infix operator fun minus(mask: BitMaskI): BitMaskI = BitMask(this.bit - mask.bit)
|
||||
}
|
||||
|
||||
class BitMask(override val bit: Long) : BitMaskI
|
||||
@@ -1,4 +1,4 @@
|
||||
package fr.dcproject.messages
|
||||
package fr.dcproject.common.email
|
||||
|
||||
import com.sendgrid.Method
|
||||
import com.sendgrid.Request
|
||||
@@ -9,6 +9,9 @@ import java.io.IOException
|
||||
class Mailer(
|
||||
private val key: String
|
||||
) {
|
||||
/**
|
||||
* Send email via Sendgrid
|
||||
*/
|
||||
fun sendEmail(action: () -> Mail): Boolean {
|
||||
val mail = action()
|
||||
|
||||
@@ -24,4 +27,4 @@ class Mailer(
|
||||
throw ex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
28
src/main/kotlin/fr/dcproject/common/entity/Action.kt
Normal file
28
src/main/kotlin/fr/dcproject/common/entity/Action.kt
Normal file
@@ -0,0 +1,28 @@
|
||||
package fr.dcproject.common.entity
|
||||
|
||||
import fr.dcproject.component.citizen.database.CitizenI
|
||||
|
||||
interface Created<C : CitizenI> : CreatedAt, CreatedBy<C> {
|
||||
class Imp<C : CitizenI>(createdBy: C) :
|
||||
Created<C>,
|
||||
CreatedBy<C> by CreatedBy.Imp(createdBy),
|
||||
CreatedAt by CreatedAt.Imp()
|
||||
}
|
||||
|
||||
interface Updated<C : CitizenI> : UpdatedAt, UpdatedBy<C> {
|
||||
class Imp<C : CitizenI>(updatedAt: C) :
|
||||
Updated<C>,
|
||||
UpdatedBy<C> by UpdatedBy.Imp(updatedAt),
|
||||
UpdatedAt by UpdatedAt.Imp()
|
||||
}
|
||||
|
||||
interface Deleted<C : CitizenI> : DeletedAt, DeletedBy<C> {
|
||||
override fun isDeleted(): Boolean = (this as DeletedAt).isDeleted()
|
||||
|
||||
class Imp<C : CitizenI>(deletedAt: C) :
|
||||
Deleted<C>,
|
||||
DeletedBy<C> by DeletedBy.Imp(deletedAt),
|
||||
DeletedAt by DeletedAt.Imp() {
|
||||
override fun isDeleted(): Boolean = (this as Deleted<C>).isDeleted()
|
||||
}
|
||||
}
|
||||
25
src/main/kotlin/fr/dcproject/common/entity/ActionBy.kt
Normal file
25
src/main/kotlin/fr/dcproject/common/entity/ActionBy.kt
Normal file
@@ -0,0 +1,25 @@
|
||||
package fr.dcproject.common.entity
|
||||
|
||||
import fr.dcproject.component.citizen.database.CitizenI
|
||||
|
||||
interface CreatedBy<T : CitizenI> {
|
||||
val createdBy: T
|
||||
|
||||
class Imp<T : CitizenI>(override val createdBy: T) : CreatedBy<T>
|
||||
}
|
||||
|
||||
interface UpdatedBy<T : CitizenI> {
|
||||
val updatedBy: T
|
||||
|
||||
class Imp<T : CitizenI>(override val updatedBy: T) : UpdatedBy<T>
|
||||
}
|
||||
|
||||
interface DeletedBy<T : CitizenI> {
|
||||
val deletedBy: T?
|
||||
|
||||
fun isDeleted(): Boolean {
|
||||
return deletedBy?.let { true } ?: false
|
||||
}
|
||||
|
||||
class Imp<T : CitizenI>(override val deletedBy: T?) : DeletedBy<T>
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user