4420 tags are not included in search results after using $meta delete on one tag (#4421)

* added failing test

* added a check for when the tag storage mode is non-versioned in meta delete to only check latest version of resource, added more test

* added change log

Co-authored-by: Steven Li <steven@smilecdr.com>
This commit is contained in:
StevenXLi 2023-01-11 08:03:51 -05:00 committed by GitHub
parent 8c48a6fb91
commit 920755427b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 10 deletions

View File

@ -0,0 +1,6 @@
---
type: fix
issue: 4420
jira: SMILE-5734
title: "Fixed a bug with $meta-delete which will cause the resource, when included as part of a search result,
to have all its tags be missing."

View File

@ -57,7 +57,6 @@ import ca.uhn.fhir.jpa.model.entity.TagTypeEnum;
import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails; import ca.uhn.fhir.jpa.model.search.SearchRuntimeDetails;
import ca.uhn.fhir.jpa.model.util.JpaConstants; import ca.uhn.fhir.jpa.model.util.JpaConstants;
import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc; import ca.uhn.fhir.jpa.partition.IRequestPartitionHelperSvc;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider; import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory; import ca.uhn.fhir.jpa.search.PersistedJpaBundleProviderFactory;
import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum; import ca.uhn.fhir.jpa.search.cache.SearchCacheStatusEnum;
@ -84,6 +83,7 @@ import ca.uhn.fhir.rest.api.server.IPreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.RequestDetails; import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceAccessDetails;
import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails; import ca.uhn.fhir.rest.api.server.SimplePreResourceShowDetails;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter; import ca.uhn.fhir.rest.api.server.storage.IDeleteExpungeJobSubmitter;
import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId; import ca.uhn.fhir.rest.api.server.storage.IResourcePersistentId;
import ca.uhn.fhir.rest.api.server.storage.TransactionDetails; import ca.uhn.fhir.rest.api.server.storage.TransactionDetails;
@ -1039,11 +1039,11 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
ResourceTable latestVersion = readEntityLatestVersion(theResourceId, theRequest, transactionDetails); ResourceTable latestVersion = readEntityLatestVersion(theResourceId, theRequest, transactionDetails);
if (latestVersion.getVersion() != entity.getVersion()) { boolean nonVersionedTags = myDaoConfig.getTagStorageMode() != DaoConfig.TagStorageModeEnum.VERSIONED;
if (latestVersion.getVersion() != entity.getVersion() || nonVersionedTags) {
doMetaDelete(theMetaDel, entity, theRequest, transactionDetails); doMetaDelete(theMetaDel, entity, theRequest, transactionDetails);
} else { } else {
doMetaDelete(theMetaDel, latestVersion, theRequest, transactionDetails); doMetaDelete(theMetaDel, latestVersion, theRequest, transactionDetails);
// Also update history entry // Also update history entry
ResourceHistoryTable history = myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(entity.getId(), entity.getVersion()); ResourceHistoryTable history = myResourceHistoryTableDao.findForIdAndVersionAndFetchProvenance(entity.getId(), entity.getVersion());
doMetaDelete(theMetaDel, history, theRequest, transactionDetails); doMetaDelete(theMetaDel, history, theRequest, transactionDetails);
@ -1703,7 +1703,6 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
} }
/** /**
* Method for updating the historical version of the resource when a history version id is included in the request. * Method for updating the historical version of the resource when a history version id is included in the request.
* *

View File

@ -427,6 +427,51 @@ public class FhirResourceDaoR4TagsTest extends BaseResourceProviderR4Test {
validatePatientSearchResultsForInlineTags(outcome); validatePatientSearchResultsForInlineTags(outcome);
} }
@Test
public void testMetaDelete_TagStorageModeNonVersioned_ShouldShowRemainingTagsInGetAllResources() {
myDaoConfig.setTagStorageMode(DaoConfig.TagStorageModeEnum.NON_VERSIONED);
Patient pt = new Patient();
Meta pMeta = new Meta();
pMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
pMeta.addTag().setSystem("urn:system2").setCode("urn:code2");
pt.setMeta(pMeta);
IIdType id = myClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
Meta meta = myClient.meta().get(Meta.class).fromResource(id).execute();
assertEquals(2, meta.getTag().size());
Meta inMeta = new Meta();
inMeta.addTag().setSystem("urn:system2").setCode("urn:code2");
meta = myClient.meta().delete().onResource(id).meta(inMeta).execute();
assertEquals(1, meta.getTag().size());
Bundle patientBundle = myClient.search().forResource("Patient").returnBundle(Bundle.class).execute();
Patient patient = (Patient) patientBundle.getEntry().get(0).getResource();
assertEquals(1, patient.getMeta().getTag().size());
}
@Test
public void testMetaDelete_TagStorageModeVersioned_ShouldShowRemainingTagsInGetAllResources() {
Patient pt = new Patient();
Meta pMeta = new Meta();
pMeta.addTag().setSystem("urn:system1").setCode("urn:code1");
pMeta.addTag().setSystem("urn:system2").setCode("urn:code2");
pt.setMeta(pMeta);
IIdType id = myClient.create().resource(pt).execute().getId().toUnqualifiedVersionless();
Meta meta = myClient.meta().get(Meta.class).fromResource(id).execute();
assertEquals(2, meta.getTag().size());
Meta inMeta = new Meta();
inMeta.addTag().setSystem("urn:system2").setCode("urn:code2");
meta = myClient.meta().delete().onResource(id).meta(inMeta).execute();
assertEquals(1, meta.getTag().size());
Bundle patientBundle = myClient.search().forResource("Patient").returnBundle(Bundle.class).execute();
Patient patient = (Patient) patientBundle.getEntry().get(0).getResource();
assertEquals(1, patient.getMeta().getTag().size());
}
@Test @Test
public void testInlineTags_Search_Profile() { public void testInlineTags_Search_Profile() {
myDaoConfig.setTagStorageMode(DaoConfig.TagStorageModeEnum.INLINE); myDaoConfig.setTagStorageMode(DaoConfig.TagStorageModeEnum.INLINE);