/** * Copyright (c) 2009-2010 Misys Open Source Solutions (MOSS) and others * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * Contributors: * Misys Open Source Solutions - initial API and implementation * - */ package org.openhealthtools.openxds.integrationtests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.io.IOException; import java.io.InputStream; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.Random; import java.util.UUID; import javax.activation.DataHandler; import javax.activation.DataSource; import javax.mail.util.ByteArrayDataSource; import javax.xml.namespace.QName; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; import org.apache.axiom.om.OMText; import org.apache.axiom.soap.SOAP12Constants; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.description.WSDL2Constants; import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.openhealthexchange.openpixpdq.data.PatientIdentifier; import org.openhealthexchange.openpixpdq.ihe.registry.HL7; import org.openhealthtools.common.utils.OMUtil; import org.openhealthtools.openxds.XdsFactory; import org.openhealthtools.openxds.registry.api.XdsRegistryPatientService; import ca.uhn.hl7v2.app.Connection; import ca.uhn.hl7v2.app.ConnectionHub; import ca.uhn.hl7v2.app.Initiator; import ca.uhn.hl7v2.llp.MinLowerLayerProtocol; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v231.segment.MSA; import ca.uhn.hl7v2.parser.PipeParser; import com.misyshealthcare.connect.net.Identifier; /** * The base class of all XDS TestCases. * * @author <a href="mailto:wenzhi.li@misys.com">Wenzhi Li</a> */ public abstract class XdsTest { protected static String hostName; protected static String repositoryUrl; protected static String registryUrl; protected static String rgUrl; protected static String igUrl; protected static int pixRegistryPort; protected static String patientId; protected static String assigningAuthority; protected static boolean validatePatient = false; /** * @throws java.lang.Exception */ @BeforeClass public static void setUpBeforeClass() throws Exception { InputStream is = XdsTest.class.getClassLoader().getResourceAsStream("test.properties"); if (is == null) { throw new Exception("Cannot load test.propertises"); } Properties properties = new java.util.Properties(); try { properties.load(is); } catch (Exception e) { throw new Exception("Cannot load test.properties", e); } hostName = properties.getProperty("pixRegistryHostName"); repositoryUrl = properties.getProperty("repositoryUrl"); registryUrl = properties.getProperty("registryUrl"); pixRegistryPort = Integer.parseInt(properties.getProperty("pixRegistryPort")); patientId = properties.getProperty("patientId"); assigningAuthority = properties.getProperty("assigningAuthority"); validatePatient = (properties.getProperty("validatePatient").equals("false")) ? false : true; rgUrl = properties.getProperty("rgUrl"); igUrl = properties.getProperty("igUrl"); //Initialize openEMPI // XdsRegistryPatientService ps = XdsFactory.getXdsRegistryPatientService(); // XdsFactory.getInstance().getBean("context"); // org.openhie.openempi.context.Context.startup(); // org.openhie.openempi.context.Context.authenticate("admin", "admin"); } /** * @throws java.lang.Exception */ @AfterClass public static void tearDownAfterClass() throws Exception { } /** * @throws java.lang.Exception */ @Before public void setUp() throws Exception { } /** * @throws java.lang.Exception */ @After public void tearDown() throws Exception { } /* * Generates a new patient Id for testing */ protected String generateAPatientId() throws Exception { String patientId = new Random().nextInt() + "^^^" + assigningAuthority; createPatient(patientId); return patientId; } protected void createPatient(String patientId) throws Exception { if (!validatePatient) return ; patientId = patientId.replace("&", "&"); //If it is a valid patient, then no need to re-create. if (isValidPatient(patientId)) return; String msg = "MSH|^~\\&|OTHER_KIOSK|HIMSSSANDIEGO|PAT_IDENTITY_X_REF_MGR_MISYS|ALLSCRIPTS|20090512132906-0300||ADT^A04^ADT_A01|7723510070655179915|P|2.3.1\r" + "EVN||20090512132906-0300\r" + "PID|||"+ patientId +"||FARNSWORTH^STEVE||19781208|M|||820 JORIE BLVD^^CHICAGO^IL^60523\r" + "PV1||O|"; PipeParser pipeParser = new PipeParser(); Message adt = pipeParser.parse(msg); ConnectionHub connectionHub = ConnectionHub.getInstance(); Connection connection = connectionHub.attach(hostName, pixRegistryPort, new PipeParser(), MinLowerLayerProtocol.class); Initiator initiator = connection.getInitiator(); Message response = initiator.sendAndReceive(adt); String responseString = pipeParser.encode(response); System.out.println("Received response:\n" + responseString); MSA msa = (MSA)response.get("MSA"); assertEquals("AA", msa.getAcknowledgementCode().getValue()); } //patientId format example: 12321^^^&1.3.6.1.4.1.21367.2009.1.2.300&ISO private boolean isValidPatient(String patientId) throws Exception { String id = HL7.getIdFromCX(patientId); Identifier aa = HL7.getAssigningAuthorityFromCX(patientId); PatientIdentifier pi = new PatientIdentifier(); pi.setId(id); pi.setAssigningAuthority(aa); XdsRegistryPatientService ps = XdsFactory.getXdsRegistryPatientService(); boolean isValid = ps.isValidPatient(pi, null); return isValid; } /** * Submit one document to support ProvideAndRegisterDocumentSet-b (ITI-41) * * @return XDSDocumentEntry.uuid * @throws * @throws Exception */ protected String submitOneDocument(String patientId) throws Exception { String message = IOUtils.toString( ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/submit_document.xml")); String document = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/referral_summary.xml")); //replace document and submission set uniqueId variables with actual uniqueIds. message = message.replace("$XDSDocumentEntry.uniqueId", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); message = message.replace("$XDSSubmissionSet.uniqueId", "1.3.6.1.4.1.21367.2009.1.2.108." + System.currentTimeMillis()); //replace the document uuid. String uuid = "urn:uuid:" + UUID.randomUUID().toString(); message = message.replace("$doc1", uuid); //replace the patient id if (patientId != null) message = message.replace("$patientId", patientId); ServiceClient sender = getRepositoryServiceClient(); OMElement request = OMUtil.xmlStringToOM(message); //Add a document request = addOneDocument(request, document, uuid); System.out.println("Request:\n" +request); OMElement response = sender.sendReceive( request ); assertNotNull(response); OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); String result = response.toString(); System.out.println("Result:\n" +result); return uuid; } public String submitMultipleDocuments(String patientId) throws Exception { String message = IOUtils.toString( ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/submit_multiple_documents.xml")); String document1 = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/referral_summary.xml")); String document2 = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/medical_summary.xml")); //replace document and submission set uniqueId variables with actual uniqueIds. message = message.replace("$XDSDocumentEntry.uniqueId", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); message = message.replace("$XDSDocumentEntry.uniqueId1", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); message = message.replace("$XDSSubmissionSet.uniqueId", "1.3.6.1.4.1.21367.2009.1.2.108." + System.currentTimeMillis()); //replace the document uuid. String uuid1 = getUUID(); message = message.replace("$doc1", uuid1); String uuid2 = getUUID(); message = message.replace("$doc2", uuid2); //replace the patient id if (patientId != null) message = message.replace("$patientId", patientId); ServiceClient sender = getRepositoryServiceClient(); OMElement request = OMUtil.xmlStringToOM(message); //Add a referral summary document request = addOneDocument(request, document1, uuid1); //Add a Discharge summary documents request = addOneDocument(request, document2, uuid2); System.out.println("Request:\n" +request); OMElement response = sender.sendReceive( request ); assertNotNull(response); OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); String result = response.toString(); System.out.println("Result:\n" +result); String uuids = uuid1 +"','"+uuid2; return uuids; } protected String getUUID(){ return "urn:uuid:" + UUID.randomUUID().toString(); } //return folder unique Id protected String submitOneDocument2Folder(String patientId) throws Exception { String message = IOUtils.toString( ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/add_document2_folder.xml")); String document1 = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/referral_summary.xml")); //replace document , submission set and folder uniqueId variables with actual uniqueIds. message = message.replace("$XDSDocumentEntry.uniqueId", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); message = message.replace("$XDSSubmissionSet.uniqueId", "1.3.6.1.4.1.21367.2009.1.2.108." + System.currentTimeMillis()); String folderUniqueId = "2.16.840.1.113883.3.65.3." + System.currentTimeMillis(); message = message.replace("$folder_uniqueid", folderUniqueId); //replace the documentId doc1 with an UUID String uuid = "urn:uuid:" + UUID.randomUUID().toString(); message = message.replace("doc1", uuid); //replace the patient id message = message.replace("$patientId", patientId); ServiceClient sender = getRepositoryServiceClient(); OMElement request = OMUtil.xmlStringToOM(message); //Add a referral summary document request = addOneDocument(request, document1, uuid); System.out.println("Request:\n" +request); OMElement response = sender.sendReceive( request ); assertNotNull(response); OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); String result = response.toString(); System.out.println("Result:\n" +result); return folderUniqueId; } /** * Submits new document and replaces the document * * @param patientId * @return Document UUID * @throws Exception */ public String replaceDocument(String patientId) throws Exception { //First submit a document String doc_uuid = submitOneDocument(patientId); //Then add a replacement doc String message = IOUtils.toString( ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/document_replacement.xml")); String document1 = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/medical_summary.xml")); //replace document and submission set variables with actual uniqueIds. message = message.replace("$XDSDocumentEntry.uniqueId", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); message = message.replace("$XDSSubmissionSet.uniqueId", "1.3.6.1.4.1.21367.2009.1.2.108." + System.currentTimeMillis()); message = message.replace("$patientId", patientId); //populate the document uuid to be replaced. message = message.replace("$rplc_doc_uuid", doc_uuid); ServiceClient sender = getRepositoryServiceClient(); OMElement request = OMUtil.xmlStringToOM(message); //Add a medical summary document request = addOneDocument(request, document1, "doc1"); System.out.println("Request:\n" +request); OMElement response = sender.sendReceive( request ); assertNotNull(response); OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); String result = response.toString(); System.out.println("Result:\n" +result); return doc_uuid; } /** * Submits document to the folder. * @param patientId * @return document UUID * @throws Exception */ protected String submitDocument2Folder(String patientId) throws Exception { String message = IOUtils.toString( ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/add_document2_folder.xml")); String document1 = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/referral_summary.xml")); //replace document , submission set and folder uniqueId variables with actual uniqueIds. message = message.replace("$XDSDocumentEntry.uniqueId", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); message = message.replace("$XDSSubmissionSet.uniqueId", "1.3.6.1.4.1.21367.2009.1.2.108." + System.currentTimeMillis()); String folderUniqueId = "2.16.840.1.113883.3.65.3." + System.currentTimeMillis(); message = message.replace("$folder_uniqueid", folderUniqueId); //replace the documentId doc1 with an UUID String uuid = "urn:uuid:" + UUID.randomUUID().toString(); message = message.replace("doc1", uuid); //replace the patient id message = message.replace("$patientId", patientId); ServiceClient sender = getRepositoryServiceClient(); OMElement request = OMUtil.xmlStringToOM(message); //Add a referral summary document request = addOneDocument(request, document1, uuid); System.out.println("Request:\n" +request); OMElement response = sender.sendReceive( request ); assertNotNull(response); OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); String result = response.toString(); System.out.println("Result:\n" +result); return uuid; } /** * Submits document to the SubmisstionSet And Folder. * @param patientId * @return document UUID * @throws Exception */ protected String submitDocument2SubmissionSet(String patientId) throws Exception { String message = IOUtils.toString( ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/add_document2_folder.xml")); String document1 = IOUtils.toString(ProvideAndRegisterDocumentSetTest.class.getResourceAsStream("/data/referral_summary.xml")); //replace document , submission set and folder uniqueId variables with actual uniqueIds. message = message.replace("$XDSDocumentEntry.uniqueId", "2.16.840.1.113883.3.65.2." + System.currentTimeMillis()); String subUniqueId = "1.3.6.1.4.1.21367.2009.1.2.108." + System.currentTimeMillis(); message = message.replace("$XDSSubmissionSet.uniqueId", subUniqueId); String folderUniqueId = "2.16.840.1.113883.3.65.3." + System.currentTimeMillis(); message = message.replace("$folder_uniqueid", folderUniqueId); //replace the documentId doc1 with an UUID String uuid = "urn:uuid:" + UUID.randomUUID().toString(); message = message.replace("doc1", uuid); //replace the patient id message = message.replace("$patientId", patientId); ServiceClient sender = getRepositoryServiceClient(); OMElement request = OMUtil.xmlStringToOM(message); //Add a referral summary document request = addOneDocument(request, document1, uuid); System.out.println("Request:\n" +request); OMElement response = sender.sendReceive( request ); assertNotNull(response); OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); String result = response.toString(); System.out.println("Result:\n" +result); return subUniqueId; } protected ServiceClient getRepositoryServiceClient() throws AxisFault { ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:ProvideAndRegisterDocumentSet-b"; boolean enableMTOM = true; sender.setOptions(getOptions(action, enableMTOM, repositoryUrl)); sender.engageModule("addressing"); return sender; } protected ServiceClient getRegistryServiceClient() throws AxisFault { ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:RegistryStoredQuery"; boolean enableMTOM = false; sender.setOptions(getOptions(action, enableMTOM, registryUrl)); sender.engageModule("addressing"); return sender; } protected ServiceClient getRetrieveDocumentServiceClient() throws AxisFault{ ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:RetrieveDocumentSet"; boolean enableMTOM = true; sender.setOptions(getOptions(action, enableMTOM, repositoryUrl)); sender.engageModule("addressing"); return sender; } protected ServiceClient getRegistryGateWayClient() throws AxisFault { ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:CrossGatewayQuery"; boolean enableMTOM = false; sender.setOptions(getOptions(action, enableMTOM, rgUrl)); sender.engageModule("addressing"); return sender; } protected ServiceClient getRepositoryGateWayClient() throws AxisFault { ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:CrossGatewayRetrieve"; boolean enableMTOM = true; sender.setOptions(getOptions(action, enableMTOM, rgUrl)); sender.engageModule("addressing"); return sender; } protected ServiceClient getIGQueryServiceClient() throws AxisFault { ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:RegistryStoredQuery"; boolean enableMTOM = false; sender.setOptions(getOptions(action, enableMTOM, igUrl)); sender.engageModule("addressing"); return sender; } protected ServiceClient getIGRetrieveServiceClient() throws AxisFault{ ConfigurationContext configctx = getContext(); ServiceClient sender = new ServiceClient(configctx,null); String action = "urn:ihe:iti:2007:RetrieveDocumentSet"; boolean enableMTOM = true; sender.setOptions(getOptions(action, enableMTOM, igUrl)); sender.engageModule("addressing"); return sender; } private ConfigurationContext getContext() throws AxisFault { //String repository = "c:\\tools\\axis2-1.5\\repository\\modules\\addressing-1.5.mar"; // String repository = "c:\\tools\\axis2-1.5\\repository"; // String axis2xml = "c:\\tools\\axis2-1.5\\conf\\axis2.xml"; // ConfigurationContext configctx = ConfigurationContextFactory // .createConfigurationContextFromFileSystem(repository, axis2xml); URL axis2repo = XdsTest.class.getResource("/axis2repository"); URL axis2testxml = XdsTest.class.getResource("/axis2_test.xml"); ConfigurationContext configctx = ConfigurationContextFactory .createConfigurationContextFromFileSystem(axis2repo.getPath(), axis2testxml.getPath()); return configctx; } protected Options getOptions(String action, boolean enableMTOM, String url) { Options options = new Options(); options.setAction(action); options.setProperty(WSDL2Constants.ATTRIBUTE_MUST_UNDERSTAND,"1"); options.setTo( new EndpointReference(url) ); options.setTransportInProtocol(Constants.TRANSPORT_HTTP); // try { // String from = InetAddress.getLocalHost().getHostAddress(); // options.setFrom(new EndpointReference(from)); // }catch(UnknownHostException e) { // //ignore From // } if (enableMTOM) options.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_TRUE); else options.setProperty(Constants.Configuration.ENABLE_MTOM, Constants.VALUE_FALSE); //use SOAP12, options.setSoapVersionURI(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); return options; } protected OMElement addOneDocument(OMElement request, String document, String documentId) throws IOException { OMFactory fac = OMAbstractFactory.getOMFactory(); OMNamespace ns = fac.createOMNamespace("urn:ihe:iti:xds-b:2007" , null); OMElement docElem = fac.createOMElement("Document", ns); docElem.addAttribute("id", documentId, null); // A string, turn it into an StreamSource DataSource ds = new ByteArrayDataSource(document, "text/xml"); DataHandler handler = new DataHandler(ds); OMText binaryData = fac.createOMText(handler, true); docElem.addChild(binaryData); Iterator iter = request.getChildrenWithLocalName("SubmitObjectsRequest"); OMElement submitObjectsRequest = null; for (;iter.hasNext();) { submitObjectsRequest = (OMElement)iter.next(); if (submitObjectsRequest != null) break; } submitObjectsRequest.insertSiblingAfter(docElem); return request; } }