All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.projecthusky.communication.mpi.impl.PixV3Query Maven / Gradle / Ivy

There is a newer version: 3.0.2
Show newest version
package org.projecthusky.communication.mpi.impl;

import java.net.URI;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.camel.CamelContext;
import org.hl7.fhir.r4.model.Identifier;
import org.projecthusky.common.communication.AffinityDomain;
import org.projecthusky.communication.mpi.V3Acknowledgement;
import org.projecthusky.communication.mpi.impl.pix.V3PixSource;
import org.projecthusky.communication.mpi.impl.pix.V3PixSourceMessageHelper;
import org.projecthusky.communication.utils.HuskyUtils;
import org.projecthusky.communication.utils.PixPdqV3Utils;
import org.projecthusky.fhir.structures.gen.FhirCommon;
import org.projecthusky.fhir.structures.gen.FhirPatient;
import org.projecthusky.xua.core.SecurityHeaderElement;
import org.openehealth.ipf.commons.audit.AuditContext;
import org.openehealth.ipf.commons.ihe.hl7v3.PIXV3;
import org.openehealth.ipf.commons.ihe.hl7v3.core.metadata.Device;
import org.openehealth.ipf.commons.ihe.hl7v3.core.requests.PixV3QueryRequest;
import org.openehealth.ipf.commons.ihe.hl7v3.core.responses.PixV3QueryResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import net.ihe.gazelle.hl7v3.datatypes.II;

