/** * 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 static org.junit.Assert.assertTrue; import gov.nist.registry.common2.registry.MetadataSupport; import java.io.IOException; import java.util.Iterator; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import org.apache.axiom.om.OMAttribute; import org.apache.axiom.om.OMElement; import org.apache.axis2.client.ServiceClient; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.openhealthtools.common.utils.OMUtil; import org.openhealthtools.openexchange.config.PropertyFacade; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.sun.xml.bind.StringInputStream; public class CrossGatewayQueryTest extends XdsTest{ static String homeProperty; /** * @throws java.lang.Exception */ @Before public void setUp() throws Exception { PropertyFacade.loadProperties(new String[]{"openxds.properties"}); } /** * @throws java.lang.Exception */ @After public void tearDown() throws Exception { } static { homeProperty = PropertyFacade.getString("home.community.id"); } /** * This test initiate a FindDocuments Cross-Gateway Query (XGQ) to the XDS * Registry server's Responding Gateway for a pre-determined Patient ID. * Request LeafClass (full metadata) be returned. * @throws Exception */ @Test public void testFindDocsLeafClass() throws Exception { //1. Submit a document first for a random patientId String patientId = generateAPatientId(); String uuids = submitMultipleDocuments(patientId); //2. Generate StoredQuery request message String message = findDocumentsQuery(patientId, "Approved", "LeafClass"); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getRegistryGateWayClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify that the 2 Documents found from the StoredQuery response. NodeList count = getNodeCount(response, "ExtrinsicObject"); assertTrue(count.getLength() == 2); String result = response.toString(); System.out.println("Result:\n" +result); } /** * This test issues a FindDocuments Cross Gateway Query (XGQ) * to the XDS Registry's Receiving Gateway requesting ObjectRefs (document references) be returned. * @throws Exception */ @Test public void testFindDocsObjectRef() throws Exception { //1. Submit a document first for a random patientId String patientId = generateAPatientId(); String uuids = submitMultipleDocuments(patientId); //2. Generate StoredQuery request message String message = findDocumentsQuery(patientId, "Approved", "ObjectRef"); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getRegistryGateWayClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify that the 2 ObjectRefs found from the StoredQuery response. NodeList count = getNodeCount(response, "ObjectRef"); assertTrue(count.getLength() == 2); String result = response.toString(); System.out.println("Result:\n" +result); } /** * Tis test initiate a GetDocuments Cross-Gateway Query (XGQ) to the XDS * Registry server's Responding Gateway for documents discovered in * test 12306. Request LeafClass be returned. * @throws Exception */ @Test public void testGetDocuments() throws Exception { //1. Submit a document first for a random patientId String patientId = generateAPatientId(); String uuids = submitMultipleDocuments(patientId); //2. Generate StoredQuery request message String message = GetDocumentsQuery(uuids, false, homeProperty); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getRegistryGateWayClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify that the 2 Documents found from the StoredQuery response. NodeList count = getNodeCount(response, "ExtrinsicObject"); assertTrue(count.getLength() == 2); String result = response.toString(); System.out.println("Result:\n" +result); } /** * This test initiate a FindDocuments Cross-Gateway Query (XGQ) to the XDS * Registry server's Responding Gateway for a pre-determined Patient ID. * Request ObjectRefs be returned. * @throws Exception */ @Test public void testFindDocusMulObjectRefs() throws Exception { //1. Submit a document first for a random patientId String patientId = generateAPatientId(); String uuids = submitMultipleDocuments(patientId); //2. Generate StoredQuery request message String message = findDocumentsQuery(patientId, "Approved", "ObjectRef"); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getRegistryGateWayClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify that the 2 Documents found from the StoredQuery response. NodeList count = getNodeCount(response, "ObjectRef"); assertTrue(count.getLength() == 2); String result = response.toString(); System.out.println("Result:\n" +result); } /** * This test initiate a FindDocuments Cross-Gateway Query (XGQ) to the XDS * Registry server's Responding Gateway for a pre-determined Patient ID. * Request LeafClass (full metadata) be returned with Approved status. * @throws Exception */ @Test public void testFindDocsApproved() throws Exception { //1. Submit a document first for a random patientId String patientId = generateAPatientId(); String uuids = submitMultipleDocuments(patientId); //2. Generate StoredQuery request message String message = findDocumentsQuery(patientId, "Approved", "LeafClass"); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getRegistryGateWayClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify that the 2 Documents found from the StoredQuery response. NodeList count = getNodeCount(response, "ExtrinsicObject"); assertTrue(count.getLength() == 2); //6. Verify that the Document Status is Approved. NodeList statusCount = getElementValue(response, "ExtrinsicObject", "status", "urn:oasis:names:tc:ebxml-regrep:StatusType:Approved"); assertTrue(statusCount.getLength() == 2); String result = response.toString(); System.out.println("Result:\n" +result); } /** * This test initiate a FindDocuments Cross-Gateway Query (XGQ) to the XDS * Registry server's Initiating Gateway for a pre-determined Patient ID. * Request LeafClass (full metadata) be returned. * @throws Exception */ @Test public void testIGFindDocsLeafClass() throws Exception { //1. Submit one or more document first for the default patientId //2. Generate StoredQuery request message String message = findDocumentsQuery(patientId, "Approved", "LeafClass"); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getIGQueryServiceClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify document count NodeList count = getNodeCount(response, "ExtrinsicObject"); String result = response.toString(); System.out.println("Result:\n" +result); assertTrue(count.getLength() >= 1); System.out.println("Result:\n" +result); //6. Verify all ExtrinsicObject have a home attribute from the XGQ response OMElement registry_object_list = MetadataSupport.firstChildWithLocalName(response, "RegistryObjectList"); for (Iterator it=registry_object_list.getChildElements(); it.hasNext(); ) { OMElement registry_object = (OMElement) it.next(); String objectHome = registry_object.getAttributeValue(MetadataSupport.home_qname); assertTrue("homeId is NULL", objectHome!=null && !objectHome.equals("")); } } /** * Tis test initiate a GetDocuments Cross-Gateway Query (XGQ) to the XDS * Registry server's Initiating Gateway for documents discovered in * test 12306. Request LeafClass be returned. * @throws Exception */ @Test public void testIGGetDocuments() throws Exception { //1. Submit a document first for a random patientId String patientId = generateAPatientId(); String uuids = submitMultipleDocuments(patientId); //2. Generate StoredQuery request message String message = GetDocumentsQuery(uuids, false, homeProperty); OMElement request = OMUtil.xmlStringToOM(message); System.out.println("Request:\n" +request); //3. Send a StoredQuery ServiceClient sender = getIGQueryServiceClient(); OMElement response = sender.sendReceive( request ); assertNotNull(response); //4. Verify the response is correct OMAttribute status = response.getAttribute(new QName("status")); assertEquals("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success", status.getAttributeValue()); //5. Verify that the 2 Documents found from the StoredQuery response. NodeList count = getNodeCount(response, "ExtrinsicObject"); assertTrue(count.getLength() == 2); String result = response.toString(); System.out.println("Result:\n" +result); } public String findDocumentsQuery(String patientId, String status, String retType){ String request = "<query:AdhocQueryRequest xsi:schemaLocation=\"urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0 ../schema/ebRS/query.xsd\" xmlns:query=\"urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:rim=\"urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0\" xmlns:rs=\"urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0\">\n"+ " <query:ResponseOption returnComposedObjects=\"true\" returnType=\""+retType+"\"/>\n"+ " <rim:AdhocQuery id=\"urn:uuid:14d4debf-8f97-4251-9a74-a90016b0af0d\">\n"; if (patientId != null) { request += " <rim:Slot name=\"$XDSDocumentEntryPatientId\">\n"+ " <rim:ValueList>\n" + " <rim:Value>'"+patientId+"'</rim:Value>\n" + " </rim:ValueList>\n"+ " </rim:Slot>\n"; } if (status != null) { request += " <rim:Slot name=\"$XDSDocumentEntryStatus\">\n" + " <rim:ValueList>\n" + " <rim:Value>('urn:oasis:names:tc:ebxml-regrep:StatusType:"+status+"')</rim:Value>\n" + " </rim:ValueList>\n" + " </rim:Slot>\n"; } request += " </rim:AdhocQuery>\n" + "</query:AdhocQueryRequest>"; return request; } private String GetDocumentsQuery(String ids, boolean uniqueId, String home){ String request = "<query:AdhocQueryRequest xsi:schemaLocation=\"urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0 ../schema/ebRS/query.xsd\" xmlns:query=\"urn:oasis:names:tc:ebxml-regrep:xsd:query:3.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:rim=\"urn:oasis:names:tc:ebxml-regrep:xsd:rim:3.0\" xmlns:rs=\"urn:oasis:names:tc:ebxml-regrep:xsd:rs:3.0\">\n"+ " <query:ResponseOption returnComposedObjects=\"true\" returnType=\"LeafClass\"/>\n"+ " <rim:AdhocQuery id=\"urn:uuid:5c4f972b-d56b-40ac-a5fc-c8ca9b40b9d4\" home=\""+home+"\">\n"; if (ids != null && uniqueId == true) { request += " <rim:Slot name=\"$XDSDocumentEntryUniqueId\">\n"+ " <rim:ValueList>\n" + " <rim:Value>('"+ids+"')</rim:Value>\n" + " </rim:ValueList>\n"+ " </rim:Slot>\n"; } else { request += " <rim:Slot name=\"$XDSDocumentEntryEntryUUID\">\n" + " <rim:ValueList>\n" + " <rim:Value>('"+ids+"')</rim:Value>\n" + " </rim:ValueList>\n" + " </rim:Slot>\n"; } request += " </rim:AdhocQuery>\n" + "</query:AdhocQueryRequest>"; return request; } //Search the ExternalIdentifier for the given patientId private NodeList getPatientIdNodes(OMElement response, String patientId, String type) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException { patientId = patientId.replaceAll("&", "&"); DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(false); // never forget this! DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(new StringInputStream(response.toString())); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = null; if (type.equalsIgnoreCase("findDocuments") || type.equalsIgnoreCase("getDocuments")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/ExtrinsicObject/ExternalIdentifier[@identificationScheme='urn:uuid:58a6f841-87b3-4a3e-92fd-a8ffeff98427' and @value='"+patientId+"']"); else if (type.equalsIgnoreCase("findFolders") || type.equalsIgnoreCase("getFolders")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/RegistryPackage/ExternalIdentifier[@identificationScheme='urn:uuid:f64ffdf0-4b97-4e06-b79f-a52b38ec2f8a' and @value='"+patientId+"']"); else if (type.equalsIgnoreCase("findSubmissionSets") || type.equalsIgnoreCase("getSubmissionSets")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/RegistryPackage/ExternalIdentifier[@identificationScheme='urn:uuid:6b5aea1a-874d-4603-a4bc-96a0a7b38446' and @value='"+patientId+"']"); else if (type.equalsIgnoreCase("getAssociations")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/Association[@targetObject !='' and @sourceObject !='']"); else if (type.equalsIgnoreCase("getReplaceDocument")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/Association[@associationType='urn:ihe:iti:2007:AssociationType:RPLC' and @targetObject !='' and @sourceObject !='']"); Object res = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) res; // for (int i = 0; i < nodes.getLength(); i++) { // System.out.println(nodes.item(i)); // } return nodes; } private NodeList getNodeCount(OMElement response, String type)throws ParserConfigurationException, IOException, SAXException, XPathExpressionException{ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(false); // never forget this! DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(new StringInputStream(response.toString())); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = null; if (type.equalsIgnoreCase("ExtrinsicObject")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/ExtrinsicObject"); if (type.equalsIgnoreCase("ObjectRef")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/ObjectRef"); Object res = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) res; return nodes; } private NodeList getElementValue(OMElement response, String type, String element, String value)throws ParserConfigurationException, IOException, SAXException, XPathExpressionException{ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(false); // never forget this! DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(new StringInputStream(response.toString())); XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = null; if (type.equalsIgnoreCase("ExtrinsicObject")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/ExtrinsicObject[@"+element+"='"+value+"']"); if (type.equalsIgnoreCase("ExternalIdentifier")) expr = xpath.compile("//AdhocQueryResponse/RegistryObjectList/ExtrinsicObject/ExternalIdentifier[@"+element+"='"+value+"']"); Object res = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) res; return nodes; } }