1       Introduction

1.1          Purpose

This document describes the use of the web service that is provided by DDS Repository.

The document provides an introduction to the general web service interface and an example of how it can be used in a specific user system.

1.2          Reading Guide

The present document is directed towards developers and architects that will be using DDS Repository on NSP. It is assumed that the reader is familiar with Web services in addition to use of Den Gode Web Service (DGWS) and Security Token Service (STS).

1.3          Document History

Version

Date

Responsible

Description

0.1

14.01.2013

Systematic

Initial version

0.9

27.02.2013

Systematic

Prepared for testing in the demonstration project

0.9a

18.04.2013

Systematic

Section 2.1.1: homeCommunityId is read from home-attribute.

Release candidate 1

1.0

19.06.2013

Systematic

Quality assured

1.1

28.11.2014

Systematic

National Patient Index (NPI) replaced by Document Sharing Service (DDS)

1.4          Definitions and References

Definition

Description

DDS

Document Sharing Service

NSI

National eHealth Authority

NSP

National Service Platform (within health care)

SHAK

Hospital Department Classification

SOR

Health service organization register

STS

Security Token Service

Reference

Description

DGWS 1.0

Den Gode Webservice 1.0

DGWS 1.0.1

Den Gode Webservice 1.0.1

HSUID-header

Healthcare Service User Identification Header (SSE/11734/IFS/0018)

IHE2

IHE Current Technical Framework – Revision 8.0, Vol. 2a: Transactions (ITI1-ITI28)  http://www.ihe.net/Technical_Framework/upload/IHE_ITI_TF_Rev8-0_Vol2a_FT_2011-08-19.pdf

IHE3

IHE Current Technical Framework – Revision 8.0, Vol. 2b: Transactions (ITI29-ITI64)

http://www.ihe.net/Technical_Framework/upload/IHE_ITI_TF_Rev8-0_Vol2b_FT_2011-08-19.pdf 

DDS Registry Querying User’s Guide

DDS Registry Querying User’s Guide (SSE/11734/PHB/0037)

DDS Registry Querying

DDS Registry Querying Interface Description (SSE/11734/IFS/0016)

DDS Repository Interface Description

DDS Repository Interface Description (SSE/11734/IFS/0017)

2       Usage of DDS Repository

DDS Repository provides an operation for extraction of document on the basis of document metadata. This document metadata is returned from the document sharing service when queried through use of the web service interface described in [DDS Registry Querying], as described in [DDS Registry Querying User’s Guide].

Extractions are performed using the standard IHE Cross-Enterprise Document Sharing (XDS), which is based on ebXML Registry Services (RS) and ebXML Registry Information Model (RIM).

The extract operation is, in IHE XDS-terms, the RetrieveDocumentSet-request in IHE Technical Framework’s transaction 43, Retrieve Document Set.

With the goal to base the operation on Retrieve Document Set to the widest extent possible, changes of the IHE XDS-standard WSDL is minimized. Accordingly, the payload of the operation is unchanged.

As described in [DDS Repository Interface Description], the DDS Repository expects that a Retrieve Document Set call contains additional headers consisting of:

  • A Security-header
  • A Medcom-header
  • A Healthcare Service User Identification (HSUID) header

The first two originate from Den Gode Webservice described in [DGWS 1.0] and [DGWS 1.0.1], while the latter is described in [HSUID-header].

The headers are added as implicit headers, i.e. by being described in the WSDL’s bindings without being added to the Retrieve Document Set SOAP body-structure.

2.1          Preparation for Invocation of the DDS Repository

Before call to DDS Repository, it is the user system’s responsibility:

  • to ensure that the pre-requisites for use as described in [DDS Repository Interface Description] are met, e.g. that safeguarding is only done by health professionals that are authorized to do so.
  • to obtain an ID card of the required security level, issued by STS

Note that the company registration number of the user system must be recorded in DDS Repository’s whitelist. Registration in the whitelist must be contracted with the DDS Repository system owner.

2.1.1      Obtaining document metadata-information for extraction

Before extraction of documents, metadata must be obtained for the documents to extract. For this purpose DDS Registry is used, described in [DDS Registry Querying] and [DDS Registry Querying User’s Guide].

The search parameters are specified on lookup, including ID of the patient for which document metadata are required.

