Page History
...
1.3 Document History
Version | Date | Responsible | Description |
0.7 | 11.1.2013 | Systematic | Initial version |
0.9 | 27.2.2013 | Systematic | Prepared for testing in the demo project. |
0.9a | 19.04.2013 | Systematic | Version for 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.2 | 05.05.2015 | Systematic | Code references has been updated due to name change from NPI to DDS |
1.3 | 26.01.2016 | Systematic | Added reference to Danish metadata profile. |
1.4 Definitions and References
Definition | Description |
DDS | Document Sharing Service |
IHE | Integrating the Healthcare Enterprise |
NSI | National eHealth Authority |
NSP | National Service Platform (within health care) |
SOR | Health Service Organization Register |
STS | Security Token Service |
XDS.b | Cross-Enterprise Document Sharing |
Reference | Description |
DGWS 1.0 | Den Gode Webservice 1.0 |
DGWS 1.0.1 | Den Gode Webservice 1.0.1 |
ITI TF-2b | IHE IT Infrastructure Technical Framework, Volume 2b (linked from http://ihe.net/Technical_Frameworks/#IT and accessible as http://ihe.net/uploadedFiles/Documents/ITI/IHE_ITI_TF_Vol2b.pdf) |
Metadata Profile | XDS Metadata for Document Sharing. Danish Profile. National eHealth Authority, Draft profile for Trial Use, version 0.90b January 30, 2015 http://svn.medcom.dk/svn/drafts/Standarder/IHE/DK_profil_metadata/Metadata-v090.docx |
DDS Registry Querying User’s Guide | DDS Registry Querying User’s Guide (SSE/11734/PHB/0037) |
DDS Registry Querying Interface | DDS Registry Querying Interface Description (SSE/11734/IFS/0016) |
DDS Registry Registering Interface | DDS Registry Registering Interface Description (SSE/11734/IFS/0015) |
2 Usage of DDS Registry
...
Versions exist for Java and .Net.
Component | Reference |
Seal.Java | |
Seal.NET |
An STS-signed ID card is obtained by using a company certificate as outlined below:
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
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’en and deserialize |
...
…
...
the // 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 calls 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.
Code Block |
---|
DGWSHeaderWrapper signedHeaders = getValidDGWSHeaders(flowId); |
3.2 Source System Creates SubmitObjectsRequest
...
3.2.1 Creation of SubmitObjectsRequest
Code Block |
---|
SubmitObjectsRequestHelper requestHelper = new SubmitObjectsRequestHelper(); |
...
SubmitObjectsRequest request = requestHelper.create(); |
3.2.2 Creation and addition of XDSDocumentEntry for on-demand document
// Unique identification of the document that must be replaced by an actual value
...
Code Block | ||||
---|---|---|---|---|
| ||||
// Unique identification of the document that must be replaced by an actual value String documentId = "urn:myorg:mydoc:doc:12345"; |
...
String repositoryUniqueId = "1.3.6.1.4.1.21367.2010.1.2.300.1"; |
...
...
ExtrinsicObjectType metadata = requestHelper.addOnDemandDocumentMetadataEntry( |
...
request
documentId,
repositoryUniqueId);
...
request
documentId,
repositoryUniqueId); |
Below it is registered which citizen (patient) the document concerns in addition to which institution/organization that created the document. In this case, the organization id 486651000016002 is provided as a SOR code and the patient is identified with patient id 1122334455 given as a social security number. Both values are coded/formatted as described in [Metadata Profile].
Code Block | ||||
---|---|---|---|---|
| ||||
String authorInstitution = "OUH Fælles Akut Amb (Svendborg)^^^^^& 1.2.208.176.1&ISO^^^^486651000016002"; |
...
String patientId = "1122334455^^^&2.16.840.1.113883.3.4208.100.2&ISO"; |
...
requestHelper.addDocumentMetadataAttributes(metadata, authorInstitution, patientId); |
...
// Add additional metadata-information in the same manner |
...
3.2.3 Creation and addition of XDSSubmissionSet
As part of the SubmitObjectsRequest, a description of the complete addition in the form of an XDSSubmissionSet must be provided. This is created and added with:
Code Block | ||
---|---|---|
| ||
RegistryPackageType submissionSet = requestHelper.addSubmissionSet(request); |
...
requestHelper.addSubmissionSetAttributes(submissionSet, patientId); |
...
// Add additional metadata-information in the same manner |
...
The added XDSDocumentEntry figure in the created XDSSubmissionSet, which is why an association between XDSSubmissionSet and XDSDocumentEntry must be added to the SubmitObjectsRequest. This is done with:
Code Block | ||
---|---|---|
| ||
requestHelper.addAssociation(request, metadata, submissionSet); |
...
3.2.4 Possible creation and addition of replacement-associations
If the (new) document metadata described above replaces pre-existing document metadata, then an association as shown below must be added to the SubmitObjectsRequest:
Code Block | ||||
---|---|---|---|---|
| ||||
oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory objFactory |
...
= new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
AssociationType1 association = objFactory.createAssociationType1(); |
...
association.setId(UUID.randomUUID().toString()); |
...
association.setAssociationType("urn:ihe:iti:2007:AssociationType:RPLC"); |
...
association.setObjectType( |
...
"urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Association"); |
...
association.setSourceObject(metadata.getId()); // Id for new metadata |
...
association.setTargetObject(toReplaceId); // Id for metadata to |
...
replace // Add replacement-association to the request |
...
request.getRegistryObjectList().getIdentifiable().add(objFactory.createAssociation(association)); |
Replacement-association must be created for each individual pre-existing document metadata- object to replace.
...
Below the ID card that has been obtained as described in section 3.1 is used to call DDS Registry’s operation RegisterOnDemandDocumentEntry. Those metadata, that are registered, are created as described in section 3.2.
Creation of service and port:
Code Block | ||
---|---|---|
| ||
URL wsdl = … // DDS Registry’s.WSDL is named |
...
DocumentRegistryService service = new DocumentRegistryService(wsdl, |
...
new QName("urn:ihe:iti:xds-b:2007", "DocumentRegistry_Service")); |
...
DocumentRegistryPortType port = service.getDocumentRegistryPortSoap(); |
Subsequently, the method on the port can be called:
Code Block | ||
---|---|---|
| ||
SubmitObjectsRequestHelper requestHelper = new SubmitObjectsRequestHelper(); |
...
SubmitObjectsRequest request = requestHelper.create(); |
...
… // request-structure is populated as described above |
...
String flowId = XMLUtil.createNonce(); // A unique flow ID that figures in the ID card |
...
DGWSHeaderWrapper signedHeaders = getValidDGWSHeaders(flowId); // see above
RegistryResponseType response =
port.documentRegistryRegisterOnDemandDocumentEntry(
request,
signedHeaders.getSecurityHeader(),
...
is created // using SEAL DGWSHeaderWrapper signedHeaders = getValidDGWSHeaders(flowId); // see above RegistryResponseType response = port.documentRegistryRegisterOnDemandDocumentEntry( request, signedHeaders.getSecurityHeader(), new Holder<Header>(signedHeaders.getMedcomHeader())); |
...
3.4 Helper Class for Creation of SubmitObjectsRequest
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package dk.nsi.ddsregistry.ws; |
...
import java.util.ArrayList; |
...
import java.util.List; |
...
import java.util.UUID; |
...
import oasis.names.tc.ebxml_regrep.xsd.lcm._3.ObjectFactory; |
...
import oasis.names.tc.ebxml_regrep.xsd.lcm._3.SubmitObjectsRequest; |
...
import oasis.names.tc.ebxml_regrep.xsd.rim._3.AssociationType1; |
...
import oasis.names.tc.ebxml_regrep.xsd.rim._3.ClassificationType; |
...
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.LocalizedStringType; |
...
import oasis.names.tc.ebxml_regrep.xsd.rim._3.RegistryPackageType; |
...
import oasis.names.tc.ebxml_regrep.xsd.rim._3.SlotType1; |
...
public class SubmitObjectsRequestHelper |
...
...
{ public SubmitObjectsRequest create() |
...
ObjectFactory objFactory = new ObjectFactory();
...
{ ObjectFactory objFactory = new ObjectFactory(); return objFactory.createSubmitObjectsRequest(); |
...
}
public ExtrinsicObjectType addOnDemandDocumentMetadataEntry(
SubmitObjectsRequest request,
String documentId,
String repositoryUniqueId) {
ExtrinsicObjectType onDemandDocumentMetadata =
createOnDemandDocumentMetadataEntry(
...
} public ExtrinsicObjectType addOnDemandDocumentMetadataEntry( SubmitObjectsRequest request, String documentId, String repositoryUniqueId) { ExtrinsicObjectType onDemandDocumentMetadata = createOnDemandDocumentMetadataEntry( UUID.randomUUID().toString(), |
...
repositoryUniqueId);
...
repositoryUniqueId); oasis.names.tc.ebxml_regrep.xsd. |
...
rim._3.ObjectFactory objFactory = new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
if (request.getRegistryObjectList() == null) |
...
{ request.setRegistryObjectList(objFactory.createRegistryObjectListType()); |
...
}
...
} request.getRegistryObjectList().getIdentifiable().add( |
...
objFactory.createExtrinsicObject(onDemandDocumentMetadata)); |
...
ExternalIdentifierType uniqueIdIdentifier =
...
ExternalIdentifierType uniqueIdIdentifier = createUniqueIdExternalIdentifierType(documentId, onDemandDocumentMetadata); |
...
onDemandDocumentMetadata.getExternalIdentifier().add(uniqueIdIdentifier); |
...
return onDemandDocumentMetadata;
}
public void addDocumentMetadataAttributes(ExtrinsicObjectType documentMetadataEntry,
String authorInstitution, String patientId) {
...
return onDemandDocumentMetadata; } public void addDocumentMetadataAttributes(ExtrinsicObjectType documentMetadataEntry, String authorInstitution, String patientId) { oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory objFactory |
...
= new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
ClassificationType classification = objFactory .createClassificationType(); |
...
classification.setId(UUID.randomUUID().toString()); |
...
classification.setClassificationScheme("urn:uuid:93606bcf-9494-43ec-9b4e-a7748d1a838d"); |
...
classification.setClassifiedObject(documentMetadataEntry.getId()); |
...
SlotType1 authorInstitutionSlot = objFactory.createSlotType1(); |
...
authorInstitutionSlot.setName("authorInstitution"); |
...
authorInstitutionSlot.setValueList(objFactory.createValueListType()); |
...
authorInstitutionSlot.getValueList().getValue().add(authorInstitution); |
...
classification.getSlot().add( |
...
authorInstitutionSlot); documentMetadataEntry.getClassification().add(classification); |
...
...
ExternalIdentifierType patientIdIdentifier = objFactory.createExternalIdentifierType(); |
...
patientIdIdentifier.setId(UUID.randomUUID().toString()); |
...
patientIdIdentifier.setIdentificationScheme("urn:uuid:58a6f841-87b3-4a3e-92fd-a8ffeff98427"); |
...
patientIdIdentifier.setRegistryObject(documentMetadataEntry.getId() |
...
); patientIdIdentifier.setValue(patientId); |
...
documentMetadataEntry.getExternalIdentifier().add(patientIdIdentifier); |
...
}
...
} public RegistryPackageType addSubmissionSet(SubmitObjectsRequest request) |
...
{ oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory |
...
objFactory = new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
RegistryPackageType submissionSetEntry = objFactory.createRegistryPackageType(); |
...
submissionSetEntry.setId(UUID.randomUUID().toString()); |
...
submissionSetEntry.setObjectType("urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:RegistryPackage"); |
...
request.getRegistryObjectList().getIdentifiable().add(objFactory.createRegistryPackage(submissionSetEntry)); |
...
...
// Classify registry package as XDSSubmissionSet (outside the RegistryPackage) |
...
ClassificationType classification = objFactory.createClassificationType(); |
...
classification.setClassificationNode("urn:uuid:a54d6aa5-d40d-43f9-88c5-b4633d873bdd"); // XDSSubmissionSet node |
...
value classification.setId(UUID.randomUUID().toString()); |
...
classification.setObjectType("urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Classification |
...
"); classification.setClassifiedObject(submissionSetEntry.getId()); |
...
request.getRegistryObjectList().getIdentifiable().add(objFactory.createClassification(classification)); |
...
return submissionSetEntry;
}
public void addSubmissionSetAttributes(RegistryPackageType submissionSetEntry, String patientId) {
...
return submissionSetEntry; } public void addSubmissionSetAttributes(RegistryPackageType submissionSetEntry, String patientId) { oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory objFactory |
...
= new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
ExternalIdentifierType patientIdIdentifier = objFactory.createExternalIdentifierType(); |
...
patientIdIdentifier.setId(UUID.randomUUID().toString()); |
...
patientIdIdentifier.setObjectType("urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:ExternalIdentifier"); |
...
patientIdIdentifier.setIdentificationScheme("urn:uuid:6b5aea1a-874d-4603-a4bc-96a0a7b38446"); |
...
patientIdIdentifier.setRegistryObject(submissionSetEntry.getId()); |
...
patientIdIdentifier.setValue(patientId); |
...
submissionSetEntry.getExternalIdentifier().add(patientIdIdentifier); |
...
}
public AssociationType1 addAssociation(SubmitObjectsRequest request,
ExtrinsicObjectType documentMetadataEntry,
RegistryPackageType submissionSetEntry) {
...
} public AssociationType1 addAssociation(SubmitObjectsRequest request, ExtrinsicObjectType documentMetadataEntry, RegistryPackageType submissionSetEntry) { oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory objFactory |
...
= new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
AssociationType1 association = objFactory.createAssociationType1(); |
...
association.setId(UUID.randomUUID().toString()); |
...
association.setAssociationType("urn:oasis:names:tc:ebxml-regrep:AssociationType:HasMember"); |
...
association.setObjectType("urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Association"); |
...
association.setSourceObject(submissionSetEntry.getId()); |
...
association.setTargetObject(documentMetadataEntry.getId( |
...
)); request.getRegistryObjectList().getIdentifiable().add(objFactory.createAssociation(association)); |
...
return association;
}
public List<AssociationType1> addAssociationsForReplacements(
SubmitObjectsRequest request,
ExtrinsicObjectType documentMetadataEntry,
List<String> extrinsicObjectIdsReplaced) {
List<AssociationType1> result = new ArrayList<AssociationType1>();
...
return association; } public List<AssociationType1> addAssociationsForReplacements( SubmitObjectsRequest request, ExtrinsicObjectType documentMetadataEntry, List<String> extrinsicObjectIdsReplaced) { List<AssociationType1> result = new ArrayList<AssociationType1>(); oasis.names.tc.ebxml_regrep.xsd.rim._3. |
...
ObjectFactory objFactory = new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
for (String extrinsicObjectId : extrinsicObjectIdsReplaced) |
...
{ AssociationType1 association = objFactory.createAssociationType1(); |
...
association.setId(UUID.randomUUID().toString( |
...
)); association.setAssociationType("urn:ihe:iti:2007:AssociationType:RPLC"); |
...
association.setObjectType("urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Association"); |
...
association.setSourceObject(documentMetadataEntry.getId()); |
...
association.setTargetObject(extrinsicObjectId); |
...
request.getRegistryObjectList().getIdentifiable().add(objFactory.createAssociation(association)); |
...
result.add(association); |
...
}
return result;
}
private ExternalIdentifierType createUniqueIdExternalIdentifierType(
String documentId, ExtrinsicObjectType metadataObjId) {
...
} return result; } private ExternalIdentifierType createUniqueIdExternalIdentifierType( String documentId, ExtrinsicObjectType metadataObjId) { oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory objFactory |
...
= new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory(); |
...
ExternalIdentifierType uniqueIdIdentifier = objFactory.createExternalIdentifierType();
...
ExternalIdentifierType uniqueIdIdentifier = objFactory.createExternalIdentifierType(); uniqueIdIdentifier.setId(UUID.randomUUID().toString()); |
...
uniqueIdIdentifier.setIdentificationScheme(XDSConstantsHelper.XDS_EXTERNAL_IDENTIFIER_UNIQUE_ID_IDENTIFICATION_SCHEME); |
...
uniqueIdIdentifier.setRegistryObject(metadataObjId.getId()); |
...
uniqueIdIdentifier.setName(objFactory.createInternationalStringType()); |
...
LocalizedStringType name = objFactory.createLocalizedStringType(); |
...
name.setValue("XDSDocumentEntry.uniqueId"); |
...
uniqueIdIdentifier.getName().getLocalizedString().add(name); |
...
uniqueIdIdentifier.setValue(documentId); |
...
return uniqueIdIdentifier;
}
private ExtrinsicObjectType createOnDemandDocumentMetadataEntry(
String documentId,
String repositoryUniqueId) {
return createDocumentMetadataEntry(
documentId,
...
return uniqueIdIdentifier; } private ExtrinsicObjectType createOnDemandDocumentMetadataEntry( String documentId, String repositoryUniqueId) { return createDocumentMetadataEntry( documentId, XDSConstantsHelper.XDS_ONDEMANDDOCUMENT_OBJ_TYPE, |
...
repositoryUniqueId); |
...
}
private ExtrinsicObjectType createStableDocumentMetadataEntry(
String documentId,
String repositoryUniqueId) {
return createDocumentMetadataEntry(
documentId,
...
} private ExtrinsicObjectType createStableDocumentMetadataEntry( String documentId, String repositoryUniqueId) { return createDocumentMetadataEntry( documentId, XDSConstantsHelper.XDS_STABLEDOCUMENT_OBJ_TYPE, |
...
repositoryUniqueId); |
...
}
private ExtrinsicObjectType createDocumentMetadataEntry(
String documentId,
String documentObjType,
String repositoryUniqueId) {
...
} private ExtrinsicObjectType createDocumentMetadataEntry( String documentId, String documentObjType, String repositoryUniqueId) { oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory objFactory |
...
= new oasis.names.tc.ebxml_regrep.xsd.rim._3.ObjectFactory( |
...
); ExtrinsicObjectType extrinsicObjectType = objFactory.createExtrinsicObjectType(); |
...
extrinsicObjectType.setId(documentId); |
...
extrinsicObjectTfype.setMimeType("text/xml"); |
...
extrinsicObjectType.setObjectType(documentObjType); |
...
SlotType1 repositoryUniqueIdSlot = objFactory.createSlotType1();
...
SlotType1 repositoryUniqueIdSlot = objFactory.createSlotType1(); repositoryUniqueIdSlot.setName("repositoryUniqueId"); |
...
repositoryUniqueIdSlot.setValueList(objFactory.createValueListType()); |
...
repositoryUniqueIdSlot.getValueList().getValue().add(repositoryUniqueId); |
...
extrinsicObjectType.getSlot().add(repositoryUniqueIdSlot ); |
...
return extrinsicObjectType;
}
}
...
return extrinsicObjectType;
}
} |
3.5 Client Generation from WSDL
...