Skip to content

Commit

Permalink
Add path value to _id search parameter and other missing search param… (
Browse files Browse the repository at this point in the history
#6128)

* Add path value to _id search parameter and other missing search parameters to IAnyResource.

* Adjust tests and remove now unnecessary addition of meta parameters which are now provided by IAnyResource

* Revert unneeded change

* _security param is not token but uri

* Add tests for new defined resource-level standard parameters

* Adjust test

---------

Co-authored-by: juan.marchionatto <juan.marchionatto@smilecdr.com>
  • Loading branch information
jmarchionatto and juan.marchionatto authored Jul 25, 2024
1 parent 2c6b3e8 commit 2275eba
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,115 @@
package org.hl7.fhir.instance.model.api;

import ca.uhn.fhir.model.api.annotation.SearchParamDefinition;
import ca.uhn.fhir.rest.gclient.DateClientParam;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
import ca.uhn.fhir.rest.gclient.UriClientParam;

/**
* An IBaseResource that has a FHIR version of DSTU3 or higher
*/
public interface IAnyResource extends IBaseResource {

String SP_RES_ID = "_id";
/**
* Search parameter constant for <b>_id</b>
*/
@SearchParamDefinition(name = "_id", path = "", description = "The ID of the resource", type = "token")
String SP_RES_ID = "_id";
@SearchParamDefinition(
name = SP_RES_ID,
path = "Resource.id",
description = "The ID of the resource",
type = "token")

/**
* <b>Fluent Client</b> search parameter constant for <b>_id</b>
* <p>
* Description: <b>the _id of a resource</b><br>
* Type: <b>string</b><br>
* Path: <b>Resource._id</b><br>
* Path: <b>Resource.id</b><br>
* </p>
*/
TokenClientParam RES_ID = new TokenClientParam(IAnyResource.SP_RES_ID);

String SP_RES_LAST_UPDATED = "_lastUpdated";
/**
* Search parameter constant for <b>_lastUpdated</b>
*/
@SearchParamDefinition(
name = SP_RES_LAST_UPDATED,
path = "Resource.meta.lastUpdated",
description = "The last updated date of the resource",
type = "date")

/**
* <b>Fluent Client</b> search parameter constant for <b>_lastUpdated</b>
* <p>
* Description: <b>The last updated date of a resource</b><br>
* Type: <b>date</b><br>
* Path: <b>Resource.meta.lastUpdated</b><br>
* </p>
*/
DateClientParam RES_LAST_UPDATED = new DateClientParam(IAnyResource.SP_RES_LAST_UPDATED);

String SP_RES_TAG = "_tag";
/**
* Search parameter constant for <b>_tag</b>
*/
@SearchParamDefinition(
name = SP_RES_TAG,
path = "Resource.meta.tag",
description = "The tag of the resource",
type = "token")

/**
* <b>Fluent Client</b> search parameter constant for <b>_tag</b>
* <p>
* Description: <b>The tag of a resource</b><br>
* Type: <b>token</b><br>
* Path: <b>Resource.meta.tag</b><br>
* </p>
*/
TokenClientParam RES_TAG = new TokenClientParam(IAnyResource.SP_RES_TAG);

String SP_RES_PROFILE = "_profile";
/**
* Search parameter constant for <b>_profile</b>
*/
@SearchParamDefinition(
name = SP_RES_PROFILE,
path = "Resource.meta.profile",
description = "The profile of the resource",
type = "uri")

/**
* <b>Fluent Client</b> search parameter constant for <b>_profile</b>
* <p>
* Description: <b>The profile of a resource</b><br>
* Type: <b>uri</b><br>
* Path: <b>Resource.meta.profile</b><br>
* </p>
*/
UriClientParam RES_PROFILE = new UriClientParam(IAnyResource.SP_RES_PROFILE);

String SP_RES_SECURITY = "_security";
/**
* Search parameter constant for <b>_security</b>
*/
@SearchParamDefinition(
name = SP_RES_SECURITY,
path = "Resource.meta.security",
description = "The security of the resource",
type = "token")

/**
* <b>Fluent Client</b> search parameter constant for <b>_security</b>
* <p>
* Description: <b>The security of a resource</b><br>
* Type: <b>token</b><br>
* Path: <b>Resource.meta.security</b><br>
* </p>
*/
TokenClientParam RES_SECURITY = new TokenClientParam(IAnyResource.SP_RES_SECURITY);

String getId();

IIdType getIdElement();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
type: fix
issue: 6123
title: "`IAnyResource` `_id` search parameter was missing `path` property value, which resulted in extractor not
working when standard search parameters were instantiated from defined context. This has been fixed, and also
`_LastUpdated`, `_tag`, `_profile`, and `_security` parameter definitions were added to the class."
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ca.uhn.fhir.jpa.searchparam.registry;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.rest.server.util.FhirContextSearchParamRegistry;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

import static org.assertj.core.api.Assertions.assertThat;
import static org.hl7.fhir.instance.model.api.IAnyResource.SP_RES_ID;
import static org.hl7.fhir.instance.model.api.IAnyResource.SP_RES_LAST_UPDATED;
import static org.hl7.fhir.instance.model.api.IAnyResource.SP_RES_PROFILE;
import static org.hl7.fhir.instance.model.api.IAnyResource.SP_RES_SECURITY;
import static org.hl7.fhir.instance.model.api.IAnyResource.SP_RES_TAG;

class FhirContextSearchParamRegistryTest {

private static final FhirContext ourFhirContext = FhirContext.forR4();

FhirContextSearchParamRegistry mySearchParamRegistry = new FhirContextSearchParamRegistry(ourFhirContext);

@ParameterizedTest
@CsvSource({
SP_RES_ID + ", Resource.id",
SP_RES_LAST_UPDATED + ", Resource.meta.lastUpdated",
SP_RES_TAG + ", Resource.meta.tag",
SP_RES_PROFILE + ", Resource.meta.profile",
SP_RES_SECURITY + ", Resource.meta.security"
})
void testResourceLevelSearchParamsAreRegistered(String theSearchParamName, String theSearchParamPath) {
RuntimeSearchParam sp = mySearchParamRegistry.getActiveSearchParam("Patient", theSearchParamName);

assertThat(sp)
.as("path is null for search parameter: '%s'", theSearchParamName)
.isNotNull().extracting("path").isEqualTo(theSearchParamPath);
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ca.uhn.fhir.jpa.dao.dstu3;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import ca.uhn.fhir.i18n.Msg;
import ca.uhn.fhir.jpa.api.config.JpaStorageSettings;
Expand All @@ -9,6 +10,7 @@
import ca.uhn.fhir.jpa.test.BaseJpaDstu3Test;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.SystemRequestDetails;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.NumberParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
Expand All @@ -17,6 +19,7 @@
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
import ca.uhn.fhir.util.ClasspathUtil;
import org.hl7.fhir.dstu3.model.Appointment;
import org.hl7.fhir.dstu3.model.Appointment.AppointmentStatus;
Expand Down Expand Up @@ -192,7 +195,7 @@ public void testCreateInvalidParamParamNullStatus() {
}

@Test
public void testCustomReferenceParameter() throws Exception {
public void testCustomReferenceParameter() {
SearchParameter sp = new SearchParameter();
sp.addBase("Patient");
sp.setCode("myDoctor");
Expand Down Expand Up @@ -238,7 +241,7 @@ public void testExtensionWithNoValueIndexesWithoutFailure() {
Patient p1 = new Patient();
p1.setActive(true);
p1.addExtension().setUrl("http://acme.org/eyecolour").addExtension().setUrl("http://foo").setValue(new StringType("VAL"));
IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless();
myPatientDao.create(p1).getId().toUnqualifiedVersionless();

}

Expand All @@ -253,7 +256,7 @@ public void testIncludeExtensionReferenceAsRecurse() {
attendingSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
attendingSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
attendingSp.getTarget().add(new CodeType("Practitioner"));
IIdType spId = mySearchParameterDao.create(attendingSp, mySrd).getId().toUnqualifiedVersionless();
mySearchParameterDao.create(attendingSp, mySrd).getId().toUnqualifiedVersionless();

mySearchParamRegistry.forceRefresh();

Expand Down Expand Up @@ -417,7 +420,7 @@ public void testSearchForExtensionReferenceWithNonMatchingTarget() {
Patient p2 = new Patient();
p2.addName().setFamily("P2");
p2.addExtension().setUrl("http://acme.org/sibling").setValue(new Reference(p1id));
IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless();
myPatientDao.create(p2).getId().toUnqualifiedVersionless();

SearchParameterMap map;
IBundleProvider results;
Expand Down Expand Up @@ -571,7 +574,7 @@ public void testSearchForExtensionToken() {
Patient p2 = new Patient();
p2.setActive(true);
p2.addExtension().setUrl("http://acme.org/eyecolour").setValue(new CodeType("green"));
IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless();
myPatientDao.create(p2).getId().toUnqualifiedVersionless();

// Try with custom gender SP
SearchParameterMap map = new SearchParameterMap();
Expand Down Expand Up @@ -889,7 +892,7 @@ public void testSearchForExtensionTwoDeepReferenceWrongType() {
.setUrl("http://acme.org/bar")
.setValue(new Reference(aptId.getValue()));

IIdType p2id = myPatientDao.create(patient).getId().toUnqualifiedVersionless();
myPatientDao.create(patient).getId().toUnqualifiedVersionless();

SearchParameterMap map;
IBundleProvider results;
Expand Down Expand Up @@ -1035,7 +1038,7 @@ public void testSearchWithCustomParam() {

Patient pat2 = new Patient();
pat.setGender(AdministrativeGender.FEMALE);
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();

SearchParameterMap map;
IBundleProvider results;
Expand Down Expand Up @@ -1069,7 +1072,7 @@ public void testSearchWithCustomParam() {
myPatientDao.search(map).size();
fail("");
} catch (InvalidRequestException e) {
assertEquals(Msg.code(1223) + "Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
assertEquals(Msg.code(1223) + "Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, _profile, _security, _tag, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
}
}

Expand All @@ -1094,7 +1097,7 @@ public void testSearchWithCustomParamDraft() {

Patient pat2 = new Patient();
pat.setGender(AdministrativeGender.FEMALE);
IIdType patId2 = myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();
myPatientDao.create(pat2, mySrd).getId().toUnqualifiedVersionless();

SearchParameterMap map;
IBundleProvider results;
Expand All @@ -1107,7 +1110,7 @@ public void testSearchWithCustomParamDraft() {
myPatientDao.search(map).size();
fail("");
} catch (InvalidRequestException e) {
assertEquals(Msg.code(1223) + "Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
assertEquals(Msg.code(1223) + "Unknown search parameter \"foo\" for resource type \"Patient\". Valid search parameters for this search are: [_id, _lastUpdated, _profile, _security, _tag, active, address, address-city, address-country, address-postalcode, address-state, address-use, animal-breed, animal-species, birthdate, death-date, deceased, email, family, gender, general-practitioner, given, identifier, language, link, name, organization, phone, phonetic, telecom]", e.getMessage());
}

// Try with normal gender SP
Expand Down Expand Up @@ -1148,10 +1151,10 @@ public void testProgramaticallyContainedByReferenceAreStillResolvable() {
.findAll()
.stream()
.filter(t -> t.getParamName().equals("medicationadministration-ingredient-medication"))
.collect(Collectors.toList());
ourLog.info("Tokens:\n * {}", tokens.stream().map(t -> t.toString()).collect(Collectors.joining("\n * ")));
.toList();
ourLog.info("Tokens:\n * {}", tokens.stream().map(ResourceIndexedSearchParamToken::toString).collect(Collectors.joining("\n * ")));
assertEquals(1, tokens.size(), tokens.toString());
assertEquals(false, tokens.get(0).isMissing());
assertFalse(tokens.get(0).isMissing());

});

Expand Down
Loading

0 comments on commit 2275eba

Please sign in to comment.