mirror of
https://github.com/pcvolkmer/etl-processor.git
synced 2025-07-17 12:52:54 +00:00
fix: serialize fhir consent resources to string, object map
This commit is contained in:
@ -1,5 +1,9 @@
|
|||||||
package dev.dnpm.etl.processor.consent;
|
package dev.dnpm.etl.processor.consent;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import dev.dnpm.etl.processor.config.GIcsConfigProperties;
|
import dev.dnpm.etl.processor.config.GIcsConfigProperties;
|
||||||
import dev.pcvolkmer.mv64e.mtb.ConsentProvision;
|
import dev.pcvolkmer.mv64e.mtb.ConsentProvision;
|
||||||
import dev.pcvolkmer.mv64e.mtb.ModelProjectConsentPurpose;
|
import dev.pcvolkmer.mv64e.mtb.ModelProjectConsentPurpose;
|
||||||
@ -8,7 +12,6 @@ import dev.pcvolkmer.mv64e.mtb.Provision;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import org.hl7.fhir.r4.model.Bundle;
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
import org.hl7.fhir.r4.model.CodeableConcept;
|
import org.hl7.fhir.r4.model.CodeableConcept;
|
||||||
import org.hl7.fhir.r4.model.Consent;
|
import org.hl7.fhir.r4.model.Consent;
|
||||||
@ -20,24 +23,38 @@ import org.slf4j.LoggerFactory;
|
|||||||
public abstract class BaseConsentService implements ICheckConsent {
|
public abstract class BaseConsentService implements ICheckConsent {
|
||||||
|
|
||||||
protected final GIcsConfigProperties gIcsConfigProperties;
|
protected final GIcsConfigProperties gIcsConfigProperties;
|
||||||
protected Logger logger = LoggerFactory.getLogger(BaseConsentService.class);
|
|
||||||
|
|
||||||
public BaseConsentService(GIcsConfigProperties gIcsConfigProperties) {
|
private final ObjectMapper objectMapper;
|
||||||
|
protected Logger logger = LoggerFactory.getLogger(BaseConsentService.class);
|
||||||
|
static FhirContext fhirCtx = FhirContext.forR4();
|
||||||
|
|
||||||
|
public BaseConsentService(GIcsConfigProperties gIcsConfigProperties,
|
||||||
|
ObjectMapper objectMapper) {
|
||||||
this.gIcsConfigProperties = gIcsConfigProperties;
|
this.gIcsConfigProperties = gIcsConfigProperties;
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void embedBroadConsentResources(Mtb mtbFile, Bundle broadConsent) {
|
public void embedBroadConsentResources(Mtb mtbFile, Bundle broadConsent) {
|
||||||
|
|
||||||
for (Bundle.BundleEntryComponent entry : broadConsent.getEntry()) {
|
for (Bundle.BundleEntryComponent entry : broadConsent.getEntry()) {
|
||||||
Resource resource = entry.getResource();
|
Resource resource = entry.getResource();
|
||||||
if (resource instanceof Consent) {
|
if (resource instanceof Consent) {
|
||||||
Map<String, Object> consentMap = new HashMap<>();
|
// since jackson convertValue does not work here,
|
||||||
consentMap.put(resource.getIdElement().getIdPart(), resource);
|
// we need another step to back to string, before we convert to object map
|
||||||
mtbFile.getMetadata().getResearchConsents().add(consentMap);
|
var asJsonString = fhirCtx.newJsonParser().encodeResourceToString(resource);
|
||||||
|
try {
|
||||||
|
var mapOfJson = objectMapper.readValue(asJsonString,
|
||||||
|
new TypeReference<HashMap<String, Object>>() {
|
||||||
|
});
|
||||||
|
mtbFile.getMetadata().getResearchConsents().add(mapOfJson);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addGenomeDbProvisions(Mtb mtbFile, Bundle consentGnomeDe) {
|
public void addGenomeDbProvisions(Mtb mtbFile, Bundle consentGnomeDe) {
|
||||||
for (Bundle.BundleEntryComponent entry : consentGnomeDe.getEntry()) {
|
for (Bundle.BundleEntryComponent entry : consentGnomeDe.getEntry()) {
|
||||||
Resource resource = entry.getResource();
|
Resource resource = entry.getResource();
|
||||||
if (!(resource instanceof Consent consentFhirResource)) {
|
if (!(resource instanceof Consent consentFhirResource)) {
|
||||||
@ -67,7 +84,8 @@ public abstract class BaseConsentService implements ICheckConsent {
|
|||||||
|
|
||||||
if (ModelProjectConsentPurpose.SEQUENCING.equals(modelProjectConsentPurpose)) {
|
if (ModelProjectConsentPurpose.SEQUENCING.equals(modelProjectConsentPurpose)) {
|
||||||
// CONVENTION: wrapping date is date of SEQUENCING consent
|
// CONVENTION: wrapping date is date of SEQUENCING consent
|
||||||
mtbFile.getMetadata().getModelProjectConsent().setDate(consentFhirResource.getDateTime());
|
mtbFile.getMetadata().getModelProjectConsent()
|
||||||
|
.setDate(consentFhirResource.getDateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
Provision provision = Provision.builder()
|
Provision provision = Provision.builder()
|
||||||
@ -79,12 +97,15 @@ public abstract class BaseConsentService implements ICheckConsent {
|
|||||||
mtbFile.getMetadata().getModelProjectConsent().getProvisions().add(provision);
|
mtbFile.getMetadata().getModelProjectConsent().getProvisions().add(provision);
|
||||||
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
logger.error("Provision code '" + provisionCode + "' is unknown and cannot be mapped.", ioe.toString());
|
logger.error(
|
||||||
|
"Provision code '" + provisionCode + "' is unknown and cannot be mapped.",
|
||||||
|
ioe.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mtbFile.getMetadata().getModelProjectConsent().getProvisions().isEmpty()) {
|
if (!mtbFile.getMetadata().getModelProjectConsent().getProvisions().isEmpty()) {
|
||||||
mtbFile.getMetadata().getModelProjectConsent().setVersion(gIcsConfigProperties.getGenomeDeConsentVersion());
|
mtbFile.getMetadata().getModelProjectConsent()
|
||||||
|
.setVersion(gIcsConfigProperties.getGenomeDeConsentVersion());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package dev.dnpm.etl.processor.consent;
|
|||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.parser.DataFormatException;
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import dev.dnpm.etl.processor.config.AppFhirConfig;
|
import dev.dnpm.etl.processor.config.AppFhirConfig;
|
||||||
import dev.dnpm.etl.processor.config.GIcsConfigProperties;
|
import dev.dnpm.etl.processor.config.GIcsConfigProperties;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -51,8 +52,8 @@ public class GicsConsentService extends BaseConsentService {
|
|||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
public GicsConsentService(GIcsConfigProperties gIcsConfigProperties,
|
public GicsConsentService(GIcsConfigProperties gIcsConfigProperties,
|
||||||
RetryTemplate retryTemplate, RestTemplate restTemplate, AppFhirConfig appFhirConfig) {
|
RetryTemplate retryTemplate, RestTemplate restTemplate, AppFhirConfig appFhirConfig, ObjectMapper objectMapper) {
|
||||||
super(gIcsConfigProperties);
|
super(gIcsConfigProperties,objectMapper);
|
||||||
|
|
||||||
this.retryTemplate = retryTemplate;
|
this.retryTemplate = retryTemplate;
|
||||||
this.restTemplate = restTemplate;
|
this.restTemplate = restTemplate;
|
||||||
|
@ -184,12 +184,13 @@ class AppConfiguration {
|
|||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnProperty(name = ["app.consent.gics.enabled"], havingValue = "true")
|
@ConditionalOnProperty(name = ["app.consent.gics.enabled"], havingValue = "true")
|
||||||
fun gicsConsentService( gIcsConfigProperties: GIcsConfigProperties,
|
fun gicsConsentService( gIcsConfigProperties: GIcsConfigProperties,
|
||||||
retryTemplate: RetryTemplate, restTemplate: RestTemplate, appFhirConfig: AppFhirConfig): ICheckConsent {
|
retryTemplate: RetryTemplate, restTemplate: RestTemplate, appFhirConfig: AppFhirConfig, getObjectMapper: ObjectMapper): ICheckConsent {
|
||||||
return GicsConsentService(
|
return GicsConsentService(
|
||||||
gIcsConfigProperties,
|
gIcsConfigProperties,
|
||||||
retryTemplate,
|
retryTemplate,
|
||||||
restTemplate,
|
restTemplate,
|
||||||
appFhirConfig
|
appFhirConfig,
|
||||||
|
getObjectMapper
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ import dev.pcvolkmer.mv64e.mtb.ModelProjectConsent
|
|||||||
import dev.pcvolkmer.mv64e.mtb.Mtb
|
import dev.pcvolkmer.mv64e.mtb.Mtb
|
||||||
import dev.pcvolkmer.mv64e.mtb.MvhMetadata
|
import dev.pcvolkmer.mv64e.mtb.MvhMetadata
|
||||||
import org.apache.commons.codec.digest.DigestUtils
|
import org.apache.commons.codec.digest.DigestUtils
|
||||||
import org.hl7.fhir.r4.model.Consent
|
|
||||||
|
|
||||||
/** Replaces patient ID with generated patient pseudonym
|
/** Replaces patient ID with generated patient pseudonym
|
||||||
*
|
*
|
||||||
@ -295,11 +294,12 @@ infix fun Mtb.pseudonymizeWith(pseudonymizeService: PseudonymizeService) {
|
|||||||
|
|
||||||
this.metadata?.researchConsents?.forEach { it ->
|
this.metadata?.researchConsents?.forEach { it ->
|
||||||
val entry = it ?: return@forEach
|
val entry = it ?: return@forEach
|
||||||
val key = entry.keys.first()
|
if (entry.contains("patient")) {
|
||||||
val consent = entry[key] as? Consent ?: return@forEach
|
// here we expect only a patient reference any other data like display
|
||||||
val patRef= "Patient/$patientPseudonym"
|
// need to be removed, since may contain unsecure data
|
||||||
consent.patient?.setReference(patRef)
|
entry.remove("patient")
|
||||||
consent.patient?.display = null
|
entry["patient"] = mapOf("reference" to "Patient/$patientPseudonym")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import dev.dnpm.etl.processor.pseudonym.anonymizeContentWith
|
|||||||
import dev.dnpm.etl.processor.pseudonym.ensureMetaDataIsInitialized
|
import dev.dnpm.etl.processor.pseudonym.ensureMetaDataIsInitialized
|
||||||
import dev.dnpm.etl.processor.pseudonym.pseudonymizeWith
|
import dev.dnpm.etl.processor.pseudonym.pseudonymizeWith
|
||||||
import dev.pcvolkmer.mv64e.mtb.Mtb
|
import dev.pcvolkmer.mv64e.mtb.Mtb
|
||||||
|
import dev.pcvolkmer.mv64e.mtb.MvhSubmissionType
|
||||||
import org.apache.commons.codec.binary.Base32
|
import org.apache.commons.codec.binary.Base32
|
||||||
import org.apache.commons.codec.digest.DigestUtils
|
import org.apache.commons.codec.digest.DigestUtils
|
||||||
import org.hl7.fhir.r4.model.Consent
|
import org.hl7.fhir.r4.model.Consent
|
||||||
@ -122,6 +123,10 @@ class RequestProcessor(
|
|||||||
)
|
)
|
||||||
|
|
||||||
consentService.addGenomeDbProvisions(mtbFile, genomeDeConsent)
|
consentService.addGenomeDbProvisions(mtbFile, genomeDeConsent)
|
||||||
|
|
||||||
|
// fixme: currently we do not have information about submission type
|
||||||
|
if (!genomeDeConsent.entry.isEmpty()) mtbFile.metadata.type = MvhSubmissionType.INITIAL
|
||||||
|
|
||||||
consentService.embedBroadConsentResources(mtbFile, broadConsent)
|
consentService.embedBroadConsentResources(mtbFile, broadConsent)
|
||||||
|
|
||||||
val broadConsentStatus = consentService.getProvisionTypeByPolicyCode(
|
val broadConsentStatus = consentService.getProvisionTypeByPolicyCode(
|
||||||
|
@ -251,7 +251,8 @@ class ExtensionsTest {
|
|||||||
private fun addConsentData(mtbFile: Mtb) {
|
private fun addConsentData(mtbFile: Mtb) {
|
||||||
val gIcsConfigProperties = GIcsConfigProperties("", "", "", true)
|
val gIcsConfigProperties = GIcsConfigProperties("", "", "", true)
|
||||||
|
|
||||||
val baseConsentService = object : BaseConsentService(gIcsConfigProperties) {
|
val baseConsentService = object : BaseConsentService(gIcsConfigProperties,
|
||||||
|
JacksonConfig().objectMapper()) {
|
||||||
override fun getTtpBroadConsentStatus(personIdentifierValue: String?): TtpConsentStatus? {
|
override fun getTtpBroadConsentStatus(personIdentifierValue: String?): TtpConsentStatus? {
|
||||||
throw NotImplementedError("dummy")
|
throw NotImplementedError("dummy")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user