mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-20 17:56:50 +00:00
refactor: add types for patient id and pseudonym
This commit is contained in:
parent
c949ec07e5
commit
c8f6e6efc8
30
src/integrationTest/kotlin/dev/dnpm/etl/processor/helpers.kt
Normal file
30
src/integrationTest/kotlin/dev/dnpm/etl/processor/helpers.kt
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of ETL-Processor
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024 Comprehensive Cancer Center Mainfranken, 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
|
||||||
|
|
||||||
|
import org.mockito.ArgumentMatchers
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
inline fun <reified T> anyValueClass(): T {
|
||||||
|
val unboxedClass = T::class.java.declaredFields.first().type
|
||||||
|
return ArgumentMatchers.any(unboxedClass as Class<T>)
|
||||||
|
?: T::class.java.getDeclaredMethod("box-impl", unboxedClass)
|
||||||
|
.invoke(null, null) as T
|
||||||
|
}
|
@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.input
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.*
|
import de.ukw.ccc.bwhc.dto.*
|
||||||
|
import dev.dnpm.etl.processor.anyValueClass
|
||||||
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
|
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
|
||||||
import dev.dnpm.etl.processor.security.TokenRepository
|
import dev.dnpm.etl.processor.security.TokenRepository
|
||||||
import dev.dnpm.etl.processor.security.UserRoleRepository
|
import dev.dnpm.etl.processor.security.UserRoleRepository
|
||||||
@ -29,7 +30,6 @@ import org.junit.jupiter.api.BeforeEach
|
|||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
import org.mockito.kotlin.any
|
import org.mockito.kotlin.any
|
||||||
import org.mockito.kotlin.never
|
import org.mockito.kotlin.never
|
||||||
@ -141,7 +141,7 @@ class MtbFileRestControllerTest {
|
|||||||
status { isAccepted() }
|
status { isAccepted() }
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(requestProcessor, times(1)).processDeletion(anyString())
|
verify(requestProcessor, times(1)).processDeletion(anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -152,7 +152,7 @@ class MtbFileRestControllerTest {
|
|||||||
status { isUnauthorized() }
|
status { isUnauthorized() }
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(requestProcessor, never()).processDeletion(anyString())
|
verify(requestProcessor, never()).processDeletion(anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
@ -19,10 +19,8 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.monitoring
|
package dev.dnpm.etl.processor.monitoring
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.AbstractTestcontainerTest
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
|
||||||
import dev.dnpm.etl.processor.output.MtbFileSender
|
import dev.dnpm.etl.processor.output.MtbFileSender
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
@ -63,8 +61,8 @@ class RequestRepositoryTest : AbstractTestcontainerTest() {
|
|||||||
fun shouldSaveRequest() {
|
fun shouldSaveRequest() {
|
||||||
val request = Request(
|
val request = Request(
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.services
|
package dev.dnpm.etl.processor.services
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.AbstractTestcontainerTest
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
import dev.dnpm.etl.processor.monitoring.Request
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestType
|
import dev.dnpm.etl.processor.monitoring.RequestType
|
||||||
import dev.dnpm.etl.processor.output.MtbFileSender
|
import dev.dnpm.etl.processor.output.MtbFileSender
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@ -67,7 +65,7 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun shouldResultInEmptyRequestList() {
|
fun shouldResultInEmptyRequestList() {
|
||||||
val actual = requestService.allRequestsByPatientPseudonym("TEST_12345678901")
|
val actual = requestService.allRequestsByPatientPseudonym(TEST_PATIENT_PSEUDONYM)
|
||||||
|
|
||||||
assertThat(actual).isEmpty()
|
assertThat(actual).isEmpty()
|
||||||
}
|
}
|
||||||
@ -78,8 +76,8 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
listOf(
|
listOf(
|
||||||
Request(
|
Request(
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -88,8 +86,8 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
// Should be ignored - wrong patient ID -->
|
// Should be ignored - wrong patient ID -->
|
||||||
Request(
|
Request(
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678902",
|
PatientPseudonym("TEST_12345678902"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdef2"),
|
Fingerprint("0123456789abcdef2"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -98,8 +96,8 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
// <--
|
// <--
|
||||||
Request(
|
Request(
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdee1"),
|
Fingerprint("0123456789abcdee1"),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -113,7 +111,7 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
fun shouldResultInSortedRequestList() {
|
fun shouldResultInSortedRequestList() {
|
||||||
setupTestData()
|
setupTestData()
|
||||||
|
|
||||||
val actual = requestService.allRequestsByPatientPseudonym("TEST_12345678901")
|
val actual = requestService.allRequestsByPatientPseudonym(TEST_PATIENT_PSEUDONYM)
|
||||||
|
|
||||||
assertThat(actual).hasSize(2)
|
assertThat(actual).hasSize(2)
|
||||||
assertThat(actual[0].fingerprint).isEqualTo(Fingerprint("0123456789abcdee1"))
|
assertThat(actual[0].fingerprint).isEqualTo(Fingerprint("0123456789abcdee1"))
|
||||||
@ -124,7 +122,7 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
fun shouldReturnDeleteRequestAsLastRequest() {
|
fun shouldReturnDeleteRequestAsLastRequest() {
|
||||||
setupTestData()
|
setupTestData()
|
||||||
|
|
||||||
val actual = requestService.isLastRequestWithKnownStatusDeletion("TEST_12345678901")
|
val actual = requestService.isLastRequestWithKnownStatusDeletion(TEST_PATIENT_PSEUDONYM)
|
||||||
|
|
||||||
assertThat(actual).isTrue()
|
assertThat(actual).isTrue()
|
||||||
}
|
}
|
||||||
@ -133,10 +131,14 @@ class RequestServiceIntegrationTest : AbstractTestcontainerTest() {
|
|||||||
fun shouldReturnLastMtbFileRequest() {
|
fun shouldReturnLastMtbFileRequest() {
|
||||||
setupTestData()
|
setupTestData()
|
||||||
|
|
||||||
val actual = requestService.lastMtbFileRequestForPatientPseudonym("TEST_12345678901")
|
val actual = requestService.lastMtbFileRequestForPatientPseudonym(TEST_PATIENT_PSEUDONYM)
|
||||||
|
|
||||||
assertThat(actual).isNotNull
|
assertThat(actual).isNotNull
|
||||||
assertThat(actual?.fingerprint).isEqualTo(Fingerprint("0123456789abcdef1"))
|
assertThat(actual?.fingerprint).isEqualTo(Fingerprint("0123456789abcdef1"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TEST_PATIENT_PSEUDONYM = PatientPseudonym("TEST_12345678901")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,15 +21,13 @@ package dev.dnpm.etl.processor.web
|
|||||||
|
|
||||||
import com.gargoylesoftware.htmlunit.WebClient
|
import com.gargoylesoftware.htmlunit.WebClient
|
||||||
import com.gargoylesoftware.htmlunit.html.HtmlPage
|
import com.gargoylesoftware.htmlunit.html.HtmlPage
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.NotFoundException
|
|
||||||
import dev.dnpm.etl.processor.config.AppConfiguration
|
import dev.dnpm.etl.processor.config.AppConfiguration
|
||||||
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
|
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
|
||||||
import dev.dnpm.etl.processor.monitoring.Report
|
import dev.dnpm.etl.processor.monitoring.Report
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
import dev.dnpm.etl.processor.monitoring.Request
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestType
|
import dev.dnpm.etl.processor.monitoring.RequestType
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import dev.dnpm.etl.processor.services.RequestService
|
import dev.dnpm.etl.processor.services.RequestService
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
@ -37,8 +35,6 @@ import org.junit.jupiter.api.Nested
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
import org.mockito.ArgumentMatchers
|
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
|
||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
import org.mockito.kotlin.any
|
import org.mockito.kotlin.any
|
||||||
import org.mockito.kotlin.whenever
|
import org.mockito.kotlin.whenever
|
||||||
@ -83,13 +79,6 @@ class HomeControllerTest {
|
|||||||
private lateinit var mockMvc: MockMvc
|
private lateinit var mockMvc: MockMvc
|
||||||
private lateinit var webClient: WebClient
|
private lateinit var webClient: WebClient
|
||||||
|
|
||||||
inline fun <reified T> anyValueClass(): T {
|
|
||||||
val unboxedClass = T::class.java.declaredFields.first().type
|
|
||||||
return ArgumentMatchers.any(unboxedClass as Class<T>)
|
|
||||||
?: T::class.java.getDeclaredMethod("box-impl", unboxedClass)
|
|
||||||
.invoke(null, null) as T
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
fun setup(
|
fun setup(
|
||||||
@Autowired mockMvc: MockMvc,
|
@Autowired mockMvc: MockMvc,
|
||||||
@ -129,8 +118,8 @@ class HomeControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
2L,
|
2L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"PSEUDO1",
|
PatientPseudonym("PSEUDO1"),
|
||||||
"PATIENT1",
|
PatientId("PATIENT1"),
|
||||||
Fingerprint("ashdkasdh"),
|
Fingerprint("ashdkasdh"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS
|
RequestStatus.SUCCESS
|
||||||
@ -138,8 +127,8 @@ class HomeControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"PSEUDO1",
|
PatientPseudonym("PSEUDO1"),
|
||||||
"PATIENT1",
|
PatientId("PATIENT1"),
|
||||||
Fingerprint("asdasdasd"),
|
Fingerprint("asdasdasd"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.ERROR
|
RequestStatus.ERROR
|
||||||
@ -163,8 +152,8 @@ class HomeControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
2L,
|
2L,
|
||||||
requestId,
|
requestId,
|
||||||
"PSEUDO1",
|
PatientPseudonym("PSEUDO1"),
|
||||||
"PATIENT1",
|
PatientId("PATIENT1"),
|
||||||
Fingerprint("ashdkasdh"),
|
Fingerprint("ashdkasdh"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -182,14 +171,14 @@ class HomeControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithMockUser(username = "admin", roles = ["ADMIN"])
|
@WithMockUser(username = "admin", roles = ["ADMIN"])
|
||||||
fun testShouldShowPatientDetails() {
|
fun testShouldShowPatientDetails() {
|
||||||
whenever(requestService.findRequestByPatientId(anyString(), any<Pageable>())).thenReturn(
|
whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn(
|
||||||
PageImpl(
|
PageImpl(
|
||||||
listOf(
|
listOf(
|
||||||
Request(
|
Request(
|
||||||
2L,
|
2L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"PSEUDO1",
|
PatientPseudonym("PSEUDO1"),
|
||||||
"PATIENT1",
|
PatientId("PATIENT1"),
|
||||||
Fingerprint("ashdkasdh"),
|
Fingerprint("ashdkasdh"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS
|
RequestStatus.SUCCESS
|
||||||
@ -197,8 +186,8 @@ class HomeControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"PSEUDO1",
|
PatientPseudonym("PSEUDO1"),
|
||||||
"PATIENT1",
|
PatientId("PATIENT1"),
|
||||||
Fingerprint("asdasdasd"),
|
Fingerprint("asdasdasd"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.ERROR
|
RequestStatus.ERROR
|
||||||
@ -254,7 +243,7 @@ class HomeControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
@WithMockUser(username = "admin", roles = ["ADMIN"])
|
@WithMockUser(username = "admin", roles = ["ADMIN"])
|
||||||
fun testShouldShowEmptyPatientDetails() {
|
fun testShouldShowEmptyPatientDetails() {
|
||||||
whenever(requestService.findRequestByPatientId(anyString(), any<Pageable>())).thenReturn(Page.empty())
|
whenever(requestService.findRequestByPatientId(anyValueClass(), any<Pageable>())).thenReturn(Page.empty())
|
||||||
|
|
||||||
val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1")
|
val page = webClient.getPage<HtmlPage>("http://localhost/patient/PSEUDO1")
|
||||||
assertThat(page.querySelectorAll("tbody tr")).isEmpty()
|
assertThat(page.querySelectorAll("tbody tr")).isEmpty()
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
package dev.dnpm.etl.processor.web
|
package dev.dnpm.etl.processor.web
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.Fingerprint
|
||||||
|
import dev.dnpm.etl.processor.PatientId
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.config.AppConfiguration
|
import dev.dnpm.etl.processor.config.AppConfiguration
|
||||||
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
|
import dev.dnpm.etl.processor.config.AppSecurityConfiguration
|
||||||
import dev.dnpm.etl.processor.monitoring.CountedState
|
import dev.dnpm.etl.processor.monitoring.CountedState
|
||||||
@ -188,8 +190,8 @@ class StatisticsRestControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
1,
|
1,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -198,8 +200,8 @@ class StatisticsRestControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
2,
|
2,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678902",
|
PatientPseudonym("TEST_12345678902"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdef2"),
|
Fingerprint("0123456789abcdef2"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -208,8 +210,8 @@ class StatisticsRestControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
3,
|
3,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdee1"),
|
Fingerprint("0123456789abcdee1"),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.ERROR,
|
RequestStatus.ERROR,
|
||||||
@ -218,8 +220,8 @@ class StatisticsRestControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
4,
|
4,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678902",
|
PatientPseudonym("TEST_12345678902"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdef2"),
|
Fingerprint("0123456789abcdef2"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.DUPLICATION,
|
RequestStatus.DUPLICATION,
|
||||||
@ -228,8 +230,8 @@ class StatisticsRestControllerTest {
|
|||||||
Request(
|
Request(
|
||||||
5,
|
5,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678902",
|
PatientPseudonym("TEST_12345678902"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdef2"),
|
Fingerprint("0123456789abcdef2"),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.UNKNOWN,
|
RequestStatus.UNKNOWN,
|
||||||
|
@ -22,6 +22,7 @@ package dev.dnpm.etl.processor.input
|
|||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.Consent
|
import de.ukw.ccc.bwhc.dto.Consent
|
||||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||||
|
import dev.dnpm.etl.processor.PatientId
|
||||||
import dev.dnpm.etl.processor.RequestId
|
import dev.dnpm.etl.processor.RequestId
|
||||||
import dev.dnpm.etl.processor.services.RequestProcessor
|
import dev.dnpm.etl.processor.services.RequestProcessor
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord
|
import org.apache.kafka.clients.consumer.ConsumerRecord
|
||||||
@ -36,6 +37,7 @@ class KafkaInputListener(
|
|||||||
|
|
||||||
override fun onMessage(data: ConsumerRecord<String, String>) {
|
override fun onMessage(data: ConsumerRecord<String, String>) {
|
||||||
val mtbFile = objectMapper.readValue(data.value(), MtbFile::class.java)
|
val mtbFile = objectMapper.readValue(data.value(), MtbFile::class.java)
|
||||||
|
val patientId = PatientId(mtbFile.patient.id)
|
||||||
val firstRequestIdHeader = data.headers().headers("requestId")?.firstOrNull()
|
val firstRequestIdHeader = data.headers().headers("requestId")?.firstOrNull()
|
||||||
val requestId = if (null != firstRequestIdHeader) {
|
val requestId = if (null != firstRequestIdHeader) {
|
||||||
RequestId(String(firstRequestIdHeader.value()))
|
RequestId(String(firstRequestIdHeader.value()))
|
||||||
@ -53,9 +55,9 @@ class KafkaInputListener(
|
|||||||
} else {
|
} else {
|
||||||
logger.debug("Accepted MTB File and process deletion")
|
logger.debug("Accepted MTB File and process deletion")
|
||||||
if (requestId.isBlank()) {
|
if (requestId.isBlank()) {
|
||||||
requestProcessor.processDeletion(mtbFile.patient.id)
|
requestProcessor.processDeletion(patientId)
|
||||||
} else {
|
} else {
|
||||||
requestProcessor.processDeletion(mtbFile.patient.id, requestId)
|
requestProcessor.processDeletion(patientId, requestId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.input
|
|||||||
|
|
||||||
import de.ukw.ccc.bwhc.dto.Consent
|
import de.ukw.ccc.bwhc.dto.Consent
|
||||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||||
|
import dev.dnpm.etl.processor.PatientId
|
||||||
import dev.dnpm.etl.processor.services.RequestProcessor
|
import dev.dnpm.etl.processor.services.RequestProcessor
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.http.ResponseEntity
|
import org.springframework.http.ResponseEntity
|
||||||
@ -46,7 +47,8 @@ class MtbFileRestController(
|
|||||||
requestProcessor.processMtbFile(mtbFile)
|
requestProcessor.processMtbFile(mtbFile)
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Accepted MTB File and process deletion")
|
logger.debug("Accepted MTB File and process deletion")
|
||||||
requestProcessor.processDeletion(mtbFile.patient.id)
|
val patientId = PatientId(mtbFile.patient.id)
|
||||||
|
requestProcessor.processDeletion(patientId)
|
||||||
}
|
}
|
||||||
return ResponseEntity.accepted().build()
|
return ResponseEntity.accepted().build()
|
||||||
}
|
}
|
||||||
@ -54,7 +56,7 @@ class MtbFileRestController(
|
|||||||
@DeleteMapping(path = ["{patientId}"])
|
@DeleteMapping(path = ["{patientId}"])
|
||||||
fun deleteData(@PathVariable patientId: String): ResponseEntity<Void> {
|
fun deleteData(@PathVariable patientId: String): ResponseEntity<Void> {
|
||||||
logger.debug("Accepted patient ID to process deletion")
|
logger.debug("Accepted patient ID to process deletion")
|
||||||
requestProcessor.processDeletion(patientId)
|
requestProcessor.processDeletion(PatientId(patientId))
|
||||||
return ResponseEntity.accepted().build()
|
return ResponseEntity.accepted().build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,7 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.monitoring
|
package dev.dnpm.etl.processor.monitoring
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import dev.dnpm.etl.processor.RequestId
|
|
||||||
import org.springframework.data.annotation.Id
|
import org.springframework.data.annotation.Id
|
||||||
import org.springframework.data.domain.Page
|
import org.springframework.data.domain.Page
|
||||||
import org.springframework.data.domain.Pageable
|
import org.springframework.data.domain.Pageable
|
||||||
@ -38,8 +36,8 @@ import java.util.*
|
|||||||
data class Request(
|
data class Request(
|
||||||
@Id val id: Long? = null,
|
@Id val id: Long? = null,
|
||||||
val uuid: RequestId = randomRequestId(),
|
val uuid: RequestId = randomRequestId(),
|
||||||
val patientId: String,
|
val patientId: PatientPseudonym,
|
||||||
val pid: String,
|
val pid: PatientId,
|
||||||
@Column("fingerprint")
|
@Column("fingerprint")
|
||||||
val fingerprint: Fingerprint,
|
val fingerprint: Fingerprint,
|
||||||
val type: RequestType,
|
val type: RequestType,
|
||||||
@ -49,8 +47,8 @@ data class Request(
|
|||||||
) {
|
) {
|
||||||
constructor(
|
constructor(
|
||||||
uuid: RequestId,
|
uuid: RequestId,
|
||||||
patientId: String,
|
patientId: PatientPseudonym,
|
||||||
pid: String,
|
pid: PatientId,
|
||||||
fingerprint: Fingerprint,
|
fingerprint: Fingerprint,
|
||||||
type: RequestType,
|
type: RequestType,
|
||||||
status: RequestStatus
|
status: RequestStatus
|
||||||
@ -59,8 +57,8 @@ data class Request(
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
uuid: RequestId,
|
uuid: RequestId,
|
||||||
patientId: String,
|
patientId: PatientPseudonym,
|
||||||
pid: String,
|
pid: PatientId,
|
||||||
fingerprint: Fingerprint,
|
fingerprint: Fingerprint,
|
||||||
type: RequestType,
|
type: RequestType,
|
||||||
status: RequestStatus,
|
status: RequestStatus,
|
||||||
@ -83,11 +81,11 @@ data class CountedState(
|
|||||||
|
|
||||||
interface RequestRepository : CrudRepository<Request, Long>, PagingAndSortingRepository<Request, Long> {
|
interface RequestRepository : CrudRepository<Request, Long>, PagingAndSortingRepository<Request, Long> {
|
||||||
|
|
||||||
fun findAllByPatientIdOrderByProcessedAtDesc(patientId: String): List<Request>
|
fun findAllByPatientIdOrderByProcessedAtDesc(patientId: PatientPseudonym): List<Request>
|
||||||
|
|
||||||
fun findByUuidEquals(uuid: RequestId): Optional<Request>
|
fun findByUuidEquals(uuid: RequestId): Optional<Request>
|
||||||
|
|
||||||
fun findRequestByPatientId(patientId: String, pageable: Pageable): Page<Request>
|
fun findRequestByPatientId(patientId: PatientPseudonym, pageable: Pageable): Page<Request>
|
||||||
|
|
||||||
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'MTB_FILE' GROUP BY status ORDER BY status, count DESC;")
|
@Query("SELECT count(*) AS count, status FROM request WHERE type = 'MTB_FILE' GROUP BY status ORDER BY status, count DESC;")
|
||||||
fun countStates(): List<CountedState>
|
fun countStates(): List<CountedState>
|
||||||
|
@ -63,7 +63,7 @@ class KafkaMtbFileSender(
|
|||||||
val dummyMtbFile = MtbFile.builder()
|
val dummyMtbFile = MtbFile.builder()
|
||||||
.withConsent(
|
.withConsent(
|
||||||
Consent.builder()
|
Consent.builder()
|
||||||
.withPatient(request.patientId)
|
.withPatient(request.patientId.value)
|
||||||
.withStatus(Consent.Status.REJECTED)
|
.withStatus(Consent.Status.REJECTED)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
@ -99,7 +99,7 @@ class KafkaMtbFileSender(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun key(request: MtbFileSender.DeleteRequest): String {
|
private fun key(request: MtbFileSender.DeleteRequest): String {
|
||||||
return "{\"pid\": \"${request.patientId}\"}"
|
return "{\"pid\": \"${request.patientId.value}\"}"
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Data(val requestId: RequestId, val content: MtbFile)
|
data class Data(val requestId: RequestId, val content: MtbFile)
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package dev.dnpm.etl.processor.output
|
package dev.dnpm.etl.processor.output
|
||||||
|
|
||||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.RequestId
|
import dev.dnpm.etl.processor.RequestId
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
import org.springframework.http.HttpStatusCode
|
import org.springframework.http.HttpStatusCode
|
||||||
@ -35,7 +36,7 @@ interface MtbFileSender {
|
|||||||
|
|
||||||
data class MtbFileRequest(val requestId: RequestId, val mtbFile: MtbFile)
|
data class MtbFileRequest(val requestId: RequestId, val mtbFile: MtbFile)
|
||||||
|
|
||||||
data class DeleteRequest(val requestId: RequestId, val patientId: String)
|
data class DeleteRequest(val requestId: RequestId, val patientId: PatientPseudonym)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.pseudonym
|
package dev.dnpm.etl.processor.pseudonym
|
||||||
|
|
||||||
|
import dev.dnpm.etl.processor.PatientId
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.config.PseudonymizeConfigProperties
|
import dev.dnpm.etl.processor.config.PseudonymizeConfigProperties
|
||||||
|
|
||||||
class PseudonymizeService(
|
class PseudonymizeService(
|
||||||
@ -26,10 +28,10 @@ class PseudonymizeService(
|
|||||||
private val configProperties: PseudonymizeConfigProperties
|
private val configProperties: PseudonymizeConfigProperties
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun patientPseudonym(patientId: String): String {
|
fun patientPseudonym(patientId: PatientId): PatientPseudonym {
|
||||||
return when (generator) {
|
return when (generator) {
|
||||||
is GpasPseudonymGenerator -> generator.generate(patientId)
|
is GpasPseudonymGenerator -> PatientPseudonym(generator.generate(patientId.value))
|
||||||
else -> "${configProperties.prefix}_${generator.generate(patientId)}"
|
else -> PatientPseudonym("${configProperties.prefix}_${generator.generate(patientId.value)}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package dev.dnpm.etl.processor.pseudonym
|
package dev.dnpm.etl.processor.pseudonym
|
||||||
|
|
||||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||||
|
import dev.dnpm.etl.processor.PatientId
|
||||||
import org.apache.commons.codec.digest.DigestUtils
|
import org.apache.commons.codec.digest.DigestUtils
|
||||||
|
|
||||||
/** Replaces patient ID with generated patient pseudonym
|
/** Replaces patient ID with generated patient pseudonym
|
||||||
@ -29,7 +30,7 @@ import org.apache.commons.codec.digest.DigestUtils
|
|||||||
* @return The MTB file containing patient pseudonymes
|
* @return The MTB file containing patient pseudonymes
|
||||||
*/
|
*/
|
||||||
infix fun MtbFile.pseudonymizeWith(pseudonymizeService: PseudonymizeService) {
|
infix fun MtbFile.pseudonymizeWith(pseudonymizeService: PseudonymizeService) {
|
||||||
val patientPseudonym = pseudonymizeService.patientPseudonym(this.patient.id)
|
val patientPseudonym = pseudonymizeService.patientPseudonym(PatientId(this.patient.id)).value
|
||||||
|
|
||||||
this.episode?.patient = patientPseudonym
|
this.episode?.patient = patientPseudonym
|
||||||
this.carePlans?.forEach { it.patient = patientPseudonym }
|
this.carePlans?.forEach { it.patient = patientPseudonym }
|
||||||
|
@ -21,9 +21,7 @@ package dev.dnpm.etl.processor.services
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import dev.dnpm.etl.processor.RequestId
|
|
||||||
import dev.dnpm.etl.processor.config.AppConfigProperties
|
import dev.dnpm.etl.processor.config.AppConfigProperties
|
||||||
import dev.dnpm.etl.processor.monitoring.Report
|
import dev.dnpm.etl.processor.monitoring.Report
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
import dev.dnpm.etl.processor.monitoring.Request
|
||||||
@ -56,17 +54,19 @@ class RequestProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun processMtbFile(mtbFile: MtbFile, requestId: RequestId) {
|
fun processMtbFile(mtbFile: MtbFile, requestId: RequestId) {
|
||||||
val pid = mtbFile.patient.id
|
val pid = PatientId(mtbFile.patient.id)
|
||||||
|
|
||||||
mtbFile pseudonymizeWith pseudonymizeService
|
mtbFile pseudonymizeWith pseudonymizeService
|
||||||
mtbFile anonymizeContentWith pseudonymizeService
|
mtbFile anonymizeContentWith pseudonymizeService
|
||||||
|
|
||||||
val request = MtbFileSender.MtbFileRequest(requestId, transformationService.transform(mtbFile))
|
val request = MtbFileSender.MtbFileRequest(requestId, transformationService.transform(mtbFile))
|
||||||
|
|
||||||
|
val patientPseudonym = PatientPseudonym(request.mtbFile.patient.id)
|
||||||
|
|
||||||
requestService.save(
|
requestService.save(
|
||||||
Request(
|
Request(
|
||||||
requestId,
|
requestId,
|
||||||
request.mtbFile.patient.id,
|
patientPseudonym,
|
||||||
pid,
|
pid,
|
||||||
fingerprint(request.mtbFile),
|
fingerprint(request.mtbFile),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
@ -101,20 +101,22 @@ class RequestProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isDuplication(pseudonymizedMtbFile: MtbFile): Boolean {
|
private fun isDuplication(pseudonymizedMtbFile: MtbFile): Boolean {
|
||||||
|
val patientPseudonym = PatientPseudonym(pseudonymizedMtbFile.patient.id)
|
||||||
|
|
||||||
val lastMtbFileRequestForPatient =
|
val lastMtbFileRequestForPatient =
|
||||||
requestService.lastMtbFileRequestForPatientPseudonym(pseudonymizedMtbFile.patient.id)
|
requestService.lastMtbFileRequestForPatientPseudonym(patientPseudonym)
|
||||||
val isLastRequestDeletion = requestService.isLastRequestWithKnownStatusDeletion(pseudonymizedMtbFile.patient.id)
|
val isLastRequestDeletion = requestService.isLastRequestWithKnownStatusDeletion(patientPseudonym)
|
||||||
|
|
||||||
return null != lastMtbFileRequestForPatient
|
return null != lastMtbFileRequestForPatient
|
||||||
&& !isLastRequestDeletion
|
&& !isLastRequestDeletion
|
||||||
&& lastMtbFileRequestForPatient.fingerprint == fingerprint(pseudonymizedMtbFile)
|
&& lastMtbFileRequestForPatient.fingerprint == fingerprint(pseudonymizedMtbFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processDeletion(patientId: String) {
|
fun processDeletion(patientId: PatientId) {
|
||||||
processDeletion(patientId, randomRequestId())
|
processDeletion(patientId, randomRequestId())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun processDeletion(patientId: String, requestId: RequestId) {
|
fun processDeletion(patientId: PatientId, requestId: RequestId) {
|
||||||
try {
|
try {
|
||||||
val patientPseudonym = pseudonymizeService.patientPseudonym(patientId)
|
val patientPseudonym = pseudonymizeService.patientPseudonym(patientId)
|
||||||
|
|
||||||
@ -123,7 +125,7 @@ class RequestProcessor(
|
|||||||
requestId,
|
requestId,
|
||||||
patientPseudonym,
|
patientPseudonym,
|
||||||
patientId,
|
patientId,
|
||||||
fingerprint(patientPseudonym),
|
fingerprint(patientPseudonym.value),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.UNKNOWN
|
RequestStatus.UNKNOWN
|
||||||
)
|
)
|
||||||
@ -147,7 +149,7 @@ class RequestProcessor(
|
|||||||
requestService.save(
|
requestService.save(
|
||||||
Request(
|
Request(
|
||||||
uuid = requestId,
|
uuid = requestId,
|
||||||
patientId = "???",
|
patientId = emptyPatientPseudonym(),
|
||||||
pid = patientId,
|
pid = patientId,
|
||||||
fingerprint = Fingerprint.empty(),
|
fingerprint = Fingerprint.empty(),
|
||||||
status = RequestStatus.ERROR,
|
status = RequestStatus.ERROR,
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.services
|
package dev.dnpm.etl.processor.services
|
||||||
|
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.RequestId
|
import dev.dnpm.etl.processor.RequestId
|
||||||
import dev.dnpm.etl.processor.monitoring.*
|
import dev.dnpm.etl.processor.monitoring.*
|
||||||
import org.springframework.data.domain.Page
|
import org.springframework.data.domain.Page
|
||||||
@ -40,15 +41,15 @@ class RequestService(
|
|||||||
fun findByUuid(uuid: RequestId): Optional<Request> =
|
fun findByUuid(uuid: RequestId): Optional<Request> =
|
||||||
requestRepository.findByUuidEquals(uuid)
|
requestRepository.findByUuidEquals(uuid)
|
||||||
|
|
||||||
fun findRequestByPatientId(patientId: String, pageable: Pageable): Page<Request> = requestRepository.findRequestByPatientId(patientId, pageable)
|
fun findRequestByPatientId(patientId: PatientPseudonym, pageable: Pageable): Page<Request> = requestRepository.findRequestByPatientId(patientId, pageable)
|
||||||
|
|
||||||
fun allRequestsByPatientPseudonym(patientPseudonym: String) = requestRepository
|
fun allRequestsByPatientPseudonym(patientPseudonym: PatientPseudonym) = requestRepository
|
||||||
.findAllByPatientIdOrderByProcessedAtDesc(patientPseudonym)
|
.findAllByPatientIdOrderByProcessedAtDesc(patientPseudonym)
|
||||||
|
|
||||||
fun lastMtbFileRequestForPatientPseudonym(patientPseudonym: String) =
|
fun lastMtbFileRequestForPatientPseudonym(patientPseudonym: PatientPseudonym) =
|
||||||
Companion.lastMtbFileRequestForPatientPseudonym(allRequestsByPatientPseudonym(patientPseudonym))
|
Companion.lastMtbFileRequestForPatientPseudonym(allRequestsByPatientPseudonym(patientPseudonym))
|
||||||
|
|
||||||
fun isLastRequestWithKnownStatusDeletion(patientPseudonym: String) =
|
fun isLastRequestWithKnownStatusDeletion(patientPseudonym: PatientPseudonym) =
|
||||||
Companion.isLastRequestWithKnownStatusDeletion(allRequestsByPatientPseudonym(patientPseudonym))
|
Companion.isLastRequestWithKnownStatusDeletion(allRequestsByPatientPseudonym(patientPseudonym))
|
||||||
|
|
||||||
fun countStates(): Iterable<CountedState> = requestRepository.countStates()
|
fun countStates(): Iterable<CountedState> = requestRepository.countStates()
|
||||||
|
@ -39,3 +39,11 @@ value class RequestId(val value: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun randomRequestId() = RequestId(UUID.randomUUID().toString())
|
fun randomRequestId() = RequestId(UUID.randomUUID().toString())
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class PatientId(val value: String)
|
||||||
|
|
||||||
|
@JvmInline
|
||||||
|
value class PatientPseudonym(val value: String)
|
||||||
|
|
||||||
|
fun emptyPatientPseudonym() = PatientPseudonym("")
|
@ -20,6 +20,7 @@
|
|||||||
package dev.dnpm.etl.processor.web
|
package dev.dnpm.etl.processor.web
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.NotFoundException
|
import dev.dnpm.etl.processor.NotFoundException
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.RequestId
|
import dev.dnpm.etl.processor.RequestId
|
||||||
import dev.dnpm.etl.processor.monitoring.ReportService
|
import dev.dnpm.etl.processor.monitoring.ReportService
|
||||||
import dev.dnpm.etl.processor.services.RequestService
|
import dev.dnpm.etl.processor.services.RequestService
|
||||||
@ -56,7 +57,7 @@ class HomeController(
|
|||||||
@PageableDefault(page = 0, size = 20, sort = ["processedAt"], direction = Sort.Direction.DESC) pageable: Pageable,
|
@PageableDefault(page = 0, size = 20, sort = ["processedAt"], direction = Sort.Direction.DESC) pageable: Pageable,
|
||||||
model: Model
|
model: Model
|
||||||
): String {
|
): String {
|
||||||
val requests = requestService.findRequestByPatientId(patientId, pageable)
|
val requests = requestService.findRequestByPatientId(PatientPseudonym(patientId), pageable)
|
||||||
model.addAttribute("patientId", patientId)
|
model.addAttribute("patientId", patientId)
|
||||||
model.addAttribute("requests", requests)
|
model.addAttribute("requests", requests)
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@ import org.apache.kafka.common.record.TimestampType
|
|||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
import org.mockito.kotlin.any
|
import org.mockito.kotlin.any
|
||||||
@ -78,7 +77,7 @@ class KafkaInputListenerTest {
|
|||||||
|
|
||||||
kafkaInputListener.onMessage(ConsumerRecord("testtopic", 0, 0, "", this.objectMapper.writeValueAsString(mtbFile)))
|
kafkaInputListener.onMessage(ConsumerRecord("testtopic", 0, 0, "", this.objectMapper.writeValueAsString(mtbFile)))
|
||||||
|
|
||||||
verify(requestProcessor, times(1)).processDeletion(anyString())
|
verify(requestProcessor, times(1)).processDeletion(anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -107,7 +106,7 @@ class KafkaInputListenerTest {
|
|||||||
kafkaInputListener.onMessage(
|
kafkaInputListener.onMessage(
|
||||||
ConsumerRecord("testtopic", 0, 0, -1L, TimestampType.NO_TIMESTAMP_TYPE, -1, -1, "", this.objectMapper.writeValueAsString(mtbFile), headers, Optional.empty())
|
ConsumerRecord("testtopic", 0, 0, -1L, TimestampType.NO_TIMESTAMP_TYPE, -1, -1, "", this.objectMapper.writeValueAsString(mtbFile), headers, Optional.empty())
|
||||||
)
|
)
|
||||||
verify(requestProcessor, times(1)).processDeletion(anyString(), anyValueClass())
|
verify(requestProcessor, times(1)).processDeletion(anyValueClass(), anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,8 +21,8 @@ package dev.dnpm.etl.processor.input
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.*
|
import de.ukw.ccc.bwhc.dto.*
|
||||||
|
import dev.dnpm.etl.processor.anyValueClass
|
||||||
import dev.dnpm.etl.processor.services.RequestProcessor
|
import dev.dnpm.etl.processor.services.RequestProcessor
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
|
||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
@ -31,7 +31,6 @@ import org.mockito.Mockito.times
|
|||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
import org.mockito.kotlin.any
|
import org.mockito.kotlin.any
|
||||||
import org.mockito.kotlin.argumentCaptor
|
|
||||||
import org.springframework.http.MediaType
|
import org.springframework.http.MediaType
|
||||||
import org.springframework.test.web.servlet.MockMvc
|
import org.springframework.test.web.servlet.MockMvc
|
||||||
import org.springframework.test.web.servlet.delete
|
import org.springframework.test.web.servlet.delete
|
||||||
@ -129,9 +128,7 @@ class MtbFileRestControllerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val captor = argumentCaptor<String>()
|
verify(requestProcessor, times(1)).processDeletion(anyValueClass())
|
||||||
verify(requestProcessor, times(1)).processDeletion(captor.capture())
|
|
||||||
assertThat(captor.firstValue).isEqualTo("TEST_12345678")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -142,9 +139,7 @@ class MtbFileRestControllerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val captor = argumentCaptor<String>()
|
verify(requestProcessor, times(1)).processDeletion(anyValueClass())
|
||||||
verify(requestProcessor, times(1)).processDeletion(captor.capture())
|
|
||||||
assertThat(captor.firstValue).isEqualTo("TEST_12345678")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -21,6 +21,7 @@ package dev.dnpm.etl.processor.output
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.*
|
import de.ukw.ccc.bwhc.dto.*
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.RequestId
|
import dev.dnpm.etl.processor.RequestId
|
||||||
import dev.dnpm.etl.processor.config.KafkaProperties
|
import dev.dnpm.etl.processor.config.KafkaProperties
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
@ -87,7 +88,7 @@ class KafkaMtbFileSenderTest {
|
|||||||
completedFuture(SendResult<String, String>(null, null))
|
completedFuture(SendResult<String, String>(null, null))
|
||||||
}.whenever(kafkaTemplate).send(anyString(), anyString(), anyString())
|
}.whenever(kafkaTemplate).send(anyString(), anyString(), anyString())
|
||||||
|
|
||||||
val response = kafkaMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, "PID"))
|
val response = kafkaMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
|
||||||
assertThat(response.status).isEqualTo(testData.requestStatus)
|
assertThat(response.status).isEqualTo(testData.requestStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ class KafkaMtbFileSenderTest {
|
|||||||
completedFuture(SendResult<String, String>(null, null))
|
completedFuture(SendResult<String, String>(null, null))
|
||||||
}.whenever(kafkaTemplate).send(anyString(), anyString(), anyString())
|
}.whenever(kafkaTemplate).send(anyString(), anyString(), anyString())
|
||||||
|
|
||||||
kafkaMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, "PID"))
|
kafkaMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
|
||||||
|
|
||||||
val captor = argumentCaptor<String>()
|
val captor = argumentCaptor<String>()
|
||||||
verify(kafkaTemplate, times(1)).send(anyString(), captor.capture(), captor.capture())
|
verify(kafkaTemplate, times(1)).send(anyString(), captor.capture(), captor.capture())
|
||||||
@ -163,7 +164,7 @@ class KafkaMtbFileSenderTest {
|
|||||||
completedFuture(SendResult<String, String>(null, null))
|
completedFuture(SendResult<String, String>(null, null))
|
||||||
}.whenever(kafkaTemplate).send(anyString(), anyString(), anyString())
|
}.whenever(kafkaTemplate).send(anyString(), anyString(), anyString())
|
||||||
|
|
||||||
kafkaMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, "PID"))
|
kafkaMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
|
||||||
|
|
||||||
val expectedCount = when (testData.exception) {
|
val expectedCount = when (testData.exception) {
|
||||||
// OK - No Retry
|
// OK - No Retry
|
||||||
@ -177,6 +178,7 @@ class KafkaMtbFileSenderTest {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val TEST_REQUEST_ID = RequestId("TestId")
|
val TEST_REQUEST_ID = RequestId("TestId")
|
||||||
|
val TEST_PATIENT_PSEUDONYM = PatientPseudonym("PID")
|
||||||
|
|
||||||
fun mtbFile(consentStatus: Consent.Status): MtbFile {
|
fun mtbFile(consentStatus: Consent.Status): MtbFile {
|
||||||
return if (consentStatus == Consent.Status.ACTIVE) {
|
return if (consentStatus == Consent.Status.ACTIVE) {
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
package dev.dnpm.etl.processor.output
|
package dev.dnpm.etl.processor.output
|
||||||
|
|
||||||
import de.ukw.ccc.bwhc.dto.*
|
import de.ukw.ccc.bwhc.dto.*
|
||||||
|
import dev.dnpm.etl.processor.PatientPseudonym
|
||||||
import dev.dnpm.etl.processor.RequestId
|
import dev.dnpm.etl.processor.RequestId
|
||||||
import dev.dnpm.etl.processor.config.RestTargetProperties
|
import dev.dnpm.etl.processor.config.RestTargetProperties
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
@ -65,7 +66,7 @@ class RestMtbFileSenderTest {
|
|||||||
withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
|
withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val response = restMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, "PID"))
|
val response = restMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
|
||||||
assertThat(response.status).isEqualTo(requestWithResponse.response.status)
|
assertThat(response.status).isEqualTo(requestWithResponse.response.status)
|
||||||
assertThat(response.body).isEqualTo(requestWithResponse.response.body)
|
assertThat(response.body).isEqualTo(requestWithResponse.response.body)
|
||||||
}
|
}
|
||||||
@ -138,7 +139,7 @@ class RestMtbFileSenderTest {
|
|||||||
withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
|
withStatus(requestWithResponse.httpStatus).body(requestWithResponse.body).createResponse(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val response = restMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, "PID"))
|
val response = restMtbFileSender.send(MtbFileSender.DeleteRequest(TEST_REQUEST_ID, TEST_PATIENT_PSEUDONYM))
|
||||||
assertThat(response.status).isEqualTo(requestWithResponse.response.status)
|
assertThat(response.status).isEqualTo(requestWithResponse.response.status)
|
||||||
assertThat(response.body).isEqualTo(requestWithResponse.response.body)
|
assertThat(response.body).isEqualTo(requestWithResponse.response.body)
|
||||||
}
|
}
|
||||||
@ -151,6 +152,7 @@ class RestMtbFileSenderTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
val TEST_REQUEST_ID = RequestId("TestId")
|
val TEST_REQUEST_ID = RequestId("TestId")
|
||||||
|
val TEST_PATIENT_PSEUDONYM = PatientPseudonym("PID")
|
||||||
|
|
||||||
private val warningBody = """
|
private val warningBody = """
|
||||||
{
|
{
|
||||||
|
@ -21,11 +21,11 @@ package dev.dnpm.etl.processor.pseudonym
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.*
|
import de.ukw.ccc.bwhc.dto.*
|
||||||
|
import dev.dnpm.etl.processor.anyValueClass
|
||||||
import org.assertj.core.api.Assertions.assertThat
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.assertThrows
|
import org.junit.jupiter.api.assertThrows
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
import org.mockito.ArgumentMatchers
|
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
import org.mockito.kotlin.doAnswer
|
import org.mockito.kotlin.doAnswer
|
||||||
@ -52,7 +52,7 @@ class ExtensionsTest {
|
|||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
"PSEUDO-ID"
|
"PSEUDO-ID"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(ArgumentMatchers.anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
val mtbFile = fakeMtbFile()
|
val mtbFile = fakeMtbFile()
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ class ExtensionsTest {
|
|||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
"PSEUDO-ID"
|
"PSEUDO-ID"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(ArgumentMatchers.anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
"TESTDOMAIN"
|
"TESTDOMAIN"
|
||||||
@ -95,7 +95,7 @@ class ExtensionsTest {
|
|||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
"PSEUDO-ID"
|
"PSEUDO-ID"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(ArgumentMatchers.anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
"TESTDOMAIN"
|
"TESTDOMAIN"
|
||||||
@ -139,7 +139,7 @@ class ExtensionsTest {
|
|||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
"PSEUDO-ID"
|
"PSEUDO-ID"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(ArgumentMatchers.anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
"TESTDOMAIN"
|
"TESTDOMAIN"
|
||||||
|
@ -21,8 +21,7 @@ package dev.dnpm.etl.processor.services
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
import de.ukw.ccc.bwhc.dto.*
|
import de.ukw.ccc.bwhc.dto.*
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import dev.dnpm.etl.processor.config.AppConfigProperties
|
import dev.dnpm.etl.processor.config.AppConfigProperties
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
import dev.dnpm.etl.processor.monitoring.Request
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
@ -34,7 +33,6 @@ import org.assertj.core.api.Assertions.assertThat
|
|||||||
import org.junit.jupiter.api.BeforeEach
|
import org.junit.jupiter.api.BeforeEach
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito.*
|
import org.mockito.Mockito.*
|
||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
@ -91,22 +89,22 @@ class RequestProcessorTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("zdlzv5s5ydmd4ktw2v5piohegc4jcyrm6j66bq6tv2uxuerndmga"),
|
Fingerprint("zdlzv5s5ydmd4ktw2v5piohegc4jcyrm6j66bq6tv2uxuerndmga"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
Instant.parse("2023-08-08T02:00:00Z")
|
Instant.parse("2023-08-08T02:00:00Z")
|
||||||
)
|
)
|
||||||
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyString())
|
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
false
|
false
|
||||||
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyString())
|
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0] as String
|
it.arguments[0] as String
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(any())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
@ -150,22 +148,22 @@ class RequestProcessorTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("zdlzv5s5ydmd4ktw2v5piohegc4jcyrm6j66bq6tv2uxuerndmga"),
|
Fingerprint("zdlzv5s5ydmd4ktw2v5piohegc4jcyrm6j66bq6tv2uxuerndmga"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
Instant.parse("2023-08-08T02:00:00Z")
|
Instant.parse("2023-08-08T02:00:00Z")
|
||||||
)
|
)
|
||||||
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyString())
|
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
false
|
false
|
||||||
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyString())
|
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0] as String
|
it.arguments[0] as String
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(any())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
@ -209,18 +207,18 @@ class RequestProcessorTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("different"),
|
Fingerprint("different"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
Instant.parse("2023-08-08T02:00:00Z")
|
Instant.parse("2023-08-08T02:00:00Z")
|
||||||
)
|
)
|
||||||
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyString())
|
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
false
|
false
|
||||||
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyString())
|
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
MtbFileSender.Response(status = RequestStatus.SUCCESS)
|
MtbFileSender.Response(status = RequestStatus.SUCCESS)
|
||||||
@ -228,7 +226,7 @@ class RequestProcessorTest {
|
|||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0] as String
|
it.arguments[0] as String
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(any())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
@ -272,18 +270,18 @@ class RequestProcessorTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("different"),
|
Fingerprint("different"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
Instant.parse("2023-08-08T02:00:00Z")
|
Instant.parse("2023-08-08T02:00:00Z")
|
||||||
)
|
)
|
||||||
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyString())
|
}.whenever(requestService).lastMtbFileRequestForPatientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
false
|
false
|
||||||
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyString())
|
}.whenever(requestService).isLastRequestWithKnownStatusDeletion(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
MtbFileSender.Response(status = RequestStatus.ERROR)
|
MtbFileSender.Response(status = RequestStatus.ERROR)
|
||||||
@ -291,7 +289,7 @@ class RequestProcessorTest {
|
|||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0] as String
|
it.arguments[0] as String
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(any())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
@ -333,13 +331,13 @@ class RequestProcessorTest {
|
|||||||
fun testShouldSendDeleteRequestAndSaveUnknownRequestStatusAtFirst() {
|
fun testShouldSendDeleteRequestAndSaveUnknownRequestStatusAtFirst() {
|
||||||
doAnswer {
|
doAnswer {
|
||||||
"PSEUDONYM"
|
"PSEUDONYM"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
MtbFileSender.Response(status = RequestStatus.UNKNOWN)
|
MtbFileSender.Response(status = RequestStatus.UNKNOWN)
|
||||||
}.whenever(sender).send(any<MtbFileSender.DeleteRequest>())
|
}.whenever(sender).send(any<MtbFileSender.DeleteRequest>())
|
||||||
|
|
||||||
this.requestProcessor.processDeletion("TEST_12345678901")
|
this.requestProcessor.processDeletion(TEST_PATIENT_ID)
|
||||||
|
|
||||||
val requestCaptor = argumentCaptor<Request>()
|
val requestCaptor = argumentCaptor<Request>()
|
||||||
verify(requestService, times(1)).save(requestCaptor.capture())
|
verify(requestService, times(1)).save(requestCaptor.capture())
|
||||||
@ -351,13 +349,13 @@ class RequestProcessorTest {
|
|||||||
fun testShouldSendDeleteRequestAndSendSuccessEvent() {
|
fun testShouldSendDeleteRequestAndSendSuccessEvent() {
|
||||||
doAnswer {
|
doAnswer {
|
||||||
"PSEUDONYM"
|
"PSEUDONYM"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
MtbFileSender.Response(status = RequestStatus.SUCCESS)
|
MtbFileSender.Response(status = RequestStatus.SUCCESS)
|
||||||
}.whenever(sender).send(any<MtbFileSender.DeleteRequest>())
|
}.whenever(sender).send(any<MtbFileSender.DeleteRequest>())
|
||||||
|
|
||||||
this.requestProcessor.processDeletion("TEST_12345678901")
|
this.requestProcessor.processDeletion(TEST_PATIENT_ID)
|
||||||
|
|
||||||
val eventCaptor = argumentCaptor<ResponseEvent>()
|
val eventCaptor = argumentCaptor<ResponseEvent>()
|
||||||
verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
|
verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
|
||||||
@ -369,13 +367,13 @@ class RequestProcessorTest {
|
|||||||
fun testShouldSendDeleteRequestAndSendErrorEvent() {
|
fun testShouldSendDeleteRequestAndSendErrorEvent() {
|
||||||
doAnswer {
|
doAnswer {
|
||||||
"PSEUDONYM"
|
"PSEUDONYM"
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(anyString())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
MtbFileSender.Response(status = RequestStatus.ERROR)
|
MtbFileSender.Response(status = RequestStatus.ERROR)
|
||||||
}.whenever(sender).send(any<MtbFileSender.DeleteRequest>())
|
}.whenever(sender).send(any<MtbFileSender.DeleteRequest>())
|
||||||
|
|
||||||
this.requestProcessor.processDeletion("TEST_12345678901")
|
this.requestProcessor.processDeletion(TEST_PATIENT_ID)
|
||||||
|
|
||||||
val eventCaptor = argumentCaptor<ResponseEvent>()
|
val eventCaptor = argumentCaptor<ResponseEvent>()
|
||||||
verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
|
verify(applicationEventPublisher, times(1)).publishEvent(eventCaptor.capture())
|
||||||
@ -385,9 +383,9 @@ class RequestProcessorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testShouldSendDeleteRequestWithPseudonymErrorAndSaveErrorRequestStatus() {
|
fun testShouldSendDeleteRequestWithPseudonymErrorAndSaveErrorRequestStatus() {
|
||||||
doThrow(RuntimeException()).whenever(pseudonymizeService).patientPseudonym(anyString())
|
doThrow(RuntimeException()).whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
this.requestProcessor.processDeletion("TEST_12345678901")
|
this.requestProcessor.processDeletion(TEST_PATIENT_ID)
|
||||||
|
|
||||||
val requestCaptor = argumentCaptor<Request>()
|
val requestCaptor = argumentCaptor<Request>()
|
||||||
verify(requestService, times(1)).save(requestCaptor.capture())
|
verify(requestService, times(1)).save(requestCaptor.capture())
|
||||||
@ -401,7 +399,7 @@ class RequestProcessorTest {
|
|||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0] as String
|
it.arguments[0] as String
|
||||||
}.whenever(pseudonymizeService).patientPseudonym(any())
|
}.whenever(pseudonymizeService).patientPseudonym(anyValueClass())
|
||||||
|
|
||||||
doAnswer {
|
doAnswer {
|
||||||
it.arguments[0]
|
it.arguments[0]
|
||||||
@ -443,4 +441,8 @@ class RequestProcessorTest {
|
|||||||
assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
|
assertThat(eventCaptor.firstValue.status).isEqualTo(RequestStatus.SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TEST_PATIENT_ID = PatientId("TEST_12345678901")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.services
|
package dev.dnpm.etl.processor.services
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.randomRequestId
|
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
import dev.dnpm.etl.processor.monitoring.Request
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
import dev.dnpm.etl.processor.monitoring.RequestRepository
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
@ -45,8 +44,8 @@ class RequestServiceTest {
|
|||||||
private fun anyRequest() = any(Request::class.java) ?: Request(
|
private fun anyRequest() = any(Request::class.java) ?: Request(
|
||||||
0L,
|
0L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_dummy",
|
PatientPseudonym("TEST_dummy"),
|
||||||
"PX",
|
PatientId("PX"),
|
||||||
Fingerprint("dummy"),
|
Fingerprint("dummy"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -67,8 +66,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -77,8 +76,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
2L,
|
2L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdefd"),
|
Fingerprint("0123456789abcdefd"),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -87,8 +86,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
3L,
|
3L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.UNKNOWN,
|
RequestStatus.UNKNOWN,
|
||||||
@ -107,8 +106,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -117,8 +116,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
2L,
|
2L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -127,8 +126,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
3L,
|
3L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.UNKNOWN,
|
RequestStatus.UNKNOWN,
|
||||||
@ -147,8 +146,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -157,8 +156,8 @@ class RequestServiceTest {
|
|||||||
Request(
|
Request(
|
||||||
1L,
|
1L,
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678902",
|
PatientPseudonym("TEST_12345678902"),
|
||||||
"P2",
|
PatientId("P2"),
|
||||||
Fingerprint("0123456789abcdef2"),
|
Fingerprint("0123456789abcdef2"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.WARNING,
|
RequestStatus.WARNING,
|
||||||
@ -190,8 +189,8 @@ class RequestServiceTest {
|
|||||||
|
|
||||||
val request = Request(
|
val request = Request(
|
||||||
randomRequestId(),
|
randomRequestId(),
|
||||||
"TEST_12345678901",
|
PatientPseudonym("TEST_12345678901"),
|
||||||
"P1",
|
PatientId("P1"),
|
||||||
Fingerprint("0123456789abcdef1"),
|
Fingerprint("0123456789abcdef1"),
|
||||||
RequestType.DELETE,
|
RequestType.DELETE,
|
||||||
RequestStatus.SUCCESS,
|
RequestStatus.SUCCESS,
|
||||||
@ -205,23 +204,23 @@ class RequestServiceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun allRequestsByPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
|
fun allRequestsByPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
|
||||||
requestService.allRequestsByPatientPseudonym("TEST_12345678901")
|
requestService.allRequestsByPatientPseudonym(PatientPseudonym("TEST_12345678901"))
|
||||||
|
|
||||||
verify(requestRepository, times(1)).findAllByPatientIdOrderByProcessedAtDesc(anyString())
|
verify(requestRepository, times(1)).findAllByPatientIdOrderByProcessedAtDesc(anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun lastMtbFileRequestForPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
|
fun lastMtbFileRequestForPatientPseudonymShouldRequestAllRequestsForPatientPseudonym() {
|
||||||
requestService.lastMtbFileRequestForPatientPseudonym("TEST_12345678901")
|
requestService.lastMtbFileRequestForPatientPseudonym(PatientPseudonym("TEST_12345678901"))
|
||||||
|
|
||||||
verify(requestRepository, times(1)).findAllByPatientIdOrderByProcessedAtDesc(anyString())
|
verify(requestRepository, times(1)).findAllByPatientIdOrderByProcessedAtDesc(anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isLastRequestDeletionShouldRequestAllRequestsForPatientPseudonym() {
|
fun isLastRequestDeletionShouldRequestAllRequestsForPatientPseudonym() {
|
||||||
requestService.isLastRequestWithKnownStatusDeletion("TEST_12345678901")
|
requestService.isLastRequestWithKnownStatusDeletion(PatientPseudonym("TEST_12345678901"))
|
||||||
|
|
||||||
verify(requestRepository, times(1)).findAllByPatientIdOrderByProcessedAtDesc(anyString())
|
verify(requestRepository, times(1)).findAllByPatientIdOrderByProcessedAtDesc(anyValueClass())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -19,9 +19,7 @@
|
|||||||
|
|
||||||
package dev.dnpm.etl.processor.services
|
package dev.dnpm.etl.processor.services
|
||||||
|
|
||||||
import dev.dnpm.etl.processor.Fingerprint
|
import dev.dnpm.etl.processor.*
|
||||||
import dev.dnpm.etl.processor.RequestId
|
|
||||||
import dev.dnpm.etl.processor.anyValueClass
|
|
||||||
import dev.dnpm.etl.processor.monitoring.Request
|
import dev.dnpm.etl.processor.monitoring.Request
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||||
import dev.dnpm.etl.processor.monitoring.RequestType
|
import dev.dnpm.etl.processor.monitoring.RequestType
|
||||||
@ -49,8 +47,8 @@ class ResponseProcessorTest {
|
|||||||
private val testRequest = Request(
|
private val testRequest = Request(
|
||||||
1L,
|
1L,
|
||||||
RequestId("TestID1234"),
|
RequestId("TestID1234"),
|
||||||
"PSEUDONYM-A",
|
PatientPseudonym("PSEUDONYM-A"),
|
||||||
"1",
|
PatientId("1"),
|
||||||
Fingerprint("dummyfingerprint"),
|
Fingerprint("dummyfingerprint"),
|
||||||
RequestType.MTB_FILE,
|
RequestType.MTB_FILE,
|
||||||
RequestStatus.UNKNOWN
|
RequestStatus.UNKNOWN
|
||||||
|
Loading…
x
Reference in New Issue
Block a user