5242 mdm clear doesn't expunge redirected golden resource (#5245)

* fix + test

* changelog

* spotless

---------

Co-authored-by: justindar <justin.dar@smilecdr.com>
This commit is contained in:
jdar8 2023-09-06 08:43:14 -07:00 committed by GitHub
parent 862c0487f6
commit d563b97ad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 3 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 5242
title: "Previously, `$mdm-clear` failed to expunge `REDIRECTED` golden resources which left them as orphans. This is now fixed."

View File

@ -36,7 +36,7 @@ import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails; import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.util.DateRangeUtil; import ca.uhn.fhir.util.DateRangeUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -82,8 +82,11 @@ public class GoldenResourceSearchSvcImpl implements IGoldenResourceSearchSvc {
DateRangeParam chunkDateRange = DateRangeParam chunkDateRange =
DateRangeUtil.narrowDateRange(searchParamMap.getLastUpdated(), theStart, theEnd); DateRangeUtil.narrowDateRange(searchParamMap.getLastUpdated(), theStart, theEnd);
searchParamMap.setLastUpdated(chunkDateRange); searchParamMap.setLastUpdated(chunkDateRange);
searchParamMap.add(
"_tag", new TokenParam(MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD)); TokenOrListParam goldenRecordStatusToken = new TokenOrListParam()
.add(MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD_REDIRECTED)
.add(MdmConstants.SYSTEM_GOLDEN_RECORD_STATUS, MdmConstants.CODE_GOLDEN_RECORD);
searchParamMap.add(Constants.PARAM_TAG, goldenRecordStatusToken);
IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceType); IFhirResourceDao<?> dao = myDaoRegistry.getResourceDao(theResourceType);
SystemRequestDetails request = new SystemRequestDetails(); SystemRequestDetails request = new SystemRequestDetails();

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.mdm.api.MdmLinkSourceEnum;
import ca.uhn.fhir.mdm.batch2.clear.MdmClearStep; import ca.uhn.fhir.mdm.batch2.clear.MdmClearStep;
import ca.uhn.fhir.mdm.model.MdmTransactionContext; import ca.uhn.fhir.mdm.model.MdmTransactionContext;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider; import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -17,7 +18,10 @@ import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender; import ch.qos.logback.core.read.ListAppender;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.r4.hapi.rest.server.helper.BatchHelperR4; import org.hl7.fhir.r4.hapi.rest.server.helper.BatchHelperR4;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.DecimalType; import org.hl7.fhir.r4.model.DecimalType;
import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.Patient; import org.hl7.fhir.r4.model.Patient;
@ -175,11 +179,49 @@ public class MdmProviderClearLinkR4Test extends BaseLinkR4Test {
assertNoHistoricalLinksExist(List.of(myPractitionerGoldenResourceId.getValueAsString(), mySourcePatientId.getValueAsString()), new ArrayList<>()); assertNoHistoricalLinksExist(List.of(myPractitionerGoldenResourceId.getValueAsString(), mySourcePatientId.getValueAsString()), new ArrayList<>());
} }
@Test
public void testClearAllLinks_deletesRedirectedGoldenResources() {
createPatientAndUpdateLinks(buildJanePatient());
assertLinkCount(3);
List<IBaseResource> allGoldenPatients = getAllGoldenPatients();
assertThat(allGoldenPatients, hasSize(2));
IIdType redirectedGoldenPatientId = allGoldenPatients.get(0).getIdElement().toVersionless();
IIdType goldenPatientId = allGoldenPatients.get(1).getIdElement().toVersionless();
myMdmProvider.mergeGoldenResources(new StringType(redirectedGoldenPatientId.getValueAsString()),
new StringType(goldenPatientId.getValueAsString()),
null,
myRequestDetails);
Patient redirectedGoldenPatient = myPatientDao.read(redirectedGoldenPatientId, myRequestDetails);
List<Coding> patientTags = redirectedGoldenPatient.getMeta().getTag();
assertTrue(patientTags.stream()
.anyMatch(tag -> tag.getCode().equals(MdmConstants.CODE_GOLDEN_RECORD_REDIRECTED)));
assertLinkCount(4);
clearMdmLinks();
assertNoLinksExist();
try {
myPatientDao.read(redirectedGoldenPatientId, myRequestDetails);
fail();
} catch (ResourceNotFoundException e) {
assertEquals(Constants.STATUS_HTTP_404_NOT_FOUND, e.getStatusCode());
assertNoGoldenPatientsExist();
}
}
private void assertNoLinksExist() { private void assertNoLinksExist() {
assertNoPatientLinksExist(); assertNoPatientLinksExist();
assertNoPractitionerLinksExist(); assertNoPractitionerLinksExist();
} }
private void assertNoGoldenPatientsExist() {
assertThat(getAllGoldenPatients(), hasSize(0));
}
private void assertNoPatientLinksExist() { private void assertNoPatientLinksExist() {
assertThat(getPatientLinks(), hasSize(0)); assertThat(getPatientLinks(), hasSize(0));
} }