1
0
mirror of https://github.com/pcvolkmer/mv64e-etl-processor synced 2025-09-13 09:02:50 +00:00

feat: configuration of genomDe test submission via 'app.genomDeTestSubmission' = 'true', is implemented, now. (#136)

Co-authored-by: Paul-Christian Volkmer <code@pcvolkmer.de>
This commit is contained in:
jlidke
2025-08-20 10:47:38 +02:00
committed by GitHub
parent c40fd7f816
commit 3b66f42eb2
2 changed files with 62 additions and 29 deletions

View File

@@ -6,9 +6,9 @@ import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import dev.dnpm.etl.processor.config.AppConfigProperties import dev.dnpm.etl.processor.config.AppConfigProperties
import dev.dnpm.etl.processor.config.GIcsConfigProperties import dev.dnpm.etl.processor.config.GIcsConfigProperties
import dev.dnpm.etl.processor.consent.MtbFileConsentService
import dev.dnpm.etl.processor.consent.ConsentDomain import dev.dnpm.etl.processor.consent.ConsentDomain
import dev.dnpm.etl.processor.consent.IConsentService import dev.dnpm.etl.processor.consent.IConsentService
import dev.dnpm.etl.processor.consent.MtbFileConsentService
import dev.dnpm.etl.processor.pseudonym.ensureMetaDataIsInitialized import dev.dnpm.etl.processor.pseudonym.ensureMetaDataIsInitialized
import dev.pcvolkmer.mv64e.mtb.* import dev.pcvolkmer.mv64e.mtb.*
import org.apache.commons.lang3.NotImplementedException import org.apache.commons.lang3.NotImplementedException
@@ -72,7 +72,7 @@ class ConsentProcessor(
val broadConsent = consentService.getConsent( val broadConsent = consentService.getConsent(
personIdentifierValue, requestDate, ConsentDomain.BROAD_CONSENT personIdentifierValue, requestDate, ConsentDomain.BROAD_CONSENT
) )
val broadConsentHasBeenAsked = !broadConsent.entry.isEmpty() val broadConsentHasBeenAsked = broadConsent.entry.isNotEmpty()
// fast exit - if patient has not been asked, we can skip and exit // fast exit - if patient has not been asked, we can skip and exit
if (!broadConsentHasBeenAsked) return false if (!broadConsentHasBeenAsked) return false
@@ -83,7 +83,7 @@ class ConsentProcessor(
addGenomeDbProvisions(mtbFile, genomeDeConsent) addGenomeDbProvisions(mtbFile, genomeDeConsent)
if (!genomeDeConsent.entry.isEmpty()) setGenomDeSubmissionType(mtbFile) if (genomeDeConsent.entry.isNotEmpty()) setGenomDeSubmissionType(mtbFile)
embedBroadConsentResources(mtbFile, broadConsent) embedBroadConsentResources(mtbFile, broadConsent)
@@ -105,8 +105,8 @@ class ConsentProcessor(
} }
fun embedBroadConsentResources(mtbFile: Mtb, broadConsent: Bundle) { fun embedBroadConsentResources(mtbFile: Mtb, broadConsent: Bundle) {
for (entry in broadConsent.getEntry()) { for (entry in broadConsent.entry) {
val resource = entry.getResource() val resource = entry.resource
if (resource is Consent) { if (resource is Consent) {
// since jackson convertValue does not work here, // since jackson convertValue does not work here,
// we need another step to back to string, before we convert to object map // we need another step to back to string, before we convert to object map
@@ -124,14 +124,14 @@ class ConsentProcessor(
} }
fun addGenomeDbProvisions(mtbFile: Mtb, consentGnomeDe: Bundle) { fun addGenomeDbProvisions(mtbFile: Mtb, consentGnomeDe: Bundle) {
for (entry in consentGnomeDe.getEntry()) { for (entry in consentGnomeDe.entry) {
val resource = entry.getResource() val resource = entry.resource
if (resource !is Consent) { if (resource !is Consent) {
continue continue
} }
// We expect only one provision in collection, therefore get first or none // We expect only one provision in collection, therefore get first or none
val provisions = resource.getProvision().getProvision() val provisions = resource.provision.provision
if (provisions.isEmpty()) { if (provisions.isEmpty()) {
continue continue
} }
@@ -139,10 +139,10 @@ class ConsentProcessor(
val provisionComponent: ProvisionComponent = provisions.first() val provisionComponent: ProvisionComponent = provisions.first()
var provisionCode: String? = null var provisionCode: String? = null
if (provisionComponent.getCode() != null && !provisionComponent.getCode().isEmpty()) { if (provisionComponent.code != null && provisionComponent.code.isNotEmpty()) {
val codableConcept: CodeableConcept = provisionComponent.getCode().first() val codableConcept: CodeableConcept = provisionComponent.code.first()
if (codableConcept.getCoding() != null && !codableConcept.getCoding().isEmpty()) { if (codableConcept.coding != null && codableConcept.coding.isNotEmpty()) {
provisionCode = codableConcept.getCoding().first().getCode() provisionCode = codableConcept.coding.first().code
} }
} }
@@ -153,12 +153,12 @@ class ConsentProcessor(
if (ModelProjectConsentPurpose.SEQUENCING == modelProjectConsentPurpose) { if (ModelProjectConsentPurpose.SEQUENCING == modelProjectConsentPurpose) {
// CONVENTION: wrapping date is date of SEQUENCING consent // CONVENTION: wrapping date is date of SEQUENCING consent
mtbFile.metadata.modelProjectConsent.date = resource.getDateTime() mtbFile.metadata.modelProjectConsent.date = resource.dateTime
} }
val provision = Provision.builder() val provision = Provision.builder()
.type(ConsentProvision.valueOf(provisionComponent.getType().name)) .type(ConsentProvision.valueOf(provisionComponent.type.name))
.date(provisionComponent.getPeriod().getStart()) .date(provisionComponent.period.start)
.purpose(modelProjectConsentPurpose).build() .purpose(modelProjectConsentPurpose).build()
mtbFile.metadata.modelProjectConsent.provisions.add(provision) mtbFile.metadata.modelProjectConsent.provisions.add(provision)
@@ -170,27 +170,22 @@ class ConsentProcessor(
} }
} }
if (!mtbFile.metadata.modelProjectConsent.provisions.isEmpty()) { if (mtbFile.metadata.modelProjectConsent.provisions.isNotEmpty()) {
mtbFile.metadata.modelProjectConsent.version = mtbFile.metadata.modelProjectConsent.version =
gIcsConfigProperties.genomeDeConsentVersion gIcsConfigProperties.genomeDeConsentVersion
} }
} }
} }
/**
* fixme: currently we do not have information about submission type
*/
private fun setGenomDeSubmissionType(mtbFile: Mtb) { private fun setGenomDeSubmissionType(mtbFile: Mtb) {
if (appConfigProperties.genomDeTestSubmission) { if (appConfigProperties.genomDeTestSubmission) {
mtbFile.metadata.type = MvhSubmissionType.TEST
// fixme: remove INITIAL and uncomment when data model is updated
mtbFile.metadata.type = MvhSubmissionType.INITIAL
// mtbFile.metadata.type = MvhSubmissionType.Test
logger.info("genomeDe submission mit TEST") logger.info("genomeDe submission mit TEST")
} else { } else {
mtbFile.metadata.type = MvhSubmissionType.INITIAL mtbFile.metadata.type = when (mtbFile.metadata.type) {
null -> MvhSubmissionType.INITIAL
else -> mtbFile.metadata.type
}
} }
} }
@@ -251,7 +246,7 @@ class ConsentProcessor(
} }
}.flatten() }.flatten()
if (!entriesOfInterest.isEmpty()) { if (entriesOfInterest.isNotEmpty()) {
return entriesOfInterest.first().type return entriesOfInterest.first().type
} }
return Consent.ConsentProvisionType.NULL return Consent.ConsentProvisionType.NULL
@@ -270,8 +265,8 @@ class ConsentProcessor(
} }
fun isRequestDateInRange(requestDate: Date?, provPeriod: Period): Boolean { fun isRequestDateInRange(requestDate: Date?, provPeriod: Period): Boolean {
val isRequestDateAfterOrEqualStart = provPeriod.getStart().compareTo(requestDate) val isRequestDateAfterOrEqualStart = provPeriod.start.compareTo(requestDate)
val isRequestDateBeforeOrEqualEnd = provPeriod.getEnd().compareTo(requestDate) val isRequestDateBeforeOrEqualEnd = provPeriod.end.compareTo(requestDate)
return isRequestDateAfterOrEqualStart <= 0 && isRequestDateBeforeOrEqualEnd >= 0 return isRequestDateAfterOrEqualStart <= 0 && isRequestDateBeforeOrEqualEnd >= 0
} }

View File

@@ -8,6 +8,7 @@ import dev.dnpm.etl.processor.config.JacksonConfig
import dev.dnpm.etl.processor.consent.ConsentDomain import dev.dnpm.etl.processor.consent.ConsentDomain
import dev.dnpm.etl.processor.consent.GicsConsentService import dev.dnpm.etl.processor.consent.GicsConsentService
import dev.pcvolkmer.mv64e.mtb.Mtb import dev.pcvolkmer.mv64e.mtb.Mtb
import dev.pcvolkmer.mv64e.mtb.MvhSubmissionType
import dev.pcvolkmer.mv64e.mtb.Patient import dev.pcvolkmer.mv64e.mtb.Patient
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.hl7.fhir.r4.model.Bundle import org.hl7.fhir.r4.model.Bundle
@@ -19,6 +20,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith import org.junit.jupiter.api.extension.ExtendWith
import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource import org.junit.jupiter.params.provider.CsvSource
import org.junit.jupiter.params.provider.ValueSource
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
@@ -191,4 +193,40 @@ class ConsentProcessorTest {
.parseResource<Bundle>(Bundle::class.java, bundle) .parseResource<Bundle>(Bundle::class.java, bundle)
} }
@ParameterizedTest
@ValueSource(booleans = [true, false])
fun mvSubmissionTypeIsSet(isTestSubmission: Boolean) {
appConfigProperties.genomDeTestSubmission = isTestSubmission
val fixture =
ConsentProcessor(
appConfigProperties,
gIcsConfigProperties,
objectMapper,
fhirContext,
gicsConsentService
)
doAnswer { getDummyBroadConsentBundle() }.whenever(gicsConsentService)
.getConsent(any(), any(), eq(ConsentDomain.BROAD_CONSENT))
doAnswer {
Bundle().addEntry(
Bundle.BundleEntryComponent().setResource(getDummyGenomDeConsent())
)
}.whenever(gicsConsentService)
.getConsent(any(), any(), eq(ConsentDomain.MODELLVORHABEN_64E))
val inputMtb = Mtb.builder()
.patient(Patient.builder().id("d611d429-5003-11f0-a144-661e92ac9503").build()).build()
val checkResult = fixture.consentGatedCheckAndTryEmbedding(inputMtb)
assertThat(checkResult).isNotNull
if (isTestSubmission)
assertThat(inputMtb.metadata.type).isEqualTo(MvhSubmissionType.TEST)
else {
assertThat(inputMtb.metadata.type).isEqualTo(MvhSubmissionType.INITIAL)
}
}
} }