The response from DDS Registry, AdhocQueryResponse, can contain several document metadata-objects in AdhocQueryResponse/RegistryObjectList. For each document metadata-object where the associated document is requested extracted, it is retrieved from /AdhocQueryResponse/RegistryObjectList. The values that will be used in the extraction are retrieved from the document metadata-object ExtrinsicObject as follows:

  • DocumentRequest.documentUniqueId: the value of ExtrinsicObject/ExternalIdentifier, where the attribute identificationScheme is set to "urn:uuid:2e82c1f6-a085-4c72-9da3-8640a32e42ab".
  • DocumentRequest.repositoryUniqueId: the value of ExtrinsicObject/Slot, where the attribute name is set to "repositoryUniqueId".
  • DocumentRequest.homeCommunityId: the value of the attribute home on the ExtrinsicObject. The value is only set when the attribute is defined for the ExtrinsicObject.

For each document, that is desired extracted, a DocumentRequest structure is created which is added to the request. See additional details in section 3.3.

2.2          Invoking the DDS Repository

On call of the operations DocumentRepository_RetrieveDocumentSet on DDS Repository, the following must be completed:

  1. A RetrieveDocumentSetRequestType is created (i.e. payload of DocumentRepository_RetrieveDocumentSet) which must be populated
  2. Security-header is populated with ID card from STS
  3. Medcom-header is created, including:
    1. A unique message ID must be assigned
    2. The medcom header’s flowID element must be assigned a unique session ID
    3. HSUID-header must be created and assigned values that respectively describe the person making the call and the patient

3       Examples of Call to DDS Repository

This section provides an example on how this service can be called.

At present, no .NET-example code for call to DDS Registry exists, but WSDL’s are available from which a Web service consumer can be created using Visual Studio’s Web service wizard combined with Seal.NET (see below).

3.1     Source System Obtains DGWS ID Card from STS

Below is outlined how a Java-based source system can use Seal.Java to obtain a STS-signed ID card.

Seal is an open source framework that assists "Den Gode Webservice", including integration with a central identity service (IdP/STS), handling of federation certificates etc.

Versions exist for Java and .Net.


An STS-signed ID card is obtained by use of a company certificate as outlined below:

Properties properties = SignatureUtil.setupCryptoProviderForJVM();

// A new SOSITestFederation(properties), can be used here if the test-environment is used 

Federation federation = new SOSIFederation(properties);

File keystoreFile = … // read in the keystore file
String keystorePassword = … // obtain the password to the keystore file
CredentialVault vault = new FileBasedCredentialVault(
  properties,
  keystoreFile,
  keystorePassword);

SOSIFactory factory = new SOSIFactory(federation, vault, properties);

String flowId = … // A unique flow ID is entered in the ID card

SystemIDCard systemIDCard = factory.createNewSystemIDCard( …); // Various ID card content parameters are provided here

SecurityTokenRequest securityTokenRequest = factory.createNewSecurityTokenRequest();
securityTokenRequest.setIDCard(systemIDCard);

SecurityTokenResponse response = … // Send securityTokenRequest to the STS and deserialize                                    
								   // response with factory.deserializeSecurityTokenResponse
…
IDCard signedIDCard = response.getIDCard();

Accordingly, an ID card signed by STS is obtained. In the examples below, it is assumed that fresh requests to call of the respective Web service operations are made; that the signed ID card is copied to the fresh request; that additional DGWS parameters are set. Below this is described as a helper function, getValidDGWSHeaders that the user is expected to create.

DGWSHeaderWrapper signedHeaders = getValidDGWSHeaders(flowId);

3.2          User System Creates HSUID-header

// Create HSUID header
dk.nsi.hsuid._2013._01.hsuid_1_1.ObjectFactory objectFactory = new
  dk.nsi.hsuid._2013._01.hsuid_1_1.ObjectFactory();
HsuidHeader hsuidHeader = objectFactory.createHeader();


// Create assertion
AssertionType assertion = objectFactory.createAssertionType();
Date now = new Date();
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTimeInMillis(now.getTime());
assertion.setIssueInstant(calendar);
assertion.setIssuer("  …  "); // Replace with name of my organization
assertion.setVersion(BigDecimal.valueOf(2.0));
assertion.setId(AssertionTypeId.HSUID);
hsuidHeader.setAssertion(assertion);


