Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deletion of single DocumentReferences over HTTP method DELETE #162

Merged
merged 1 commit into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,13 @@
<version>${camel-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.openehealth.ipf.commons</groupId>
<artifactId>ipf-commons-ihe-xds</artifactId>
<version>${ipf-version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>

</dependencies>

Expand Down
8 changes: 8 additions & 0 deletions src/main/java/ch/bfh/ti/i4mi/mag/MagConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}

}
28 changes: 11 additions & 17 deletions src/main/java/ch/bfh/ti/i4mi/mag/mhd/iti67/IdRequestConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<Response> {

private Config config;

@Autowired
public Iti67FromIti57ResponseConverter(final Config config) {
this.config = config;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
package ch.bfh.ti.i4mi.mag.mhd.iti67;
/*
* Copyright 2020 the original author or authors.
*
Expand All @@ -14,14 +13,14 @@
* 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;
import java.util.UUID;

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.*;
Expand All @@ -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;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;

Expand All @@ -42,8 +44,10 @@
*
* @author alexander kreutz
*/
@Component
public class Iti67ResponseConverter extends BaseQueryResponseConverter {

@Autowired
public Iti67ResponseConverter(final Config config) {
super(config);
}
Expand Down
Loading
Loading