diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java index c613c40e7a6..15d87ec6ce9 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/PartitioningSqlR4Test.java @@ -20,6 +20,7 @@ import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.ResourceTag; import ca.uhn.fhir.jpa.model.entity.SearchParamPresent; import ca.uhn.fhir.jpa.model.util.JpaConstants; +import ca.uhn.fhir.jpa.partition.SystemRequestDetails; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.util.SqlQuery; import ca.uhn.fhir.rest.api.Constants; @@ -46,6 +47,7 @@ import org.hamcrest.Matchers; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r4.model.Bundle; +import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.DateTimeType; import org.hl7.fhir.r4.model.Enumerations; import org.hl7.fhir.r4.model.IdType; @@ -56,6 +58,7 @@ import org.hl7.fhir.r4.model.Practitioner; import org.hl7.fhir.r4.model.PractitionerRole; import org.hl7.fhir.r4.model.Quantity; import org.hl7.fhir.r4.model.SearchParameter; +import org.hl7.fhir.r4.model.ValueSet; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -73,6 +76,7 @@ import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast; import static org.apache.commons.lang3.StringUtils.countMatches; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.Matchers.startsWith; @@ -2573,6 +2577,41 @@ public class PartitioningSqlR4Test extends BasePartitioningR4Test { } + + @Test + public void testSearch_TokenParam_CodeInValueSet() { + + CodeSystem cs = new CodeSystem(); + cs.setUrl("http://cs"); + cs.setStatus(Enumerations.PublicationStatus.ACTIVE); + cs.setContent(CodeSystem.CodeSystemContentMode.COMPLETE); + cs.addConcept().setCode("A"); + cs.addConcept().setCode("B"); + myCodeSystemDao.create(cs, new SystemRequestDetails()); + + ValueSet vs = new ValueSet(); + vs.setStatus(Enumerations.PublicationStatus.ACTIVE); + vs.setUrl("http://vs"); + vs.getCompose().addInclude().setSystem("http://cs"); + myValueSetDao.create(vs, new SystemRequestDetails()); + + createObservation(withPutPartition(1), withId("OBS1"), withObservationCode("http://cs", "A")); + createObservation(withPutPartition(1), withId("OBS2"), withObservationCode("http://cs", "B")); + createObservation(withPutPartition(1), withId("OBS3"), withObservationCode("http://cs", "C")); + + logAllTokenIndexes(); + + myCaptureQueriesListener.clear(); + addReadPartitions(PARTITION_1); + SearchParameterMap map = SearchParameterMap.newSynchronous("code", new TokenParam("http://vs").setModifier(TokenParamModifier.IN)); + IBundleProvider outcome = myObservationDao.search(map, mySrd); + List actual = toUnqualifiedVersionlessIdValues(outcome); + myCaptureQueriesListener.logSelectQueries(); + assertThat(actual, containsInAnyOrder("Observation/OBS1", "Observation/OBS2")); + + } + + @Test public void testSearch_RefParam_TargetForcedId_SearchDefaultPartition() { createUniqueCompositeSp(); diff --git a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java index 7e50bf27652..25f70906c9a 100644 --- a/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java +++ b/hapi-fhir-jpaserver-model/src/main/java/ca/uhn/fhir/jpa/model/entity/ResourceIndexedSearchParamToken.java @@ -246,6 +246,9 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa @Override public String toString() { ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + if (getPartitionId() != null) { + b.append("partitionId", getPartitionId().getPartitionId()); + } b.append("resourceType", getResourceType()); b.append("paramName", getParamName()); if (isMissing()) { diff --git a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/ITestDataBuilder.java b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/ITestDataBuilder.java index 61563e7ccb4..7338eb60364 100644 --- a/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/ITestDataBuilder.java +++ b/hapi-fhir-test-utilities/src/main/java/ca/uhn/fhir/test/utilities/ITestDataBuilder.java @@ -20,14 +20,11 @@ package ca.uhn.fhir.test.utilities; * #L% */ -import static org.apache.commons.lang3.StringUtils.isNotBlank; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.matchesPattern; - import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; +import org.hl7.fhir.instance.model.api.IBase; import org.hl7.fhir.instance.model.api.IBaseReference; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.ICompositeType; @@ -37,6 +34,10 @@ import org.hl7.fhir.instance.model.api.IPrimitiveType; import javax.annotation.Nullable; import java.util.function.Consumer; +import static org.apache.commons.lang3.StringUtils.isNotBlank; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.matchesPattern; + /** * This is an experiment to see if we can make test data creation for storage unit tests a bit more readable. */ @@ -175,7 +176,19 @@ public interface ITestDataBuilder { }; } - default Consumer withObservationHasMember(@Nullable IIdType theHasMember) { + default Consumer withObservationCode(@Nullable String theSystem, @Nullable String theCode) { + return t -> { + ICompositeType codeableConcept = (ICompositeType) getFhirContext().getElementDefinition("CodeableConcept").newInstance(); + IBase coding = getFhirContext().newTerser().addElement(codeableConcept, "coding"); + getFhirContext().newTerser().addElement(coding, "system", theSystem); + getFhirContext().newTerser().addElement(coding, "code", theCode); + + RuntimeResourceDefinition resourceDef = getFhirContext().getResourceDefinition(t.getClass()); + resourceDef.getChildByName("code").getMutator().addValue(t, codeableConcept); + }; + } + + default Consumer withObservationHasMember(@Nullable IIdType theHasMember) { return t -> { if (theHasMember != null) { IBaseReference reference = (IBaseReference) getFhirContext().getElementDefinition("Reference").newInstance(); @@ -187,7 +200,7 @@ public interface ITestDataBuilder { }; } - default Consumer withOrganization(@Nullable IIdType theHasMember) { + default Consumer withOrganization(@Nullable IIdType theHasMember) { return t -> { if (theHasMember != null) { IBaseReference reference = (IBaseReference) getFhirContext().getElementDefinition("Reference").newInstance();