// Create attribute statement
AttributeStatement attributeStatement = objectFactory.createAttributeStatement();
attributeStatement.setId(AttributeStatementId.HSUIDdata);


// Create attribute for acting user (Danish: bruger)
dk.nsi.hsuid._2013._01.hsuid_1_1.Attribute actingUserAttribute = objectFactory.createAttribute();
actingUserAttribute.setName("nsi:ActingUserCivilRegistrationNumber");
actingUserAttribute.setAttributeValue(" … "); // Insert social security number without                                                                                                            //  hyphen for user
attributeStatement.getAttribute().add(actingUserAttribute);


// Create attribute for acting user’s organization
dk.nsi.hsuid._2013._01.hsuid_1_1.Attribute orgUsingAttribute = objectFactory.createAttribute();
orgUsingAttribute.setName("nsi:OrgUsingID");
// Here, the acting user’s organization is set to 12345678 in the SOR classification.
// Use name format "nsi:ynumber" and "nsi:skskode", respectively, for organization stated
// in classifications for general practitioner and hospital departments (respectively)
orgUsingAttribute.setNameFormat(SubjectIdentifierType.valueOf("nsi:sor"));
orgUsingAttribute.setAttributeValue("12345678");
attributeStatement.getAttribute().add(orgUsingAttribute);

… // The additional attributes in the HSUID-header are set with similar code

assertion.setAttributeStatement(attributeStatement);

The created hsuidHeader is now ready for use.

3.3     The User System Creates RetrieveDocumentSetRequestType

For the request is created a RetrieveDocumentSetRequestType structure containing identification of one or more documents.

// For each desired document, values are retrieved as described above
String homeCommunityId = " … ";
String repositoryUniqueId = " … ";
String documentUniqueId = " … ";


ihe.iti.xds_b._2007.ObjectFactory objFactory = new ihe.iti.xds_b._2007.ObjectFactory();
RetrieveDocumentSetRequestType request = objFactory.createRetrieveDocumentSetRequestType();
DocumentRequest documentRequest = objFactory.createRetrieveDocumentSetRequestTypeDocumentRequest();
documentRequest.setHomeCommunityId(homeCommunityId);
documentRequest.setRepositoryUniqueId(repositoryUniqueId);
documentRequest.setDocumentUniqueId(documentUniqueId);
request.getDocumentRequest().add(documentRequest);


3.4          User System Calls RetrieveDocumentSet

Creation of service and port:

URL wsdl = new URL(" ... "); // Point to WSDL file
DocumentRepositoryService service =
  new DocumentRepositoryService(wsdl,
                                                   new QName("urn:ihe:iti:xds-b:2007",
                                                   "DocumentRepository_Service"));
DocumentRepositoryPortType port =
  service.getDocumentRepositoryPortSoap12(new MTOMFeature()); // Enable MTOM


Herefter kan metoden på porten kaldes:

HsuidHeader hsuidHeader = … // Created as described above
RetrieveDocumentSetRequestType request = … // Created as described above

String flowId = XMLUtil.createNonce(); // A unique flow ID that figures in the ID card is created using SEAL
DGWSHeaderWrapper signedHeaders = getValidDGWSHeaders(flowId); // see above

RetrieveDocumentSetResponseType response =
  port.documentRepositoryRetrieveDocumentSet(
                   request,
                    signedHeaders.getSecurityHeader(),
                    new Holder<Header>(signedHeaders.getMedcomHeader()),
                    hsuidHeader);

The document(s) can now be output as bytes in response, provided that the call was successful:

if ("urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success".equals(
          response.getRegistryResponse().getStatus()) {
  for (RetrieveDocumentSetResponseType.DocumentResponse documentEntry:
          response.getDocumentResponse()) {
    if ("text/xml".equals(documentEntry.getMimeType()) { // handle text/xml
      byte[] documentBytes = documentEntry.getDocument();
      … // handle the bytes
    }
    else if (…) { … } // handle other MIME types
  }
}

3.5          Client Generation from WSDL

A Web service client can be generated based on the DDS Repository WSDL-file, see [DDS Repository Interface Description]. It is not given that the Web service client’s proxy classes can be generated based on a deployed service (using ?wsdl-extension on the service), as such calls are not necessarily supported.

  • No labels