mirror of
https://github.com/pcvolkmer/mv64e-etl-processor
synced 2025-09-13 09:02:50 +00:00
Compare commits
17 Commits
v0.11.0-rc
...
gics-provi
Author | SHA1 | Date | |
---|---|---|---|
|
4bd6117ba8 | ||
|
ace5637ed8 | ||
|
88857cf201 | ||
|
db89d84353 | ||
3d9d84438d | |||
10b5bedac3 | |||
96f22a6744 | |||
6dfec5c341 | |||
c38c0c6197 | |||
4602032bcf | |||
9cc9f130df | |||
b92fbae2c5 | |||
5704282a1c | |||
ba21d029d1 | |||
b7aa187293 | |||
8402462c3b | |||
d3e6aa5821 |
@@ -268,7 +268,7 @@ zur Nutzung des MTB-File-Endpunkts eine HTTP-Basic-Authentifizierung voraussetze
|
|||||||

|

|
||||||
|
|
||||||
In diesem Fall kann der Endpunkt für das Onkostar-Plugin *
|
In diesem Fall kann der Endpunkt für das Onkostar-Plugin *
|
||||||
*[onkostar-plugin-dnpmexport](https://github.com/CCC-MF/onkostar-plugin-dnpmexport)** wie folgt
|
*[mv64e-onkostar-plugin-export](https://github.com/pcvolkmer/mv64e-onkostar-plugin-export)** wie folgt
|
||||||
konfiguriert werden:
|
konfiguriert werden:
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -427,9 +427,9 @@ Die PEM-Datei mit dem/den Root CA Zertifikat(en) muss dabei im vorbereiteten Ver
|
|||||||
#### Integration zur Laufzeit
|
#### Integration zur Laufzeit
|
||||||
|
|
||||||
Hier muss die Umgebungsvariable `SERVICE_BINDING_ROOT` z.B. auf den Wert `/bindings` gesetzt sein.
|
Hier muss die Umgebungsvariable `SERVICE_BINDING_ROOT` z.B. auf den Wert `/bindings` gesetzt sein.
|
||||||
Zudem muss ein Verzeichnis `bindings/ca-certificates` - analog zum Verzeichnis [
|
Zudem muss ein Verzeichnis `bindings/ca-certificates` - analog zum Verzeichnis
|
||||||
`bindings/ca-certificates`](bindings/ca-certificates) mit einer PEM-Datei als Docker-Volume
|
[`bindings/ca-certificates`](bindings/ca-certificates) mit einer PEM-Datei und der
|
||||||
eingebunden werden.
|
Datei [`bindings/ca-certificates/type`](bindings/ca-certificates/type) als Docker-Volume eingebunden werden.
|
||||||
|
|
||||||
Beispiel für Docker-Compose:
|
Beispiel für Docker-Compose:
|
||||||
|
|
||||||
|
@@ -5,24 +5,24 @@ import org.springframework.boot.gradle.tasks.bundling.BootBuildImage
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
war
|
war
|
||||||
id("org.springframework.boot") version "3.5.3"
|
id("org.springframework.boot") version "3.5.5"
|
||||||
id("io.spring.dependency-management") version "1.1.7"
|
id("io.spring.dependency-management") version "1.1.7"
|
||||||
kotlin("jvm") version "1.9.25"
|
kotlin("jvm") version "2.2.10"
|
||||||
kotlin("plugin.spring") version "1.9.25"
|
kotlin("plugin.spring") version "2.2.10"
|
||||||
jacoco
|
jacoco
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.dnpm"
|
group = "dev.dnpm"
|
||||||
version = "0.11.0-SNAPSHOT"
|
version = "0.12.0-SNAPSHOT"
|
||||||
|
|
||||||
var versions = mapOf(
|
var versions = mapOf(
|
||||||
"mtb-dto" to "0.1.0-SNAPSHOT",
|
"mtb-dto" to "0.1.0-SNAPSHOT",
|
||||||
"hapi-fhir" to "7.6.1",
|
"hapi-fhir" to "8.4.0",
|
||||||
"mockito-kotlin" to "5.4.0",
|
"mockito-kotlin" to "6.0.0",
|
||||||
"archunit" to "1.3.0",
|
"archunit" to "1.4.1",
|
||||||
// Webjars
|
// Webjars
|
||||||
"webjars-locator" to "0.52",
|
"webjars-locator" to "0.52",
|
||||||
"echarts" to "5.4.3",
|
"echarts" to "6.0.0",
|
||||||
"htmx.org" to "1.9.12"
|
"htmx.org" to "1.9.12"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -111,6 +111,8 @@ dependencies {
|
|||||||
integrationTestImplementation("com.tngtech.archunit:archunit:${versions["archunit"]}")
|
integrationTestImplementation("com.tngtech.archunit:archunit:${versions["archunit"]}")
|
||||||
integrationTestImplementation("org.htmlunit:htmlunit")
|
integrationTestImplementation("org.htmlunit:htmlunit")
|
||||||
integrationTestImplementation("org.springframework:spring-webflux")
|
integrationTestImplementation("org.springframework:spring-webflux")
|
||||||
|
// Fix for CVE-2024-25710
|
||||||
|
integrationTestImplementation("org.apache.commons:commons-compress:1.26.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<KotlinCompile> {
|
tasks.withType<KotlinCompile> {
|
||||||
|
125
dev-compose.yml
125
dev-compose.yml
@@ -1,26 +1,121 @@
|
|||||||
services:
|
services:
|
||||||
kafka:
|
kafka:
|
||||||
image: bitnami/kafka
|
image: apache/kafka
|
||||||
hostname: kafka
|
hostname: kafka
|
||||||
ports:
|
ports:
|
||||||
- "9092:9092"
|
- "9092:9092"
|
||||||
- "9094:9094"
|
- "9094:9094"
|
||||||
environment:
|
environment:
|
||||||
ALLOW_PLAINTEXT_LISTENER: "yes"
|
ALLOW_PLAINTEXT_LISTENER: "yes"
|
||||||
KAFKA_CFG_NODE_ID: "0"
|
KAFKA_NODE_ID: "0"
|
||||||
KAFKA_CFG_PROCESS_ROLES: "controller,broker"
|
KAFKA_KRAFT_CLUSTER_ID: "mv64e-etl-processor-dev"
|
||||||
KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
|
KAFKA_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
|
||||||
KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
|
KAFKA_PROCESS_ROLES: "controller,broker"
|
||||||
KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
||||||
KAFKA_CFG_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
||||||
KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: true
|
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1"
|
||||||
KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
|
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1"
|
||||||
KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: "1"
|
||||||
healthcheck:
|
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0"
|
||||||
test: kafka-topics --bootstrap-server kafka:9092 --list
|
KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
|
||||||
interval: 30s
|
# Without SSL
|
||||||
timeout: 10s
|
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
|
||||||
retries: 3
|
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
|
||||||
|
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
||||||
|
# Using SSL
|
||||||
|
# KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
|
||||||
|
# KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,EXTERNAL://localhost:9094
|
||||||
|
# KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,EXTERNAL:SSL,PLAINTEXT:PLAINTEXT
|
||||||
|
# KAFKA_SSL_KEYSTORE_TYPE: "PEM"
|
||||||
|
# KAFKA_SSL_KEYSTORE_CERTIFICATE_CHAIN: -----BEGIN CERTIFICATE-----
|
||||||
|
# MIIDCzCCAfOgAwIBAgIUaXNh4PahaKeLUaab2rUPSVESx28wDQYJKoZIhvcNAQEL
|
||||||
|
# BQAwFTETMBEGA1UEAwwKRXhhbXBsZSBDQTAeFw0yNTA4MjExODEyMTFaFw0zNTA4
|
||||||
|
# MTkxODEyMTFaMBUxEzARBgNVBAMMCkV4YW1wbGUgQ0EwggEiMA0GCSqGSIb3DQEB
|
||||||
|
# AQUAA4IBDwAwggEKAoIBAQCsqalqVOLFglVbX9oSHU91ebyL1kPyb/2N90UGQIcD
|
||||||
|
# UAjzKxxysId1Vdvtbbwgli6UgfPwlzFP2Wlw51h496yL4QU/9tNV956UJ1RoS/fG
|
||||||
|
# qBAEHctqavfMI27UQmIzw4pGMkGzEQxRMc6a9pdabBhbMMTJsjtmOv2YMYHj1HHK
|
||||||
|
# Dr7wTBTt2l0eRyCR0kZ8XGIMWhYowPa4EMpC7+4e5Nf/7LSJZWLLy9jXPpazsjkJ
|
||||||
|
# jEmDNlFfx2tZiq0Wz2Xj1pZSDLbcuIX4IHcLfMvagibfrCMX/h6+WuW42sWPRuBW
|
||||||
|
# wB6cHGlXs+K/gBBWxtD7sOTacO5hbHFsfaJOhSEIGoIpAgMBAAGjUzBRMB0GA1Ud
|
||||||
|
# DgQWBBT2S/C2++ECY+CSuN5KKql0umfbTDAfBgNVHSMEGDAWgBT2S/C2++ECY+CS
|
||||||
|
# uN5KKql0umfbTDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj
|
||||||
|
# H4DdwqrOHg7sVsqiwDsZfTharpUDCYeG5XhrJQlnA9eKwyofTb929W/fjOwBdDtg
|
||||||
|
# 9THT/omR0lA8/UyHtezMT6nMsCn4HG2mXvx6ghgvA3jrFTEY7R80dHkboLMTV3u4
|
||||||
|
# RYgC9S3BJPcbJYpM0cXzkp2T0F4FxWZlfqefuedHuX3zcCxpgVD56qQb2a131TX7
|
||||||
|
# O3UDJfVg8a65IFtehndqILgLVrf7w6+pbmDAlCg5RKrt2USEYyZXYdyTryJbdtn4
|
||||||
|
# BCLp0avYtSYVUGwgH0oUCpkjQRwMg1003TTz8SNnmE7mAXHYljyYejnjL8vBHfch
|
||||||
|
# 8tTDVXQn08BT9H3jZTnF
|
||||||
|
# -----END CERTIFICATE-----
|
||||||
|
# -----BEGIN CERTIFICATE-----
|
||||||
|
# MIIC+TCCAeGgAwIBAgIUUoCwz8GS6xQ3mmI7RUUYSNPIOi4wDQYJKoZIhvcNAQEL
|
||||||
|
# BQAwFTETMBEGA1UEAwwKRXhhbXBsZSBDQTAeFw0yNTA4MjExODE0NDhaFw0zNTA4
|
||||||
|
# MTkxODE0NDhaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB
|
||||||
|
# BQADggEPADCCAQoCggEBAL9PW99MhhBwdEmTHyZgfnhfTrxZPrNU6z1UdV8b82Lk
|
||||||
|
# 3p75o8eCKa9iOd7DDQlo75hQBhhX0+Xc3mucrstx5p8TYFMbypif8ojWh3LM++P8
|
||||||
|
# tz3ezQZlq86ycyKpm8dqlA03b227tFDfiYTev2eD2HN40BU7yDAYhhqd/QW8+MV2
|
||||||
|
# jkcRGv5cE21GZxWmPUpkVN+bNoBC8H90WmkST90LfeYF+wZnlsAJZH6AQzR1GnGD
|
||||||
|
# ICE5evMhC78hvRnpgeA310SyxssZEigkePL5lTZOBPY2IuzBqL05agyVTiVq4Xd6
|
||||||
|
# y3xOqXoxxOhZu06yd3nymorqeTgbF1fW8wQF0u3KsFECAwEAAaNCMEAwHQYDVR0O
|
||||||
|
# BBYEFHk9jMWRAAt2YsBSxUcOQVoWayoHMB8GA1UdIwQYMBaAFPZL8Lb74QJj4JK4
|
||||||
|
# 3koqqXS6Z9tMMA0GCSqGSIb3DQEBCwUAA4IBAQBqabAA9INONDaLHqs9i9YQHm/g
|
||||||
|
# AnB7xRl/RFbERKKCTSMZUYM8oEaaH0W2ENoPMc/7xOB/R8a7Rm62PTr6syxwhZrY
|
||||||
|
# 5NtGKJOD+rh90/5l83tulf93KqOJtGkiv6NBDvCNrITcA+UKRk/z4GcFi2YjWAl4
|
||||||
|
# wvY44lzTasMKSpjUQ5N0VNANcW3nVuEgPQ8rrr0NOK/5j4guPjsXDsixa47gqblA
|
||||||
|
# 5xGfBKeVmEXdPbzawZfP4hPIw7DpX2m8Y0erswF1ZxkIV73V3TDsFSLcqSKSzZr6
|
||||||
|
# mtj8COlV9Us7zqaJbV5eOl7GN1T9orZJwZmX1Z46gCkkSLYDP/dqtl2j9JgN
|
||||||
|
# -----END CERTIFICATE-----
|
||||||
|
# KAFKA_SSL_KEYSTORE_KEY: -----BEGIN PRIVATE KEY-----
|
||||||
|
# MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/T1vfTIYQcHRJ
|
||||||
|
# kx8mYH54X068WT6zVOs9VHVfG/Ni5N6e+aPHgimvYjneww0JaO+YUAYYV9Pl3N5r
|
||||||
|
# nK7LceafE2BTG8qYn/KI1odyzPvj/Lc93s0GZavOsnMiqZvHapQNN29tu7RQ34mE
|
||||||
|
# 3r9ng9hzeNAVO8gwGIYanf0FvPjFdo5HERr+XBNtRmcVpj1KZFTfmzaAQvB/dFpp
|
||||||
|
# Ek/dC33mBfsGZ5bACWR+gEM0dRpxgyAhOXrzIQu/Ib0Z6YHgN9dEssbLGRIoJHjy
|
||||||
|
# +ZU2TgT2NiLswai9OWoMlU4lauF3est8Tql6McToWbtOsnd58pqK6nk4GxdX1vME
|
||||||
|
# BdLtyrBRAgMBAAECggEAC1wXfPlqxoQe65WAVoOJTvV90+JKvlRPCZu/wm+C8r7b
|
||||||
|
# Vz5Ekt6wQflHrWoQlpv0CivKSNzCONZ2IJazrGHti0mXwSeXzptEyApRDaiNVnrV
|
||||||
|
# mKdnrjcQThw7iPXgSaWS9/vwMmhgayLy5ABkBi4GhsjINlKP7wctw1vZP+N6NCNd
|
||||||
|
# Ql3taStvDKmG0SfJHF6/2o/XBpof3IJEL7ghbzyTTbWWaO34J1mJ8A+AmjGhj9GE
|
||||||
|
# Dp3XuOrO9W7MVd1nfZDtGBS8qf80AwROyodZZRma9vZuWJZ5aQFi2CnUEtU1T+Uv
|
||||||
|
# tW+F6tg2FOMr8M0Fb79wGIDwSF8u/QcTvwhEzZAfiQKBgQDioOofnE1oB1DOMnqZ
|
||||||
|
# SOFjs+vsirvS6G3lo27+HkE3TgvCHR4sk1305AiXtjmPu8iaUCo9qn18MtduY2RS
|
||||||
|
# CcKMOG/FxhmDyP5I29DhJRhvERIpJd0kcSDQOgtaoVPC1XzIlyTqte6nGX9kAnA/
|
||||||
|
# x/OOXrZ0hjhMNDcZzf2NasPYJQKBgQDYGqTobkVBk+eekNWklnTh41/649rUIgTu
|
||||||
|
# JStArtY2hgaEInYcGa2e7cEj7nIHA0iGy3EJ2yvwoUIyxtoXVcGohu2IrzlhS33T
|
||||||
|
# R4jA7nE2/yHZrEMEJovuSU0eMw7rgvEtL79Q0RToYnTY1EU6X/BBoFfiiEeNMHKz
|
||||||
|
# zjDOOQ6ZvQKBgGCWChIc0FSkwYiPtPZ9PCn89XCjk/cIPkYfiF9fT5Ydeh9pv4Fp
|
||||||
|
# 8SI8yXi3HgMnGhDCV65eagqztGMEky3voO2X4/MbQaaL0+wDWxuJbsdvNBk7XOt6
|
||||||
|
# F20HP+2JUiR4Ti1DVWV+0k5/LG7YJzTXp/KmZQZ2aan4mv8xbn2F4h/NAoGAI4ou
|
||||||
|
# OLN53FEQtHkpSYoc6tFUBZTXdi+qE+g09sxKGmlsROrN9c0bSpnbO6eJRTH7CYAH
|
||||||
|
# tRFAZrB+jI87ar8FvEuEYQhALYoWxVpsWR5drCfFT2EPHG2icavIbQEEoSLFuyKx
|
||||||
|
# Gf9oqtcWVFqEkBcbEg/mpDC5Y7TmCEAOsrubdRkCgYEAl7B+EzIdG0rabGoti09q
|
||||||
|
# QXfyiTjR7nQYkhpLxMCeNlCpQ8Y15XSa8bm1UIGYqj/ZBpeBNhrj64IHoub5Vd43
|
||||||
|
# tzbb8yNgoLUd16TU1VvyccCMGQVPIF8RkDsAtEawV2eoXbHAstN99xbC8jsLNZRQ
|
||||||
|
# fcfgTiQaXRJmlVx6jfbfZd4=
|
||||||
|
# -----END PRIVATE KEY-----
|
||||||
|
# #KAFKA_SSL_KEYSTORE_CREDENTIALS: example
|
||||||
|
# KAFKA_SSL_KEY_CREDENTIALS: example
|
||||||
|
# KAFKA_SSL_TRUSTSTORE_TYPE: "PEM"
|
||||||
|
# KAFKA_SSL_TRUSTSTORE_CERTIFICATES: -----BEGIN CERTIFICATE-----
|
||||||
|
# MIIDCzCCAfOgAwIBAgIUaXNh4PahaKeLUaab2rUPSVESx28wDQYJKoZIhvcNAQEL
|
||||||
|
# BQAwFTETMBEGA1UEAwwKRXhhbXBsZSBDQTAeFw0yNTA4MjExODEyMTFaFw0zNTA4
|
||||||
|
# MTkxODEyMTFaMBUxEzARBgNVBAMMCkV4YW1wbGUgQ0EwggEiMA0GCSqGSIb3DQEB
|
||||||
|
# AQUAA4IBDwAwggEKAoIBAQCsqalqVOLFglVbX9oSHU91ebyL1kPyb/2N90UGQIcD
|
||||||
|
# UAjzKxxysId1Vdvtbbwgli6UgfPwlzFP2Wlw51h496yL4QU/9tNV956UJ1RoS/fG
|
||||||
|
# qBAEHctqavfMI27UQmIzw4pGMkGzEQxRMc6a9pdabBhbMMTJsjtmOv2YMYHj1HHK
|
||||||
|
# Dr7wTBTt2l0eRyCR0kZ8XGIMWhYowPa4EMpC7+4e5Nf/7LSJZWLLy9jXPpazsjkJ
|
||||||
|
# jEmDNlFfx2tZiq0Wz2Xj1pZSDLbcuIX4IHcLfMvagibfrCMX/h6+WuW42sWPRuBW
|
||||||
|
# wB6cHGlXs+K/gBBWxtD7sOTacO5hbHFsfaJOhSEIGoIpAgMBAAGjUzBRMB0GA1Ud
|
||||||
|
# DgQWBBT2S/C2++ECY+CSuN5KKql0umfbTDAfBgNVHSMEGDAWgBT2S/C2++ECY+CS
|
||||||
|
# uN5KKql0umfbTDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj
|
||||||
|
# H4DdwqrOHg7sVsqiwDsZfTharpUDCYeG5XhrJQlnA9eKwyofTb929W/fjOwBdDtg
|
||||||
|
# 9THT/omR0lA8/UyHtezMT6nMsCn4HG2mXvx6ghgvA3jrFTEY7R80dHkboLMTV3u4
|
||||||
|
# RYgC9S3BJPcbJYpM0cXzkp2T0F4FxWZlfqefuedHuX3zcCxpgVD56qQb2a131TX7
|
||||||
|
# O3UDJfVg8a65IFtehndqILgLVrf7w6+pbmDAlCg5RKrt2USEYyZXYdyTryJbdtn4
|
||||||
|
# BCLp0avYtSYVUGwgH0oUCpkjQRwMg1003TTz8SNnmE7mAXHYljyYejnjL8vBHfch
|
||||||
|
# 8tTDVXQn08BT9H3jZTnF
|
||||||
|
# -----END CERTIFICATE-----
|
||||||
|
# KAFKA_SSL_CLIENT_AUTH: none
|
||||||
|
###
|
||||||
|
|
||||||
## Use AKHQ as Kafka web frontend
|
## Use AKHQ as Kafka web frontend
|
||||||
akhq:
|
akhq:
|
||||||
|
@@ -282,6 +282,30 @@ class HomeControllerTest {
|
|||||||
assertThat(page.querySelectorAll("tbody tr")).isEmpty()
|
assertThat(page.querySelectorAll("tbody tr")).isEmpty()
|
||||||
assertThat(page.querySelectorAll("div.notification.info")).hasSize(1)
|
assertThat(page.querySelectorAll("div.notification.info")).hasSize(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "admin", roles = ["ADMIN"])
|
||||||
|
fun testShouldShowNoConsentStatusBadge() {
|
||||||
|
whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn(
|
||||||
|
PageImpl(
|
||||||
|
listOf(
|
||||||
|
Request(
|
||||||
|
1L,
|
||||||
|
randomRequestId(),
|
||||||
|
PatientPseudonym("PSEUDO1"),
|
||||||
|
PatientId("PATIENT1"),
|
||||||
|
Fingerprint("ashdkasdh"),
|
||||||
|
RequestType.MTB_FILE,
|
||||||
|
RequestStatus.NO_CONSENT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1")
|
||||||
|
assertThat(page.querySelectorAll("tbody tr")).hasSize(1)
|
||||||
|
assertThat(page.querySelectorAll("tbody tr > td > small").first().textContent).isEqualTo("NO_CONSENT")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -39,12 +39,14 @@ public class GicsConsentService implements IConsentService {
|
|||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
private final FhirContext fhirContext;
|
private final FhirContext fhirContext;
|
||||||
private final GIcsConfigProperties gIcsConfigProperties;
|
private final GIcsConfigProperties gIcsConfigProperties;
|
||||||
|
private final String BROAD_CONSENT_PROFILE_URI = "https://www.medizininformatik-initiative.de/fhir/modul-consent/StructureDefinition/mii-pr-consent-einwilligung";
|
||||||
|
private final String BROAD_CONSENT_POLICY = "urn:oid:2.16.840.1.113883.3.1937.777.24.2.1791";
|
||||||
|
|
||||||
public GicsConsentService(
|
public GicsConsentService(
|
||||||
GIcsConfigProperties gIcsConfigProperties,
|
GIcsConfigProperties gIcsConfigProperties,
|
||||||
RetryTemplate retryTemplate,
|
RetryTemplate retryTemplate,
|
||||||
RestTemplate restTemplate,
|
RestTemplate restTemplate,
|
||||||
AppFhirConfig appFhirConfig
|
AppFhirConfig appFhirConfig
|
||||||
) {
|
) {
|
||||||
this.retryTemplate = retryTemplate;
|
this.retryTemplate = retryTemplate;
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
@@ -54,34 +56,34 @@ public class GicsConsentService implements IConsentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Parameters getFhirRequestParameters(
|
protected Parameters getFhirRequestParameters(
|
||||||
String personIdentifierValue
|
String personIdentifierValue
|
||||||
) {
|
) {
|
||||||
var result = new Parameters();
|
var result = new Parameters();
|
||||||
result.addParameter(
|
result.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("personIdentifier")
|
.setName("personIdentifier")
|
||||||
.setValue(
|
.setValue(
|
||||||
new Identifier()
|
new Identifier()
|
||||||
.setValue(personIdentifierValue)
|
.setValue(personIdentifierValue)
|
||||||
.setSystem(this.gIcsConfigProperties.getPersonIdentifierSystem())
|
.setSystem(this.gIcsConfigProperties.getPersonIdentifierSystem())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
result.addParameter(
|
result.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("domain")
|
.setName("domain")
|
||||||
.setValue(
|
.setValue(
|
||||||
new StringType()
|
new StringType()
|
||||||
.setValue(this.gIcsConfigProperties.getBroadConsentDomainName())
|
.setValue(this.gIcsConfigProperties.getBroadConsentDomainName())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
result.addParameter(
|
result.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("policy")
|
.setName("policy")
|
||||||
.setValue(
|
.setValue(
|
||||||
new Coding()
|
new Coding()
|
||||||
.setCode(this.gIcsConfigProperties.getBroadConsentPolicyCode())
|
.setCode(this.gIcsConfigProperties.getBroadConsentPolicyCode())
|
||||||
.setSystem(this.gIcsConfigProperties.getBroadConsentPolicySystem())
|
.setSystem(this.gIcsConfigProperties.getBroadConsentPolicySystem())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -89,10 +91,10 @@ public class GicsConsentService implements IConsentService {
|
|||||||
* 'ignoreVersionNumber'.
|
* 'ignoreVersionNumber'.
|
||||||
*/
|
*/
|
||||||
result.addParameter(
|
result.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("version")
|
.setName("version")
|
||||||
.setValue(new StringType().setValue("1.1")
|
.setValue(new StringType().setValue("1.1")
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* add config parameter with:
|
/* add config parameter with:
|
||||||
@@ -101,17 +103,17 @@ public class GicsConsentService implements IConsentService {
|
|||||||
* unknownStateIsConsideredAsDecline -> true
|
* unknownStateIsConsideredAsDecline -> true
|
||||||
*/
|
*/
|
||||||
var config = new ParametersParameterComponent()
|
var config = new ParametersParameterComponent()
|
||||||
.setName("config")
|
.setName("config")
|
||||||
.addPart(
|
.addPart(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("ignoreVersionNumber")
|
.setName("ignoreVersionNumber")
|
||||||
.setValue(new BooleanType().setValue(true))
|
.setValue(new BooleanType().setValue(true))
|
||||||
)
|
)
|
||||||
.addPart(
|
.addPart(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("unknownStateIsConsideredAsDecline")
|
.setName("unknownStateIsConsideredAsDecline")
|
||||||
.setValue(new BooleanType().setValue(false))
|
.setValue(new BooleanType().setValue(false))
|
||||||
);
|
);
|
||||||
|
|
||||||
result.addParameter(config);
|
result.addParameter(config);
|
||||||
|
|
||||||
@@ -130,8 +132,8 @@ public class GicsConsentService implements IConsentService {
|
|||||||
headers.setContentType(MediaType.APPLICATION_XML);
|
headers.setContentType(MediaType.APPLICATION_XML);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
StringUtils.isBlank(this.gIcsConfigProperties.getUsername())
|
StringUtils.isBlank(this.gIcsConfigProperties.getUsername())
|
||||||
|| StringUtils.isBlank(this.gIcsConfigProperties.getPassword())
|
|| StringUtils.isBlank(this.gIcsConfigProperties.getPassword())
|
||||||
) {
|
) {
|
||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
@@ -145,28 +147,28 @@ public class GicsConsentService implements IConsentService {
|
|||||||
HttpEntity<String> requestEntity = new HttpEntity<>(parameterAsXml, this.headersWithHttpBasicAuth());
|
HttpEntity<String> requestEntity = new HttpEntity<>(parameterAsXml, this.headersWithHttpBasicAuth());
|
||||||
try {
|
try {
|
||||||
var responseEntity = retryTemplate.execute(
|
var responseEntity = retryTemplate.execute(
|
||||||
ctx -> restTemplate.exchange(endpointUri(endpoint), HttpMethod.POST, requestEntity, String.class)
|
ctx -> restTemplate.exchange(endpointUri(endpoint), HttpMethod.POST, requestEntity, String.class)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
if (responseEntity.getStatusCode().is2xxSuccessful()) {
|
||||||
return responseEntity.getBody();
|
return responseEntity.getBody();
|
||||||
} else {
|
} else {
|
||||||
var msg = String.format(
|
var msg = String.format(
|
||||||
"Trusted party system reached but request failed! code: '%s' response: '%s'",
|
"Trusted party system reached but request failed! code: '%s' response: '%s'",
|
||||||
responseEntity.getStatusCode(), responseEntity.getBody());
|
responseEntity.getStatusCode(), responseEntity.getBody());
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (RestClientException e) {
|
} catch (RestClientException e) {
|
||||||
var msg = String.format("Get consents status request failed reason: '%s",
|
var msg = String.format("Get consents status request failed reason: '%s",
|
||||||
e.getMessage());
|
e.getMessage());
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
} catch (TerminatedRetryException terminatedRetryException) {
|
} catch (TerminatedRetryException terminatedRetryException) {
|
||||||
var msg = String.format(
|
var msg = String.format(
|
||||||
"Get consents status process has been terminated. termination reason: '%s",
|
"Get consents status process has been terminated. termination reason: '%s",
|
||||||
terminatedRetryException.getMessage());
|
terminatedRetryException.getMessage());
|
||||||
log.error(msg);
|
log.error(msg);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -175,45 +177,45 @@ public class GicsConsentService implements IConsentService {
|
|||||||
@Override
|
@Override
|
||||||
public TtpConsentStatus getTtpBroadConsentStatus(String personIdentifierValue) {
|
public TtpConsentStatus getTtpBroadConsentStatus(String personIdentifierValue) {
|
||||||
var consentStatusResponse = callGicsApi(
|
var consentStatusResponse = callGicsApi(
|
||||||
getFhirRequestParameters(personIdentifierValue),
|
getFhirRequestParameters(personIdentifierValue),
|
||||||
GicsConsentService.IS_CONSENTED_ENDPOINT
|
GicsConsentService.IS_CONSENTED_ENDPOINT
|
||||||
);
|
);
|
||||||
return evaluateConsentResponse(consentStatusResponse);
|
return evaluateConsentResponse(consentStatusResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Bundle currentConsentForPersonAndTemplate(
|
protected Bundle currentConsentForPersonAndTemplate(
|
||||||
String personIdentifierValue,
|
String personIdentifierValue,
|
||||||
ConsentDomain consentDomain,
|
ConsentDomain consentDomain,
|
||||||
Date requestDate
|
Date requestDate
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var requestParameter = buildRequestParameterCurrentPolicyStatesForPerson(
|
var requestParameter = buildRequestParameterCurrentPolicyStatesForPerson(
|
||||||
personIdentifierValue,
|
personIdentifierValue,
|
||||||
requestDate,
|
requestDate,
|
||||||
consentDomain
|
consentDomain
|
||||||
);
|
);
|
||||||
|
|
||||||
var consentDataSerialized = callGicsApi(requestParameter,
|
var consentDataSerialized = callGicsApi(requestParameter,
|
||||||
GicsConsentService.IS_POLICY_STATES_FOR_PERSON_ENDPOINT);
|
GicsConsentService.IS_POLICY_STATES_FOR_PERSON_ENDPOINT);
|
||||||
|
|
||||||
if (consentDataSerialized == null) {
|
if (consentDataSerialized == null) {
|
||||||
// error occurred - should not process further!
|
// error occurred - should not process further!
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"consent data request failed - stopping processing! - try again or fix other problems first.");
|
"consent data request failed - stopping processing! - try again or fix other problems first.");
|
||||||
}
|
}
|
||||||
var iBaseResource = fhirContext.newJsonParser()
|
var iBaseResource = fhirContext.newJsonParser()
|
||||||
.parseResource(consentDataSerialized);
|
.parseResource(consentDataSerialized);
|
||||||
if (iBaseResource instanceof OperationOutcome) {
|
if (iBaseResource instanceof OperationOutcome) {
|
||||||
// log error - very likely a configuration error
|
// log error - very likely a configuration error
|
||||||
String errorMessage =
|
String errorMessage =
|
||||||
"Consent request failed! Check outcome:\n " + consentDataSerialized;
|
"Consent request failed! Check outcome:\n " + consentDataSerialized;
|
||||||
log.error(errorMessage);
|
log.error(errorMessage);
|
||||||
throw new IllegalStateException(errorMessage);
|
throw new IllegalStateException(errorMessage);
|
||||||
} else if (iBaseResource instanceof Bundle bundle) {
|
} else if (iBaseResource instanceof Bundle bundle) {
|
||||||
return bundle;
|
return bundle;
|
||||||
} else {
|
} else {
|
||||||
String errorMessage = "Consent request failed! Unexpected response received! -> "
|
String errorMessage = "Consent request failed! Unexpected response received! -> "
|
||||||
+ consentDataSerialized;
|
+ consentDataSerialized;
|
||||||
log.error(errorMessage);
|
log.error(errorMessage);
|
||||||
throw new IllegalStateException(errorMessage);
|
throw new IllegalStateException(errorMessage);
|
||||||
}
|
}
|
||||||
@@ -228,43 +230,43 @@ public class GicsConsentService implements IConsentService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Parameters buildRequestParameterCurrentPolicyStatesForPerson(
|
protected Parameters buildRequestParameterCurrentPolicyStatesForPerson(
|
||||||
String personIdentifierValue,
|
String personIdentifierValue,
|
||||||
Date requestDate,
|
Date requestDate,
|
||||||
ConsentDomain consentDomain
|
ConsentDomain consentDomain
|
||||||
) {
|
) {
|
||||||
var requestParameter = new Parameters();
|
var requestParameter = new Parameters();
|
||||||
requestParameter.addParameter(
|
requestParameter.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("personIdentifier")
|
.setName("personIdentifier")
|
||||||
.setValue(
|
.setValue(
|
||||||
new Identifier()
|
new Identifier()
|
||||||
.setValue(personIdentifierValue)
|
.setValue(personIdentifierValue)
|
||||||
.setSystem(this.gIcsConfigProperties.getPersonIdentifierSystem())
|
.setSystem(this.gIcsConfigProperties.getPersonIdentifierSystem())
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
requestParameter.addParameter(
|
requestParameter.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("domain")
|
.setName("domain")
|
||||||
.setValue(new StringType().setValue(getConsentDomainName(consentDomain)))
|
.setValue(new StringType().setValue(getConsentDomainName(consentDomain)))
|
||||||
);
|
);
|
||||||
|
|
||||||
Parameters nestedConfigParameters = new Parameters();
|
Parameters nestedConfigParameters = new Parameters();
|
||||||
nestedConfigParameters
|
nestedConfigParameters
|
||||||
.addParameter(
|
.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("idMatchingType")
|
.setName("idMatchingType")
|
||||||
.setValue(new Coding()
|
.setValue(new Coding()
|
||||||
.setSystem("https://ths-greifswald.de/fhir/CodeSystem/gics/IdMatchingType")
|
.setSystem("https://ths-greifswald.de/fhir/CodeSystem/gics/IdMatchingType")
|
||||||
.setCode("AT_LEAST_ONE")
|
.setCode("AT_LEAST_ONE")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.addParameter("ignoreVersionNumber", false)
|
.addParameter("ignoreVersionNumber", false)
|
||||||
.addParameter("unknownStateIsConsideredAsDecline", false)
|
.addParameter("unknownStateIsConsideredAsDecline", false)
|
||||||
.addParameter("requestDate", new DateType().setValue(requestDate));
|
.addParameter("requestDate", new DateType().setValue(requestDate));
|
||||||
|
|
||||||
requestParameter.addParameter(
|
requestParameter.addParameter(
|
||||||
new ParametersParameterComponent().setName("config").addPart().setResource(nestedConfigParameters)
|
new ParametersParameterComponent().setName("config").addPart().setResource(nestedConfigParameters)
|
||||||
);
|
);
|
||||||
|
|
||||||
return requestParameter;
|
return requestParameter;
|
||||||
@@ -291,7 +293,7 @@ public class GicsConsentService implements IConsentService {
|
|||||||
}
|
}
|
||||||
} else if (response instanceof OperationOutcome outcome) {
|
} else if (response instanceof OperationOutcome outcome) {
|
||||||
log.error("failed to get consent status from ttp. probably configuration error. "
|
log.error("failed to get consent status from ttp. probably configuration error. "
|
||||||
+ "outcome: '{}'", fhirContext.newJsonParser().encodeToString(outcome));
|
+ "outcome: '{}'", fhirContext.newJsonParser().encodeToString(outcome));
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (DataFormatException dfe) {
|
} catch (DataFormatException dfe) {
|
||||||
@@ -302,6 +304,36 @@ public class GicsConsentService implements IConsentService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Bundle getConsent(String patientId, Date requestDate, ConsentDomain consentDomain) {
|
public Bundle getConsent(String patientId, Date requestDate, ConsentDomain consentDomain) {
|
||||||
return currentConsentForPersonAndTemplate(patientId, consentDomain, requestDate);
|
Bundle gIcsResultBundle = currentConsentForPersonAndTemplate(patientId, consentDomain, requestDate);
|
||||||
|
if (ConsentDomain.BROAD_CONSENT == consentDomain) {
|
||||||
|
return convertGicsResultToMiiBroadConsent(gIcsResultBundle);
|
||||||
|
}
|
||||||
|
return gIcsResultBundle;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Bundle convertGicsResultToMiiBroadConsent(Bundle gIcsResultBundle) {
|
||||||
|
if (gIcsResultBundle == null
|
||||||
|
|| gIcsResultBundle.getEntry().isEmpty()
|
||||||
|
|| !(gIcsResultBundle.getEntry().getFirst().getResource() instanceof Consent))
|
||||||
|
return gIcsResultBundle;
|
||||||
|
|
||||||
|
Bundle.BundleEntryComponent bundleEntryComponent = gIcsResultBundle.getEntry().getFirst();
|
||||||
|
|
||||||
|
var consentAsOne = (Consent) bundleEntryComponent.getResource();
|
||||||
|
if (consentAsOne.getPolicy().stream().noneMatch(p -> p.getUri().equals(BROAD_CONSENT_POLICY))) {
|
||||||
|
consentAsOne.addPolicy(new Consent.ConsentPolicyComponent().setUri(BROAD_CONSENT_POLICY));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (consentAsOne.getMeta().getProfile().stream().noneMatch(p -> p.getValue().equals(BROAD_CONSENT_PROFILE_URI))) {
|
||||||
|
consentAsOne.getMeta().addProfile(BROAD_CONSENT_PROFILE_URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
consentAsOne.setPolicyRule(null);
|
||||||
|
|
||||||
|
gIcsResultBundle.getEntry().stream().skip(1).forEach(c -> consentAsOne.getProvision().addProvision(((Consent) c.getResource()).getProvision().getProvisionFirstRep()));
|
||||||
|
|
||||||
|
gIcsResultBundle.getEntry().clear();
|
||||||
|
gIcsResultBundle.addEntry(bundleEntryComponent);
|
||||||
|
return gIcsResultBundle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,8 +23,6 @@ import ca.uhn.fhir.context.FhirContext;
|
|||||||
import ca.uhn.fhir.parser.IParser;
|
import ca.uhn.fhir.parser.IParser;
|
||||||
import dev.dnpm.etl.processor.config.AppFhirConfig;
|
import dev.dnpm.etl.processor.config.AppFhirConfig;
|
||||||
import dev.dnpm.etl.processor.config.GPasConfigProperties;
|
import dev.dnpm.etl.processor.config.GPasConfigProperties;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.hc.core5.net.URIBuilder;
|
import org.apache.hc.core5.net.URIBuilder;
|
||||||
@@ -39,9 +37,11 @@ import org.springframework.http.*;
|
|||||||
import org.springframework.retry.support.RetryTemplate;
|
import org.springframework.retry.support.RetryTemplate;
|
||||||
import org.springframework.web.client.HttpClientErrorException.BadRequest;
|
import org.springframework.web.client.HttpClientErrorException.BadRequest;
|
||||||
import org.springframework.web.client.HttpClientErrorException.Unauthorized;
|
import org.springframework.web.client.HttpClientErrorException.Unauthorized;
|
||||||
import org.springframework.web.client.RestClientException;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
public class GpasPseudonymGenerator implements Generator {
|
public class GpasPseudonymGenerator implements Generator {
|
||||||
|
|
||||||
private final FhirContext r4Context;
|
private final FhirContext r4Context;
|
||||||
@@ -52,10 +52,10 @@ public class GpasPseudonymGenerator implements Generator {
|
|||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
private final @NotNull String genomDeTanDomain;
|
private final @NotNull String genomDeTanDomain;
|
||||||
private final @NotNull String pidPsnDomain;
|
private final @NotNull String pidPsnDomain;
|
||||||
protected final static String createOrGetPsn = "$pseudonymizeAllowCreate";
|
protected static final String CREATE_OR_GET_PSN = "$pseudonymizeAllowCreate";
|
||||||
protected final static String createMultiDomainPsn = "$pseudonymize-secondary";
|
protected static final String CREATE_MULTI_DOMAIN_PSN = "$pseudonymize-secondary";
|
||||||
private final static String SINGLE_PSN_PART_NAME = "pseudonym";
|
private static final String SINGLE_PSN_PART_NAME = "pseudonym";
|
||||||
private final static String MULTI_PSN_PART_NAME = "value";
|
private static final String MULTI_PSN_PART_NAME = "value";
|
||||||
|
|
||||||
public GpasPseudonymGenerator(GPasConfigProperties gpasCfg, RetryTemplate retryTemplate,
|
public GpasPseudonymGenerator(GPasConfigProperties gpasCfg, RetryTemplate retryTemplate,
|
||||||
RestTemplate restTemplate, AppFhirConfig appFhirConfig) {
|
RestTemplate restTemplate, AppFhirConfig appFhirConfig) {
|
||||||
@@ -85,7 +85,7 @@ public class GpasPseudonymGenerator implements Generator {
|
|||||||
switch (domainType) {
|
switch (domainType) {
|
||||||
case SINGLE_PSN_DOMAIN -> {
|
case SINGLE_PSN_DOMAIN -> {
|
||||||
final var requestBody = createSinglePsnRequestBody(id, pidPsnDomain);
|
final var requestBody = createSinglePsnRequestBody(id, pidPsnDomain);
|
||||||
final var responseEntity = getGpasPseudonym(requestBody, createOrGetPsn);
|
final var responseEntity = getGpasPseudonym(requestBody, CREATE_OR_GET_PSN);
|
||||||
final var gPasPseudonymResult = (Parameters) r4Context.newJsonParser()
|
final var gPasPseudonymResult = (Parameters) r4Context.newJsonParser()
|
||||||
.parseResource(responseEntity.getBody());
|
.parseResource(responseEntity.getBody());
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ public class GpasPseudonymGenerator implements Generator {
|
|||||||
}
|
}
|
||||||
case MULTI_PSN_DOMAIN -> {
|
case MULTI_PSN_DOMAIN -> {
|
||||||
final var requestBody = createMultiPsnRequestBody(id, genomDeTanDomain);
|
final var requestBody = createMultiPsnRequestBody(id, genomDeTanDomain);
|
||||||
final var responseEntity = getGpasPseudonym(requestBody, createMultiDomainPsn);
|
final var responseEntity = getGpasPseudonym(requestBody, CREATE_MULTI_DOMAIN_PSN);
|
||||||
final var gPasPseudonymResult = (Parameters) r4Context.newJsonParser()
|
final var gPasPseudonymResult = (Parameters) r4Context.newJsonParser()
|
||||||
.parseResource(responseEntity.getBody());
|
.parseResource(responseEntity.getBody());
|
||||||
|
|
||||||
@@ -150,23 +150,22 @@ public class GpasPseudonymGenerator implements Generator {
|
|||||||
log.debug("API request succeeded. Response: {}", responseEntity.getStatusCode());
|
log.debug("API request succeeded. Response: {}", responseEntity.getStatusCode());
|
||||||
return responseEntity;
|
return responseEntity;
|
||||||
}
|
}
|
||||||
} catch (RestClientException rce) {
|
} catch (BadRequest e) {
|
||||||
if (rce instanceof BadRequest) {
|
String msg = "gPas or request configuration is incorrect. Please check both."
|
||||||
String msg = "gPas or request configuration is incorrect. Please check both."
|
+ e.getMessage();
|
||||||
+ rce.getMessage();
|
log.error(msg);
|
||||||
log.debug(
|
throw new PseudonymRequestFailed(msg, e);
|
||||||
msg);
|
} catch (Unauthorized e) {
|
||||||
throw new PseudonymRequestFailed(msg, rce);
|
var msg = "gPas access credentials are invalid check your configuration. msg: '%s"
|
||||||
}
|
.formatted(e.getMessage());
|
||||||
if (rce instanceof Unauthorized) {
|
log.error(msg);
|
||||||
var msg = "gPas access credentials are invalid check your configuration. msg: '%s".formatted(
|
throw new PseudonymRequestFailed(msg, e);
|
||||||
rce.getMessage());
|
}
|
||||||
log.error(msg);
|
catch (Exception unexpected) {
|
||||||
throw new PseudonymRequestFailed(msg, rce);
|
|
||||||
}
|
|
||||||
} catch (Exception unexpected) {
|
|
||||||
throw new PseudonymRequestFailed(
|
throw new PseudonymRequestFailed(
|
||||||
"API request due unexpected error unsuccessful gPas unsuccessful.", unexpected);
|
"API request due unexpected error unsuccessful gPas unsuccessful.",
|
||||||
|
unexpected
|
||||||
|
);
|
||||||
}
|
}
|
||||||
throw new PseudonymRequestFailed(
|
throw new PseudonymRequestFailed(
|
||||||
"API request due unexpected error unsuccessful gPas unsuccessful.");
|
"API request due unexpected error unsuccessful gPas unsuccessful.");
|
||||||
|
@@ -31,6 +31,7 @@ import org.apache.kafka.clients.consumer.ConsumerRecord
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.kafka.listener.MessageListener
|
import org.springframework.kafka.listener.MessageListener
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
class KafkaInputListener(
|
class KafkaInputListener(
|
||||||
private val requestProcessor: RequestProcessor,
|
private val requestProcessor: RequestProcessor,
|
||||||
@@ -49,19 +50,16 @@ class KafkaInputListener(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun guessMimeType(record: ConsumerRecord<String, String>): String {
|
private fun guessMimeType(record: ConsumerRecord<String, String>): String? {
|
||||||
if (record.headers().headers("contentType").toList().isEmpty()) {
|
if (record.headers().headers("contentType").toList().isEmpty()) {
|
||||||
// Fallback if no contentType set (old behavior)
|
// Fallback if no contentType set (old behavior)
|
||||||
return MediaType.APPLICATION_JSON_VALUE
|
return MediaType.APPLICATION_JSON_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
return record.headers().headers("contentType")?.firstOrNull()?.value().contentToString()
|
return record.headers().headers("contentType")?.firstOrNull()?.value()?.toString(Charset.forName("UTF-8"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDnpmV2Message(record: ConsumerRecord<String, String>) {
|
private fun handleDnpmV2Message(record: ConsumerRecord<String, String>) {
|
||||||
// Do not handle DNPM-V2 for now
|
|
||||||
logger.warn("Ignoring MTB File in DNPM V2 format: Not implemented yet")
|
|
||||||
|
|
||||||
val mtbFile = objectMapper.readValue(record.value(), Mtb::class.java)
|
val mtbFile = objectMapper.readValue(record.value(), Mtb::class.java)
|
||||||
val patientId = PatientId(mtbFile.patient.id)
|
val patientId = PatientId(mtbFile.patient.id)
|
||||||
val firstRequestIdHeader = record.headers().headers("requestId")?.firstOrNull()
|
val firstRequestIdHeader = record.headers().headers("requestId")?.firstOrNull()
|
||||||
|
@@ -30,6 +30,7 @@ import org.springframework.data.relational.core.mapping.Table
|
|||||||
import org.springframework.data.repository.CrudRepository
|
import org.springframework.data.repository.CrudRepository
|
||||||
import org.springframework.data.repository.PagingAndSortingRepository
|
import org.springframework.data.repository.PagingAndSortingRepository
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
import java.time.temporal.ChronoUnit
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@Table("request")
|
@Table("request")
|
||||||
@@ -65,6 +66,12 @@ data class Request(
|
|||||||
processedAt: Instant
|
processedAt: Instant
|
||||||
) :
|
) :
|
||||||
this(null, uuid, patientPseudonym, pid, fingerprint, type, status, processedAt)
|
this(null, uuid, patientPseudonym, pid, fingerprint, type, status, processedAt)
|
||||||
|
|
||||||
|
fun isPendingUnknown(): Boolean {
|
||||||
|
return this.status == RequestStatus.UNKNOWN && this.processedAt.isBefore(
|
||||||
|
Instant.now().minus(10, ChronoUnit.MINUTES)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmRecord
|
@JvmRecord
|
||||||
@@ -90,19 +97,23 @@ interface RequestRepository : CrudRepository<Request, Long>, PagingAndSortingRep
|
|||||||
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'MTB_FILE' GROUP BY status ORDER BY status, count DESC;")
|
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'MTB_FILE' GROUP BY status ORDER BY status, count DESC;")
|
||||||
fun countStates(): List<CountedState>
|
fun countStates(): List<CountedState>
|
||||||
|
|
||||||
@Query("SELECT count(*) AS count, status FROM (" +
|
@Query(
|
||||||
"SELECT status, rank() OVER (PARTITION BY patient_pseudonym ORDER BY processed_at DESC) AS rank FROM request " +
|
"SELECT count(*) AS count, status FROM (" +
|
||||||
"WHERE type = 'MTB_FILE' AND status NOT IN ('DUPLICATION') " +
|
"SELECT status, rank() OVER (PARTITION BY patient_pseudonym ORDER BY processed_at DESC) AS rank FROM request " +
|
||||||
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;")
|
"WHERE type = 'MTB_FILE' AND status NOT IN ('DUPLICATION') " +
|
||||||
|
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;"
|
||||||
|
)
|
||||||
fun findPatientUniqueStates(): List<CountedState>
|
fun findPatientUniqueStates(): List<CountedState>
|
||||||
|
|
||||||
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'DELETE' GROUP BY status ORDER BY status, count DESC;")
|
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'DELETE' GROUP BY status ORDER BY status, count DESC;")
|
||||||
fun countDeleteStates(): List<CountedState>
|
fun countDeleteStates(): List<CountedState>
|
||||||
|
|
||||||
@Query("SELECT count(*) AS count, status FROM (" +
|
@Query(
|
||||||
"SELECT status, rank() OVER (PARTITION BY patient_pseudonym ORDER BY processed_at DESC) AS rank FROM request " +
|
"SELECT count(*) AS count, status FROM (" +
|
||||||
"WHERE type = 'DELETE'" +
|
"SELECT status, rank() OVER (PARTITION BY patient_pseudonym ORDER BY processed_at DESC) AS rank FROM request " +
|
||||||
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;")
|
"WHERE type = 'DELETE'" +
|
||||||
|
") rank WHERE rank = 1 GROUP BY status ORDER BY status, count DESC;"
|
||||||
|
)
|
||||||
fun findPatientUniqueDeleteStates(): List<CountedState>
|
fun findPatientUniqueDeleteStates(): List<CountedState>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,6 @@ import dev.pcvolkmer.mv64e.mtb.Mtb
|
|||||||
import dev.pcvolkmer.mv64e.mtb.MvhMetadata
|
import dev.pcvolkmer.mv64e.mtb.MvhMetadata
|
||||||
import org.apache.kafka.clients.producer.ProducerRecord
|
import org.apache.kafka.clients.producer.ProducerRecord
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.http.MediaType
|
|
||||||
import org.springframework.kafka.core.KafkaTemplate
|
import org.springframework.kafka.core.KafkaTemplate
|
||||||
import org.springframework.retry.support.RetryTemplate
|
import org.springframework.retry.support.RetryTemplate
|
||||||
|
|
||||||
@@ -47,8 +46,9 @@ class KafkaMtbFileSender(
|
|||||||
ProducerRecord(
|
ProducerRecord(
|
||||||
kafkaProperties.outputTopic,
|
kafkaProperties.outputTopic,
|
||||||
key(request),
|
key(request),
|
||||||
objectMapper.writeValueAsString(request)
|
objectMapper.writeValueAsString(request),
|
||||||
)
|
)
|
||||||
|
record.headers().add("requestId", request.requestId.value.toByteArray())
|
||||||
when (request) {
|
when (request) {
|
||||||
is DnpmV2MtbFileRequest -> record.headers()
|
is DnpmV2MtbFileRequest -> record.headers()
|
||||||
.add(
|
.add(
|
||||||
@@ -82,7 +82,6 @@ class KafkaMtbFileSender(
|
|||||||
ProducerRecord(
|
ProducerRecord(
|
||||||
kafkaProperties.outputTopic,
|
kafkaProperties.outputTopic,
|
||||||
key(request),
|
key(request),
|
||||||
// Always use old BwhcV1FileRequest with Consent REJECT
|
|
||||||
objectMapper.writeValueAsString(
|
objectMapper.writeValueAsString(
|
||||||
DnpmV2MtbFileRequest(
|
DnpmV2MtbFileRequest(
|
||||||
request.requestId,
|
request.requestId,
|
||||||
@@ -90,7 +89,7 @@ class KafkaMtbFileSender(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
record.headers().add("requestId", request.requestId.value.toByteArray())
|
||||||
val result = kafkaTemplate.send(record)
|
val result = kafkaTemplate.send(record)
|
||||||
if (result.get() != null) {
|
if (result.get() != null) {
|
||||||
logger.debug("Sent deletion request via KafkaMtbFileSender")
|
logger.debug("Sent deletion request via KafkaMtbFileSender")
|
||||||
|
@@ -137,15 +137,7 @@ class ConsentProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val provisionComponent: ProvisionComponent = provisions.first()
|
val provisionComponent: ProvisionComponent = provisions.first()
|
||||||
|
val provisionCode = getProvisionCode(provisionComponent)
|
||||||
var provisionCode: String? = null
|
|
||||||
if (provisionComponent.code != null && provisionComponent.code.isNotEmpty()) {
|
|
||||||
val codableConcept: CodeableConcept = provisionComponent.code.first()
|
|
||||||
if (codableConcept.coding != null && codableConcept.coding.isNotEmpty()) {
|
|
||||||
provisionCode = codableConcept.coding.first().code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (provisionCode != null) {
|
if (provisionCode != null) {
|
||||||
try {
|
try {
|
||||||
val modelProjectConsentPurpose =
|
val modelProjectConsentPurpose =
|
||||||
@@ -177,6 +169,17 @@ class ConsentProcessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getProvisionCode(provisionComponent: ProvisionComponent): String? {
|
||||||
|
var provisionCode: String? = null
|
||||||
|
if (provisionComponent.code != null && provisionComponent.code.isNotEmpty()) {
|
||||||
|
val codableConcept: CodeableConcept = provisionComponent.code.first()
|
||||||
|
if (codableConcept.coding != null && codableConcept.coding.isNotEmpty()) {
|
||||||
|
provisionCode = codableConcept.coding.first().code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return provisionCode
|
||||||
|
}
|
||||||
|
|
||||||
private fun setGenomDeSubmissionType(mtbFile: Mtb) {
|
private fun setGenomDeSubmissionType(mtbFile: Mtb) {
|
||||||
if (appConfigProperties.genomDeTestSubmission) {
|
if (appConfigProperties.genomDeTestSubmission) {
|
||||||
mtbFile.metadata.type = MvhSubmissionType.TEST
|
mtbFile.metadata.type = MvhSubmissionType.TEST
|
||||||
@@ -238,9 +241,9 @@ class ConsentProcessor(
|
|||||||
consent.provision.provision.filter { subProvision ->
|
consent.provision.provision.filter { subProvision ->
|
||||||
isRequestDateInRange(requestDate, subProvision.period)
|
isRequestDateInRange(requestDate, subProvision.period)
|
||||||
// search coding entries of current provision for code and system
|
// search coding entries of current provision for code and system
|
||||||
subProvision.code.map { c -> c.coding }.flatten().firstOrNull { code ->
|
subProvision.code.map { c -> c.coding }.flatten().any { code ->
|
||||||
targetCode.equals(code.code) && targetSystem.equals(code.system)
|
targetCode.equals(code.code) && targetSystem.equals(code.system)
|
||||||
} != null
|
}
|
||||||
}.map { subProvision ->
|
}.map { subProvision ->
|
||||||
subProvision
|
subProvision
|
||||||
}
|
}
|
||||||
@@ -257,11 +260,11 @@ class ConsentProcessor(
|
|||||||
researchAllowedPolicySystem: String?,
|
researchAllowedPolicySystem: String?,
|
||||||
policyRules: Collection<Coding>
|
policyRules: Collection<Coding>
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return policyRules.find { code ->
|
return policyRules.any { code ->
|
||||||
researchAllowedPolicySystem.equals(code.getSystem()) && (researchAllowedPolicyOid.equals(
|
researchAllowedPolicySystem.equals(code.getSystem()) && (researchAllowedPolicyOid.equals(
|
||||||
code.getCode()
|
code.getCode()
|
||||||
))
|
))
|
||||||
} != null
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isRequestDateInRange(requestDate: Date?, provPeriod: Period): Boolean {
|
fun isRequestDateInRange(requestDate: Date?, provPeriod: Period): Boolean {
|
||||||
|
@@ -18,13 +18,107 @@ spring:
|
|||||||
issuer-uri: https://dnpm.dev/auth/realms/intern
|
issuer-uri: https://dnpm.dev/auth/realms/intern
|
||||||
user-name-attribute: name
|
user-name-attribute: name
|
||||||
|
|
||||||
|
# kafka:
|
||||||
|
# security:
|
||||||
|
# protocol: "SSL"
|
||||||
|
# ssl:
|
||||||
|
# key-store-type: "PEM"
|
||||||
|
# key-store-certificate-chain: -----BEGIN CERTIFICATE-----
|
||||||
|
# MIIDCzCCAfOgAwIBAgIUaXNh4PahaKeLUaab2rUPSVESx28wDQYJKoZIhvcNAQEL
|
||||||
|
# BQAwFTETMBEGA1UEAwwKRXhhbXBsZSBDQTAeFw0yNTA4MjExODEyMTFaFw0zNTA4
|
||||||
|
# MTkxODEyMTFaMBUxEzARBgNVBAMMCkV4YW1wbGUgQ0EwggEiMA0GCSqGSIb3DQEB
|
||||||
|
# AQUAA4IBDwAwggEKAoIBAQCsqalqVOLFglVbX9oSHU91ebyL1kPyb/2N90UGQIcD
|
||||||
|
# UAjzKxxysId1Vdvtbbwgli6UgfPwlzFP2Wlw51h496yL4QU/9tNV956UJ1RoS/fG
|
||||||
|
# qBAEHctqavfMI27UQmIzw4pGMkGzEQxRMc6a9pdabBhbMMTJsjtmOv2YMYHj1HHK
|
||||||
|
# Dr7wTBTt2l0eRyCR0kZ8XGIMWhYowPa4EMpC7+4e5Nf/7LSJZWLLy9jXPpazsjkJ
|
||||||
|
# jEmDNlFfx2tZiq0Wz2Xj1pZSDLbcuIX4IHcLfMvagibfrCMX/h6+WuW42sWPRuBW
|
||||||
|
# wB6cHGlXs+K/gBBWxtD7sOTacO5hbHFsfaJOhSEIGoIpAgMBAAGjUzBRMB0GA1Ud
|
||||||
|
# DgQWBBT2S/C2++ECY+CSuN5KKql0umfbTDAfBgNVHSMEGDAWgBT2S/C2++ECY+CS
|
||||||
|
# uN5KKql0umfbTDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj
|
||||||
|
# H4DdwqrOHg7sVsqiwDsZfTharpUDCYeG5XhrJQlnA9eKwyofTb929W/fjOwBdDtg
|
||||||
|
# 9THT/omR0lA8/UyHtezMT6nMsCn4HG2mXvx6ghgvA3jrFTEY7R80dHkboLMTV3u4
|
||||||
|
# RYgC9S3BJPcbJYpM0cXzkp2T0F4FxWZlfqefuedHuX3zcCxpgVD56qQb2a131TX7
|
||||||
|
# O3UDJfVg8a65IFtehndqILgLVrf7w6+pbmDAlCg5RKrt2USEYyZXYdyTryJbdtn4
|
||||||
|
# BCLp0avYtSYVUGwgH0oUCpkjQRwMg1003TTz8SNnmE7mAXHYljyYejnjL8vBHfch
|
||||||
|
# 8tTDVXQn08BT9H3jZTnF
|
||||||
|
# -----END CERTIFICATE-----
|
||||||
|
# -----BEGIN CERTIFICATE-----
|
||||||
|
# MIIC+TCCAeGgAwIBAgIUUoCwz8GS6xQ3mmI7RUUYSNPIOi4wDQYJKoZIhvcNAQEL
|
||||||
|
# BQAwFTETMBEGA1UEAwwKRXhhbXBsZSBDQTAeFw0yNTA4MjExODE0NDhaFw0zNTA4
|
||||||
|
# MTkxODE0NDhaMBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEB
|
||||||
|
# BQADggEPADCCAQoCggEBAL9PW99MhhBwdEmTHyZgfnhfTrxZPrNU6z1UdV8b82Lk
|
||||||
|
# 3p75o8eCKa9iOd7DDQlo75hQBhhX0+Xc3mucrstx5p8TYFMbypif8ojWh3LM++P8
|
||||||
|
# tz3ezQZlq86ycyKpm8dqlA03b227tFDfiYTev2eD2HN40BU7yDAYhhqd/QW8+MV2
|
||||||
|
# jkcRGv5cE21GZxWmPUpkVN+bNoBC8H90WmkST90LfeYF+wZnlsAJZH6AQzR1GnGD
|
||||||
|
# ICE5evMhC78hvRnpgeA310SyxssZEigkePL5lTZOBPY2IuzBqL05agyVTiVq4Xd6
|
||||||
|
# y3xOqXoxxOhZu06yd3nymorqeTgbF1fW8wQF0u3KsFECAwEAAaNCMEAwHQYDVR0O
|
||||||
|
# BBYEFHk9jMWRAAt2YsBSxUcOQVoWayoHMB8GA1UdIwQYMBaAFPZL8Lb74QJj4JK4
|
||||||
|
# 3koqqXS6Z9tMMA0GCSqGSIb3DQEBCwUAA4IBAQBqabAA9INONDaLHqs9i9YQHm/g
|
||||||
|
# AnB7xRl/RFbERKKCTSMZUYM8oEaaH0W2ENoPMc/7xOB/R8a7Rm62PTr6syxwhZrY
|
||||||
|
# 5NtGKJOD+rh90/5l83tulf93KqOJtGkiv6NBDvCNrITcA+UKRk/z4GcFi2YjWAl4
|
||||||
|
# wvY44lzTasMKSpjUQ5N0VNANcW3nVuEgPQ8rrr0NOK/5j4guPjsXDsixa47gqblA
|
||||||
|
# 5xGfBKeVmEXdPbzawZfP4hPIw7DpX2m8Y0erswF1ZxkIV73V3TDsFSLcqSKSzZr6
|
||||||
|
# mtj8COlV9Us7zqaJbV5eOl7GN1T9orZJwZmX1Z46gCkkSLYDP/dqtl2j9JgN
|
||||||
|
# -----END CERTIFICATE-----
|
||||||
|
# ### For dev/testing purposes only!
|
||||||
|
# key-store-key: -----BEGIN PRIVATE KEY-----
|
||||||
|
# MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC/T1vfTIYQcHRJ
|
||||||
|
# kx8mYH54X068WT6zVOs9VHVfG/Ni5N6e+aPHgimvYjneww0JaO+YUAYYV9Pl3N5r
|
||||||
|
# nK7LceafE2BTG8qYn/KI1odyzPvj/Lc93s0GZavOsnMiqZvHapQNN29tu7RQ34mE
|
||||||
|
# 3r9ng9hzeNAVO8gwGIYanf0FvPjFdo5HERr+XBNtRmcVpj1KZFTfmzaAQvB/dFpp
|
||||||
|
# Ek/dC33mBfsGZ5bACWR+gEM0dRpxgyAhOXrzIQu/Ib0Z6YHgN9dEssbLGRIoJHjy
|
||||||
|
# +ZU2TgT2NiLswai9OWoMlU4lauF3est8Tql6McToWbtOsnd58pqK6nk4GxdX1vME
|
||||||
|
# BdLtyrBRAgMBAAECggEAC1wXfPlqxoQe65WAVoOJTvV90+JKvlRPCZu/wm+C8r7b
|
||||||
|
# Vz5Ekt6wQflHrWoQlpv0CivKSNzCONZ2IJazrGHti0mXwSeXzptEyApRDaiNVnrV
|
||||||
|
# mKdnrjcQThw7iPXgSaWS9/vwMmhgayLy5ABkBi4GhsjINlKP7wctw1vZP+N6NCNd
|
||||||
|
# Ql3taStvDKmG0SfJHF6/2o/XBpof3IJEL7ghbzyTTbWWaO34J1mJ8A+AmjGhj9GE
|
||||||
|
# Dp3XuOrO9W7MVd1nfZDtGBS8qf80AwROyodZZRma9vZuWJZ5aQFi2CnUEtU1T+Uv
|
||||||
|
# tW+F6tg2FOMr8M0Fb79wGIDwSF8u/QcTvwhEzZAfiQKBgQDioOofnE1oB1DOMnqZ
|
||||||
|
# SOFjs+vsirvS6G3lo27+HkE3TgvCHR4sk1305AiXtjmPu8iaUCo9qn18MtduY2RS
|
||||||
|
# CcKMOG/FxhmDyP5I29DhJRhvERIpJd0kcSDQOgtaoVPC1XzIlyTqte6nGX9kAnA/
|
||||||
|
# x/OOXrZ0hjhMNDcZzf2NasPYJQKBgQDYGqTobkVBk+eekNWklnTh41/649rUIgTu
|
||||||
|
# JStArtY2hgaEInYcGa2e7cEj7nIHA0iGy3EJ2yvwoUIyxtoXVcGohu2IrzlhS33T
|
||||||
|
# R4jA7nE2/yHZrEMEJovuSU0eMw7rgvEtL79Q0RToYnTY1EU6X/BBoFfiiEeNMHKz
|
||||||
|
# zjDOOQ6ZvQKBgGCWChIc0FSkwYiPtPZ9PCn89XCjk/cIPkYfiF9fT5Ydeh9pv4Fp
|
||||||
|
# 8SI8yXi3HgMnGhDCV65eagqztGMEky3voO2X4/MbQaaL0+wDWxuJbsdvNBk7XOt6
|
||||||
|
# F20HP+2JUiR4Ti1DVWV+0k5/LG7YJzTXp/KmZQZ2aan4mv8xbn2F4h/NAoGAI4ou
|
||||||
|
# OLN53FEQtHkpSYoc6tFUBZTXdi+qE+g09sxKGmlsROrN9c0bSpnbO6eJRTH7CYAH
|
||||||
|
# tRFAZrB+jI87ar8FvEuEYQhALYoWxVpsWR5drCfFT2EPHG2icavIbQEEoSLFuyKx
|
||||||
|
# Gf9oqtcWVFqEkBcbEg/mpDC5Y7TmCEAOsrubdRkCgYEAl7B+EzIdG0rabGoti09q
|
||||||
|
# QXfyiTjR7nQYkhpLxMCeNlCpQ8Y15XSa8bm1UIGYqj/ZBpeBNhrj64IHoub5Vd43
|
||||||
|
# tzbb8yNgoLUd16TU1VvyccCMGQVPIF8RkDsAtEawV2eoXbHAstN99xbC8jsLNZRQ
|
||||||
|
# fcfgTiQaXRJmlVx6jfbfZd4=
|
||||||
|
# -----END PRIVATE KEY-----
|
||||||
|
# trust-store-type: "PEM"
|
||||||
|
# trust-store-certificates: -----BEGIN CERTIFICATE-----
|
||||||
|
# MIIDCzCCAfOgAwIBAgIUaXNh4PahaKeLUaab2rUPSVESx28wDQYJKoZIhvcNAQEL
|
||||||
|
# BQAwFTETMBEGA1UEAwwKRXhhbXBsZSBDQTAeFw0yNTA4MjExODEyMTFaFw0zNTA4
|
||||||
|
# MTkxODEyMTFaMBUxEzARBgNVBAMMCkV4YW1wbGUgQ0EwggEiMA0GCSqGSIb3DQEB
|
||||||
|
# AQUAA4IBDwAwggEKAoIBAQCsqalqVOLFglVbX9oSHU91ebyL1kPyb/2N90UGQIcD
|
||||||
|
# UAjzKxxysId1Vdvtbbwgli6UgfPwlzFP2Wlw51h496yL4QU/9tNV956UJ1RoS/fG
|
||||||
|
# qBAEHctqavfMI27UQmIzw4pGMkGzEQxRMc6a9pdabBhbMMTJsjtmOv2YMYHj1HHK
|
||||||
|
# Dr7wTBTt2l0eRyCR0kZ8XGIMWhYowPa4EMpC7+4e5Nf/7LSJZWLLy9jXPpazsjkJ
|
||||||
|
# jEmDNlFfx2tZiq0Wz2Xj1pZSDLbcuIX4IHcLfMvagibfrCMX/h6+WuW42sWPRuBW
|
||||||
|
# wB6cHGlXs+K/gBBWxtD7sOTacO5hbHFsfaJOhSEIGoIpAgMBAAGjUzBRMB0GA1Ud
|
||||||
|
# DgQWBBT2S/C2++ECY+CSuN5KKql0umfbTDAfBgNVHSMEGDAWgBT2S/C2++ECY+CS
|
||||||
|
# uN5KKql0umfbTDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj
|
||||||
|
# H4DdwqrOHg7sVsqiwDsZfTharpUDCYeG5XhrJQlnA9eKwyofTb929W/fjOwBdDtg
|
||||||
|
# 9THT/omR0lA8/UyHtezMT6nMsCn4HG2mXvx6ghgvA3jrFTEY7R80dHkboLMTV3u4
|
||||||
|
# RYgC9S3BJPcbJYpM0cXzkp2T0F4FxWZlfqefuedHuX3zcCxpgVD56qQb2a131TX7
|
||||||
|
# O3UDJfVg8a65IFtehndqILgLVrf7w6+pbmDAlCg5RKrt2USEYyZXYdyTryJbdtn4
|
||||||
|
# BCLp0avYtSYVUGwgH0oUCpkjQRwMg1003TTz8SNnmE7mAXHYljyYejnjL8vBHfch
|
||||||
|
# 8tTDVXQn08BT9H3jZTnF
|
||||||
|
# -----END CERTIFICATE-----
|
||||||
|
|
||||||
app:
|
app:
|
||||||
rest:
|
rest:
|
||||||
uri: http://localhost/api
|
uri: http://localhost/api
|
||||||
#kafka:
|
#kafka:
|
||||||
# topic: test
|
|
||||||
# response-topic: test_response
|
|
||||||
# servers: localhost:9094
|
# servers: localhost:9094
|
||||||
|
# group-id: "test1234"
|
||||||
|
# input-topic: test_input
|
||||||
|
# output-topic: test_output
|
||||||
|
# output-response-topic: test_response
|
||||||
security:
|
security:
|
||||||
admin-user: admin
|
admin-user: admin
|
||||||
admin-password: "{noop}very-secret"
|
admin-password: "{noop}very-secret"
|
||||||
|
@@ -16,7 +16,5 @@ spring:
|
|||||||
content:
|
content:
|
||||||
enabled: true
|
enabled: true
|
||||||
paths: /**/*.js,/**/*.css,/**/*.svg,/**/*.jpeg
|
paths: /**/*.js,/**/*.css,/**/*.svg,/**/*.jpeg
|
||||||
app:
|
|
||||||
isGenomDeTestSubmission: true
|
|
||||||
server:
|
server:
|
||||||
forward-headers-strategy: framework
|
forward-headers-strategy: framework
|
||||||
|
7
src/main/resources/banner.txt
Normal file
7
src/main/resources/banner.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
__ _ _ _ _
|
||||||
|
_ __ _____ __/ /_ | || | ___ ___| |_| | _ __ _ __ ___ ___ ___ ___ ___ ___ _ __
|
||||||
|
| '_ ` _ \ \ / / '_ \| || |_ / _ \_____ / _ \ __| |_____| '_ \| '__/ _ \ / __/ _ \/ __/ __|/ _ \| '__|
|
||||||
|
| | | | | \ V /| (_) |__ _| __/_____| __/ |_| |_____| |_) | | | (_) | (_| __/\__ \__ \ (_) | |
|
||||||
|
|_| |_| |_|\_/ \___/ |_| \___| \___|\__|_| | .__/|_| \___/ \___\___||___/___/\___/|_|
|
||||||
|
|_|
|
||||||
|
:: mv64e-etl-processor :: ${application.formatted-version}
|
@@ -52,8 +52,10 @@
|
|||||||
<td th:if="${request.status.value.contains('success')}" class="bg-green"><small>[[ ${request.status} ]]</small></td>
|
<td th:if="${request.status.value.contains('success')}" class="bg-green"><small>[[ ${request.status} ]]</small></td>
|
||||||
<td th:if="${request.status.value.contains('warning')}" class="bg-yellow"><small>[[ ${request.status} ]]</small></td>
|
<td th:if="${request.status.value.contains('warning')}" class="bg-yellow"><small>[[ ${request.status} ]]</small></td>
|
||||||
<td th:if="${request.status.value.contains('error')}" class="bg-red"><small>[[ ${request.status} ]]</small></td>
|
<td th:if="${request.status.value.contains('error')}" class="bg-red"><small>[[ ${request.status} ]]</small></td>
|
||||||
<td th:if="${request.status.value == 'unknown'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
|
<td th:if="${request.status.value == 'unknown' and not request.isPendingUnknown()}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
|
||||||
|
<td th:if="${request.status.value == 'unknown' and request.isPendingUnknown()}" class="bg-yellow"><small>⏰ [[ ${request.status} ]] ⏰</small></td>
|
||||||
<td th:if="${request.status.value == 'duplication'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
|
<td th:if="${request.status.value == 'duplication'}" class="bg-gray"><small>[[ ${request.status} ]]</small></td>
|
||||||
|
<td th:if="${request.status.value == 'no-consent'}" class="bg-blue"><small>[[ ${request.status} ]]</small></td>
|
||||||
<td th:style="${request.type.value == 'delete'} ? 'color: red;'"><small>[[ ${request.type} ]]</small></td>
|
<td th:style="${request.type.value == 'delete'} ? 'color: red;'"><small>[[ ${request.type} ]]</small></td>
|
||||||
<td th:if="not ${request.report}">[[ ${request.uuid} ]]</td>
|
<td th:if="not ${request.report}">[[ ${request.uuid} ]]</td>
|
||||||
<td th:if="${request.report}">
|
<td th:if="${request.report}">
|
||||||
@@ -100,4 +102,4 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -24,14 +24,15 @@ import java.time.Instant;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||||
import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError;
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError;
|
||||||
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||||
|
|
||||||
@ContextConfiguration(classes = {AppConfiguration.class, ObjectMapper.class})
|
@ContextConfiguration(classes = {AppConfiguration.class, ObjectMapper.class})
|
||||||
@TestPropertySource(properties = {
|
@TestPropertySource(properties = {
|
||||||
"app.consent.service=gics",
|
"app.consent.service=gics",
|
||||||
"app.consent.gics.uri=http://localhost:8090/ttp-fhir/fhir/gics"
|
"app.consent.gics.uri=http://localhost:8090/ttp-fhir/fhir/gics"
|
||||||
})
|
})
|
||||||
@RestClientTest
|
@RestClientTest
|
||||||
class GicsConsentServiceTest {
|
class GicsConsentServiceTest {
|
||||||
@@ -46,8 +47,8 @@ class GicsConsentServiceTest {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp(
|
void setUp(
|
||||||
@Autowired AppFhirConfig appFhirConfig,
|
@Autowired AppFhirConfig appFhirConfig,
|
||||||
@Autowired GIcsConfigProperties gIcsConfigProperties
|
@Autowired GIcsConfigProperties gIcsConfigProperties
|
||||||
) {
|
) {
|
||||||
this.appFhirConfig = appFhirConfig;
|
this.appFhirConfig = appFhirConfig;
|
||||||
this.gIcsConfigProperties = gIcsConfigProperties;
|
this.gIcsConfigProperties = gIcsConfigProperties;
|
||||||
@@ -56,33 +57,33 @@ class GicsConsentServiceTest {
|
|||||||
|
|
||||||
this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate);
|
this.mockRestServiceServer = MockRestServiceServer.createServer(restTemplate);
|
||||||
this.gicsConsentService = new GicsConsentService(
|
this.gicsConsentService = new GicsConsentService(
|
||||||
this.gIcsConfigProperties,
|
this.gIcsConfigProperties,
|
||||||
RetryTemplate.builder().maxAttempts(1).build(),
|
RetryTemplate.builder().maxAttempts(1).build(),
|
||||||
restTemplate,
|
restTemplate,
|
||||||
this.appFhirConfig
|
this.appFhirConfig
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldReturnTtpBroadConsentStatus() {
|
void shouldReturnTtpBroadConsentStatus() {
|
||||||
final Parameters consentedResponse = new Parameters()
|
final Parameters consentedResponse = new Parameters()
|
||||||
.addParameter(
|
.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("consented")
|
.setName("consented")
|
||||||
.setValue(new BooleanType().setValue(true))
|
.setValue(new BooleanType().setValue(true))
|
||||||
);
|
);
|
||||||
|
|
||||||
mockRestServiceServer
|
mockRestServiceServer
|
||||||
.expect(
|
.expect(
|
||||||
requestTo(
|
requestTo(
|
||||||
"http://localhost:8090/ttp-fhir/fhir/gics" + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
"http://localhost:8090/ttp-fhir/fhir/gics" + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
||||||
)
|
|
||||||
.andRespond(
|
|
||||||
withSuccess(
|
|
||||||
appFhirConfig.fhirContext().newJsonParser().encodeResourceToString(consentedResponse),
|
|
||||||
MediaType.APPLICATION_JSON
|
|
||||||
)
|
)
|
||||||
);
|
.andRespond(
|
||||||
|
withSuccess(
|
||||||
|
appFhirConfig.fhirContext().newJsonParser().encodeResourceToString(consentedResponse),
|
||||||
|
MediaType.APPLICATION_JSON
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
||||||
assertThat(consentStatus).isEqualTo(TtpConsentStatus.BROAD_CONSENT_GIVEN);
|
assertThat(consentStatus).isEqualTo(TtpConsentStatus.BROAD_CONSENT_GIVEN);
|
||||||
@@ -91,22 +92,22 @@ class GicsConsentServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldReturnRevokedConsent() {
|
void shouldReturnRevokedConsent() {
|
||||||
final Parameters revokedResponse = new Parameters()
|
final Parameters revokedResponse = new Parameters()
|
||||||
.addParameter(
|
.addParameter(
|
||||||
new ParametersParameterComponent()
|
new ParametersParameterComponent()
|
||||||
.setName("consented")
|
.setName("consented")
|
||||||
.setValue(new BooleanType().setValue(false))
|
.setValue(new BooleanType().setValue(false))
|
||||||
);
|
);
|
||||||
|
|
||||||
mockRestServiceServer
|
mockRestServiceServer
|
||||||
.expect(
|
.expect(
|
||||||
requestTo(
|
requestTo(
|
||||||
"http://localhost:8090/ttp-fhir/fhir/gics" + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
"http://localhost:8090/ttp-fhir/fhir/gics" + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
||||||
)
|
)
|
||||||
.andRespond(
|
.andRespond(
|
||||||
withSuccess(
|
withSuccess(
|
||||||
appFhirConfig.fhirContext().newJsonParser().encodeResourceToString(revokedResponse),
|
appFhirConfig.fhirContext().newJsonParser().encodeResourceToString(revokedResponse),
|
||||||
MediaType.APPLICATION_JSON)
|
MediaType.APPLICATION_JSON)
|
||||||
);
|
);
|
||||||
|
|
||||||
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
||||||
assertThat(consentStatus).isEqualTo(TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED);
|
assertThat(consentStatus).isEqualTo(TtpConsentStatus.BROAD_CONSENT_MISSING_OR_REJECTED);
|
||||||
@@ -116,23 +117,23 @@ class GicsConsentServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldReturnInvalidParameterResponse() {
|
void shouldReturnInvalidParameterResponse() {
|
||||||
final OperationOutcome responseWithErrorOutcome = new OperationOutcome()
|
final OperationOutcome responseWithErrorOutcome = new OperationOutcome()
|
||||||
.addIssue(
|
.addIssue(
|
||||||
new OperationOutcomeIssueComponent()
|
new OperationOutcomeIssueComponent()
|
||||||
.setSeverity(IssueSeverity.ERROR)
|
.setSeverity(IssueSeverity.ERROR)
|
||||||
.setCode(IssueType.PROCESSING)
|
.setCode(IssueType.PROCESSING)
|
||||||
.setDiagnostics("Invalid policy parameter...")
|
.setDiagnostics("Invalid policy parameter...")
|
||||||
);
|
);
|
||||||
|
|
||||||
mockRestServiceServer
|
mockRestServiceServer
|
||||||
.expect(
|
.expect(
|
||||||
requestTo(GICS_BASE_URI + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
requestTo(GICS_BASE_URI + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
||||||
)
|
|
||||||
.andRespond(
|
|
||||||
withSuccess(
|
|
||||||
appFhirConfig.fhirContext().newJsonParser().encodeResourceToString(responseWithErrorOutcome),
|
|
||||||
MediaType.APPLICATION_JSON
|
|
||||||
)
|
)
|
||||||
);
|
.andRespond(
|
||||||
|
withSuccess(
|
||||||
|
appFhirConfig.fhirContext().newJsonParser().encodeResourceToString(responseWithErrorOutcome),
|
||||||
|
MediaType.APPLICATION_JSON
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
||||||
assertThat(consentStatus).isEqualTo(TtpConsentStatus.FAILED_TO_ASK);
|
assertThat(consentStatus).isEqualTo(TtpConsentStatus.FAILED_TO_ASK);
|
||||||
@@ -141,12 +142,12 @@ class GicsConsentServiceTest {
|
|||||||
@Test
|
@Test
|
||||||
void shouldReturnRequestError() {
|
void shouldReturnRequestError() {
|
||||||
mockRestServiceServer
|
mockRestServiceServer
|
||||||
.expect(
|
.expect(
|
||||||
requestTo(GICS_BASE_URI + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
requestTo(GICS_BASE_URI + GicsConsentService.IS_CONSENTED_ENDPOINT)
|
||||||
)
|
)
|
||||||
.andRespond(
|
.andRespond(
|
||||||
withServerError()
|
withServerError()
|
||||||
);
|
);
|
||||||
|
|
||||||
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
var consentStatus = gicsConsentService.getTtpBroadConsentStatus("123456");
|
||||||
assertThat(consentStatus).isEqualTo(TtpConsentStatus.FAILED_TO_ASK);
|
assertThat(consentStatus).isEqualTo(TtpConsentStatus.FAILED_TO_ASK);
|
||||||
@@ -156,26 +157,29 @@ class GicsConsentServiceTest {
|
|||||||
void buildRequestParameterCurrentPolicyStatesForPersonTest() {
|
void buildRequestParameterCurrentPolicyStatesForPersonTest() {
|
||||||
String pid = "12345678";
|
String pid = "12345678";
|
||||||
var result = gicsConsentService
|
var result = gicsConsentService
|
||||||
.buildRequestParameterCurrentPolicyStatesForPerson(
|
.buildRequestParameterCurrentPolicyStatesForPerson(
|
||||||
pid,
|
pid,
|
||||||
Date.from(Instant.now()),
|
Date.from(Instant.now()),
|
||||||
ConsentDomain.MODELLVORHABEN_64E
|
ConsentDomain.MODELLVORHABEN_64E
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThat(result.getParameter())
|
assertThat(result.getParameter())
|
||||||
.as("should contain 3 parameter resources")
|
.as("should contain 3 parameter resources")
|
||||||
.hasSize(3);
|
.hasSize(3);
|
||||||
|
|
||||||
assertThat(((StringType) result.getParameter("domain").getValue()).getValue())
|
assertThat(((StringType) result.getParameter("domain").getValue()).getValue())
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
gIcsConfigProperties.getGenomDeConsentDomainName()
|
gIcsConfigProperties.getGenomDeConsentDomainName()
|
||||||
);
|
);
|
||||||
|
|
||||||
assertThat(((Identifier) result.getParameter("personIdentifier").getValue()).getValue())
|
assertThat(((Identifier) result.getParameter("personIdentifier").getValue()).getValue())
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
pid
|
pid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void convertGicsResultToMiiBroadConsent() {
|
||||||
|
fail("todo: implement Test gicsConsentService.convertGicsResultToMiiBroadConsent");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -244,7 +244,14 @@ class KafkaInputListenerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun shouldNotProcessDnpmV2Request() {
|
fun shouldProcessDnpmV2Request() {
|
||||||
|
whenever(consentEvaluator.check(any())).thenReturn(
|
||||||
|
ConsentEvaluation(
|
||||||
|
TtpConsentStatus.BROAD_CONSENT_GIVEN,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
val mtbFile = Mtb.builder()
|
val mtbFile = Mtb.builder()
|
||||||
.patient(Patient.builder().id("DUMMY_12345678").build())
|
.patient(Patient.builder().id("DUMMY_12345678").build())
|
||||||
.metadata(
|
.metadata(
|
||||||
@@ -285,7 +292,7 @@ class KafkaInputListenerTest {
|
|||||||
Optional.empty()
|
Optional.empty()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
verify(requestProcessor, times(0)).processDeletion(
|
verify(requestProcessor, times(1)).processDeletion(
|
||||||
anyValueClass(), anyValueClass(), eq(
|
anyValueClass(), anyValueClass(), eq(
|
||||||
TtpConsentStatus.UNKNOWN_CHECK_FILE
|
TtpConsentStatus.UNKNOWN_CHECK_FILE
|
||||||
)
|
)
|
||||||
|
@@ -163,6 +163,8 @@ class KafkaMtbFileSenderTest {
|
|||||||
assertThat(captor.firstValue.key()).isEqualTo("{\"pid\": \"PID\"}")
|
assertThat(captor.firstValue.key()).isEqualTo("{\"pid\": \"PID\"}")
|
||||||
assertThat(captor.firstValue.headers().headers("contentType")).isNotNull
|
assertThat(captor.firstValue.headers().headers("contentType")).isNotNull
|
||||||
assertThat(captor.firstValue.headers().headers("contentType")?.firstOrNull()?.value()).isEqualTo(CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray())
|
assertThat(captor.firstValue.headers().headers("contentType")?.firstOrNull()?.value()).isEqualTo(CustomMediaType.APPLICATION_VND_DNPM_V2_MTB_JSON_VALUE.toByteArray())
|
||||||
|
assertThat(captor.firstValue.headers().headers("requestId")).isNotNull
|
||||||
|
assertThat(captor.firstValue.headers().headers("requestId")?.firstOrNull()?.value()).isEqualTo(TEST_REQUEST_ID.value.toByteArray())
|
||||||
assertThat(captor.firstValue.value()).isNotNull
|
assertThat(captor.firstValue.value()).isNotNull
|
||||||
assertThat(captor.firstValue.value()).isEqualTo(objectMapper.writeValueAsString(dnmpV2kafkaRecordData(TEST_REQUEST_ID)))
|
assertThat(captor.firstValue.value()).isEqualTo(objectMapper.writeValueAsString(dnmpV2kafkaRecordData(TEST_REQUEST_ID)))
|
||||||
}
|
}
|
||||||
|
@@ -80,7 +80,7 @@ class ConsentProcessorTest {
|
|||||||
val checkResult = consentProcessor.consentGatedCheckAndTryEmbedding(inputMtb)
|
val checkResult = consentProcessor.consentGatedCheckAndTryEmbedding(inputMtb)
|
||||||
|
|
||||||
assertThat(checkResult).isTrue
|
assertThat(checkResult).isTrue
|
||||||
assertThat(inputMtb.metadata.researchConsents).hasSize(26)
|
assertThat(inputMtb.metadata.researchConsents).isNotEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
Reference in New Issue
Block a user