Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "OHF IHE XDS Document Consumer"

(New page: OHF XDS Document Consumer Architecture & API Documentation Version 0.2.0 � =API Documentation = The XDS Document Consumer provides an API for the execution of the following IHE Tra...)
 
Line 5: Line 5:
 
Version 0.2.0  
 
Version 0.2.0  
  
 
 
=API Documentation =
 
=API Documentation =
 
The XDS Document Consumer provides an API for the execution of the following IHE Transactions: ITI-16:  
 
The XDS Document Consumer provides an API for the execution of the following IHE Transactions: ITI-16:  

Revision as of 21:40, 27 June 2007

OHF XDS Document Consumer

Architecture & API Documentation

Version 0.2.0

API Documentation

The XDS Document Consumer provides an API for the execution of the following IHE Transactions: ITI-16: Query Registry, ITI-17: Retrieve Document and ITI-18: Registry Stored Query. The API also provides utility functions for the construction of SQL queries for ITI-16 and for stored queries for ITI-18. The API currently supports automatic construction of the FindDocuments and the GetDocuments query for ITI-16 and for ITI-18.

Use Case 1 – Registry Stored Query: FindDocuments Query

Joe User, using his EMR Application, wants to find all documents where:

  • patientID is “JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO”
  • Only “Approved” documents are returned
  • Creation time on the document is between 20031225 and 20060101
  • Healthcare Facility Type Code is “Outpatient”

Flow of Execution

XDS Consumer Flow of Execution.jpg

API Highlights

The most significant method portions in the above control flow are Consumer.invokeStoredQuery() and the construction of the FindDocumentsQuery (which extends the more generic StoredQuery object).

Sample Code

Description

The following sample code illustrates how the XDS Consumer issues a FindDocumentsQuery Stored Query to the XDS Registry.

Code

