mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-04-19 17:26:51 +00:00
Do not append custom prefix to gPAS pseudonym
This commit is contained in:
parent
47830ed9f7
commit
7f048e2483
@ -19,7 +19,6 @@
|
||||
|
||||
package dev.dnpm.etl.processor.pseudonym
|
||||
|
||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||
import dev.dnpm.etl.processor.config.PseudonymizeConfigProperties
|
||||
|
||||
class PseudonymizeService(
|
||||
@ -27,38 +26,11 @@ class PseudonymizeService(
|
||||
private val configProperties: PseudonymizeConfigProperties
|
||||
) {
|
||||
|
||||
fun pseudonymize(mtbFile: MtbFile): MtbFile {
|
||||
val patientPseudonym = patientPseudonym(mtbFile.patient.id)
|
||||
|
||||
mtbFile.episode.patient = patientPseudonym
|
||||
mtbFile.carePlans.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.patient.id = patientPseudonym
|
||||
mtbFile.claims.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.consent.patient = patientPseudonym
|
||||
mtbFile.claimResponses.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.diagnoses.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.ecogStatus.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.familyMemberDiagnoses.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.geneticCounsellingRequests.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.histologyReevaluationRequests.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.histologyReports.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.lastGuidelineTherapies.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.molecularPathologyFindings.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.molecularTherapies.forEach { it.history.forEach { it.patient = patientPseudonym } }
|
||||
mtbFile.ngsReports.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.previousGuidelineTherapies.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.rebiopsyRequests.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.recommendations.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.recommendations.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.responses.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.specimens.forEach { it.patient = patientPseudonym }
|
||||
mtbFile.specimens.forEach { it.patient = patientPseudonym }
|
||||
|
||||
return mtbFile
|
||||
}
|
||||
|
||||
fun patientPseudonym(patientId: String): String {
|
||||
return "${configProperties.prefix}_${generator.generate(patientId)}"
|
||||
return when (generator) {
|
||||
is GpasPseudonymGenerator -> generator.generate(patientId)
|
||||
else -> "${configProperties.prefix}_${generator.generate(patientId)}"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* This file is part of ETL-Processor
|
||||
*
|
||||
* Copyright (c) 2023 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.pseudonym
|
||||
|
||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||
|
||||
infix fun MtbFile.pseudonymizeWith(pseudonymizeService: PseudonymizeService) {
|
||||
val patientPseudonym = pseudonymizeService.patientPseudonym(this.patient.id)
|
||||
|
||||
this.episode.patient = patientPseudonym
|
||||
this.carePlans.forEach { it.patient = patientPseudonym }
|
||||
this.patient.id = patientPseudonym
|
||||
this.claims.forEach { it.patient = patientPseudonym }
|
||||
this.consent.patient = patientPseudonym
|
||||
this.claimResponses.forEach { it.patient = patientPseudonym }
|
||||
this.diagnoses.forEach { it.patient = patientPseudonym }
|
||||
this.ecogStatus.forEach { it.patient = patientPseudonym }
|
||||
this.familyMemberDiagnoses.forEach { it.patient = patientPseudonym }
|
||||
this.geneticCounsellingRequests.forEach { it.patient = patientPseudonym }
|
||||
this.histologyReevaluationRequests.forEach { it.patient = patientPseudonym }
|
||||
this.histologyReports.forEach { it.patient = patientPseudonym }
|
||||
this.lastGuidelineTherapies.forEach { it.patient = patientPseudonym }
|
||||
this.molecularPathologyFindings.forEach { it.patient = patientPseudonym }
|
||||
this.molecularTherapies.forEach { it.history.forEach { it.patient = patientPseudonym } }
|
||||
this.ngsReports.forEach { it.patient = patientPseudonym }
|
||||
this.previousGuidelineTherapies.forEach { it.patient = patientPseudonym }
|
||||
this.rebiopsyRequests.forEach { it.patient = patientPseudonym }
|
||||
this.recommendations.forEach { it.patient = patientPseudonym }
|
||||
this.recommendations.forEach { it.patient = patientPseudonym }
|
||||
this.responses.forEach { it.patient = patientPseudonym }
|
||||
this.specimens.forEach { it.patient = patientPseudonym }
|
||||
this.specimens.forEach { it.patient = patientPseudonym }
|
||||
}
|
@ -27,6 +27,7 @@ import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||
import dev.dnpm.etl.processor.monitoring.RequestType
|
||||
import dev.dnpm.etl.processor.output.MtbFileSender
|
||||
import dev.dnpm.etl.processor.pseudonym.PseudonymizeService
|
||||
import dev.dnpm.etl.processor.pseudonym.pseudonymizeWith
|
||||
import org.apache.commons.codec.binary.Base32
|
||||
import org.apache.commons.codec.digest.DigestUtils
|
||||
import org.slf4j.LoggerFactory
|
||||
@ -47,12 +48,13 @@ class RequestProcessor(
|
||||
|
||||
fun processMtbFile(mtbFile: MtbFile) {
|
||||
val pid = mtbFile.patient.id
|
||||
val pseudonymized = pseudonymizeService.pseudonymize(mtbFile)
|
||||
|
||||
if (isDuplication(pseudonymized)) {
|
||||
mtbFile pseudonymizeWith pseudonymizeService
|
||||
|
||||
if (isDuplication(mtbFile)) {
|
||||
requestService.save(
|
||||
Request(
|
||||
patientId = pseudonymized.patient.id,
|
||||
patientId = mtbFile.patient.id,
|
||||
pid = pid,
|
||||
fingerprint = fingerprint(mtbFile),
|
||||
status = RequestStatus.DUPLICATION,
|
||||
@ -64,19 +66,19 @@ class RequestProcessor(
|
||||
return
|
||||
}
|
||||
|
||||
val request = MtbFileSender.MtbFileRequest(UUID.randomUUID().toString(), pseudonymized)
|
||||
val request = MtbFileSender.MtbFileRequest(UUID.randomUUID().toString(), mtbFile)
|
||||
|
||||
val responseStatus = sender.send(request)
|
||||
if (responseStatus.status == MtbFileSender.ResponseStatus.SUCCESS || responseStatus.status == MtbFileSender.ResponseStatus.WARNING) {
|
||||
logger.info(
|
||||
"Sent file for Patient '{}' using '{}'",
|
||||
pseudonymized.patient.id,
|
||||
mtbFile.patient.id,
|
||||
sender.javaClass.simpleName
|
||||
)
|
||||
} else {
|
||||
logger.error(
|
||||
"Error sending file for Patient '{}' using '{}'",
|
||||
pseudonymized.patient.id,
|
||||
mtbFile.patient.id,
|
||||
sender.javaClass.simpleName
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* This file is part of ETL-Processor
|
||||
*
|
||||
* Copyright (c) 2023 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.pseudonym
|
||||
|
||||
import de.ukw.ccc.bwhc.dto.*
|
||||
import dev.dnpm.etl.processor.config.PseudonymizeConfigProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.ArgumentMatchers.anyString
|
||||
import org.mockito.Mock
|
||||
import org.mockito.junit.jupiter.MockitoExtension
|
||||
import org.mockito.kotlin.doAnswer
|
||||
import org.mockito.kotlin.whenever
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class PseudonymizeServiceTest {
|
||||
|
||||
private val mtbFile = MtbFile.builder()
|
||||
.withPatient(
|
||||
Patient.builder()
|
||||
.withId("123")
|
||||
.withBirthDate("2000-08-08")
|
||||
.withGender(Patient.Gender.MALE)
|
||||
.build()
|
||||
)
|
||||
.withConsent(
|
||||
Consent.builder()
|
||||
.withId("1")
|
||||
.withStatus(Consent.Status.ACTIVE)
|
||||
.withPatient("123")
|
||||
.build()
|
||||
)
|
||||
.withEpisode(
|
||||
Episode.builder()
|
||||
.withId("1")
|
||||
.withPatient("123")
|
||||
.withPeriod(PeriodStart("2023-08-08"))
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
|
||||
@Test
|
||||
fun shouldNotUsePseudonymPrefixForGpas(@Mock generator: GpasPseudonymGenerator) {
|
||||
doAnswer {
|
||||
it.arguments[0]
|
||||
}.whenever(generator).generate(anyString())
|
||||
|
||||
val pseudonymizeService = PseudonymizeService(generator, PseudonymizeConfigProperties())
|
||||
|
||||
mtbFile.pseudonymizeWith(pseudonymizeService)
|
||||
|
||||
assertThat(mtbFile.patient.id).isEqualTo("123")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldUsePseudonymPrefixForBuiltin(@Mock generator: AnonymizingGenerator) {
|
||||
doAnswer {
|
||||
it.arguments[0]
|
||||
}.whenever(generator).generate(anyString())
|
||||
|
||||
val pseudonymizeService = PseudonymizeService(generator, PseudonymizeConfigProperties())
|
||||
|
||||
mtbFile.pseudonymizeWith(pseudonymizeService)
|
||||
|
||||
assertThat(mtbFile.patient.id).isEqualTo("UNKNOWN_123")
|
||||
}
|
||||
|
||||
}
|
@ -82,7 +82,7 @@ class RequestProcessorTest {
|
||||
uuid = UUID.randomUUID().toString(),
|
||||
patientId = "TEST_12345678901",
|
||||
pid = "P1",
|
||||
fingerprint = "cwaxsvectyfj4qcw4hiwzx5fwwo7lekyagpzd2ayuf36jlvi6msa",
|
||||
fingerprint = "xrysxpozhbs2lnrjgf3yq4fzj33kxr7xr5c2cbuskmelfdmckl3a",
|
||||
type = RequestType.MTB_FILE,
|
||||
status = RequestStatus.SUCCESS,
|
||||
processedAt = Instant.parse("2023-08-08T02:00:00Z")
|
||||
@ -94,8 +94,8 @@ class RequestProcessorTest {
|
||||
}.`when`(requestService).isLastRequestDeletion(anyString())
|
||||
|
||||
doAnswer {
|
||||
it.arguments[0] as MtbFile
|
||||
}.`when`(pseudonymizeService).pseudonymize(any())
|
||||
it.arguments[0] as String
|
||||
}.`when`(pseudonymizeService).patientPseudonym(any())
|
||||
|
||||
val mtbFile = MtbFile.builder()
|
||||
.withPatient(
|
||||
@ -153,8 +153,8 @@ class RequestProcessorTest {
|
||||
}.`when`(sender).send(any<MtbFileSender.MtbFileRequest>())
|
||||
|
||||
doAnswer {
|
||||
it.arguments[0] as MtbFile
|
||||
}.`when`(pseudonymizeService).pseudonymize(any())
|
||||
it.arguments[0] as String
|
||||
}.`when`(pseudonymizeService).patientPseudonym(any())
|
||||
|
||||
val mtbFile = MtbFile.builder()
|
||||
.withPatient(
|
||||
@ -212,8 +212,8 @@ class RequestProcessorTest {
|
||||
}.`when`(sender).send(any<MtbFileSender.MtbFileRequest>())
|
||||
|
||||
doAnswer {
|
||||
it.arguments[0] as MtbFile
|
||||
}.`when`(pseudonymizeService).pseudonymize(any())
|
||||
it.arguments[0] as String
|
||||
}.`when`(pseudonymizeService).patientPseudonym(any())
|
||||
|
||||
val mtbFile = MtbFile.builder()
|
||||
.withPatient(
|
||||
|
Loading…
x
Reference in New Issue
Block a user