From bc955b8539f79d38ee94b13cbc7c1a305472d339 Mon Sep 17 00:00:00 2001 From: Jens Kristian Villadsen Date: Tue, 6 Feb 2024 02:26:20 +0100 Subject: [PATCH] introduced _list fix (#5664) * introduced fix * Add value * Added backing tests * Ignore _list as _has is done --- .../fhir/jpa/dao/BaseHapiFhirResourceDao.java | 6 +- .../uhn/fhir/jpa/provider/r4/ListR4Test.java | 74 +++++++++++++++++++ ...rCapabilityStatementProviderJpaR4Test.java | 2 +- .../resources/vm/jpa_resource_provider.vm | 5 ++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ListR4Test.java diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 079f9dc8215..9fada93f0db 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -151,6 +151,7 @@ import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -1985,8 +1986,11 @@ public abstract class BaseHapiFhirResourceDao extends B private void translateListSearchParams(SearchParameterMap theParams) { + Set>>> entryHashSet = new HashSet<>(theParams.entrySet()); + // Translate _list=42 to _has=List:item:_id=42 - for (String key : theParams.keySet()) { + for (Map.Entry>> stringListEntry : entryHashSet) { + String key = stringListEntry.getKey(); if (Constants.PARAM_LIST.equals((key))) { List> andOrValues = theParams.get(key); theParams.remove(key); diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ListR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ListR4Test.java new file mode 100644 index 00000000000..eade89cf397 --- /dev/null +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ListR4Test.java @@ -0,0 +1,74 @@ +package ca.uhn.fhir.jpa.provider.r4; + +import ca.uhn.fhir.jpa.provider.BaseResourceProviderR4Test; +import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.ListResource; +import org.hl7.fhir.r4.model.Organization; +import org.hl7.fhir.r4.model.Practitioner; +import org.hl7.fhir.r4.model.Reference; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ListR4Test extends BaseResourceProviderR4Test { + + + private IIdType orgInList; + private IIdType practitionerInList; + private IIdType list; + private String identifierSystem = "http://example123.com/identifier"; + + + @BeforeEach + @Override + public void before() throws Exception { + super.before(); + + orgInList = createOrganization(withActiveTrue(), withIdentifier(identifierSystem, "B")); + practitionerInList = createPractitioner(withActiveTrue()); + ListResource testList = new ListResource() + .addEntry(new ListResource.ListEntryComponent().setItem(new Reference(orgInList.toUnqualifiedVersionless().getValue()))) + .addEntry(new ListResource.ListEntryComponent().setItem(new Reference(practitionerInList.toUnqualifiedVersionless().getValue()))); + + list = doCreateResource(testList); + + } + + @Test + public void organizationSearchUsingListReturnsOnlyOrgInList() { + Bundle results = (Bundle) myClient.search() + .forResource(Organization.class) + .whereMap(Collections.singletonMap("_list", Collections.singletonList(list.getIdPart()))) + .execute(); + + assertEquals(1, results.getEntry().size()); + assertEquals(orgInList.toUnqualifiedVersionless().getValue(), results.getEntryFirstRep().getResource().getIdElement().toUnqualifiedVersionless().getValue()); + } + + @Test + public void organizationSearchUsingListWorksWithAnotherParameter() { + Bundle results = (Bundle) myClient.search() + .forResource(Organization.class) + .whereMap(Collections.singletonMap("_list", Collections.singletonList(list.getIdPart()))) + .and(Organization.IDENTIFIER.hasSystemWithAnyCode(identifierSystem)) + .execute(); + + assertEquals(1, results.getEntry().size()); + assertEquals(orgInList.toUnqualifiedVersionless().getValue(), results.getEntryFirstRep().getResource().getIdElement().toUnqualifiedVersionless().getValue()); + } + + @Test + public void practitionerSearchUsingListReturnsOnlyPractitionerInList() { + Bundle results = (Bundle) myClient.search() + .forResource(Practitioner.class) + .whereMap(Collections.singletonMap("_list", Collections.singletonList(list.getIdPart()))) + .execute(); + + assertEquals(1, results.getEntry().size()); + assertEquals(practitionerInList.toUnqualifiedVersionless().getValue(), results.getEntryFirstRep().getResource().getIdElement().toUnqualifiedVersionless().getValue()); + } +} diff --git a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java index e64c5ddd7d7..51632c5c249 100644 --- a/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java +++ b/hapi-fhir-jpaserver-test-r4/src/test/java/ca/uhn/fhir/jpa/provider/r4/ServerCapabilityStatementProviderJpaR4Test.java @@ -346,7 +346,7 @@ public class ServerCapabilityStatementProviderJpaR4Test extends BaseResourceProv CapabilityStatement cs = myClient.capabilities().ofType(CapabilityStatement.class).execute(); for (CapabilityStatement.CapabilityStatementRestResourceComponent nextResource : cs.getRestFirstRep().getResource()) { for (CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent nextSp : nextResource.getSearchParam()) { - if (nextSp.getName().equals("_has")) { + if (nextSp.getName().equals("_has") || nextSp.getName().equals("_list")) { if (nextSp.getDefinition() == null) { continue; } diff --git a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm index 469f943a495..53b9842104d 100644 --- a/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm +++ b/hapi-tinder-plugin/src/main/resources/vm/jpa_resource_provider.vm @@ -69,6 +69,10 @@ public class ${className}ResourceProvider extends @OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_PROFILE) UriAndListParam theSearchForProfile, + @Description(shortDefinition="Search the contents of the resource's data using a list") + @OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_LIST) + StringAndListParam theList, + @Description(shortDefinition="Search for resources which have the given source value (Resource.meta.source)") @OptionalParam(name=ca.uhn.fhir.rest.api.Constants.PARAM_SOURCE) UriAndListParam theSearchForSource, @@ -149,6 +153,7 @@ public class ${className}ResourceProvider extends paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_SECURITY, theSearchForSecurity); paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_PROFILE, theSearchForProfile); paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_SOURCE, theSearchForSource); + paramMap.add(ca.uhn.fhir.rest.api.Constants.PARAM_LIST, theList); paramMap.add("_has", theHas); #foreach ( $param in $searchParams ) paramMap.add("${param.name}", the${param.nameCapitalized});