summaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorPaul-Christian Volkmer2026-05-12 09:51:22 +0200
committerGitHub2026-05-12 07:51:22 +0000
commit6c50e2b76e78b44d65de9d68b842a9f77bab85c3 (patch)
treea33d8e5dbe3162d785ed8a3b64f0c72456927b0f /src/main
parentf6351d7a431bc539b4e57da94b4c5da87bcb262e (diff)
feat: use Jackson 3 for JSON serde (#286)
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/AbstractConsentService.java2
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/ConsentDomain.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/GicsConsentService.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/GicsGetBroadConsentService.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/IConsentService.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/MiiBroadConsentEvaluator.java2
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/MtbFileConsentService.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/consent/TtpConsentStatus.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/pseudonym/Generator.java3
-rw-r--r--src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java3
-rw-r--r--src/main/java/dev/dnpm/etl/processor/pseudonym/PseudonymRequestFailed.java20
-rw-r--r--src/main/java/dev/dnpm/etl/processor/pseudonym/PsnDomainType.java20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/EtlProcessorApplication.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/Exceptions.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/ServletInitializer.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt525
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppFhirConfig.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppJdbcConfiguration.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt17
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AppWebConfig.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/AuditConfiguration.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/Jackson2Config.kt85
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/config/JacksonConfig.kt67
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/consent/ConsentEvaluator.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/functions.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/input/KafkaInputListener.kt9
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/input/MtbFileRestController.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/ReportService.kt96
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestStatus.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestType.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/monitoring/SubmissionType.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSender.kt11
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/output/MtbFileSender.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/output/MtbRequest.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSender.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/output/RestMtbFileSender.kt2
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/pseudonym/AnonymizingGenerator.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapPseudonymGenerator.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapService.kt20
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeService.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/pseudonym/extensions.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/security/TokenService.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/security/UserRole.kt4
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/security/UserRoleService.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/services/ConsentProcessor.kt37
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/services/RequestProcessor.kt8
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/services/ResponseProcessor.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/services/TransformationService.kt13
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessor.kt98
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/types.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/ApplicationControllerAdvice.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt3
-rw-r--r--src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt10
-rw-r--r--src/main/resources/static/icon.svg2
-rw-r--r--src/main/resources/static/user.svg1
-rw-r--r--src/main/resources/templates/report.html2
65 files changed, 917 insertions, 467 deletions
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/AbstractConsentService.java b/src/main/java/dev/dnpm/etl/processor/consent/AbstractConsentService.java
index 5c9878c..1dcb74e 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/AbstractConsentService.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/AbstractConsentService.java
@@ -2,7 +2,7 @@
* This file is part of ETL-Processor
*
* Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
- * Copyright (c) 2023-2025 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/ConsentDomain.java b/src/main/java/dev/dnpm/etl/processor/consent/ConsentDomain.java
index e339ba4..9c0359a 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/ConsentDomain.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/ConsentDomain.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.consent;
public enum ConsentDomain {
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/GicsConsentService.java b/src/main/java/dev/dnpm/etl/processor/consent/GicsConsentService.java
index d445182..20fa3c4 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/GicsConsentService.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/GicsConsentService.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.consent;
import dev.dnpm.etl.processor.config.AppFhirConfig;
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/GicsGetBroadConsentService.java b/src/main/java/dev/dnpm/etl/processor/consent/GicsGetBroadConsentService.java
index d657306..2439e44 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/GicsGetBroadConsentService.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/GicsGetBroadConsentService.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.consent;
import dev.dnpm.etl.processor.config.AppFhirConfig;
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/IConsentService.java b/src/main/java/dev/dnpm/etl/processor/consent/IConsentService.java
index f9230ec..43c000c 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/IConsentService.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/IConsentService.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.consent;
import java.util.Date;
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/MiiBroadConsentEvaluator.java b/src/main/java/dev/dnpm/etl/processor/consent/MiiBroadConsentEvaluator.java
index c815f7a..28ee6be 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/MiiBroadConsentEvaluator.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/MiiBroadConsentEvaluator.java
@@ -2,7 +2,7 @@
* This file is part of ETL-Processor
*
* Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
- * Copyright (c) 2023-2025 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/MtbFileConsentService.java b/src/main/java/dev/dnpm/etl/processor/consent/MtbFileConsentService.java
index cc8107f..db9d690 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/MtbFileConsentService.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/MtbFileConsentService.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.consent;
import java.util.Date;
diff --git a/src/main/java/dev/dnpm/etl/processor/consent/TtpConsentStatus.java b/src/main/java/dev/dnpm/etl/processor/consent/TtpConsentStatus.java
index b92f58d..7aacb20 100644
--- a/src/main/java/dev/dnpm/etl/processor/consent/TtpConsentStatus.java
+++ b/src/main/java/dev/dnpm/etl/processor/consent/TtpConsentStatus.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.consent;
public enum TtpConsentStatus {
diff --git a/src/main/java/dev/dnpm/etl/processor/pseudonym/Generator.java b/src/main/java/dev/dnpm/etl/processor/pseudonym/Generator.java
index e72a8f8..79e90db 100644
--- a/src/main/java/dev/dnpm/etl/processor/pseudonym/Generator.java
+++ b/src/main/java/dev/dnpm/etl/processor/pseudonym/Generator.java
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java b/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
index 478c5c9..b4641aa 100644
--- a/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
+++ b/src/main/java/dev/dnpm/etl/processor/pseudonym/GpasPseudonymGenerator.java
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2024-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/java/dev/dnpm/etl/processor/pseudonym/PseudonymRequestFailed.java b/src/main/java/dev/dnpm/etl/processor/pseudonym/PseudonymRequestFailed.java
index 397455a..b1a215e 100644
--- a/src/main/java/dev/dnpm/etl/processor/pseudonym/PseudonymRequestFailed.java
+++ b/src/main/java/dev/dnpm/etl/processor/pseudonym/PseudonymRequestFailed.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.pseudonym;
public class PseudonymRequestFailed extends RuntimeException {
diff --git a/src/main/java/dev/dnpm/etl/processor/pseudonym/PsnDomainType.java b/src/main/java/dev/dnpm/etl/processor/pseudonym/PsnDomainType.java
index 55cb212..b1cec26 100644
--- a/src/main/java/dev/dnpm/etl/processor/pseudonym/PsnDomainType.java
+++ b/src/main/java/dev/dnpm/etl/processor/pseudonym/PsnDomainType.java
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.pseudonym;
public enum PsnDomainType {
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/EtlProcessorApplication.kt b/src/main/kotlin/dev/dnpm/etl/processor/EtlProcessorApplication.kt
index 75147ea..26d87da 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/EtlProcessorApplication.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/EtlProcessorApplication.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/Exceptions.kt b/src/main/kotlin/dev/dnpm/etl/processor/Exceptions.kt
index 1c590fc..92eff9a 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/Exceptions.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/Exceptions.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/ServletInitializer.kt b/src/main/kotlin/dev/dnpm/etl/processor/ServletInitializer.kt
index e35cddf..1963bd3 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/ServletInitializer.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/ServletInitializer.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt
index 63f50a6..01bab32 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfigProperties.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt
index 61f3c40..1c18aab 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppConfiguration.kt
@@ -2,7 +2,7 @@
* This file is part of ETL-Processor
*
* Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
- * Copyright (c) 2023-2025 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -45,7 +45,7 @@ import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.ConfigurationCondition
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration
import org.springframework.http.converter.StringHttpMessageConverter
-import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
+import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter
import org.springframework.retry.RetryCallback
import org.springframework.retry.RetryContext
import org.springframework.retry.RetryListener
@@ -58,6 +58,7 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager
import org.springframework.web.client.HttpClientErrorException
import org.springframework.web.client.RestTemplate
import reactor.core.publisher.Sinks
+import tools.jackson.databind.json.JsonMapper
import kotlin.time.Duration.Companion.seconds
import kotlin.time.toJavaDuration
@@ -75,280 +76,276 @@ import kotlin.time.toJavaDuration
@EnableScheduling
class AppConfiguration {
- private val logger = LoggerFactory.getLogger(AppConfiguration::class.java)
-
- fun stringHttpMessageConverter(): StringHttpMessageConverter {
- return StringHttpMessageConverter()
- }
-
- @Bean
- fun mappingJacksonHttpMessageConverter(
- objectMapper: ObjectMapper
- ): MappingJackson2HttpMessageConverter {
- val converter = MappingJackson2HttpMessageConverter()
- converter.setObjectMapper(objectMapper)
- return converter
- }
-
- @Bean
- fun restTemplate(objectMapper: ObjectMapper): RestTemplate {
- return RestTemplateBuilder()
- .messageConverters(
- stringHttpMessageConverter(),
- mappingJacksonHttpMessageConverter(objectMapper),
+ private val logger = LoggerFactory.getLogger(AppConfiguration::class.java)
+
+ fun stringHttpMessageConverter(): StringHttpMessageConverter {
+ return StringHttpMessageConverter()
+ }
+
+ @Bean
+ fun jacksonJsonHttpMapperConverter(jsonMapper: JsonMapper): JacksonJsonHttpMessageConverter {
+ return JacksonJsonHttpMessageConverter(jsonMapper)
+ }
+
+ @Bean
+ fun restTemplate(jsonMapper: JsonMapper): RestTemplate {
+ return RestTemplateBuilder()
+ .messageConverters(
+ stringHttpMessageConverter(),
+ jacksonJsonHttpMapperConverter(jsonMapper),
+ )
+ .build()
+ }
+
+ @Bean
+ fun appFhirConfig(): AppFhirConfig {
+ return AppFhirConfig()
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
+ @ConditionalOnProperty(value = ["app.pseudonymize.gpas.soap-endpoint"])
+ @Bean
+ fun gpasSoapProxyFactoryBean(gpasConfigProperties: GPasConfigProperties): JaxWsProxyFactoryBean {
+ val proxyFactory = JaxWsProxyFactoryBean()
+ proxyFactory.serviceClass = GpasSoapService::class.java
+ proxyFactory.address = gpasConfigProperties.soapEndpoint
+ return proxyFactory
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
+ @ConditionalOnProperty(value = ["app.pseudonymize.gpas.soap-endpoint"])
+ @Bean
+ fun gpasSoapProxy(gpasConfigProperties: GPasConfigProperties): GpasSoapService {
+ return gpasSoapProxyFactoryBean(gpasConfigProperties).create() as GpasSoapService
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
+ @ConditionalOnProperty(value = ["app.pseudonymize.gpas.soap-endpoint"])
+ @Bean
+ fun gpasSoapPseudonymGenerator(
+ configProperties: GPasConfigProperties,
+ retryTemplate: RetryTemplate,
+ gpasSoapService: GpasSoapService,
+ appFhirConfig: AppFhirConfig,
+ ): Generator {
+ logger.info("Selected 'GpasSoapPseudonym Generator'")
+ return GpasSoapPseudonymGenerator(
+ configProperties,
+ retryTemplate,
+ gpasSoapService,
+ appFhirConfig,
)
- .build()
- }
-
- @Bean
- fun appFhirConfig(): AppFhirConfig {
- return AppFhirConfig()
- }
-
- @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
- @ConditionalOnProperty(value = ["app.pseudonymize.gpas.soap-endpoint"])
- @Bean
- fun gpasSoapProxyFactoryBean(gpasConfigProperties: GPasConfigProperties): JaxWsProxyFactoryBean {
- val proxyFactory = JaxWsProxyFactoryBean()
- proxyFactory.serviceClass = GpasSoapService::class.java
- proxyFactory.address = gpasConfigProperties.soapEndpoint
- return proxyFactory
- }
-
- @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
- @ConditionalOnProperty(value = ["app.pseudonymize.gpas.soap-endpoint"])
- @Bean
- fun gpasSoapProxy(gpasConfigProperties: GPasConfigProperties): GpasSoapService {
- return gpasSoapProxyFactoryBean(gpasConfigProperties).create() as GpasSoapService
- }
-
- @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
- @ConditionalOnProperty(value = ["app.pseudonymize.gpas.soap-endpoint"])
- @Bean
- fun gpasSoapPseudonymGenerator(
- configProperties: GPasConfigProperties,
- retryTemplate: RetryTemplate,
- gpasSoapService: GpasSoapService,
- appFhirConfig: AppFhirConfig,
- ): Generator {
- logger.info("Selected 'GpasSoapPseudonym Generator'")
- return GpasSoapPseudonymGenerator(
- configProperties,
- retryTemplate,
- gpasSoapService,
- appFhirConfig,
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
+ @ConditionalOnProperty(value = ["app.pseudonymize.gpas.uri"])
+ @Bean
+ fun gpasPseudonymGenerator(
+ configProperties: GPasConfigProperties,
+ retryTemplate: RetryTemplate,
+ restTemplate: RestTemplate,
+ appFhirConfig: AppFhirConfig,
+ ): Generator {
+ logger.info("Selected 'GpasPseudonym Generator'")
+ return GpasPseudonymGenerator(configProperties, retryTemplate, restTemplate, appFhirConfig)
+ }
+
+ @ConditionalOnProperty(
+ value = ["app.pseudonymize.generator"],
+ havingValue = "BUILDIN",
+ matchIfMissing = true,
)
- }
-
- @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
- @ConditionalOnProperty(value = ["app.pseudonymize.gpas.uri"])
- @Bean
- fun gpasPseudonymGenerator(
- configProperties: GPasConfigProperties,
- retryTemplate: RetryTemplate,
- restTemplate: RestTemplate,
- appFhirConfig: AppFhirConfig,
- ): Generator {
- logger.info("Selected 'GpasPseudonym Generator'")
- return GpasPseudonymGenerator(configProperties, retryTemplate, restTemplate, appFhirConfig)
- }
-
- @ConditionalOnProperty(
- value = ["app.pseudonymize.generator"],
- havingValue = "BUILDIN",
- matchIfMissing = true,
- )
- @Bean
- fun buildinPseudonymGenerator(): Generator {
- logger.info("Selected 'BUILDIN Pseudonym Generator'")
- return AnonymizingGenerator()
- }
-
- @Bean
- fun pseudonymizeService(
- generator: Generator,
- pseudonymizeConfigProperties: PseudonymizeConfigProperties,
- ): PseudonymizeService {
- return PseudonymizeService(generator, pseudonymizeConfigProperties)
- }
-
- @Bean
- fun reportService(): ReportService {
- return ReportService(getObjectMapper())
- }
-
- @Bean
- fun getObjectMapper(): ObjectMapper {
- return JacksonConfig().objectMapper()
- }
-
- @Bean
- fun transformationService(configProperties: AppConfigProperties): TransformationService {
- logger.info("Apply ${configProperties.transformations.size} transformation rules")
- return TransformationService(
- getObjectMapper(),
- configProperties.transformations.map { Transformation.of(it.path) from it.from to it.to },
- )
- }
-
- @Bean
- fun retryTemplate(configProperties: AppConfigProperties): RetryTemplate {
- return RetryTemplateBuilder()
- .notRetryOn(IllegalArgumentException::class.java)
- .notRetryOn(HttpClientErrorException.BadRequest::class.java)
- .notRetryOn(HttpClientErrorException.UnprocessableContent::class.java)
- .exponentialBackoff(2.seconds.toJavaDuration(), 1.25, 5.seconds.toJavaDuration())
- .customPolicy(SimpleRetryPolicy(configProperties.maxRetryAttempts))
- .withListener(
- object : RetryListener {
- override fun <T : Any, E : Throwable> onError(
- context: RetryContext,
- callback: RetryCallback<T, E>,
- throwable: Throwable,
- ) {
- logger.warn("Error occured: {}. Retrying {}", throwable.message, context.retryCount)
- }
- }
+ @Bean
+ fun buildinPseudonymGenerator(): Generator {
+ logger.info("Selected 'BUILDIN Pseudonym Generator'")
+ return AnonymizingGenerator()
+ }
+
+ @Bean
+ fun pseudonymizeService(
+ generator: Generator,
+ pseudonymizeConfigProperties: PseudonymizeConfigProperties,
+ ): PseudonymizeService {
+ return PseudonymizeService(generator, pseudonymizeConfigProperties)
+ }
+
+ @Bean
+ fun reportService(): ReportService {
+ return ReportService(getJsonMapper())
+ }
+
+ @Bean
+ fun getJsonMapper(): JsonMapper {
+ return JacksonConfig().jsonMapper()
+ }
+
+ @Bean
+ fun transformationService(configProperties: AppConfigProperties): TransformationService {
+ logger.info("Apply ${configProperties.transformations.size} transformation rules")
+ return TransformationService(
+ getJsonMapper(),
+ configProperties.transformations.map { Transformation.of(it.path) from it.from to it.to },
)
- .build()
- }
-
- @ConditionalOnProperty(value = ["app.security.enable-tokens"], havingValue = "true")
- @Bean
- fun tokenService(
- userDetailsManager: InMemoryUserDetailsManager,
- passwordEncoder: PasswordEncoder,
- tokenRepository: TokenRepository,
- ): TokenService {
- return TokenService(userDetailsManager, passwordEncoder, tokenRepository)
- }
-
- @Bean
- fun statisticsUpdateProducer(): Sinks.Many<Any> {
- return Sinks.many().multicast().directBestEffort()
- }
-
- @Bean
- fun connectionCheckUpdateProducer(): Sinks.Many<ConnectionCheckResult> {
- return Sinks.many().multicast().onBackpressureBuffer()
- }
-
- @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
- @Bean
- fun gPasConnectionCheckService(
- restTemplate: RestTemplate,
- gPasConfigProperties: GPasConfigProperties,
- connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
- ): ConnectionCheckService {
- return GPasConnectionCheckService(
- restTemplate,
- gPasConfigProperties,
- connectionCheckUpdateProducer,
- )
- }
-
- @ConditionalOnProperty(value = ["app.pseudonymizer"], havingValue = "GPAS")
- @ConditionalOnMissingBean
- @Bean
- fun gPasConnectionCheckServiceOnDeprecatedProperty(
- restTemplate: RestTemplate,
- gPasConfigProperties: GPasConfigProperties,
- connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
- ): ConnectionCheckService {
- return GPasConnectionCheckService(
- restTemplate,
- gPasConfigProperties,
- connectionCheckUpdateProducer,
- )
- }
-
- @Bean
- fun jdbcConfiguration(): AbstractJdbcConfiguration {
- return AppJdbcConfiguration()
- }
-
- @Conditional(GicsEnabledCondition::class)
- @Bean
- fun gicsConsentService(
- gIcsConfigProperties: GIcsConfigProperties,
- retryTemplate: RetryTemplate,
- restTemplate: RestTemplate,
- appFhirConfig: AppFhirConfig,
- ): IConsentService {
- return GicsConsentService(gIcsConfigProperties, retryTemplate, restTemplate, appFhirConfig)
- }
-
- @Conditional(GicsGetBroadConsentEnabledCondition::class)
- @Bean
- fun gicsGetBroadConsentService(
- gIcsConfigProperties: GIcsConfigProperties,
- retryTemplate: RetryTemplate,
- restTemplate: RestTemplate,
- appFhirConfig: AppFhirConfig,
- ): IConsentService {
- return GicsGetBroadConsentService(
- gIcsConfigProperties,
- retryTemplate,
- restTemplate,
- appFhirConfig,
- )
- }
-
- @Conditional(GicsEnabledCondition::class)
- @Bean
- fun consentProcessor(
- configProperties: AppConfigProperties,
- gIcsConfigProperties: GIcsConfigProperties,
- getObjectMapper: ObjectMapper,
- appFhirConfig: AppFhirConfig,
- gicsConsentService: IConsentService,
- ): ConsentProcessor {
- return ConsentProcessor(
- configProperties,
- gIcsConfigProperties,
- getObjectMapper,
- appFhirConfig.fhirContext(),
- gicsConsentService,
- )
- }
-
- @Conditional(GicsEnabledCondition::class)
- @Bean
- fun gIcsConnectionCheckService(
- restTemplate: RestTemplate,
- gIcsConfigProperties: GIcsConfigProperties,
- connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
- ): ConnectionCheckService {
- return GIcsConnectionCheckService(
- restTemplate,
- gIcsConfigProperties,
- connectionCheckUpdateProducer,
- )
- }
+ }
+
+ @Bean
+ fun retryTemplate(configProperties: AppConfigProperties): RetryTemplate {
+ return RetryTemplateBuilder()
+ .notRetryOn(IllegalArgumentException::class.java)
+ .notRetryOn(HttpClientErrorException.BadRequest::class.java)
+ .notRetryOn(HttpClientErrorException.UnprocessableContent::class.java)
+ .exponentialBackoff(2.seconds.toJavaDuration(), 1.25, 5.seconds.toJavaDuration())
+ .customPolicy(SimpleRetryPolicy(configProperties.maxRetryAttempts))
+ .withListener(
+ object : RetryListener {
+ override fun <T : Any, E : Throwable> onError(
+ context: RetryContext,
+ callback: RetryCallback<T, E>,
+ throwable: Throwable,
+ ) {
+ logger.warn("Error occured: {}. Retrying {}", throwable.message, context.retryCount)
+ }
+ }
+ )
+ .build()
+ }
+
+ @ConditionalOnProperty(value = ["app.security.enable-tokens"], havingValue = "true")
+ @Bean
+ fun tokenService(
+ userDetailsManager: InMemoryUserDetailsManager,
+ passwordEncoder: PasswordEncoder,
+ tokenRepository: TokenRepository,
+ ): TokenService {
+ return TokenService(userDetailsManager, passwordEncoder, tokenRepository)
+ }
+
+ @Bean
+ fun statisticsUpdateProducer(): Sinks.Many<Any> {
+ return Sinks.many().multicast().directBestEffort()
+ }
+
+ @Bean
+ fun connectionCheckUpdateProducer(): Sinks.Many<ConnectionCheckResult> {
+ return Sinks.many().multicast().onBackpressureBuffer()
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymize.generator"], havingValue = "GPAS")
+ @Bean
+ fun gPasConnectionCheckService(
+ restTemplate: RestTemplate,
+ gPasConfigProperties: GPasConfigProperties,
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
+ ): ConnectionCheckService {
+ return GPasConnectionCheckService(
+ restTemplate,
+ gPasConfigProperties,
+ connectionCheckUpdateProducer,
+ )
+ }
+
+ @ConditionalOnProperty(value = ["app.pseudonymizer"], havingValue = "GPAS")
+ @ConditionalOnMissingBean
+ @Bean
+ fun gPasConnectionCheckServiceOnDeprecatedProperty(
+ restTemplate: RestTemplate,
+ gPasConfigProperties: GPasConfigProperties,
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
+ ): ConnectionCheckService {
+ return GPasConnectionCheckService(
+ restTemplate,
+ gPasConfigProperties,
+ connectionCheckUpdateProducer,
+ )
+ }
+
+ @Bean
+ fun jdbcConfiguration(): AbstractJdbcConfiguration {
+ return AppJdbcConfiguration()
+ }
+
+ @Conditional(GicsEnabledCondition::class)
+ @Bean
+ fun gicsConsentService(
+ gIcsConfigProperties: GIcsConfigProperties,
+ retryTemplate: RetryTemplate,
+ restTemplate: RestTemplate,
+ appFhirConfig: AppFhirConfig,
+ ): IConsentService {
+ return GicsConsentService(gIcsConfigProperties, retryTemplate, restTemplate, appFhirConfig)
+ }
+
+ @Conditional(GicsGetBroadConsentEnabledCondition::class)
+ @Bean
+ fun gicsGetBroadConsentService(
+ gIcsConfigProperties: GIcsConfigProperties,
+ retryTemplate: RetryTemplate,
+ restTemplate: RestTemplate,
+ appFhirConfig: AppFhirConfig,
+ ): IConsentService {
+ return GicsGetBroadConsentService(
+ gIcsConfigProperties,
+ retryTemplate,
+ restTemplate,
+ appFhirConfig,
+ )
+ }
+
+ @Conditional(GicsEnabledCondition::class)
+ @Bean
+ fun consentProcessor(
+ configProperties: AppConfigProperties,
+ gIcsConfigProperties: GIcsConfigProperties,
+ getObjectMapper: JsonMapper,
+ appFhirConfig: AppFhirConfig,
+ gicsConsentService: IConsentService,
+ ): ConsentProcessor {
+ return ConsentProcessor(
+ configProperties,
+ gIcsConfigProperties,
+ getObjectMapper,
+ appFhirConfig.fhirContext(),
+ gicsConsentService,
+ )
+ }
+
+ @Conditional(GicsEnabledCondition::class)
+ @Bean
+ fun gIcsConnectionCheckService(
+ restTemplate: RestTemplate,
+ gIcsConfigProperties: GIcsConfigProperties,
+ connectionCheckUpdateProducer: Sinks.Many<ConnectionCheckResult>,
+ ): ConnectionCheckService {
+ return GIcsConnectionCheckService(
+ restTemplate,
+ gIcsConfigProperties,
+ connectionCheckUpdateProducer,
+ )
+ }
- @Bean
- @ConditionalOnMissingBean
- fun iGetConsentService(): IConsentService {
- return MtbFileConsentService()
- }
+ @Bean
+ @ConditionalOnMissingBean
+ fun iGetConsentService(): IConsentService {
+ return MtbFileConsentService()
+ }
}
class GicsEnabledCondition :
AnyNestedCondition(ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN) {
- @ConditionalOnProperty(name = ["app.consent.service"], havingValue = "gics")
- @ConditionalOnProperty(name = ["app.consent.gics.uri"])
- class OnGicsServiceSelected {
- // Just for Condition
- }
+ @ConditionalOnProperty(name = ["app.consent.service"], havingValue = "gics")
+ @ConditionalOnProperty(name = ["app.consent.gics.uri"])
+ class OnGicsServiceSelected {
+ // Just for Condition
+ }
}
class GicsGetBroadConsentEnabledCondition :
AnyNestedCondition(ConfigurationCondition.ConfigurationPhase.REGISTER_BEAN) {
- @ConditionalOnProperty(name = ["app.consent.service"], havingValue = "gics_get_bc")
- @ConditionalOnProperty(name = ["app.consent.gics.uri"])
- class OnGicsGetBroadConsentServiceSelected {
- // Just for Condition
- }
+ @ConditionalOnProperty(name = ["app.consent.service"], havingValue = "gics_get_bc")
+ @ConditionalOnProperty(name = ["app.consent.gics.uri"])
+ class OnGicsGetBroadConsentServiceSelected {
+ // Just for Condition
+ }
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppFhirConfig.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppFhirConfig.kt
index 052822e..a7e6378 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppFhirConfig.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppFhirConfig.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.config
import ca.uhn.fhir.context.FhirContext
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppJdbcConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppJdbcConfiguration.kt
index 769faf3..a5bf1ae 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppJdbcConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppJdbcConfiguration.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.config
import dev.dnpm.etl.processor.Fingerprint
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt
index 24fc58c..aa3e6cb 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppKafkaConfiguration.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -19,7 +20,6 @@
package dev.dnpm.etl.processor.config
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.consent.ConsentEvaluator
import dev.dnpm.etl.processor.input.KafkaInputListener
import dev.dnpm.etl.processor.monitoring.ConnectionCheckResult
@@ -43,6 +43,7 @@ import org.springframework.kafka.listener.ContainerProperties
import org.springframework.kafka.listener.KafkaMessageListenerContainer
import org.springframework.retry.support.RetryTemplate
import reactor.core.publisher.Sinks
+import tools.jackson.databind.json.JsonMapper
@Configuration
@EnableConfigurationProperties(value = [KafkaProperties::class])
@@ -57,10 +58,10 @@ class AppKafkaConfiguration {
kafkaTemplate: KafkaTemplate<String, String>,
kafkaProperties: KafkaProperties,
retryTemplate: RetryTemplate,
- objectMapper: ObjectMapper,
+ jsonMapper: JsonMapper,
): MtbFileSender {
logger.info("Selected 'KafkaMtbFileSender'")
- return KafkaMtbFileSender(kafkaTemplate, kafkaProperties, retryTemplate, objectMapper)
+ return KafkaMtbFileSender(kafkaTemplate, kafkaProperties, retryTemplate, jsonMapper)
}
@Bean
@@ -77,8 +78,8 @@ class AppKafkaConfiguration {
@Bean
fun kafkaResponseProcessor(
applicationEventPublisher: ApplicationEventPublisher,
- objectMapper: ObjectMapper,
- ): KafkaResponseProcessor = KafkaResponseProcessor(applicationEventPublisher, objectMapper)
+ jsonMapper: JsonMapper,
+ ): KafkaResponseProcessor = KafkaResponseProcessor(applicationEventPublisher, jsonMapper)
@Bean
@ConditionalOnProperty(value = ["app.kafka.input-topic"])
@@ -99,9 +100,9 @@ class AppKafkaConfiguration {
@ConditionalOnProperty(value = ["app.kafka.input-topic"])
fun kafkaInputListener(
requestProcessor: RequestProcessor,
- objectMapper: ObjectMapper,
+ jsonMapper: JsonMapper,
consentEvaluator: ConsentEvaluator,
- ): KafkaInputListener = KafkaInputListener(requestProcessor, consentEvaluator, objectMapper)
+ ): KafkaInputListener = KafkaInputListener(requestProcessor, consentEvaluator, jsonMapper)
@Bean
fun kafkaConnectionCheckService(
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt
index 565209e..d10a32f 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppRestConfiguration.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt
index 60b1a9c..b87a1bd 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppSecurityConfiguration.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AppWebConfig.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AppWebConfig.kt
index 3aa50f2..7efa5c8 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AppWebConfig.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AppWebConfig.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.config
import org.springframework.boot.convert.ApplicationConversionService
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/AuditConfiguration.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/AuditConfiguration.kt
index 45763ee..1f392c0 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/AuditConfiguration.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/AuditConfiguration.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.config
import org.springframework.context.annotation.Bean
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/Jackson2Config.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/Jackson2Config.kt
new file mode 100644
index 0000000..27204d0
--- /dev/null
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/Jackson2Config.kt
@@ -0,0 +1,85 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package dev.dnpm.etl.processor.config
+
+import ca.uhn.fhir.context.FhirContext
+import com.fasterxml.jackson.annotation.JsonInclude
+import com.fasterxml.jackson.core.JsonGenerator
+import com.fasterxml.jackson.core.JsonParser
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
+import org.hl7.fhir.r4.model.Consent
+import org.springframework.context.annotation.Bean
+import org.springframework.context.annotation.Configuration
+
+/**
+ * @deprecated Use JacksonConfig instead
+ * @since 0.16
+ */
+@Deprecated("Use JacksonConfig instead")
+@Configuration
+class Jackson2Config {
+ companion object {
+ var fhirContext: FhirContext = FhirContext.forR4()
+
+ @JvmStatic fun fhirContext(): FhirContext = fhirContext
+ }
+
+ @Bean
+ fun objectMapper(): com.fasterxml.jackson.databind.ObjectMapper =
+ com.fasterxml.jackson.databind
+ .ObjectMapper()
+ .registerModule(Jackson2FhirResourceModule())
+ .disable(com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+ .registerModule(JavaTimeModule())
+ .registerModule(Jdk8Module())
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL)
+}
+
+class Jackson2FhirResourceModule : com.fasterxml.jackson.databind.module.SimpleModule() {
+ init {
+ addSerializer(Consent::class.java, Jackson2ConsentResourceSerializer())
+ addDeserializer(Consent::class.java, Jackson2ConsentResourceDeserializer())
+ }
+}
+
+class Jackson2ConsentResourceSerializer : com.fasterxml.jackson.databind.JsonSerializer<Consent>() {
+ override fun serialize(
+ value: Consent,
+ gen: JsonGenerator,
+ serializers: com.fasterxml.jackson.databind.SerializerProvider,
+ ) {
+ val json = Jackson2Config.fhirContext().newJsonParser().encodeResourceToString(value)
+ gen.writeRawValue(json)
+ }
+}
+
+class Jackson2ConsentResourceDeserializer : com.fasterxml.jackson.databind.JsonDeserializer<Consent>() {
+ override fun deserialize(
+ p: JsonParser?,
+ ctxt: com.fasterxml.jackson.databind.DeserializationContext?,
+ ): Consent {
+ val jsonNode = p?.readValueAsTree<com.fasterxml.jackson.databind.JsonNode>()
+ val json = jsonNode?.toString()
+
+ return Jackson2Config.fhirContext().newJsonParser().parseResource(json) as Consent
+ }
+}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/config/JacksonConfig.kt b/src/main/kotlin/dev/dnpm/etl/processor/config/JacksonConfig.kt
index 847880d..94f08c7 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/config/JacksonConfig.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/config/JacksonConfig.kt
@@ -1,19 +1,38 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.config
import ca.uhn.fhir.context.FhirContext
import com.fasterxml.jackson.annotation.JsonInclude
-import com.fasterxml.jackson.core.JsonGenerator
-import com.fasterxml.jackson.core.JsonParser
-import com.fasterxml.jackson.databind.*
-import com.fasterxml.jackson.databind.module.SimpleModule
-import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
-import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import org.hl7.fhir.r4.model.Consent
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
+import tools.jackson.databind.*
+import tools.jackson.databind.json.JsonMapper
+import tools.jackson.databind.module.SimpleModule
+import tools.jackson.module.kotlin.KotlinModule
@Configuration
class JacksonConfig {
+
companion object {
var fhirContext: FhirContext = FhirContext.forR4()
@@ -21,36 +40,38 @@ class JacksonConfig {
}
@Bean
- fun objectMapper(): ObjectMapper =
- ObjectMapper()
- .registerModule(Jackson2FhirResourceModule())
- .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
- .registerModule(JavaTimeModule())
- .registerModule(Jdk8Module())
- .setSerializationInclusion(JsonInclude.Include.NON_NULL)
+ fun jsonMapper(): JsonMapper =
+ JsonMapper
+ .builder()
+ .addModule(JacksonFhirResourceModule())
+ .addModule(KotlinModule.Builder().build())
+ .changeDefaultPropertyInclusion {
+ it.withContentInclusion(JsonInclude.Include.NON_NULL)
+ it.withValueInclusion(JsonInclude.Include.NON_NULL)
+ }.build()
}
-class Jackson2FhirResourceModule : SimpleModule() {
+class JacksonFhirResourceModule : SimpleModule() {
init {
- addSerializer(Consent::class.java, Jackson2ConsentResourceSerializer())
- addDeserializer(Consent::class.java, Jackson2ConsentResourceDeserializer())
+ addSerializer(Consent::class.java, JacksonConsentResourceSerializer())
+ addDeserializer(Consent::class.java, JacksonConsentResourceDeserializer())
}
}
-class Jackson2ConsentResourceSerializer : JsonSerializer<Consent>() {
+class JacksonConsentResourceSerializer : ValueSerializer<Consent>() {
override fun serialize(
- value: Consent,
- gen: JsonGenerator,
- serializers: SerializerProvider,
+ value: Consent?,
+ gen: tools.jackson.core.JsonGenerator?,
+ ctxt: SerializationContext?,
) {
val json = JacksonConfig.fhirContext().newJsonParser().encodeResourceToString(value)
- gen.writeRawValue(json)
+ gen?.writeRawValue(json)
}
}
-class Jackson2ConsentResourceDeserializer : JsonDeserializer<Consent>() {
+class JacksonConsentResourceDeserializer : ValueDeserializer<Consent>() {
override fun deserialize(
- p: JsonParser?,
+ p: tools.jackson.core.JsonParser?,
ctxt: DeserializationContext?,
): Consent {
val jsonNode = p?.readValueAsTree<JsonNode>()
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/consent/ConsentEvaluator.kt b/src/main/kotlin/dev/dnpm/etl/processor/consent/ConsentEvaluator.kt
index 58f647f..a8b8fdb 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/consent/ConsentEvaluator.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/consent/ConsentEvaluator.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/functions.kt b/src/main/kotlin/dev/dnpm/etl/processor/functions.kt
index aa4fc75..8326ad0 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/functions.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/functions.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2026 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/input/KafkaInputListener.kt b/src/main/kotlin/dev/dnpm/etl/processor/input/KafkaInputListener.kt
index 03cd03d..a126e07 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/input/KafkaInputListener.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/input/KafkaInputListener.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -19,7 +20,6 @@
package dev.dnpm.etl.processor.input
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.CustomMediaType
import dev.dnpm.etl.processor.PatientId
import dev.dnpm.etl.processor.RequestId
@@ -31,12 +31,13 @@ import org.apache.kafka.clients.consumer.ConsumerRecord
import org.slf4j.LoggerFactory
import org.springframework.http.MediaType
import org.springframework.kafka.listener.MessageListener
+import tools.jackson.databind.json.JsonMapper
import java.nio.charset.Charset
class KafkaInputListener(
private val requestProcessor: RequestProcessor,
private val consentEvaluator: ConsentEvaluator,
- private val objectMapper: ObjectMapper,
+ private val jsonMapper: JsonMapper,
) : MessageListener<String, String> {
private val logger = LoggerFactory.getLogger(KafkaInputListener::class.java)
@@ -71,7 +72,7 @@ class KafkaInputListener(
private fun handleDnpmV2Message(record: ConsumerRecord<String, String>) {
try {
- val mtbFile = objectMapper.readValue(record.value(), Mtb::class.java)
+ val mtbFile = jsonMapper.readValue(record.value(), Mtb::class.java)
val patientId = PatientId(mtbFile.patient.id)
val firstRequestIdHeader = record.headers().headers("requestId")?.firstOrNull()
val requestId =
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/input/MtbFileRestController.kt b/src/main/kotlin/dev/dnpm/etl/processor/input/MtbFileRestController.kt
index c9825c7..47f0766 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/input/MtbFileRestController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/input/MtbFileRestController.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt
index a88cf10..c9c73a2 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ConnectionCheckService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2024-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ReportService.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ReportService.kt
index c54aa7a..b9359fc 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ReportService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/ReportService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -19,64 +20,61 @@
package dev.dnpm.etl.processor.monitoring
-import com.fasterxml.jackson.annotation.JsonAlias
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.fasterxml.jackson.annotation.JsonValue
-import com.fasterxml.jackson.core.JsonParseException
-import com.fasterxml.jackson.databind.JsonMappingException
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.monitoring.ReportService.Issue
import dev.dnpm.etl.processor.monitoring.ReportService.Severity
+import tools.jackson.core.JacksonException
+import tools.jackson.databind.EnumNamingStrategies
+import tools.jackson.databind.annotation.EnumNaming
+import tools.jackson.databind.json.JsonMapper
import java.util.*
-class ReportService(private val objectMapper: ObjectMapper) {
+class ReportService(private val jsonMapper: JsonMapper) {
- fun deserialize(dataQualityReport: String?): List<Issue> {
- if (dataQualityReport.isNullOrBlank()) {
- return listOf()
+ fun deserialize(dataQualityReport: String?): List<Issue> {
+ if (dataQualityReport.isNullOrBlank()) {
+ return listOf()
+ }
+ return try {
+ jsonMapper.readValue(dataQualityReport, DataQualityReport::class.java).issues.sortedBy {
+ it.severity
+ }
+ } catch (_: JacksonException) {
+ val otherIssue =
+ Issue(Severity.ERROR, Optional.of("Not parsable data quality report '$dataQualityReport'"))
+ return listOf(otherIssue)
+ } catch (e: Exception) {
+ throw e
+ }
}
- return try {
- objectMapper.readValue(dataQualityReport, DataQualityReport::class.java).issues.sortedBy {
- it.severity
- }
- } catch (e: Exception) {
- val otherIssue =
- Issue(Severity.ERROR, "Not parsable data quality report '$dataQualityReport'")
- return when (e) {
- is JsonMappingException -> listOf(otherIssue)
- is JsonParseException -> listOf(otherIssue)
- else -> throw e
- }
- }
- }
- @JsonIgnoreProperties(ignoreUnknown = true)
- private data class DataQualityReport(
- @param:JsonProperty(value = "issues") val issues: List<Issue>
- )
+ private data class DataQualityReport(
+ val issues: List<Issue>
+ )
- @JsonIgnoreProperties(ignoreUnknown = true)
- data class Issue(
- @param:JsonProperty(value = "severity") val severity: Severity,
- @param:JsonProperty(value = "message") @param:JsonAlias("details") val message: String,
- @param:JsonProperty(value = "path") val path: Optional<String> = Optional.empty(),
- )
+ data class Issue(
+ val severity: Severity,
+ val message: Optional<String> = Optional.empty(),
+ val details: Optional<String> = Optional.empty(),
+ val path: Optional<String> = Optional.empty(),
+ ) {
+ fun getMessage() = message.orElse(details.orElse("No details available"))
+ }
- enum class Severity(@JsonValue val value: String) {
- FATAL("fatal"),
- ERROR("error"),
- WARNING("warning"),
- INFO("info"),
- }
+ @EnumNaming(EnumNamingStrategies.LowerCaseStrategy::class)
+ enum class Severity(val value: String) {
+ FATAL("fatal"),
+ ERROR("error"),
+ WARNING("warning"),
+ INFO("info"),
+ }
}
fun List<Issue>.asRequestStatus(): RequestStatus {
- val severity = this.minOfOrNull { it.severity }
- return when (severity) {
- Severity.FATAL,
- Severity.ERROR -> RequestStatus.ERROR
- Severity.WARNING -> RequestStatus.WARNING
- else -> RequestStatus.SUCCESS
- }
+ val severity = this.minOfOrNull { it.severity }
+ return when (severity) {
+ Severity.FATAL,
+ Severity.ERROR -> RequestStatus.ERROR
+ Severity.WARNING -> RequestStatus.WARNING
+ else -> RequestStatus.SUCCESS
+ }
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
index 8b2776a..a1f5c3d 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/Request.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestStatus.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestStatus.kt
index a0cd4ad..f1bf304 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestStatus.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestStatus.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestType.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestType.kt
index ef7f1e3..9611232 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestType.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/RequestType.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/SubmissionType.kt b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/SubmissionType.kt
index 351281e..4001b7e 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/monitoring/SubmissionType.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/monitoring/SubmissionType.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.monitoring
enum class SubmissionType(
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSender.kt b/src/main/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSender.kt
index bcd532f..8c20b7c 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSender.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/output/KafkaMtbFileSender.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -19,7 +20,6 @@
package dev.dnpm.etl.processor.output
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.CustomMediaType
import dev.dnpm.etl.processor.config.KafkaProperties
import dev.dnpm.etl.processor.monitoring.RequestStatus
@@ -29,12 +29,13 @@ import org.apache.kafka.clients.producer.ProducerRecord
import org.slf4j.LoggerFactory
import org.springframework.kafka.core.KafkaTemplate
import org.springframework.retry.support.RetryTemplate
+import tools.jackson.databind.json.JsonMapper
class KafkaMtbFileSender(
private val kafkaTemplate: KafkaTemplate<String, String>,
private val kafkaProperties: KafkaProperties,
private val retryTemplate: RetryTemplate,
- private val objectMapper: ObjectMapper,
+ private val jsonMapper: JsonMapper,
) : MtbFileSender {
private val logger = LoggerFactory.getLogger(KafkaMtbFileSender::class.java)
@@ -45,7 +46,7 @@ class KafkaMtbFileSender(
ProducerRecord(
kafkaProperties.outputTopic,
key(request),
- objectMapper.writeValueAsString(request.content),
+ jsonMapper.writeValueAsString(request.content),
)
record.headers().add("requestId", request.requestId.value.toByteArray())
record.headers().add("requestMethod", "POST".toByteArray())
@@ -82,7 +83,7 @@ class KafkaMtbFileSender(
ProducerRecord(
kafkaProperties.outputTopic,
key(request),
- objectMapper.writeValueAsString(
+ jsonMapper.writeValueAsString(
DnpmV2MtbFileRequest(request.requestId, dummyMtbFile),
),
)
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/output/MtbFileSender.kt b/src/main/kotlin/dev/dnpm/etl/processor/output/MtbFileSender.kt
index c81b572..3d0a8dd 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/output/MtbFileSender.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/output/MtbFileSender.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/output/MtbRequest.kt b/src/main/kotlin/dev/dnpm/etl/processor/output/MtbRequest.kt
index b228c4c..75401e6 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/output/MtbRequest.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/output/MtbRequest.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSender.kt b/src/main/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSender.kt
index 5aad133..89232bd 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSender.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/output/RestDipMtbFileSender.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/output/RestMtbFileSender.kt b/src/main/kotlin/dev/dnpm/etl/processor/output/RestMtbFileSender.kt
index 0d8ed7b..7e25827 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/output/RestMtbFileSender.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/output/RestMtbFileSender.kt
@@ -2,7 +2,7 @@
* This file is part of ETL-Processor
*
* Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
- * Copyright (c) 2023-2025 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/AnonymizingGenerator.kt b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/AnonymizingGenerator.kt
index 90d867f..b3c80e2 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/AnonymizingGenerator.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/AnonymizingGenerator.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapPseudonymGenerator.kt b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapPseudonymGenerator.kt
index 089736c..589a2d4 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapPseudonymGenerator.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapPseudonymGenerator.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.pseudonym
import dev.dnpm.etl.processor.config.AppFhirConfig
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapService.kt b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapService.kt
index f1121b8..4daba3a 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/GpasSoapService.kt
@@ -1,3 +1,23 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.pseudonym
import jakarta.jws.WebMethod
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeService.kt b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeService.kt
index 77ab87d..9eec9f3 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/PseudonymizeService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/extensions.kt b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/extensions.kt
index d8969c1..6615b35 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/extensions.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/pseudonym/extensions.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2024-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/security/TokenService.kt b/src/main/kotlin/dev/dnpm/etl/processor/security/TokenService.kt
index fd75446..74f3127 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/security/TokenService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/security/TokenService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2024-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/security/UserRole.kt b/src/main/kotlin/dev/dnpm/etl/processor/security/UserRole.kt
index bfe966a..c67c89d 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/security/UserRole.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/security/UserRole.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (C) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -15,7 +16,6 @@
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
- *
*/
package dev.dnpm.etl.processor.security
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/security/UserRoleService.kt b/src/main/kotlin/dev/dnpm/etl/processor/security/UserRoleService.kt
index bf46b84..0c1fe11 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/security/UserRoleService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/security/UserRoleService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2024-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/ConsentProcessor.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/ConsentProcessor.kt
index 4a9a6bd..a95420a 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/services/ConsentProcessor.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/services/ConsentProcessor.kt
@@ -1,9 +1,27 @@
+/*
+ * This file is part of ETL-Processor
+ *
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published
+ * by the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
package dev.dnpm.etl.processor.services
import ca.uhn.fhir.context.FhirContext
import com.fasterxml.jackson.core.JsonProcessingException
-import com.fasterxml.jackson.core.type.TypeReference
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.config.AppConfigProperties
import dev.dnpm.etl.processor.config.GIcsConfigProperties
import dev.dnpm.etl.processor.consent.ConsentDomain
@@ -11,10 +29,6 @@ import dev.dnpm.etl.processor.consent.IConsentService
import dev.dnpm.etl.processor.consent.MtbFileConsentService
import dev.dnpm.etl.processor.pseudonym.ensureMetaDataIsInitialized
import dev.pcvolkmer.mv64e.mtb.*
-import java.io.IOException
-import java.time.Clock
-import java.time.Instant
-import java.util.*
import org.apache.commons.lang3.NotImplementedException
import org.hl7.fhir.r4.model.*
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent
@@ -23,12 +37,17 @@ import org.hl7.fhir.r4.model.Consent.ProvisionComponent
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service
+import tools.jackson.databind.json.JsonMapper
+import java.io.IOException
+import java.time.Clock
+import java.time.Instant
+import java.util.*
@Service
class ConsentProcessor(
private val appConfigProperties: AppConfigProperties,
private val gIcsConfigProperties: GIcsConfigProperties,
- private val objectMapper: ObjectMapper,
+ private val jsonMapper: JsonMapper,
private val fhirContext: FhirContext,
private val consentService: IConsentService,
) {
@@ -119,9 +138,9 @@ class ConsentProcessor(
val asJsonString = fhirContext.newJsonParser().encodeResourceToString(resource)
try {
val mapOfJson: MvhMetadata.ResearchConsent? =
- objectMapper.readValue<MvhMetadata.ResearchConsent?>(
+ jsonMapper.readValue(
asJsonString,
- object : TypeReference<MvhMetadata.ResearchConsent?>() {},
+ MvhMetadata.ResearchConsent::class.java,
)
mtbFile.metadata.researchConsents.add(mapOfJson)
} catch (e: JsonProcessingException) {
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/RequestProcessor.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/RequestProcessor.kt
index f0eed7f..b94fbbc 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/services/RequestProcessor.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/services/RequestProcessor.kt
@@ -2,7 +2,7 @@
* This file is part of ETL-Processor
*
* Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
- * Copyright (c) 2023-2026 Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -20,7 +20,6 @@
package dev.dnpm.etl.processor.services
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.*
import dev.dnpm.etl.processor.config.AppConfigProperties
import dev.dnpm.etl.processor.consent.TtpConsentStatus
@@ -41,6 +40,7 @@ import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationEventPublisher
import org.springframework.stereotype.Service
+import tools.jackson.databind.json.JsonMapper
import java.time.Instant
import java.util.*
@@ -50,7 +50,7 @@ class RequestProcessor(
private val transformationService: TransformationService,
private val sender: MtbFileSender,
private val requestService: RequestService,
- private val objectMapper: ObjectMapper,
+ private val jsonMapper: JsonMapper,
private val applicationEventPublisher: ApplicationEventPublisher,
private val appConfigProperties: AppConfigProperties,
private val consentProcessor: ConsentProcessor?,
@@ -292,7 +292,7 @@ class RequestProcessor(
private fun <T> fingerprint(request: MtbFileRequest<T>): Fingerprint {
return when (request) {
- is DnpmV2MtbFileRequest -> fingerprint(objectMapper.writeValueAsString(request.content))
+ is DnpmV2MtbFileRequest -> fingerprint(jsonMapper.writeValueAsString(request.content))
}
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt
index eb57a6c..b967f2d 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/services/RequestService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/ResponseProcessor.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/ResponseProcessor.kt
index 3ecac71..947ec17 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/services/ResponseProcessor.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/services/ResponseProcessor.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/TransformationService.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/TransformationService.kt
index df8ac3d..755e6b3 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/services/TransformationService.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/services/TransformationService.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -19,18 +20,18 @@
package dev.dnpm.etl.processor.services
-import com.fasterxml.jackson.databind.ObjectMapper
import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.PathNotFoundException
import dev.pcvolkmer.mv64e.mtb.Mtb
+import tools.jackson.databind.json.JsonMapper
class TransformationService(
- private val objectMapper: ObjectMapper,
+ private val jsonMapper: JsonMapper,
private val transformations: List<Transformation>,
) {
fun transform(mtbFile: Mtb): Mtb {
- val json = transform(objectMapper.writeValueAsString(mtbFile))
- return objectMapper.readValue(json, Mtb::class.java)
+ val json = transform(jsonMapper.writeValueAsString(mtbFile))
+ return jsonMapper.readValue(json, Mtb::class.java)
}
private fun transform(content: String): String {
@@ -61,7 +62,7 @@ class TransformationService(
newValue,
{ it.item(HashMap::class.java)[last] == existingValue },
)
- } catch (e: PathNotFoundException) {
+ } catch (_: PathNotFoundException) {
// Ignore
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessor.kt b/src/main/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessor.kt
index e70f1e7..41f7720 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessor.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/services/kafka/KafkaResponseProcessor.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
@@ -19,71 +20,70 @@
package dev.dnpm.etl.processor.services.kafka
-import com.fasterxml.jackson.annotation.JsonAlias
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.RequestId
import dev.dnpm.etl.processor.monitoring.RequestStatus
import dev.dnpm.etl.processor.output.asRequestStatus
import dev.dnpm.etl.processor.services.ResponseEvent
-import java.time.Instant
-import java.util.*
import org.apache.kafka.clients.consumer.ConsumerRecord
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationEventPublisher
import org.springframework.kafka.listener.MessageListener
+import tools.jackson.databind.PropertyNamingStrategies
+import tools.jackson.databind.annotation.JsonNaming
+import tools.jackson.databind.json.JsonMapper
+import java.time.Instant
+import java.util.*
class KafkaResponseProcessor(
private val eventPublisher: ApplicationEventPublisher,
- private val objectMapper: ObjectMapper,
+ private val jsonMapper: JsonMapper,
) : MessageListener<String, String> {
- private val logger = LoggerFactory.getLogger(KafkaResponseProcessor::class.java)
+ private val logger = LoggerFactory.getLogger(KafkaResponseProcessor::class.java)
- override fun onMessage(data: ConsumerRecord<String, String>) {
- try {
- Optional.of(objectMapper.readValue(data.value(), ResponseBody::class.java))
+ override fun onMessage(data: ConsumerRecord<String, String>) {
+ try {
+ Optional.of(jsonMapper.readValue(data.value(), ResponseBody::class.java))
} catch (e: Exception) {
- logger.error("Cannot process Kafka response", e)
- Optional.empty()
+ logger.error("Cannot process Kafka response", e)
+ Optional.empty()
}
- .ifPresentOrElse(
- { responseBody ->
- val event =
- ResponseEvent(
- RequestId(responseBody.requestId),
- Instant.ofEpochMilli(data.timestamp()),
- responseBody.statusCode.asRequestStatus(),
- when (responseBody.statusCode.asRequestStatus()) {
- RequestStatus.SUCCESS -> {
- Optional.empty()
- }
+ .ifPresentOrElse(
+ { responseBody ->
+ val event =
+ ResponseEvent(
+ RequestId(responseBody.requestId),
+ Instant.ofEpochMilli(data.timestamp()),
+ responseBody.statusCode.asRequestStatus(),
+ when (responseBody.statusCode.asRequestStatus()) {
+ RequestStatus.SUCCESS -> {
+ Optional.empty()
+ }
- RequestStatus.WARNING,
- RequestStatus.ERROR -> {
- Optional.of(objectMapper.writeValueAsString(responseBody.statusBody))
- }
+ RequestStatus.WARNING,
+ RequestStatus.ERROR -> {
+ Optional.of(jsonMapper.writeValueAsString(responseBody.statusBody))
+ }
- else -> {
- logger.error(
- "Kafka response: Unknown response code '{}'!",
- responseBody.statusCode,
- )
- Optional.empty()
- }
- },
- )
- eventPublisher.publishEvent(event)
- },
- { logger.error("No requestId in Kafka response") },
- )
- }
+ else -> {
+ logger.error(
+ "Kafka response: Unknown response code '{}'!",
+ responseBody.statusCode,
+ )
+ Optional.empty()
+ }
+ },
+ )
+ eventPublisher.publishEvent(event)
+ },
+ { logger.error("No requestId in Kafka response") },
+ )
+ }
- data class ResponseBody(
- @param:JsonProperty("request_id") @param:JsonAlias("requestId") val requestId: String,
- @param:JsonProperty("status_code") @param:JsonAlias("statusCode") val statusCode: Int,
- @param:JsonProperty("status_body")
- @param:JsonAlias("statusBody")
- val statusBody: Map<String, Any>,
- )
+ @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)
+ data class ResponseBody(
+ val requestId: String,
+ val statusCode: Int,
+ val statusBody: Map<String, Any>,
+ )
}
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/types.kt b/src/main/kotlin/dev/dnpm/etl/processor/types.kt
index 9244297..9abd25d 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/types.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/types.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2025 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2025-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/ApplicationControllerAdvice.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/ApplicationControllerAdvice.kt
index e81b348..508d12b 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/ApplicationControllerAdvice.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/ApplicationControllerAdvice.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt
index b77bdf9..5bd25b7 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/ConfigController.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt
index 6622348..6347735 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/HomeController.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt
index 9b49f5a..c62553a 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/LoginController.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2024-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt
index 8dfe595..4cb99f1 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsController.kt
@@ -1,7 +1,8 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
diff --git a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt
index 8843d8e..3ea9667 100644
--- a/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt
+++ b/src/main/kotlin/dev/dnpm/etl/processor/web/StatisticsRestController.kt
@@ -1,7 +1,7 @@
/*
* This file is part of ETL-Processor
*
- * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
+ * Copyright (c) 2023 Comprehensive Cancer Center Mainfranken
* Copyright (c) 2023-2026 Paul-Christian Volkmer, Datenintegrationszentrum Philipps-Universität Marburg and Contributors
*
* This program is free software: you can redistribute it and/or modify
@@ -20,8 +20,6 @@
package dev.dnpm.etl.processor.web
-import com.fasterxml.jackson.annotation.JsonProperty
-import com.fasterxml.jackson.annotation.JsonPropertyOrder
import dev.dnpm.etl.processor.monitoring.RequestStatus
import dev.dnpm.etl.processor.monitoring.RequestType
import dev.dnpm.etl.processor.services.RequestService
@@ -34,6 +32,8 @@ import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Sinks
+import tools.jackson.databind.PropertyNamingStrategies
+import tools.jackson.databind.annotation.JsonNaming
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
@@ -201,15 +201,13 @@ data class DateNameValues(
val nameValues: NameValues,
)
-@JsonPropertyOrder(value = ["error", "warning", "success", "no_consent", "duplication", "blocked_initial", "unknown"])
+@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)
data class NameValues(
val error: Int = 0,
val warning: Int = 0,
val success: Int = 0,
- @field:JsonProperty("no_consent")
val noConsent: Int = 0,
val duplication: Int = 0,
- @field:JsonProperty("blocked_initial")
val blockedInitial: Int = 0,
val unknown: Int = 0,
)
diff --git a/src/main/resources/static/icon.svg b/src/main/resources/static/icon.svg
index 90c3a65..7b36666 100644
--- a/src/main/resources/static/icon.svg
+++ b/src/main/resources/static/icon.svg
@@ -1,6 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
<svg
width="256"
height="256"
diff --git a/src/main/resources/static/user.svg b/src/main/resources/static/user.svg
index 506d632..abec848 100644
--- a/src/main/resources/static/user.svg
+++ b/src/main/resources/static/user.svg
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="24" height="24" version="1.1" viewBox="0 0 6.35 6.35" xmlns="http://www.w3.org/2000/svg">
<g transform="matrix(1.2 0 0 1.2 -108.01 -85.977)">
<rect x="90.01" y="71.647" width="5.2917" height="5.2917" rx=".96212" fill="#b3b3b3"/>
diff --git a/src/main/resources/templates/report.html b/src/main/resources/templates/report.html
index bad8ca2..bdc7457 100644
--- a/src/main/resources/templates/report.html
+++ b/src/main/resources/templates/report.html
@@ -34,7 +34,7 @@
<td th:if="${issue.severity.value == 'error'}" class="bg-red"><small>[[ ${issue.severity} ]]</small></td>
<td th:if="${issue.severity.value == 'fatal'}" class="bg-red"><small>[[ ${issue.severity} ]]</small></td>
<td>
- <div class="issue-message">[[ ${issue.message} ]]</div>
+ <div class="issue-message">[[ ${issue.getMessage()} ]]</div>
<div class="issue-path" th:if="${issue.path.isPresent()}">[[ ${issue.path.get()} ]]</div>
<div class="issue-path" th:if="${issue.path.isEmpty()}"><i>Keine Angabe</i></div>
</td>