From 3508c428a09b4f9244f17e3c2c9053b5e49eb48c Mon Sep 17 00:00:00 2001 From: Thomas Papke Date: Mon, 1 Apr 2024 16:59:00 +0200 Subject: [PATCH] #2 Add support for Remove Metadata (ITI-62) * Fix validation handling for RPLC associations --- .../remove/RemoveDocumentsProcessor.java | 60 +++++++++++-------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/openehealth/app/xdstofhir/registry/remove/RemoveDocumentsProcessor.java b/src/main/java/org/openehealth/app/xdstofhir/registry/remove/RemoveDocumentsProcessor.java index cee8ed4..be85ec3 100644 --- a/src/main/java/org/openehealth/app/xdstofhir/registry/remove/RemoveDocumentsProcessor.java +++ b/src/main/java/org/openehealth/app/xdstofhir/registry/remove/RemoveDocumentsProcessor.java @@ -48,9 +48,9 @@ public Response remove(RemoveMetadata metadataToRemove) { var docBundleResult = client.search().forResource(DocumentReference.class) .withProfile(MappingSupport.MHD_COMPREHENSIVE_PROFILE) - .include(DocumentReference.INCLUDE_RELATESTO) + .include(DocumentReference.INCLUDE_RELATED) .revInclude(ListResource.INCLUDE_ITEM) - .revInclude(DocumentReference.INCLUDE_RELATED) + .revInclude(DocumentReference.INCLUDE_RELATESTO) .where(DocumentReference.IDENTIFIER.exactly().systemAndValues(URI_URN,uuidsToDelete)) .returnBundle(Bundle.class) .execute(); @@ -58,32 +58,17 @@ public Response remove(RemoveMetadata metadataToRemove) { // collect all List Resources (SubmissionSet, Folder) without duplicates (hapi domain objects do not implement equal / hashcode) var uniqueResults = new TreeSet((a, b) -> Comparator.comparing(IAnyResource::getId).compare(a, b)); - var docResult = new PagingFhirResultIterator(docBundleResult, DocumentReference.class, client); + var docResult = BundleUtil.toListOfResourcesOfType(client.getFhirContext(), docBundleResult, DocumentReference.class); uniqueResults.addAll(BundleUtil.toListOfResourcesOfType(client.getFhirContext(), docBundleResult, ListResource.class)); - docResult.forEachRemaining(doc -> { + + docResult.forEach(doc -> { processAssociations(doc, doc.getRelatesTo(), uuidsToDelete, builder); if (addToDeleteTransaction(doc, uuidsToDelete, builder)) { validateNoReferencesExists(doc, docResult, unmodifiedUuidsToDelete, errorInfo); } }); - var reverseSearchCriteria = Collections.singletonMap("item:identifier", Collections.singletonList( - uuidsToDelete.stream().map(MappingSupport::toUrnCoded).map(urnCoded -> URI_URN + "|" + urnCoded).collect(Collectors.joining(",")))); - var referenceQuery = client.search().forResource(ListResource.class) - .whereMap(reverseSearchCriteria) - .revInclude(ListResource.INCLUDE_ITEM) - .returnBundle(Bundle.class); - - var listQuery = client.search().forResource(ListResource.class) - .where(ListResource.IDENTIFIER.exactly().systemAndValues(URI_URN,uuidsToDelete)) - .revInclude(ListResource.INCLUDE_ITEM) - .returnBundle(Bundle.class); - - new PagingFhirResultIterator(referenceQuery.execute(), ListResource.class, client) - .forEachRemaining(uniqueResults::add); - - new PagingFhirResultIterator(listQuery.execute(), ListResource.class, client) - .forEachRemaining(uniqueResults::add); + uniqueResults.addAll(fetchFolderAndSubmissionSets(uuidsToDelete)); uniqueResults.forEach(ref -> { processAssociations(ref, ref.getEntry(), uuidsToDelete, builder); @@ -117,22 +102,47 @@ public Response remove(RemoveMetadata metadataToRemove) { return response; } + private List fetchFolderAndSubmissionSets(List uuidsToDelete) { + var result = new ArrayList(); + var reverseSearchCriteria = Collections.singletonMap("item:identifier", Collections.singletonList( + uuidsToDelete.stream().map(MappingSupport::toUrnCoded).map(urnCoded -> URI_URN + "|" + urnCoded).collect(Collectors.joining(",")))); + var referenceQuery = client.search().forResource(ListResource.class) + .whereMap(reverseSearchCriteria) + .revInclude(ListResource.INCLUDE_ITEM) + .returnBundle(Bundle.class); + + var listQuery = client.search().forResource(ListResource.class) + .where(ListResource.IDENTIFIER.exactly().systemAndValues(URI_URN,uuidsToDelete)) + .revInclude(ListResource.INCLUDE_ITEM) + .returnBundle(Bundle.class); + + new PagingFhirResultIterator(referenceQuery.execute(), ListResource.class, client) + .forEachRemaining(result::add); + + new PagingFhirResultIterator(listQuery.execute(), ListResource.class, client) + .forEachRemaining(result::add); + return result; + } + private void validateNoReferencesExists(DocumentReference doc, - PagingFhirResultIterator docResult, ArrayList uuidsToDelete, List errorInfo) { + List docResult, List uuidsToDelete, List errorInfo) { var listOfRelations = new ArrayList(); - docResult.forEachRemaining(aDoc -> { + docResult.forEach(aDoc -> { var entryUuid = StoredQueryMapper.entryUuidFrom(aDoc); if (!uuidsToDelete.contains(entryUuid) && aDoc != doc) listOfRelations.addAll(aDoc.getRelatesTo()); }); - doc.getRelatesTo().stream().filter(docRel -> docRel.getCode().equals(DocumentRelationshipType.REPLACES)).forEach(relDoc -> { + doc.getRelatesTo().stream().filter(docRel -> DocumentRelationshipType.REPLACES.equals(docRel.getCode())).forEach(relDoc -> { var entryUuid = StoredQueryMapper.entryUuidFrom(relDoc.getTarget().getResource()); if (!uuidsToDelete.contains(entryUuid)){ errorInfo.add(new ErrorInfo(ErrorCode.REFERENCE_EXISTS_EXCEPTION, "Some references still exists to " + entryUuid, Severity.ERROR, null, null)); } }); - listOfRelations.stream().map(DocumentReferenceRelatesToComponent::getTarget).filter(Objects::nonNull) + listOfRelations.stream() + .filter(rel -> !uuidsToDelete.contains(rel.getId())) + .map(DocumentReferenceRelatesToComponent::getTarget) + .filter(Objects::nonNull) .map(Reference::getResource).filter(DocumentReference.class::isInstance) .map(DocumentReference.class::cast) .filter(docRef -> docRef.equalsDeep(doc))