diff --git a/pom.xml b/pom.xml
index 963665b2..a0a71868 100644
--- a/pom.xml
+++ b/pom.xml
@@ -314,6 +314,13 @@
${camel-version}
test
+
+ org.openehealth.ipf.commons
+ ipf-commons-ihe-xds
+ ${ipf-version}
+ test-jar
+ test
+
diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/MagConstants.java b/src/main/java/ch/bfh/ti/i4mi/mag/MagConstants.java
index 82b94341..7eb5e2e4 100644
--- a/src/main/java/ch/bfh/ti/i4mi/mag/MagConstants.java
+++ b/src/main/java/ch/bfh/ti/i4mi/mag/MagConstants.java
@@ -34,4 +34,12 @@ public static class FhirCodingSystemIds {
public static final String MHD_DOCUMENT_ID_TYPE = "https://profiles.ihe.net/ITI/MHD/CodeSystem/DocumentIdentifierTypes";
}
+ @UtilityClass
+ public static class DeletionStatuses {
+ private static final String PREFIX = "urn:e-health-suisse:2019:deletionStatus:";
+ public static final String NOT_REQUESTED = PREFIX + "deletionNotRequested";
+ public static final String REQUESTED = PREFIX + "deletionRequested";
+ public static final String PROHIBITED = PREFIX + "deletionProhibited";
+ }
+
}
diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/IdRequestConverter.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/IdRequestConverter.java
index 51f60417..6ad9bc83 100644
--- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/IdRequestConverter.java
+++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/IdRequestConverter.java
@@ -16,47 +16,41 @@
package ch.bfh.ti.i4mi.mag.mhd.iti67;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
+import ch.bfh.ti.i4mi.mag.BaseRequestConverter;
import org.apache.camel.Header;
import org.openehealth.ipf.commons.ihe.xds.core.requests.QueryRegistry;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetDocumentsQuery;
import org.openehealth.ipf.commons.ihe.xds.core.requests.query.QueryReturnType;
-import ch.bfh.ti.i4mi.mag.BaseRequestConverter;
+import java.util.Collections;
/**
* ITI-67 to ITI-18 request converter
- *
- * @author oliver egger
*
+ * @author oliver egger
*/
public class IdRequestConverter extends BaseRequestConverter {
/**
* convert ITI-67 request to ITI-18 request
- *
- * @param searchParameter
- * @return
*/
public QueryRegistry idToGetDocumentsQuery(@Header(value = "FhirHttpUri") String fhirHttpUri) {
if (fhirHttpUri != null && fhirHttpUri.contains("/")) {
boolean getLeafClass = true;
- String uuid = fhirHttpUri.substring(fhirHttpUri.lastIndexOf("/") + 1);
- if (!uuid.startsWith("urn:uuid:")) {
- uuid = "urn:uuid:"+uuid;
- }
-
+
GetDocumentsQuery query = new GetDocumentsQuery();
- final QueryRegistry queryRegistry = new QueryRegistry(query);
- query.setUuids(Collections.singletonList(uuid));
+ final QueryRegistry queryRegistry = new QueryRegistry(query);
+ query.setLogicalUuid(Collections.singletonList(extractId(fhirHttpUri)));
queryRegistry.setReturnType((getLeafClass) ? QueryReturnType.LEAF_CLASS : QueryReturnType.OBJECT_REF);
return queryRegistry;
}
return null;
+ }
+ public static String extractId(String fhirHttpUri) {
+ String uuid = fhirHttpUri.substring(fhirHttpUri.lastIndexOf("/") + 1);
+ return uuid.startsWith("urn:uuid:") ? uuid : "urn:uuid:" + uuid;
}
+
}
diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67FromIti57ResponseConverter.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67FromIti57ResponseConverter.java
index 31e463ab..1d2f5f1f 100644
--- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67FromIti57ResponseConverter.java
+++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67FromIti57ResponseConverter.java
@@ -22,13 +22,17 @@
import org.openehealth.ipf.commons.ihe.fhir.translation.ToFhirTranslator;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Response;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Status;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
import java.util.Map;
+@Component
public class Iti67FromIti57ResponseConverter extends BaseResponseConverter implements ToFhirTranslator {
private Config config;
+ @Autowired
public Iti67FromIti57ResponseConverter(final Config config) {
this.config = config;
}
diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RequestUpdateConverter.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RequestUpdateConverter.java
index b5223acd..0c16f34a 100644
--- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RequestUpdateConverter.java
+++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RequestUpdateConverter.java
@@ -1,4 +1,3 @@
-package ch.bfh.ti.i4mi.mag.mhd.iti67;
/*
* Copyright 2020 the original author or authors.
*
@@ -14,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package ch.bfh.ti.i4mi.mag.mhd.iti67;
import java.time.ZonedDateTime;
import java.util.HashMap;
@@ -21,7 +21,6 @@
import ch.bfh.ti.i4mi.mag.Config;
import ch.bfh.ti.i4mi.mag.MagConstants;
-import org.apache.camel.Body;
import org.hl7.fhir.r4.model.*;
import org.openehealth.ipf.commons.core.URN;
import org.openehealth.ipf.commons.ihe.xds.core.metadata.*;
@@ -44,112 +43,124 @@
@Component
public class Iti67RequestUpdateConverter extends Iti65RequestConverter {
- private final Config config;
-
- @Autowired
- public Iti67RequestUpdateConverter(Config config) {
- this.config = config;
- }
-
- /**
- * ITI-67 Response to ITI-57 request converter
- *
- * @param searchParameter
- * @return
- */
- public SubmitObjectsRequest convertDocumentReferenceToDocumentEntry(@Body DocumentReference documentReference) {
-
- SubmissionSet submissionSet = new SubmissionSet();
- submissionSet.setSubmissionTime(new Timestamp(ZonedDateTime.now(), Timestamp.Precision.SECOND));
-
- Extension source =
- getExtensionByUrl(documentReference, "https://profiles.ihe.net/ITI/MHD/StructureDefinition/ihe-sourceId");
- if (source != null && source.getValue() instanceof Identifier) {
- submissionSet.setSourceId(noPrefix(((Identifier) source.getValue()).getValue()));
- } else {
- submissionSet.setSourceId(noPrefix(config.getDocumentSourceId()));
- }
+ private final Config config;
- Extension designationType =
- getExtensionByUrl(documentReference, "https://profiles.ihe.net/ITI/MHD/StructureDefinition/ihe-designationType");
- if (designationType != null && designationType.getValue() instanceof CodeableConcept) {
- submissionSet.setContentTypeCode(transformCodeableConcept((CodeableConcept) designationType.getValue()));
- } else {
- submissionSet.setContentTypeCode(new Code("71388002", new LocalizedString("Procedure"), "2.16.840.1.113883.6.96"));
+ @Autowired
+ public Iti67RequestUpdateConverter(Config config) {
+ this.config = config;
}
- Extension authorRoleExt =
- getExtensionByUrl(documentReference, MagConstants.FhirExtensionUrls.CH_AUTHOR_ROLE);
- if (authorRoleExt != null) {
- Identifiable identifiable = null;
- if (authorRoleExt != null) {
- Coding coding = authorRoleExt.castToCoding(authorRoleExt.getValue());
- if (coding != null) {
- identifiable = new Identifiable(coding.getCode(), new AssigningAuthority(noPrefix(coding.getSystem())));
- }
- }
- submissionSet.setAuthor(transformAuthor(null, null, identifiable));
+ /**
+ * ITI-67 Response to ITI-57 request converter
+ */
+ public SubmitObjectsRequest createMetadataUpdateRequest(DocumentReference documentReference) {
+ DocumentEntry documentEntry = translateDocumentMetadata(documentReference);
+ SubmissionSet submissionSet = createSubmissionSet();
+ enrichSubmissionSet(submissionSet, documentReference);
+ return createMetadataUpdateRequest(submissionSet, documentEntry);
}
- RegisterDocumentSetBuilder builder = new RegisterDocumentSetBuilder(true, submissionSet); // TODO should be
- // true?
- DocumentEntry entry = new DocumentEntry();
- entry.setExtraMetadata(new HashMap<>());
- processDocumentReference(documentReference, entry);
-
- Extension repositoryUniqueIdExtension = documentReference
- .getExtensionByUrl(MagConstants.FhirExtensionUrls.REPOSITORY_UNIQUE_ID);
- if (repositoryUniqueIdExtension != null && repositoryUniqueIdExtension.getValue() instanceof Identifier) {
- Identifier identifier = (Identifier) repositoryUniqueIdExtension.getValue();
- entry.setRepositoryUniqueId(noPrefix(identifier.getValue()));
+ public SubmitObjectsRequest createMetadataUpdateRequest(SubmissionSet submissionSet, DocumentEntry documentEntry) {
+ submissionSet.setPatientId(documentEntry.getPatientId());
+ int currentVersion = Integer.parseInt(documentEntry.getVersion().getVersionName());
+ RegisterDocumentSetBuilder builder = new RegisterDocumentSetBuilder(true, submissionSet)
+ .withDocument(documentEntry)
+ .withAssociation(createHasMemberAssociationWithOriginalPreviousLabel(currentVersion, submissionSet, documentEntry));
+ documentEntry.getVersion().setVersionName(Integer.toString(currentVersion + 1));
+
+ // Submission contains a DocumentEntry object.
+ // The logicalID attribute is present in the DocumentEntry object and has a UUID
+ // formatted value.
+ // The SubmissionSet to DocumentEntry HasMember Association has a Slot with name
+ // PreviousVersion. This Slot has a single value, the version number of the
+ // previous version, the one being replaced.
+
+ return EbXML30Converters.convert(builder.build());
}
- Extension documentAvailabilityExtension = documentReference
- .getExtensionByUrl(MagConstants.FhirExtensionUrls.DOCUMENT_AVAILABILITY);
- if (documentAvailabilityExtension != null && documentAvailabilityExtension.getValue() instanceof Coding) {
- Coding coding = (Coding) documentAvailabilityExtension.getValue();
- if (MagConstants.FhirCodingSystemIds.RFC_3986.equals(coding.getSystem()) && coding.getCode().startsWith("urn:ihe:iti:2010:DocumentAvailability:")) {
- entry.setDocumentAvailability(DocumentAvailability.valueOfOpcode(coding.getCode().substring(38)));
- }
- }
+ private void enrichSubmissionSet(SubmissionSet submissionSet, DocumentReference documentReference) {
+ Extension source =
+ getExtensionByUrl(documentReference, "https://profiles.ihe.net/ITI/MHD/StructureDefinition/ihe-sourceId");
+ if (source != null && source.getValue() instanceof Identifier) {
+ submissionSet.setSourceId(noPrefix(((Identifier) source.getValue()).getValue()));
+ } else {
+ submissionSet.setSourceId(noPrefix(config.getDocumentSourceId()));
+ }
+
+ Extension designationType =
+ getExtensionByUrl(documentReference, "https://profiles.ihe.net/ITI/MHD/StructureDefinition/ihe-designationType");
+ if (designationType != null && designationType.getValue() instanceof CodeableConcept) {
+ submissionSet.setContentTypeCode(transformCodeableConcept((CodeableConcept) designationType.getValue()));
+ } else {
+ submissionSet.setContentTypeCode(new Code("71388002", new LocalizedString("Procedure"), "2.16.840.1.113883.6.96"));
+ }
- submissionSet.setPatientId(entry.getPatientId());
- submissionSet.assignEntryUuid();
- builder.withDocument(entry);
-
- int version;
- Extension versionExtension = documentReference.getExtensionByUrl(MagConstants.FhirExtensionUrls.DOCUMENT_ENTRY_VERSION);
- if ((versionExtension != null) && (versionExtension.getValue() instanceof PositiveIntType)) {
- PositiveIntType versionElement = (PositiveIntType) versionExtension.getValue();
- version = versionElement.getValue();
- } else {
- version = 1;
+ Extension authorRoleExt =
+ getExtensionByUrl(documentReference, MagConstants.FhirExtensionUrls.CH_AUTHOR_ROLE);
+ if (authorRoleExt != null) {
+ Coding coding = authorRoleExt.castToCoding(authorRoleExt.getValue());
+ if (coding != null) {
+ Identifiable identifiable = new Identifiable(coding.getCode(), new AssigningAuthority(noPrefix(coding.getSystem())));
+ submissionSet.setAuthor(transformAuthor(null, null, identifiable));
+ }
+ }
}
- builder.withAssociation(createHasMemberAssociationWithOriginalPreviousLabel(version, submissionSet, entry));
+ private DocumentEntry translateDocumentMetadata(DocumentReference documentReference) {
+ DocumentEntry entry = new DocumentEntry();
+ entry.setExtraMetadata(new HashMap<>());
+ processDocumentReference(documentReference, entry);
- // Submission contains a DocumentEntry object.
- // The logicalID attribute is present in the DocumentEntry object and has a UUID
- // formatted value.
- // The SubmissionSet to DocumentEntry HasMember Association has a Slot with name
- // PreviousVersion. This Slot has a single value, the version number of the
- // previous version, the one being replaced.
+ Extension repositoryUniqueIdExtension = documentReference
+ .getExtensionByUrl(MagConstants.FhirExtensionUrls.REPOSITORY_UNIQUE_ID);
+ if (repositoryUniqueIdExtension != null && repositoryUniqueIdExtension.getValue() instanceof Identifier) {
+ Identifier identifier = (Identifier) repositoryUniqueIdExtension.getValue();
+ entry.setRepositoryUniqueId(noPrefix(identifier.getValue()));
+ }
- return EbXML30Converters.convert(builder.build());
- }
+ Extension documentAvailabilityExtension = documentReference
+ .getExtensionByUrl(MagConstants.FhirExtensionUrls.DOCUMENT_AVAILABILITY);
+ if (documentAvailabilityExtension != null && documentAvailabilityExtension.getValue() instanceof Coding) {
+ Coding coding = (Coding) documentAvailabilityExtension.getValue();
+ if (MagConstants.FhirCodingSystemIds.RFC_3986.equals(coding.getSystem()) && coding.getCode().startsWith("urn:ihe:iti:2010:DocumentAvailability:")) {
+ entry.setDocumentAvailability(DocumentAvailability.valueOfOpcode(coding.getCode().substring(38)));
+ }
+ }
- private Association createHasMemberAssociationWithOriginalPreviousLabel(int version, SubmissionSet submissionSet, DocumentEntry entry) {
- var assoc = createHasMemberAssociation(entry.getEntryUuid(), submissionSet);
- assoc.setLabel(AssociationLabel.ORIGINAL);
- assoc.setPreviousVersion(Integer.toString(version));
- assoc.setAssociationPropagation(true);
- return assoc;
- }
+ int version;
+ Extension versionExtension = documentReference.getExtensionByUrl(MagConstants.FhirExtensionUrls.DOCUMENT_ENTRY_VERSION);
+ if ((versionExtension != null) && (versionExtension.getValue() instanceof PositiveIntType)) {
+ PositiveIntType versionElement = (PositiveIntType) versionExtension.getValue();
+ version = versionElement.getValue();
+ } else {
+ version = 1;
+ }
+ entry.setVersion(new Version(Integer.toString(version)));
+ return entry;
+ }
- private Association createHasMemberAssociation(String entryUuid, SubmissionSet submissionSet) {
- return new Association(AssociationType.HAS_MEMBER, new URN(UUID.randomUUID()).toString(),
- submissionSet.getEntryUuid(), entryUuid);
+ private Association createHasMemberAssociationWithOriginalPreviousLabel(int version, SubmissionSet submissionSet, DocumentEntry entry) {
+ var assoc = createHasMemberAssociation(entry.getEntryUuid(), submissionSet);
+ assoc.setLabel(AssociationLabel.ORIGINAL);
+ assoc.setPreviousVersion(Integer.toString(version));
+ assoc.setAssociationPropagation(true);
+ return assoc;
+ }
- }
+ private Association createHasMemberAssociation(String entryUuid, SubmissionSet submissionSet) {
+ return new Association(AssociationType.HAS_MEMBER, new URN(UUID.randomUUID()).toString(),
+ submissionSet.getEntryUuid(), entryUuid);
+
+ }
+
+ public SubmissionSet createSubmissionSet() {
+ SubmissionSet submissionSet = new SubmissionSet();
+ submissionSet.setSubmissionTime(new Timestamp(ZonedDateTime.now(), Timestamp.Precision.SECOND));
+ submissionSet.setContentTypeCode(new Code("71388002", new LocalizedString("Procedure"), "2.16.840.1.113883.6.96"));
+ submissionSet.setSourceId(noPrefix(config.getDocumentSourceId()));
+ submissionSet.assignEntryUuid();
+ submissionSet.assignUniqueId();
+ return submissionSet;
+ }
}
diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67ResponseConverter.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67ResponseConverter.java
index 143df2f9..70a6d996 100644
--- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67ResponseConverter.java
+++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67ResponseConverter.java
@@ -34,6 +34,8 @@
import org.openehealth.ipf.commons.ihe.xds.core.responses.QueryResponse;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Status;
import org.owasp.esapi.codecs.Hex;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
import java.util.*;
@@ -42,8 +44,10 @@
*
* @author alexander kreutz
*/
+@Component
public class Iti67ResponseConverter extends BaseQueryResponseConverter {
+ @Autowired
public Iti67ResponseConverter(final Config config) {
super(config);
}
diff --git a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java
index 2fe5305e..a8285e2b 100644
--- a/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java
+++ b/src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/Iti67RouteBuilder.java
@@ -18,12 +18,17 @@
import static org.openehealth.ipf.platform.camel.ihe.fhir.core.FhirCamelTranslators.translateToFhir;
+import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
+import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
+import ch.bfh.ti.i4mi.mag.MagConstants;
import org.apache.camel.builder.PredicateBuilder;
import org.apache.camel.builder.RouteBuilder;
import org.hl7.fhir.r4.model.DocumentReference;
import org.openehealth.ipf.commons.ihe.fhir.Constants;
+import org.openehealth.ipf.commons.ihe.xds.core.metadata.*;
import org.openehealth.ipf.commons.ihe.xds.core.responses.QueryResponse;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Response;
+import org.openehealth.ipf.commons.ihe.xds.core.responses.Status;
import org.openehealth.ipf.commons.ihe.xds.core.stub.ebrs30.lcm.SubmitObjectsRequest;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
@@ -33,6 +38,9 @@
import ch.bfh.ti.i4mi.mag.xua.AuthTokenConverter;
import lombok.extern.slf4j.Slf4j;
+import java.util.HashMap;
+import java.util.List;
+
/**
* IHE MHD: Find Document References [ITI-67] for Document Responder
* https://oehf.github.io/ipf-docs/docs/ihe/iti67/
@@ -43,40 +51,39 @@
class Iti67RouteBuilder extends RouteBuilder {
private final Config config;
+ private final Iti67ResponseConverter iti67ResponseConverter;
private final Iti67RequestUpdateConverter iti67RequestUpdateConverter;
+ private final Iti67FromIti57ResponseConverter iti67FromIti57ResponseConverter;
- public Iti67RouteBuilder(final Config config, Iti67RequestUpdateConverter iti67RequestUpdateConverter) {
+ public Iti67RouteBuilder(final Config config,
+ Iti67ResponseConverter iti67ResponseConverter,
+ Iti67RequestUpdateConverter iti67RequestUpdateConverter,
+ Iti67FromIti57ResponseConverter iti67FromIti57ResponseConverter)
+ {
super();
log.debug("Iti67RouteBuilder initialized");
this.config = config;
+ this.iti67ResponseConverter = iti67ResponseConverter;
this.iti67RequestUpdateConverter = iti67RequestUpdateConverter;
+ this.iti67FromIti57ResponseConverter = iti67FromIti57ResponseConverter;
}
- @Override
- public void configure() throws Exception {
- log.debug("Iti67RouteBuilder configure");
- final String endpoint = String.format("xds-iti18://%s" +
- "?secure=%s", this.config.getIti18HostUrl(), this.config.isHttps() ? "true" : "false")
- +
+ private String createEndpointUri(String schema, String partialUrl) {
+ return schema + "://" + partialUrl +
+ "?secure=" + config.isHttps() +
"&audit=true" +
"&auditContext=#myAuditContext" +
- // "&sslContextParameters=#pixContext" +
- "&inInterceptors=#soapResponseLogger" +
+ "&inInterceptors=#soapResponseLogger" +
"&inFaultInterceptors=#soapResponseLogger"+
- "&outInterceptors=#soapRequestLogger" +
+ "&outInterceptors=#soapRequestLogger" +
"&outFaultInterceptors=#soapRequestLogger";
- final String endpoint57 = String.format("xds-iti57://%s" +
- "?secure=%s", this.config.getIti57HostUrl(), this.config.isHttps() ? "true" : "false")
- +
- "&audit=true" +
- "&auditContext=#myAuditContext" +
- // "&sslContextParameters=#pixContext" +
- "&inInterceptors=#soapResponseLogger" +
- "&inFaultInterceptors=#soapResponseLogger"+
- "&outInterceptors=#soapRequestLogger" +
- "&outFaultInterceptors=#soapRequestLogger";
-
- // xds-iti57:serviceName[?parameters]
+ }
+
+ @Override
+ public void configure() throws Exception {
+ log.debug("Iti67RouteBuilder configure");
+ final String metadataQueryEndpoint = createEndpointUri("xds-iti18", this.config.getIti18HostUrl());
+ final String metadataUpdateEndpoint = createEndpointUri("xds-iti57", this.config.getIti57HostUrl());
from("mhd-iti67-v401:translation?audit=true&auditContext=#myAuditContext").routeId("mdh-documentreference-adapter")
// pass back errors to the endpoint
@@ -86,22 +93,65 @@ public void configure() throws Exception {
.when(header(Constants.FHIR_REQUEST_PARAMETERS).isNotNull())
.bean(Utils.class,"searchParameterToBody")
.bean(Iti67RequestConverter.class)
- .to(endpoint)
- .process(translateToFhir(new Iti67ResponseConverter(config) , QueryResponse.class))
+ .to(metadataQueryEndpoint)
+ .process(translateToFhir(iti67ResponseConverter, QueryResponse.class))
.endChoice()
.when(PredicateBuilder.and(header("FhirHttpUri").isNotNull(),header("FhirHttpMethod").isEqualTo("GET")))
.bean(IdRequestConverter.class)
- .to(endpoint)
- .process(translateToFhir(new Iti67ResponseConverter(config) , QueryResponse.class))
+ .to(metadataQueryEndpoint)
+ .process(translateToFhir(iti67ResponseConverter, QueryResponse.class))
.endChoice()
.when(PredicateBuilder.and(header("FhirHttpUri").isNotNull(),header("FhirHttpMethod").isEqualTo("PUT")))
.process(exchange -> {
DocumentReference documentReference = exchange.getIn().getMandatoryBody(DocumentReference.class);
- SubmitObjectsRequest submitObjectsRequest = iti67RequestUpdateConverter.convertDocumentReferenceToDocumentEntry(documentReference);
+ SubmitObjectsRequest submitObjectsRequest = iti67RequestUpdateConverter.createMetadataUpdateRequest(documentReference);
exchange.getMessage().setBody(submitObjectsRequest);
})
- .to(endpoint57)
- .process(translateToFhir(new Iti67FromIti57ResponseConverter(config), Response.class))
+ .to(metadataUpdateEndpoint)
+ .process(translateToFhir(iti67FromIti57ResponseConverter, Response.class))
+ .endChoice()
+ .when(PredicateBuilder.and(header("FhirHttpUri").isNotNull(),header("FhirHttpMethod").isEqualTo("DELETE")))
+ .process(exchange -> {
+ exchange.setProperty("DOCUMENT_ENTRY_LOGICAL_ID", IdRequestConverter.extractId(exchange.getIn().getHeader("FhirHttpUri", String.class)));
+ })
+ .bean(IdRequestConverter.class)
+ .to(metadataQueryEndpoint)
+ .process(exchange -> {
+ QueryResponse queryResponse = exchange.getIn().getMandatoryBody(QueryResponse.class);
+ if (queryResponse.getStatus() != Status.SUCCESS) {
+ iti67FromIti57ResponseConverter.processError(queryResponse);
+ }
+ if (queryResponse.getDocumentEntries().isEmpty()) {
+ throw new ResourceNotFoundException(exchange.getProperty("DOCUMENT_ENTRY_LOGICAL_ID", String.class));
+ }
+ if (queryResponse.getDocumentEntries().size() > 1) {
+ throw new InternalErrorException("Expected at most one Document Entry, got " + queryResponse.getDocumentEntries().size());
+ }
+
+ DocumentEntry documentEntry = queryResponse.getDocumentEntries().get(0);
+ if (documentEntry.getExtraMetadata() == null) {
+ documentEntry.setExtraMetadata(new HashMap<>());
+ }
+ documentEntry.getExtraMetadata().put(MagConstants.XdsExtraMetadataSlotNames.CH_DELETION_STATUS, List.of(MagConstants.DeletionStatuses.REQUESTED));
+ if (documentEntry.getLogicalUuid() == null) {
+ documentEntry.setLogicalUuid(documentEntry.getEntryUuid());
+ }
+ documentEntry.assignEntryUuid();
+ if (documentEntry.getVersion() == null) {
+ documentEntry.setVersion(new Version("1"));
+ }
+
+ SubmissionSet submissionSet = iti67RequestUpdateConverter.createSubmissionSet();
+ SubmitObjectsRequest updateRequest = iti67RequestUpdateConverter.createMetadataUpdateRequest(submissionSet, documentEntry);
+ exchange.getMessage().setBody(updateRequest);
+ log.info("Prepared document metadata update request");
+ })
+ .choice()
+ .when(exchange -> exchange.getIn().getBody() instanceof SubmitObjectsRequest)
+ .to(metadataUpdateEndpoint)
+ .process(translateToFhir(new Iti67FromIti57ResponseConverter(config), Response.class))
+ .endChoice()
+ .end()
.endChoice()
.end();
}
diff --git a/src/main/java/org/openehealth/ipf/commons/ihe/fhir/iti67_v401/Iti67ResourceProvider.java b/src/main/java/org/openehealth/ipf/commons/ihe/fhir/iti67_v401/Iti67ResourceProvider.java
index eda0a995..a4309fb1 100644
--- a/src/main/java/org/openehealth/ipf/commons/ihe/fhir/iti67_v401/Iti67ResourceProvider.java
+++ b/src/main/java/org/openehealth/ipf/commons/ihe/fhir/iti67_v401/Iti67ResourceProvider.java
@@ -22,6 +22,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import ca.uhn.fhir.rest.annotation.*;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.r4.model.DocumentReference;
import org.hl7.fhir.r4.model.IdType;
@@ -32,16 +33,6 @@
import org.openehealth.ipf.commons.ihe.fhir.iti67.Iti67SearchParameters;
import ca.uhn.fhir.model.api.Include;
-import ca.uhn.fhir.rest.annotation.ConditionalUrlParam;
-import ca.uhn.fhir.rest.annotation.IdParam;
-import ca.uhn.fhir.rest.annotation.IncludeParam;
-import ca.uhn.fhir.rest.annotation.OptionalParam;
-import ca.uhn.fhir.rest.annotation.Read;
-import ca.uhn.fhir.rest.annotation.RequiredParam;
-import ca.uhn.fhir.rest.annotation.ResourceParam;
-import ca.uhn.fhir.rest.annotation.Search;
-import ca.uhn.fhir.rest.annotation.Sort;
-import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
@@ -206,7 +197,16 @@ public MethodOutcome update(
// Run down the route
return requestAction(theReference, null, httpServletRequest, httpServletResponse, requestDetails);
}
-
+ @SuppressWarnings("unused")
+ @Delete(type = DocumentReference.class)
+ public MethodOutcome delete(
+ @IdParam IdType id,
+ RequestDetails requestDetails,
+ HttpServletRequest httpServletRequest,
+ HttpServletResponse httpServletResponse)
+ {
+ return requestAction(id, null, httpServletRequest, httpServletResponse, requestDetails);
+ }
}
diff --git a/src/test/java/ch/bfh/ti/i4mi/mag/mhd/Iti57RequestTranslatorTest.java b/src/test/java/ch/bfh/ti/i4mi/mag/mhd/Iti57RequestTranslatorTest.java
index 5c6cc690..1f01e445 100644
--- a/src/test/java/ch/bfh/ti/i4mi/mag/mhd/Iti57RequestTranslatorTest.java
+++ b/src/test/java/ch/bfh/ti/i4mi/mag/mhd/Iti57RequestTranslatorTest.java
@@ -34,7 +34,7 @@ public static void beforeAll() {
@Test
public void test1() {
DocumentReference documentReference = (DocumentReference) FhirContext.forR4().newJsonParser().parseResource(Iti57RequestTranslatorTest.class.getClassLoader().getResourceAsStream("update-request-1.json"));
- SubmitObjectsRequest ebXml = iti67RequestUpdateConverter.convertDocumentReferenceToDocumentEntry(documentReference);
+ SubmitObjectsRequest ebXml = iti67RequestUpdateConverter.createMetadataUpdateRequest(documentReference);
String ebXmlString = XdsRenderingUtils.renderEbxml(ebXml);
Assertions.assertTrue(ebXmlString.contains(MagConstants.XdsExtraMetadataSlotNames.CH_DELETION_STATUS));
diff --git a/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTest.java b/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTest.java
index c6c5e3fd..082d3dee 100644
--- a/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTest.java
+++ b/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTest.java
@@ -8,10 +8,11 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.io.support.ClassicRequestBuilder;
import org.hl7.fhir.r4.model.DocumentReference;
-
-import static org.junit.jupiter.api.Assertions.*;
-
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,7 +21,13 @@
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
import java.util.Locale;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Dmytro Rud
@@ -75,7 +82,20 @@ public void testMetadataUpdate() {
errorCatched = true;
}
assertTrue(errorCatched);
+ }
+ @Test
+ public void testDocumentDeletion() throws IOException {
+ try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
+ ClassicHttpRequest httpRequest = ClassicRequestBuilder.delete("http://localhost:" + serverPort + "/fhir/DocumentReference/" + UUID.randomUUID())
+ .setCharset(StandardCharsets.UTF_8)
+ .build();
+ String response = httpClient.execute(httpRequest, httpResponse -> {
+ assertEquals(200, httpResponse.getCode());
+ return httpResponse.toString();
+ });
+ log.info(response);
+ }
}
}
diff --git a/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTestRouteBuilder.java b/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTestRouteBuilder.java
index 6c71b0ed..d9e0e818 100644
--- a/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTestRouteBuilder.java
+++ b/src/test/java/ch/bfh/ti/i4mi/mag/mhd/MhdTestRouteBuilder.java
@@ -1,12 +1,26 @@
package ch.bfh.ti.i4mi.mag.mhd;
+import ch.bfh.ti.i4mi.mag.MagConstants;
import org.apache.camel.builder.RouteBuilder;
+import org.openehealth.ipf.commons.ihe.xds.core.SampleData;
+import org.openehealth.ipf.commons.ihe.xds.core.metadata.AssigningAuthority;
+import org.openehealth.ipf.commons.ihe.xds.core.metadata.DocumentEntry;
+import org.openehealth.ipf.commons.ihe.xds.core.metadata.Identifiable;
+import org.openehealth.ipf.commons.ihe.xds.core.metadata.Version;
+import org.openehealth.ipf.commons.ihe.xds.core.requests.QueryRegistry;
import org.openehealth.ipf.commons.ihe.xds.core.requests.RegisterDocumentSet;
+import org.openehealth.ipf.commons.ihe.xds.core.requests.query.GetDocumentsQuery;
+import org.openehealth.ipf.commons.ihe.xds.core.responses.QueryResponse;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Response;
import org.openehealth.ipf.commons.ihe.xds.core.responses.Status;
import org.openehealth.ipf.platform.camel.ihe.xds.XdsCamelValidators;
import org.springframework.stereotype.Component;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+
/**
* @author Dmytro Rud
*/
@@ -16,14 +30,60 @@ public class MhdTestRouteBuilder extends RouteBuilder {
@Override
public void configure() throws Exception {
+ from("xds-iti18://iti18Endpoint")
+ .process(XdsCamelValidators.iti18RequestValidator())
+ .process(exchange -> {
+ log.info("Received ITI-18 request");
+ QueryRegistry iti18Request = exchange.getIn().getMandatoryBody(QueryRegistry.class);
+ assertInstanceOf(GetDocumentsQuery.class, iti18Request.getQuery());
+
+ DocumentEntry documentEntry = SampleData.createDocumentEntry(new Identifiable("testIti18-1", new AssigningAuthority("1.2.3.4.5")));
+ documentEntry.assignEntryUuid();
+ documentEntry.setVersion(new Version("42"));
+
+ QueryResponse iti18Response = new QueryResponse(Status.SUCCESS);
+ iti18Response.getDocumentEntries().add(documentEntry);
+ exchange.getMessage().setBody(iti18Response);
+ })
+ .process(XdsCamelValidators.iti18ResponseValidator())
+ ;
+
from("xds-iti57://iti57Endpoint")
.process(XdsCamelValidators.iti57RequestValidator())
+ .to("direct:handle-metadata-update")
+ .process(XdsCamelValidators.iti57ResponseValidator())
+ ;
+
+ from("rmu-iti92://iti92Endpoint")
+ .process(XdsCamelValidators.iti92RequestValidator())
+ .to("direct:handle-metadata-update")
+ .process(XdsCamelValidators.iti92ResponseValidator())
+ ;
+
+ from("direct:handle-metadata-update")
.process(exchange -> {
- log.info("Received ITI-57 request");
- RegisterDocumentSet request = exchange.getIn().getMandatoryBody(RegisterDocumentSet.class);
- Response response = new Response();
- response.setStatus((request.getDocumentEntries().get(0).getSize() % 2 == 0) ? Status.SUCCESS : Status.FAILURE);
- exchange.getMessage().setBody(response);
+ log.info("Received metadata update request");
+ RegisterDocumentSet updateRequest = exchange.getIn().getMandatoryBody(RegisterDocumentSet.class);
+ Response updateResponse = new Response();
+
+ if ("testIti18-1".equals(updateRequest.getSubmissionSet().getPatientId().getId())) {
+ assertEquals(1, updateRequest.getAssociations().size());
+ assertEquals("42", updateRequest.getAssociations().get(0).getPreviousVersion());
+
+ assertEquals(1, updateRequest.getDocumentEntries().size());
+ DocumentEntry documentEntry = updateRequest.getDocumentEntries().get(0);
+ assertEquals("43", documentEntry.getVersion().getVersionName());
+ assertEquals(1, documentEntry.getExtraMetadata().size());
+ List deletionStatuses = documentEntry.getExtraMetadata().get(MagConstants.XdsExtraMetadataSlotNames.CH_DELETION_STATUS);
+ assertEquals(1, deletionStatuses.size());
+ assertEquals(MagConstants.DeletionStatuses.REQUESTED, deletionStatuses.get(0));
+
+ updateResponse.setStatus(Status.SUCCESS);
+ } else {
+ RegisterDocumentSet request = exchange.getIn().getMandatoryBody(RegisterDocumentSet.class);
+ updateResponse.setStatus((request.getDocumentEntries().get(0).getSize() % 2 == 0) ? Status.SUCCESS : Status.FAILURE);
+ }
+ exchange.getMessage().setBody(updateResponse);
})
;