//////////////////////////////////////////////////////////////////////////////// 
//If an instance does not already exist, create an instance of the XDS Consumer 
//and provide the XDS Registry url and port. 
//////////////////////////////////////////////////////////////////////////////// 
String registryURL = “http://my.registry.url:8080”;
Consumer c = new Consumer(registryURL); 
//////////////////////////////////////////////////////////////////////////////// 
//Construct the parameters to our FindDocumentsQuery 
//////////////////////////////////////////////////////////////////////////////// 
// Set up the patient ID: “JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO” 
CX patientId = Hl7v2Factory.eINSTANCE.createCX(); 
patientId.setIdNumber("JM19400814"); 
patientId.setAssigningAuthorityUniversalId("1.3.6.1.4.1.21367.2005.1.1"); 
patientId.setAssigningAuthorityUniversalIdType("ISO"); 
// Set up the date-time range for creationTime between Dec 25, 2003 and Jan 01, 
//2006 
DateTimeRange[] creationTimeRange = {new 
DateTimeRange(DocumentEntryConstants.CREATION_TIME, “20031225”, “20060101”}; 
//Create a list of healthcare facility codes we want to search on. In this 
//example we only want documents where the healthcare facility is “Outpatient” 
CodedMetadataType hcfc1 = MetadataFactory.eINSTANCE.createCodedMetadataType(); 
hcfc1.setCode("Outpatient"); 
//Create a list of document status types we want to search on. In this example, 
//we only want “Approved” documents. 
AvailabilityStatusType status = {AvailabilityStatusType.Approved}; 
//////////////////////////////////////////////////////////////////////////////// 
//Construct our FindDocumentsQuery for patient 
//“JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO” 
//////////////////////////////////////////////////////////////////////////////// 
FindDocumentsQuery query = new FindDocumentsQuery( 
    patientId, 
    null, // no classCodes 
    new DateTimeRange[]{creationTimeRange}, 
    null, // no practiceSettingCodes 
    new CodedMetadataType[]{hcfc1}, 
    null, // no eventCodes 
    null, // no confidentialityCodes 
    null, // no formatCodes 
    status); 
//////////////////////////////////////////////////////////////////////////////// 
//Execute the query. 
///////////////////////////////////////////////////////////////////////////// 
List docList = null; 
try { 
         c.invokeStoredQuery(query, false, "JOE USER"); 
} catch (Exception e) { 
System.out.println(e.toString()); 
throw e; 
} 
if(docList == null){ 
     System.out.println("NO DOCUMENT FOUND"); 
} 

Use Case 2 – Registry Stored Query: GetDocuments Query

Joe User, using his EMR Application, wants to find all documents where:

  • The document uniqueId is “1144362162012”

Flow of Execution

consumer

API Highlights

The most significant method portions in the above control flow are Consumer.invokeStoredQuery(), explained in the previous section, and the construction of the GetDocumentsQuery (which extends the more generic StoredQuery object).

Sample Code

Description

The following sample code illustrates how the XDS Consumer issues a GetDocumentQuery Stored Query to the XDS Registry.

Code

//////////////////////////////////////////////////////////////////////////////// 
//We assume a Consumer c has already been appropriately constructed as in 
//Section 3.1.3.2 
//////////////////////////////////////////////////////////////////////////////// 
//////////////////////////////////////////////////////////////////////////////// 
//Construct our GetDocumentQuery for document with uniqueID “1144362162012”; 
//thus, the argument for the “isUUID” parameter is ‘false’. 
//////////////////////////////////////////////////////////////////////////////// 
GetDocumentQuery query = new GetDocumentQuery(new String[]{“1144362162012”}, false); 
//////////////////////////////////////////////////////////////////////////////// 
//Execute the query. 
////////////////////////////////////////////////////////////////////////////// 
List docList = null; 
try { 
     c.invokeStoredQuery(query, false, "JOE USER"); 
} catch (Exception e) { 
     System.out.println(e.toString()); 
     throw e; 
} 
if(docList == null){ 
     System.out.println("NO DOCUMENT FOUND"); 
} 


Use Case 3 – Query Registry: FindDocuments Query

Joe User, using his EMR Application, wants to find all documents where:

  • patientID is “JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO”
  • Only “Approved” documents are returned
  • Creation time on the document is between 20031225 and 20060101
  • Healthcare Facility Type Code is “Outpatient”

Flow of Execution

Consumer Flow of Execution 3.jpg

API Highlights

The most significant method portions in the above control flow are Consumer.query() and the construction of the FindDocumentsQuery (which extends the more generic Query object).

3.3.3 Sample Code 3.3.3.1 Description The following sample code illustrates how the XDS Consumer issues a FindDocumentsQuery SQL-based Query to the XDS Registry.

3.3.3.2 Code

//////////////////////////////////////////////////////////////////////////////// 
//If an instance does not already exist, create an instance of the XDS Consumer 
//and provide the XDS Registry url and port. 
//////////////////////////////////////////////////////////////////////////////// 
String registryURL = “http://my.registry.url:8080”; 
Consumer c = new Consumer(registryURL); 
//////////////////////////////////////////////////////////////////////////////// 
//Construct the parameters to our FindDocumentsQuery 
//////////////////////////////////////////////////////////////////////////////// 
// Set up the patient ID: “JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO” 
CX patientId = Hl7v2Factory.eINSTANCE.createCX(); 
patientId.setIdNumber("JM19400814"); 
patientId.setAssigningAuthorityUniversalId("1.3.6.1.4.1.21367.2005.1.1"); 
patientId.setAssigningAuthorityUniversalIdType("ISO"); 
// Set up the date-time range for creationTime between Dec 25, 2003 and Jan 01, 
//2006 
DateTimeRange[] creationTimeRange = {new 
DateTimeRange(DocumentEntryConstants.CREATION_TIME, “20031225”, “20060101”}; 
//Create a list of healthcare facility codes we want to search on. In this 
//example we only want documents where the healthcare facility is “Outpatient” 
CodedMetadataType hcfc1 = MetadataFactory.eINSTANCE.createCodedMetadataType(); 
hcfc1.setCode("Outpatient"); 
//Create a list of document status types we want to search on. In this example, 
//we only want “Approved” documents. 
AvailabilityStatusType status = {AvailabilityStatusType.Approved}; 
//////////////////////////////////////////////////////////////////////////////// 
//Construct our FindDocumentsQuery for patient 
//“JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO” 
//////////////////////////////////////////////////////////////////////////////// 
FindDocumentsQuery query = new FindDocumentsQuery( 
	patientId, 
	null, // no classCodes 
	new DateTimeRange[]{creationTimeRange}, 
	null, // no practiceSettingCodes 
	new CodedMetadataType[]{hcfc1}, 
	null, // no eventCodes 
	null, // no confidentialityCodes 
	null, // no formatCodes 
	status); 
//////////////////////////////////////////////////////////////////////////////// 
//Execute the query. 
///////////////////////////////////////////////////////////////////////////// 
List docList = null; 
try { 
      c.query(query, false, "JOE USER"); 
} catch (Exception e) { 
      System.out.println(e.toString()); 
      throw e; 
} 
if(docList == null){ 
      System.out.println("NO DOCUMENT FOUND"); 
} 


Use Case 4 – Query Registry: Raw SQL Query

Joe User, using his EMR Application, wants to find all documents where:

SELECT doc.id FROM ExtrinsicObject doc WHERE doc.id = 'urn:uuid:4c7aa6ba-4c727346-9639-000f1fd35f02' 

Flow of Execution

Consumer Flow of Execution 4.jpg

API Highlights

The most significant method portions in the above control flow is Consumer.query(). This is described below in greater detail.

3.4.3 Sample Code 3.4.3.1 Description The following sample code illustrates how the XDS Consumer issues a raw SQL query to the XDS Registry.

3.4.3.2 Code

//////////////////////////////////////////////////////////////////////////////// 
//We assume a Consumer c has already been appropriately constructed as in 
//Section 3.1.3.2 
//Set up SQL query string 
//////////////////////////////////////////////////////////////////////////////// 
String queryString = “SELECT doc.id FROM ExtrinsicObject doc WHERE doc.id = ” + 
“\'urn:uuid:4c7aa6ba-4c72-7346-9639-000f1fd35f02\'”; 
//////////////////////////////////////////////////////////////////////////////// 
//Execute the query. 
//////////////////////////////////////////////////////////////////////////////// 
List docList = null; 
try { 
    c.query(queryString, false, "JOE USER"); 
} catch (Exception e) { 
    System.out.println(e.toString()); 
    throw e; 
} 
if(docList == null){ 
    System.out.println("NO DOCUMENT FOUND"); 
}

Use Case 5 – Retrieve

Joe User, using his EMR Application, wants to retrieve a document he has just queried and found where:

Flow of Execution

Consumer Flow of Execution 5.jpg

API Highlights

The most significant method portions in the above control flow is Consumer.retrieveDocument(). This is described below in greater detail.

Sample Code

Description

The following sample code illustrates how the XDS Consumer retrieves a document from the XDS Repository.

Code

//////////////////////////////////////////////////////////////////////////////// 
//We assume a Consumer c has already been appropriately constructed. 
//Additionally, we assume a DocumentEntryType docEntry filled 
//with XDS metadata for the desired document has already been obtained from 
//the issuing a query to the XDS Registry. 
//////////////////////////////////////////////////////////////////////////////// 
// do the retrieve 
InputStream document = null; 
try{ 
     document = c.retrieveDocument(docEntry.getUri(), "JOE USER"); 
catch(Exception e){ 
     // if an exception happens, the retrieve has failed 
     System.out.println("Error when attempting to retrieve from: " + 
     docEntry.getUri(), e); 
     throw e; 
} 
if(document == null){ 
      // if null is returned, then the repository returned null, something else 
      // is wrong. 
      System.out.println("Document InputStream is null."); 
      throw new Exception("Document InputStream is null."); 
} 

Security

Node Authentication

Node Authentication is accomplished using Java keystores. For more information regarding the creation of keystores and truststores in Java see the OHF ATNA Agent documentation. Once you have created your java keystore containing your private key and a truststore containing all keys of your trusted partners, simply run the OHF XDS Consumer with the following JVM arguments:

-Djavax.net.ssl.keyStore=<location of your keystore file> 
-Djavax.net.ssl.keyStorePassword=<password to your keystore file> 
-Djavax.net.ssl.trustStore=<location of your truststore file> 
-Djavax.net.ssl.trustStorePassword=<password to your truststore file> 

Auditing

All auditing events surrounding any of the OHF XDS Consumer transactions are taken care of by this plugin. Auditing is enabled by default and audit messages, by default, are sent to

syslog://lswin10.dfw.ibm.com:515. 

To disable auditing for all OHF events call the following:

AtnaAgentFactory.getAtnaAgent().setDoAudit(false); 


To switch the url of the Audit Record Repository to which the audit events are being sent, call the following:

AtnaAgentFactory.getAtnaAgent().setAuditRepository(new URI( “syslog://new.audit.url));. 

To re-enable auditing for all OHF events, call the following:

AtnaAgentFactory.getAtnaAgent().setDoAudit(true); 

To create your own auditing message for application specific events, please see the OHF ATNA Agent documentation.

Auditing Example Code

Description

The following sample code illustrates how the above auditing commands can be used in conjunction with the OHF XDS Consumer.

Code

//////////////////////////////////////////////////////////////////////////////// 
//If an instance does not already exist, create an instance of the XDS Consumer 
//and provide the XDS Registry url and port. 
//////////////////////////////////////////////////////////////////////////////// 
String registryURL = “http://my.registry.url:8080”; 
Consumer c = new Consumer(registryURL); 
//////////////////////////////////////////////////////////////////////////////// 
//Switch Audit Record Repository end point 
//////////////////////////////////////////////////////////////////////////////// 
String auditURL = “syslog://my.audit.url:515”; 
AtnaAgentFactory.getAtnaAgent().setAuditRepository(new URI(auditURL)); 
//////////////////////////////////////////////////////////////////////////////// 
//Construct the parameters to our FindDocumentsQuery 
//////////////////////////////////////////////////////////////////////////////// 
// Set up the patient ID: “JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO” 
CX patientId = Hl7v2Factory.eINSTANCE.createCX(); 
patientId.setIdNumber("JM19400814"); 
patientId.setAssigningAuthorityUniversalId("1.3.6.1.4.1.21367.2005.1.1"); 
patientId.setAssigningAuthorityUniversalIdType("ISO"); 
//////////////////////////////////////////////////////////////////////////////// 
//Construct our FindDocumentsQuery for patient 
//“JM19400814^^^&1.3.6.1.4.1.21367.2005.1.1&ISO” 
//////////////////////////////////////////////////////////////////////////////// 
FindDocumentsQuery q = new FindDocumentsQuery(patientId, new 
AvailabilityStatusType[]{AvailabilityStatusType.APPROVED_LITERAL}); 
//////////////////////////////////////////////////////////////////////////////// 
//Execute the query. 
//////////////////////////////////////////////////////////////////////////////// 
List docList = null; 
try { 
     c.query(queryString, false, "JOE USER"); 
} catch (Exception e) { 
     System.out.println(e.toString()); 
     throw e; 
} 
if(docList == null){ 
     System.out.println("NO DOCUMENT FOUND"); 
     System.exit(0); 
} 
if(docList.size() == 0){ 
System.out.println("NO DOCUMENT FOUND"); 
System.exit(0); 
///////////////////////////////////////////////////////////////////////// 
// Get the first document entry URL and retrieve 
///////////////////////////////////////////////////////////////////////// 
DocumentEntryType docEntry = (DocumentEntryType)docList.get(0); 
if(docEntry.getUri() == null){ 
     System.out.println("Malformed DocumentEntry.URI is null."); 
     throw new Exception("Malformed DocumentEntry.URI is null."); 
} 
//Turn off auditing for the retrieve (suppose we want to do this … for some 
//reason). 
AtnaAgentFactory.getAtnaAgent().setDoAudit(true); 
// finally get the document 
InputStream document = c.retrieveDocument(docEntry.getUri(), "JOE USER"); 
if(document == null){ 
     System.out.println("Document InputStream is null."); 
     throw new Exception("Document InputStream is null."); 
} 

Configuration

The following is a list of configurable aspects:

  • Java properties for TLS communication (set the following as JVM arguments):
-Djavax.net.ssl.keyStore=<location of your keystore file> 
-Djavax.net.ssl.keyStorePassword=<password to your keystore file> 
-Djavax.net.ssl.trustStore=<location of your truststore file> 
-Djavax.net.ssl.trustStorePassword=<password to your truststore file> 
  • Audit Record Repository url and port:
String auditURL = “syslog://my.audit.url:515”; 
AtnaAgentFactory.getAtnaAgent().setAuditRepository(new URI(auditURL)); 
  • Enable/Disable auditing flag
AtnaAgentFactory.getAtnaAgent().setDoAudit(true); // enable 
AtnaAgentFactory.getAtnaAgent().setDoAudit(false); // disable 
  • Initiating user ID, for auditing (an API parameter on each transaction)
  • XDS Registry url and port (an API parameter on the constructor of the OHF XDS Consumer)
  • Logging is configurable. For more information about logging, consult Section 6 of this document.

Debugging Recommendations

The XDS Consumer uses Apache Log4j. If you are experiencing bugs related to the Consumer, you may enable debug level logging by adding the following category to your log4j XML configuration file.

<category name="org.eclipse.ohf.ihe.xds.consumer"> 
      <priority value="debug" /> 
</category > 


For more information about Log4j please see: Log4J documentetion

For an example log4j XML configuration file and to see how it is loaded at run time see org.eclipse.ohf.ihe.xds.source/resources/conf/submitTest_log4j.xml and org.eclipse.ohf.ihe.xds.source/src_tests/SubmitTest.java, respectively. These can be obtained by downloading the plugin org.eclipse.ohf.ihe.xds.source from the Eclipse CVS technology repository.

Pending Integration and API changes

Below is a laundry list of anticipated changes to the XDS Consumer:

  1. Bugzilla bug 165105 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=165105) outlines a potential API change for the next phase of this XDS Consumer.
  2. In the next phase of the XDS Consumer, Stored Query support for the entire minimum query catalog specified in ITI-18 is anticipated to be enabled. We are considering expanding minimum query catalog support for the Registry Query transaction.
  3. We anticipate supporting the new web-service version of the Retrieve Transaction that is in development for the 2007-2008 season.


Glossary

No glossary terms at this time.

Back to the top