mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-07-01 06:02:54 +00:00
feat: Broad Consent and GenomDE Consent can be embedded into mtb file
This commit is contained in:
@ -214,13 +214,11 @@ public class GicsConsentService implements ICheckConsent {
|
||||
}
|
||||
|
||||
public Bundle getBroadConsent(String personIdentifierValue, Date requestDate) {
|
||||
String consentDomainName = gIcsConfigProperties.getBroadConsentDomainName();
|
||||
return currentConsentForPersonAndTemplate(personIdentifierValue, ConsentDomain.BroadConsent,
|
||||
requestDate);
|
||||
}
|
||||
|
||||
public Bundle getGnomDeConsent(String personIdentifierValue, Date requestDate) {
|
||||
|
||||
public Bundle getGenomDeConsent(String personIdentifierValue, Date requestDate) {
|
||||
return currentConsentForPersonAndTemplate(personIdentifierValue,
|
||||
ConsentDomain.Modelvorhaben64e, requestDate);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import de.ukw.ccc.bwhc.dto.MtbFile
|
||||
import dev.dnpm.etl.processor.*
|
||||
import dev.dnpm.etl.processor.config.AppConfigProperties
|
||||
import dev.dnpm.etl.processor.consent.GicsConsentService
|
||||
import dev.dnpm.etl.processor.consent.TtpConsentStatus
|
||||
import dev.dnpm.etl.processor.monitoring.Report
|
||||
import dev.dnpm.etl.processor.monitoring.Request
|
||||
@ -32,9 +33,17 @@ import dev.dnpm.etl.processor.output.*
|
||||
import dev.dnpm.etl.processor.pseudonym.PseudonymizeService
|
||||
import dev.dnpm.etl.processor.pseudonym.anonymizeContentWith
|
||||
import dev.dnpm.etl.processor.pseudonym.pseudonymizeWith
|
||||
import dev.pcvolkmer.mv64e.mtb.ConsentProvision
|
||||
import dev.pcvolkmer.mv64e.mtb.ModelProjectConsent
|
||||
import dev.pcvolkmer.mv64e.mtb.ModelProjectConsentPurpose
|
||||
import dev.pcvolkmer.mv64e.mtb.Mtb
|
||||
import dev.pcvolkmer.mv64e.mtb.MvhMetadata
|
||||
import dev.pcvolkmer.mv64e.mtb.Provision
|
||||
import org.apache.commons.codec.binary.Base32
|
||||
import org.apache.commons.codec.digest.DigestUtils
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource
|
||||
import org.hl7.fhir.r4.model.Bundle
|
||||
import org.hl7.fhir.r4.model.Consent
|
||||
import org.springframework.context.ApplicationEventPublisher
|
||||
import org.springframework.stereotype.Service
|
||||
import java.time.Instant
|
||||
@ -48,7 +57,8 @@ class RequestProcessor(
|
||||
private val requestService: RequestService,
|
||||
private val objectMapper: ObjectMapper,
|
||||
private val applicationEventPublisher: ApplicationEventPublisher,
|
||||
private val appConfigProperties: AppConfigProperties
|
||||
private val appConfigProperties: AppConfigProperties,
|
||||
private val gicsConsentService: GicsConsentService?
|
||||
) {
|
||||
|
||||
fun processMtbFile(mtbFile: MtbFile) {
|
||||
@ -69,12 +79,84 @@ class RequestProcessor(
|
||||
|
||||
fun processMtbFile(mtbFile: Mtb, requestId: RequestId) {
|
||||
val pid = PatientId(mtbFile.patient.id)
|
||||
|
||||
addConsentToMtb(mtbFile)
|
||||
mtbFile pseudonymizeWith pseudonymizeService
|
||||
mtbFile anonymizeContentWith pseudonymizeService
|
||||
val request = DnpmV2MtbFileRequest(requestId, transformationService.transform(mtbFile))
|
||||
saveAndSend(request, pid)
|
||||
}
|
||||
|
||||
fun addConsentToMtb(mtbFile: Mtb) {
|
||||
if (gicsConsentService == null) return
|
||||
// init metadata if necessary
|
||||
if (mtbFile.metadata == null) {
|
||||
val mvhMetadata = MvhMetadata.builder().build();
|
||||
mtbFile.metadata = mvhMetadata
|
||||
if (mtbFile.metadata.researchConsents == null) {
|
||||
mtbFile.metadata.researchConsents = mutableListOf()
|
||||
}
|
||||
if (mtbFile.metadata.modelProjectConsent == null) {
|
||||
mtbFile.metadata.modelProjectConsent = ModelProjectConsent()
|
||||
mtbFile.metadata.modelProjectConsent.provisions = mutableListOf()
|
||||
}
|
||||
}
|
||||
|
||||
// fixme Date should be extracted from mtbFile
|
||||
val consentGnomeDe =
|
||||
gicsConsentService.getGenomDeConsent(mtbFile.patient.id, Date.from(Instant.now()))
|
||||
addGenomeDbProvisions(mtbFile, consentGnomeDe)
|
||||
|
||||
// fixme Date should be extracted from mtbFile
|
||||
val broadConsent =
|
||||
gicsConsentService.getBroadConsent(mtbFile.patient.id, Date.from(Instant.now()))
|
||||
embedBroadConsentResources(mtbFile, broadConsent)
|
||||
}
|
||||
|
||||
fun embedBroadConsentResources(
|
||||
mtbFile: Mtb,
|
||||
broadConsent: Bundle
|
||||
) {
|
||||
broadConsent.entry.forEach { it ->
|
||||
mtbFile.metadata.researchConsents.add(mapOf(it.resource.id to it as IBaseResource))
|
||||
}
|
||||
}
|
||||
|
||||
fun addGenomeDbProvisions(
|
||||
mtbFile: Mtb,
|
||||
consentGnomeDe: Bundle
|
||||
) {
|
||||
consentGnomeDe.entry.forEach { it ->
|
||||
{
|
||||
val consent = it.resource as Consent
|
||||
val provisionComponent = consent.provision.provision.firstOrNull()
|
||||
val provisionCode =
|
||||
provisionComponent?.code?.firstOrNull()?.coding?.firstOrNull()?.code
|
||||
var isValidCode = true
|
||||
if (provisionCode != null) {
|
||||
var modelProjectConsentPurpose: ModelProjectConsentPurpose =
|
||||
ModelProjectConsentPurpose.SEQUENCING
|
||||
if (provisionCode == "Teilnahme") {
|
||||
modelProjectConsentPurpose = ModelProjectConsentPurpose.SEQUENCING
|
||||
} else if (provisionCode == "Fallidentifizierung") {
|
||||
modelProjectConsentPurpose = ModelProjectConsentPurpose.CASE_IDENTIFICATION
|
||||
} else if (provisionCode == "Rekontaktierung") {
|
||||
modelProjectConsentPurpose = ModelProjectConsentPurpose.REIDENTIFICATION
|
||||
} else {
|
||||
isValidCode = false
|
||||
}
|
||||
if (isValidCode) mtbFile.metadata.modelProjectConsent.provisions.add(
|
||||
Provision.builder().type(
|
||||
ConsentProvision.forValue(provisionComponent.type.name)
|
||||
).date(provisionComponent.period.start).purpose(
|
||||
modelProjectConsentPurpose
|
||||
).build()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> saveAndSend(request: MtbFileRequest<T>, pid: PatientId) {
|
||||
requestService.save(
|
||||
Request(
|
||||
@ -126,7 +208,9 @@ class RequestProcessor(
|
||||
|
||||
return null != lastMtbFileRequestForPatient
|
||||
&& !isLastRequestDeletion
|
||||
&& lastMtbFileRequestForPatient.fingerprint == fingerprint(pseudonymizedMtbFileRequest)
|
||||
&& lastMtbFileRequestForPatient.fingerprint == fingerprint(
|
||||
pseudonymizedMtbFileRequest
|
||||
)
|
||||
}
|
||||
|
||||
fun processDeletion(patientId: PatientId, isConsented: TtpConsentStatus) {
|
||||
|
@ -22,6 +22,7 @@ package dev.dnpm.etl.processor.pseudonym
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import de.ukw.ccc.bwhc.dto.*
|
||||
import de.ukw.ccc.bwhc.dto.Patient
|
||||
import dev.dnpm.etl.processor.config.JacksonConfig
|
||||
import dev.pcvolkmer.mv64e.mtb.*
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.jupiter.api.Nested
|
||||
@ -39,6 +40,9 @@ import java.util.*
|
||||
|
||||
@ExtendWith(MockitoExtension::class)
|
||||
class ExtensionsTest {
|
||||
fun getObjectMapper() : ObjectMapper {
|
||||
return JacksonConfig().objectMapper()
|
||||
}
|
||||
|
||||
@Nested
|
||||
inner class UsingBwhcDatamodel {
|
||||
@ -46,13 +50,14 @@ class ExtensionsTest {
|
||||
val FAKE_MTB_FILE_PATH = "fake_MTBFile.json"
|
||||
val CLEAN_PATIENT_ID = "5dad2f0b-49c6-47d8-a952-7b9e9e0f7549"
|
||||
|
||||
|
||||
private fun fakeMtbFile(): MtbFile {
|
||||
val mtbFile = ClassPathResource(FAKE_MTB_FILE_PATH).inputStream
|
||||
return ObjectMapper().readValue(mtbFile, MtbFile::class.java)
|
||||
return getObjectMapper().readValue(mtbFile, MtbFile::class.java)
|
||||
}
|
||||
|
||||
private fun MtbFile.serialized(): String {
|
||||
return ObjectMapper().writeValueAsString(this)
|
||||
return getObjectMapper().writeValueAsString(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -211,11 +216,11 @@ class ExtensionsTest {
|
||||
|
||||
private fun fakeMtbFile(): Mtb {
|
||||
val mtbFile = ClassPathResource(FAKE_MTB_FILE_PATH).inputStream
|
||||
return ObjectMapper().readValue(mtbFile, Mtb::class.java)
|
||||
return getObjectMapper().readValue(mtbFile, Mtb::class.java)
|
||||
}
|
||||
|
||||
private fun Mtb.serialized(): String {
|
||||
return ObjectMapper().writeValueAsString(this)
|
||||
return getObjectMapper().writeValueAsString(this)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -25,6 +25,7 @@ import dev.dnpm.etl.processor.Fingerprint
|
||||
import dev.dnpm.etl.processor.PatientId
|
||||
import dev.dnpm.etl.processor.PatientPseudonym
|
||||
import dev.dnpm.etl.processor.config.AppConfigProperties
|
||||
import dev.dnpm.etl.processor.consent.GicsConsentService
|
||||
import dev.dnpm.etl.processor.consent.TtpConsentStatus
|
||||
import dev.dnpm.etl.processor.monitoring.Request
|
||||
import dev.dnpm.etl.processor.monitoring.RequestStatus
|
||||
@ -59,7 +60,7 @@ class RequestProcessorTest {
|
||||
private lateinit var requestService: RequestService
|
||||
private lateinit var applicationEventPublisher: ApplicationEventPublisher
|
||||
private lateinit var appConfigProperties: AppConfigProperties
|
||||
|
||||
private lateinit var gicsConsentService : GicsConsentService
|
||||
private lateinit var requestProcessor: RequestProcessor
|
||||
|
||||
@BeforeEach
|
||||
@ -68,7 +69,8 @@ class RequestProcessorTest {
|
||||
@Mock transformationService: TransformationService,
|
||||
@Mock sender: RestMtbFileSender,
|
||||
@Mock requestService: RequestService,
|
||||
@Mock applicationEventPublisher: ApplicationEventPublisher
|
||||
@Mock applicationEventPublisher: ApplicationEventPublisher,
|
||||
@Mock gicsConsentService: GicsConsentService
|
||||
) {
|
||||
this.pseudonymizeService = pseudonymizeService
|
||||
this.transformationService = transformationService
|
||||
@ -76,6 +78,7 @@ class RequestProcessorTest {
|
||||
this.requestService = requestService
|
||||
this.applicationEventPublisher = applicationEventPublisher
|
||||
this.appConfigProperties = AppConfigProperties(null)
|
||||
this.gicsConsentService = gicsConsentService
|
||||
|
||||
val objectMapper = ObjectMapper()
|
||||
|
||||
@ -86,7 +89,8 @@ class RequestProcessorTest {
|
||||
requestService,
|
||||
objectMapper,
|
||||
applicationEventPublisher,
|
||||
appConfigProperties
|
||||
appConfigProperties,
|
||||
gicsConsentService
|
||||
)
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user