package gov.hhs.fha.nhinc.cpp; import gov.hhs.fha.nhinc.common.subscriptionb2overridefordocuments.NotificationMessageHolderType; import gov.hhs.fha.nhinc.common.subscriptionb2overridefordocuments.NotificationMessageHolderType.Message; import gov.hhs.fha.nhinc.common.subscriptionb2overridefordocuments.NotifyDocumentType; import gov.hhs.fha.nhinc.entitynotificationconsumer.EntityNotificationConsumerPortType; import gov.hhs.fha.nhinc.mpilib.MiniMpi; import gov.hhs.fha.nhinc.mpilib.Patient; import gov.hhs.fha.nhinc.mpilib.Patients; import gov.hhs.fha.nhinc.properties.PropertyAccessException; import gov.hhs.fha.nhinc.properties.PropertyAccessor; import gov.hhs.fha.nhinc.repository.model.Document; import gov.hhs.fha.nhinc.repository.model.DocumentQueryParams; import gov.hhs.fha.nhinc.repository.service.DocumentService; import ihe.iti.xds_b._2007.RetrieveDocumentSetRequestType; import ihe.iti.xds_b._2007.RetrieveDocumentSetRequestType.DocumentRequest; import java.util.List; import java.util.UUID; import javax.xml.bind.JAXBElement; import javax.xml.ws.BindingProvider; import oasis.names.tc.ebxml_regrep.xsd.query._3.AdhocQueryResponse; import oasis.names.tc.ebxml_regrep.xsd.rim._3.ExternalIdentifierType; import oasis.names.tc.ebxml_regrep.xsd.rim._3.ExtrinsicObjectType; import oasis.names.tc.ebxml_regrep.xsd.rim._3.IdentifiableType; import oasis.names.tc.ebxml_regrep.xsd.rim._3.InternationalStringType; import oasis.names.tc.ebxml_regrep.xsd.rim._3.LocalizedStringType; import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryObjectListType; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import gov.hhs.fha.nhinc.common.nhinccommon.AssertionType; import gov.hhs.fha.nhinc.common.nhinccommon.PersonNameType; import gov.hhs.fha.nhinc.common.nhinccommon.UserType; import gov.hhs.fha.nhinc.common.nhinccommon.HomeCommunityType; import gov.hhs.fha.nhinc.common.nhinccommon.CeType; /** * * @author svalluripalli */ public class CPPOperations extends Thread { public static final String CPP_CLASS_CODE = "XNHIN-CONSENT"; private static Log log = LogFactory.getLog(CPPOperations.class); private static String ADAPTER_PROPFILE_NAME = "adapter"; private static String ENTITY_NOTIFICATION_CONSUMER_ENDPOINT_URL = "EntityNotificationConsumerURL"; private static String ASSERTIONINFO_PROPFILE_NAME = "assertioninfo"; private static String DATE_OF_SIGNATURE = "SignDate"; private static String EXPIRATION_DATE = "ExpirationDate"; private static String FIRST_NAME = "UserFirstName"; private static String LAST_NAME = "UserLastName"; private static String USER_NAME = "UserName"; private static String ORG_NAME = "UserOrganization"; private static String USER_ROLE_CD = "UserRoleCode"; private static String USER_ROLE_CD_SYSTEM = "UserRoleCodeSystem"; private static String USER_ROLE_CD_SYSTEM_NAME = "UserRoleCodeSystemName"; private static String USER_ROLE_DISPLAY_NAME = "UserRoleDisplayName"; private static String PURPOSE_FOR_USE_ROLE_CD = "PurposeForUseRoleCode"; private static String PURPOSE_FOR_USE_CODE_SYSTEM = "PurposeForUseCodeSystem"; private static String PURPOSE_FOR_USE_CODE_SYSTEM_NAME = "PurposeForUseCodeSystemName"; private static String PURPOSE_FOR_USE_DISPLAY_NAME = "PurposeForUseDisplayName"; private static String CONTENT_REFERENCE = "ContentReference"; private static String CONTENT = "Content"; private static String SubscribeeCommunityList_PROPFILE_NAME = "SubscribeeCommunityList"; private static final String EBXML_RESPONSE_DOCID_IDENTIFICATION_SCHEME = "urn:uuid:2e82c1f6-a085-4c72-9da3-8640a32e42ab"; private static final String EBXML_RESPONSE_PATIENTID_IDENTIFICATION_SCHEME = "urn:uuid:58a6f841-87b3-4a3e-92fd-a8ffeff98427"; private static final String EBXML_RESPONSE_DOCID_NAME = "XDSDocumentEntry.uniqueId"; private static final String EBXML_RESPONSE_PATIENTID_NAME = "XDSDocumentEntry.patientId"; private String patId; private String orgId; private String xacml; private boolean finished = false; public boolean isFinished() { return finished; } public void setFinished(boolean finished) { this.finished = finished; } public boolean isSendSuccessful() { return sendSuccessful; } public void setSendSuccessful(boolean sendSuccessful) { this.sendSuccessful = sendSuccessful; } private boolean sendSuccessful = false; public void init(String patientId, String organisationId, String xacmlDocument){ this.patId = patientId; this.orgId = organisationId; this.xacml = xacmlDocument; } public void run() { DocumentService docService = new DocumentService(); log.debug("Saving CPP..."); log.debug("patId: " + patId); Document doc = retreiveCPP(patId, orgId); doc.setClassCode(CPP_CLASS_CODE); doc.setRawData(xacml.getBytes()); doc.setPatientId(patId); doc.setSourcePatientId(patId); doc.setDocumentUniqueId(patId + '-' + CPP_CLASS_CODE); doc.setDocumentTitle("Consumer Preferences Profile"); log.debug("Calling save document"); docService.saveDocument(doc); updateOptInNotifyDocument(patId, orgId, xacml, doc); } public Document retreiveCPP(String patId, String orgId) { log.debug("Check existing CPP document"); Document doc = new Document(); DocumentService docService = new DocumentService(); DocumentQueryParams params = new DocumentQueryParams(); java.util.LinkedList cc = new java.util.LinkedList(); java.util.List docs; cc.add(CPP_CLASS_CODE); params.setClassCodes(cc); params.setPatientId(patId); docs = docService.documentQuery(params); if (docs.size() == 1) { log.debug("found cpp"); doc = docs.get(0); } return doc; } /** * * @param patId * @param orgId * @param xacml * @param doc */ public void updateOptInNotifyDocument(String patId, String orgId, String xacml, gov.hhs.fha.nhinc.repository.model.Document doc) { String ack = ""; ack = updateOptIn(patId, orgId, xacml); log.info(ack); try { // Call Web Service Operation gov.hhs.fha.nhinc.entitynotificationconsumer.EntityNotificationConsumerPortType port = getEntityNotificationConsumerWebservice(); gov.hhs.fha.nhinc.common.nhinccommonentity.NotifySubscribersOfDocumentRequestType notifySubscribersOfDocumentRequest = new gov.hhs.fha.nhinc.common.nhinccommonentity.NotifySubscribersOfDocumentRequestType(); DocumentRequest documentRequest = new DocumentRequest(); documentRequest.setDocumentUniqueId(doc.getDocumentUniqueId()); RetrieveDocumentSetRequestType retrieveDocumentSetRequestType = new RetrieveDocumentSetRequestType(); retrieveDocumentSetRequestType.getDocumentRequest().add(documentRequest); Message message = new Message(); message.setRetrieveDocumentSetRequest(retrieveDocumentSetRequestType); NotificationMessageHolderType notificationMessageHolderType = new NotificationMessageHolderType(); notificationMessageHolderType.setMessage(message); NotifyDocumentType notifyDocumentType = new NotifyDocumentType(); notifyDocumentType.getNotificationMessage().add(notificationMessageHolderType); notifySubscribersOfDocumentRequest.setNotify(notifyDocumentType); RegistryObjectListType registryObjectListType = buildRegistryObjectList(patId, orgId, xacml, doc); notifySubscribersOfDocumentRequest.setRegistryObjectList(registryObjectListType); AssertionType assertion = buildAssertion(orgId); notifySubscribersOfDocumentRequest.setAssertion(assertion); gov.hhs.fha.nhinc.common.nhinccommon.AcknowledgementType result = port.notifySubscribersOfDocument(notifySubscribersOfDocumentRequest); System.out.println("Result = " + result); log.info(result.getMessage()); } catch (Exception ex) { ex.printStackTrace(); } } private static RegistryObjectListType buildRegistryObjectList(String patId, String orgId, String xacml, gov.hhs.fha.nhinc.repository.model.Document doc){ AdhocQueryResponse oAdhocQueryResponse = new AdhocQueryResponse(); RegistryObjectListType oRegObjList = new RegistryObjectListType(); oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory oRimObjectFactory = new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); oAdhocQueryResponse.setRegistryObjectList(oRegObjList); List> olRegObjs = oRegObjList.getIdentifiable(); ExternalIdentifierType oExtId = new ExternalIdentifierType(); ExternalIdentifierType oExtId1 = new ExternalIdentifierType(); ExtrinsicObjectType oExObj = new ExtrinsicObjectType(); JAXBElement oJAXBExtId = oRimObjectFactory.createExtrinsicObject(oExObj); oExtId.setHome(orgId); UUID oDocumentUUID = UUID.randomUUID(); String sDocumentUUID = "urn:uuid:" + oDocumentUUID.toString(); oExtId.setId(sDocumentUUID); oExtId.setIdentificationScheme(EBXML_RESPONSE_DOCID_IDENTIFICATION_SCHEME); oExtId.setName(CreateSingleValueInternationalStringType(EBXML_RESPONSE_DOCID_NAME)); oExtId1.setName(CreateSingleValueInternationalStringType(EBXML_RESPONSE_PATIENTID_NAME)); oExtId1.setHome(orgId); UUID oDocumentUUID1 = UUID.randomUUID(); String sDocumentUUID1 = "urn:uuid:" + oDocumentUUID1.toString(); oExtId1.setId(sDocumentUUID1); oExtId1.setIdentificationScheme(EBXML_RESPONSE_PATIENTID_IDENTIFICATION_SCHEME); oExObj.getExternalIdentifier().add(oExtId1); oExObj.getExternalIdentifier().add(oExtId); olRegObjs.add(oJAXBExtId); return oRegObjList; } private static InternationalStringType CreateSingleValueInternationalStringType(String sLocStrValue) { log.debug("DocumentTransforms.CreateSingleValueInternationalStringType() -- Begin"); InternationalStringType oName = new InternationalStringType(); List olLocStr = oName.getLocalizedString(); LocalizedStringType oNameLocStr = new LocalizedStringType(); olLocStr.add(oNameLocStr); oNameLocStr.setCharset("UTF-8"); oNameLocStr.setValue(sLocStrValue); oNameLocStr.setLang("en-us"); log.debug("DocumentTransforms.CreateSingleValueInternationalStringType() -- End"); return oName; } private static AssertionType buildAssertion(String gatewayOid){ log.debug("Begin - CPPOperations.buildAssertion() - "); AssertionType assertion = new AssertionType(); String svalue = ""; try { assertion.setHaveSignature(true); assertion.setHaveWitnessSignature(true); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, DATE_OF_SIGNATURE); if (svalue != null && svalue.length() > 0) { assertion.setDateOfSignature(svalue.trim()); } else { assertion.setDateOfSignature(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, EXPIRATION_DATE); if (null != svalue && svalue.length() > 0) { assertion.setExpirationDate(svalue.trim()); } else { assertion.setExpirationDate(""); } PersonNameType aPersonName = new PersonNameType(); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, FIRST_NAME); if(null != svalue && svalue.length() > 0){ aPersonName.setGivenName(svalue.trim()); } else { aPersonName.setGivenName(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, LAST_NAME); if(null != svalue && svalue.length() > 0){ aPersonName.setFamilyName(svalue.trim()); } else { aPersonName.setFamilyName(""); } UserType aUser = new UserType(); aUser.setPersonName(aPersonName); HomeCommunityType userHm = new HomeCommunityType(); svalue = PropertyAccessor.getProperty(SubscribeeCommunityList_PROPFILE_NAME, gatewayOid); if (null != svalue && svalue.length() > 0) { userHm.setName(svalue.trim()); } else { userHm.setName(""); } userHm.setHomeCommunityId(gatewayOid); aUser.setOrg(userHm); CeType userCe = new CeType(); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, USER_ROLE_CD); if(null!=svalue && svalue.length()>0){ userCe.setCode(svalue.trim()); } else { userCe.setCode(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, USER_ROLE_CD_SYSTEM); if(null!=svalue && svalue.length()>0){ userCe.setCodeSystem(svalue.trim()); } else { userCe.setCodeSystem(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, USER_ROLE_CD_SYSTEM_NAME); if(null!=svalue && svalue.length()>0){ userCe.setCodeSystemName(svalue.trim()); } else { userCe.setCodeSystemName(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, USER_ROLE_DISPLAY_NAME); if(null!=svalue && svalue.length()>0){ userCe.setDisplayName(svalue.trim()); } else { userCe.setDisplayName(""); } aUser.setRoleCoded(userCe); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, USER_NAME); if(null!=svalue && svalue.length()>0){ aUser.setUserName(svalue.trim()); } else { aUser.setUserName(""); } assertion.setUserInfo(aUser); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, ORG_NAME); HomeCommunityType hm = new HomeCommunityType(); if (null != svalue && svalue.length() > 0) { hm.setName(svalue.trim()); } else { hm.setName(""); } assertion.setHomeCommunity(hm); CeType ce = new CeType(); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, PURPOSE_FOR_USE_ROLE_CD); if(null!=svalue && svalue.length()>0){ ce.setCode(svalue.trim()); } else { ce.setCode(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, PURPOSE_FOR_USE_CODE_SYSTEM); if(null!=svalue && svalue.length()>0){ ce.setCodeSystem(svalue.trim()); } else { ce.setCodeSystem(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, PURPOSE_FOR_USE_CODE_SYSTEM_NAME); if(null!=svalue && svalue.length()>0){ ce.setCodeSystemName(svalue.trim()); } else { ce.setCodeSystemName(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, PURPOSE_FOR_USE_DISPLAY_NAME); if(null!=svalue && svalue.length()>0){ ce.setDisplayName(svalue.trim()); } else { ce.setDisplayName(""); } assertion.setPurposeOfDisclosureCoded(ce); svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, CONTENT_REFERENCE); if(null!=svalue && svalue.length()>0){ assertion.setClaimFormRef(svalue.trim()); } else { assertion.setClaimFormRef(""); } svalue = PropertyAccessor.getProperty(ASSERTIONINFO_PROPFILE_NAME, CONTENT); svalue = svalue.trim(); if(null!=svalue && svalue.length()>0){ assertion.setClaimFormRaw(svalue.getBytes()); } else { assertion.setClaimFormRaw("".getBytes()); } } catch (PropertyAccessException propExp) { propExp.printStackTrace(); } log.debug("End - CPPOperations.buildAssertion() - "); return assertion; } private EntityNotificationConsumerPortType getEntityNotificationConsumerWebservice() throws PropertyAccessException { String endpointURL = PropertyAccessor.getProperty(ADAPTER_PROPFILE_NAME, ENTITY_NOTIFICATION_CONSUMER_ENDPOINT_URL); log.info("EntitySubscriptionURL :" + endpointURL); EntityNotificationConsumerPortType entitynotificationconsumerPort = null; gov.hhs.fha.nhinc.entitynotificationconsumer.EntityNotificationConsumer service = new gov.hhs.fha.nhinc.entitynotificationconsumer.EntityNotificationConsumer(); entitynotificationconsumerPort = service.getEntityNotificationConsumerPortSoap11(); // Need to load in the correct UDDI endpoint URL address. //-------------------------------------------------------- ((BindingProvider) entitynotificationconsumerPort).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL); return entitynotificationconsumerPort; } /** * * @param patId * @param orgId * @param xacml * @return String */ public String updateOptIn(String patId, String orgId, String xacml) { log.debug("updateOptIn in MPI"); String ack = ""; org.w3c.dom.Document doc = CPPUtils.ByteArrayToDoc(xacml.getBytes()); boolean optInStatus = CPPUtils.isOptedIn(doc); Patient searchParams = new Patient(); searchParams.getIdentifiers().add(patId, orgId); //Search for patient MiniMpi mpi = MiniMpi.GetMpiInstance(); Patients searchResults = mpi.Search(searchParams, false, true); if (searchResults != null && searchResults.size() > 0) { if (searchResults.size() > 1) { return "More than one Patient found in MPI"; } Patient patFound = searchResults.get(0); if (optInStatus && patFound.isOptedIn()) { return "Patient was already Opted In nothing to Update"; } if (!optInStatus && !patFound.isOptedIn()) { return "Patient was already Opted Out nothing to Update"; } patFound.setOptedIn(optInStatus); Patient updatedPatient = mpi.AddUpdate(patFound); if (updatedPatient != null && updatedPatient.getIdentifiers().get(0).getId() != null) { ack = "Patient OptInOut Flag Updated Successfully"; } else { ack = "Patient OptInOut Flag Not Updated"; } } else { ack = "Patient Not Found in MPI"; } return ack; } }