/**
 * PixV3Query
 * 

* PixV3Query implements the Actor Patient Identity Source from ITI-44 Patient * Identity Feed HL7 V3 and the Actor Patient Identifier Cross-reference * Consumer from ITI-45 PIXV3 Query */ @Component public class PixV3Query extends PixPdqV3QueryBase { private static final Logger LOGGER = LoggerFactory.getLogger(PixV3Query.class.getName()); private V3PixSource pixSource; public PixV3Query() { } public PixV3Query(AffinityDomain affinityDomain, String homeCommunityOid, CamelContext context, AuditContext auditContext) { super(affinityDomain, homeCommunityOid, context); this.pixSource = new V3PixSource(this.pixSourceUri, context, auditContext); setAuditContext(auditContext); } public PixV3Query(AffinityDomain affinityDomain, String homeCommunityOid, String homeCommunityNamespace, String domainToReturnOid, String domainToReturnNamespace, CamelContext context, AuditContext auditContext) { super(affinityDomain, homeCommunityOid, homeCommunityNamespace, domainToReturnOid, domainToReturnNamespace, context); this.pixSource = new V3PixSource(this.pixSourceUri, context, auditContext); setAuditContext(auditContext); } /** * query the mpi with patient id and return the ids in the queried domains * from the mpi. *

* Implements ITI-45 Patient Identifier Cross-reference Consumer Queries the * Patient Identifier Cross-reference Manager for a list of corresponding * patientidentifiers, if any * * @param patient * the patient * @param queryDomainOids * the query domain oids * @param queryDomainNamespaces * the query domain namespaces * @param assertion * a security header element for example an assertion * @param messageId * a id preset or null, if the id shall be generated * * @return the list of string */ // TODO: queryDomainNamespaces redundant, not used in method public List queryPatientId(org.projecthusky.fhir.structures.gen.FhirPatient patient, List queryDomainOids, List queryDomainNamespaces, SecurityHeaderElement assertion, String messageId) { // the list of Oids of the data sources requested List domainToReturnOids = new LinkedList<>(); // read the data source OIDs from method arguments or use the OIDs set // in the constructor if (queryDomainOids != null) { domainToReturnOids = queryDomainOids; } else { if (this.domainToReturnOid != null) { domainToReturnOids.add(this.domainToReturnOid); } } // prepare for call var v3PixConsumerQueryRequest = new PixV3QueryRequest(); var senderDev = new Device(); var id = new II(); id.setRoot(this.senderApplicationOid); senderDev.getIds().add(id); v3PixConsumerQueryRequest.setSender(senderDev); var receiverDev = new Device(); var idReceiver = new II(); idReceiver.setRoot(this.receiverApplicationOid); receiverDev.getIds().add(idReceiver); v3PixConsumerQueryRequest.setReceiver(receiverDev); v3PixConsumerQueryRequest .setQueryId(PixPdqV3Utils.createIIwithUniqueExtension(this.senderApplicationOid)); v3PixConsumerQueryRequest .setMessageId(PixPdqV3Utils.createIIwithUniqueExtension(this.senderApplicationOid)); // add the patient identifier final String homeCommunityPatientId = this.getHomeCommunityPatientId(patient); // return empty result set if the homeCommunityPatientId is not set // TODO: should throw an exception, if null if (homeCommunityPatientId == null) { LOGGER.error("homeCommunityPatientId not provided"); return domainToReturnOids; } v3PixConsumerQueryRequest.setQueryPatientId(PixPdqV3Utils.createII(this.homeCommunityOid, homeCommunityPatientId, this.homeCommunityNamespace)); for (String domainToReturnOid : domainToReturnOids) { v3PixConsumerQueryRequest.getDataSourceOids().add(domainToReturnOid); } PixV3QueryResponse v3PixConsumerResponse = null; try { v3PixConsumerResponse = sendQuery(v3PixConsumerQueryRequest, assertion, this.pixQueryUri, messageId); final List returnIds = new LinkedList<>(); for (String domainToReturnOid : domainToReturnOids) { returnIds.add(getPatientDomainId(v3PixConsumerResponse, domainToReturnOid)); } return returnIds; } catch (final Exception e) { LOGGER.error("exception queryPatient", e); // TODO: this should throw an exception and not just an empty result // set return domainToReturnOids; } } /** * adds a patient to the mpi. implements ITI-44 Patient Identity Source – * Add Patient Record * * @param patient * the patient * @param assertion * a security header element for example an assertion * @return true, if successful */ public boolean addPatient(FhirPatient patient, SecurityHeaderElement assertion, String messageId) { if (pixSource == null) { pixSource = new V3PixSource(this.pixSourceUri, getCamelContext(), getAuditContext()); } LOGGER.debug("creating v3RecordAddedMessage"); var ret = false; final var v3RecordAddedMessage = new V3PixSourceMessageHelper(true, false, false, this.senderApplicationOid, this.senderFacilityOid, this.receiverApplicationOid, this.receiverFacilityOid); LOGGER.debug("add demographic data"); addDemographicData(patient, v3RecordAddedMessage); try { final V3Acknowledgement v3pixack = pixSource.sendRecordAdded( v3RecordAddedMessage.getV3RecordAddedMessage(), assertion, messageId); ret = checkResponse(v3pixack); } catch (final Exception e) { LOGGER.error("addPatient failed", e); } return ret; } /** * Merge patient. implements ITI-44 Patient Identity Source – Patient * Identity Merge *

* Patient Registry Duplicates Resolved message indicates that the Patient * Identity Source has done a merge within a specific Patient Identification * Domain. That is, the surviving identifier (patient ID) has subsumed a * duplicate patient identifier. * * @param patient * the patient (with the surviving identifier) * @param obsoleteId * the obsolete id (duplicate patient identifier) * @param assertion * a security header element for example an assertion * @return true, if successful */ public boolean mergePatient(FhirPatient patient, String obsoleteId, SecurityHeaderElement assertion, String messageId) { if (pixSource == null) { pixSource = new V3PixSource(this.pixSourceUri, getCamelContext(), getAuditContext()); } var ret = false; final var v3pixSourceMsgMerge = new V3PixSourceMessageHelper(false, false, true, this.senderApplicationOid, this.senderFacilityOid, this.receiverApplicationOid, this.receiverFacilityOid); addDemographicData(patient, v3pixSourceMsgMerge); v3pixSourceMsgMerge.getV3MergePatientsMessage().setObsoletePatientID(obsoleteId, this.homeCommunityOid, this.homeCommunityNamespace); try { final V3Acknowledgement v3pixack = pixSource.sendMergePatients( v3pixSourceMsgMerge.getV3MergePatientsMessage(), assertion, messageId); ret = checkResponse(v3pixack); } catch (final Exception e) { LOGGER.error("mergePatient failed", e); } return ret; } /** * updates the demographic information of the patient in the mpi. *

* implements ITI-44 Patient Identity Source – Revise Patient Record updates * the demographic information of the patient in the mpi. * * @param patient * the patient * @param assertion * a security header element for example an assertion * @return true, if successful */ public boolean updatePatient(FhirPatient patient, SecurityHeaderElement assertion, String messageId) { if (pixSource == null) { pixSource = new V3PixSource(this.pixSourceUri, getCamelContext(), getAuditContext()); } final var v3RecordRevisedMessage = new V3PixSourceMessageHelper(false, true, false, this.senderApplicationOid, this.senderFacilityOid, this.receiverApplicationOid, this.receiverFacilityOid); addDemographicData(patient, v3RecordRevisedMessage); try { final V3Acknowledgement v3pixack = pixSource.sendRecordRevised( v3RecordRevisedMessage.getV3RecordRevisedMessage(), assertion, messageId); return checkResponse(v3pixack); } catch (final Exception e) { LOGGER.error("updatePatient failed", e); return false; } } /** * Checks the response, error are logged. * * @param response * the response * @return true, if response has no error, false if there are errors */ protected boolean checkResponse(V3Acknowledgement response) { if (response.hasError()) { LOGGER.error("AcknowledgementCode: {}", response.getAcknowledgementCode()); LOGGER.error("Query error text: {}", response.getErrorText()); return false; } return true; } /** * Query patient id. * * @param patient * the patient * @param assertion * a security header element for example an assertion * @return the string */ public String queryPatientId(FhirPatient patient, SecurityHeaderElement assertion, String messageId) { List ids = queryPatientId(patient, null, null, assertion, messageId); if (ids != null && !ids.isEmpty()) { return ids.get(0); } return null; } /** * Gets the home community patient id. * * @param patient * the patient * @return the home community patient id */ protected String getHomeCommunityPatientId(FhirPatient patient) { for (final Identifier Identifier : patient.getIdentifier()) { if (Identifier.getSystem().startsWith(FhirCommon.OID_URN) && FhirCommon .removeUrnOidPrefix(Identifier.getSystem()).equals(this.homeCommunityOid)) { return Identifier.getValue(); } } return null; } /** * Gets the patient domain id. * * @param v3PixConsumerResponse * the v3 pix consumer response * @param rootOid * the root oid * @return the patient domain id */ public String getPatientDomainId(PixV3QueryResponse v3PixConsumerResponse, String rootOid) { String retVal = null; if ((rootOid != null) && (v3PixConsumerResponse != null) && ((!v3PixConsumerResponse.getPatientIds().isEmpty()) || (!v3PixConsumerResponse.getAsOtherIDs().isEmpty()))) { for (var i = 0; i < v3PixConsumerResponse.getPatientIds().size(); i++) { final II id = v3PixConsumerResponse.getPatientIds().get(i); if (id != null && id.getRoot() != null && id.getRoot().equals(rootOid)) { retVal = id.getExtension(); } } if (retVal == null) { retVal = getIdFromOthers(v3PixConsumerResponse, rootOid); } } return retVal; } private String getIdFromOthers(PixV3QueryResponse v3PixConsumerResponse, String rootOid) { for (var i = 0; i < v3PixConsumerResponse.getAsOtherIDs().size(); i++) { final II id = v3PixConsumerResponse.getAsOtherIDs().get(i).getId().get(0); if (id != null && id.getRoot() != null && id.getRoot().equals(rootOid)) { return id.getExtension(); } } return null; } private PixV3QueryResponse sendQuery(PixV3QueryRequest request, SecurityHeaderElement assertion, URI pdqDest, String messageId) throws Exception { final String endpoint = HuskyUtils.createEndpoint( PIXV3.Interactions.ITI_45.getWsTransactionConfiguration().getName(), // pdqDest, // true, // getAuditContext().isAuditEnabled()); LOGGER.info("Sending request to '{}' endpoint", endpoint); Map outgoingHeaders = new HashMap<>(); outgoingHeaders.put("Accept", "application/soap+xml"); outgoingHeaders.put("Content-Type", "application/soap+xml; charset=UTF-8; action=\"urn:hl7-org:v3:PRPA_IN201309UV02\""); final var exchange = send(endpoint, request, assertion, messageId, outgoingHeaders); return exchange.getMessage().getBody(PixV3QueryResponse.class); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy