[(servermethodbinding)] Fix method binding to handle special search names(_id:[modifier], _language:[modifier])

This commit is contained in:
Petro Mykhaylyshyn 2019-07-09 14:45:01 +03:00 committed by James Agnew
parent 45602c8135
commit 8e9b7b590c
2 changed files with 101 additions and 7 deletions

View File

@ -219,7 +219,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
}
}
for (String next : theRequest.getParameters().keySet()) {
if (next.startsWith("_") && !SPECIAL_SEARCH_PARAMS.contains(next)) {
if (next.startsWith("_") && !SPECIAL_SEARCH_PARAMS.contains(truncModifierPart(next))) {
methodParamsTemp.add(next);
}
}
@ -235,6 +235,13 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
return true;
}
private String truncModifierPart(String param) {
int indexOfSeparator = param.indexOf(":");
if (indexOfSeparator != -1) {
return param.substring(0, indexOfSeparator);
}
return param;
}
@Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {

View File

@ -7,10 +7,7 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle;
import ca.uhn.fhir.model.dstu2.resource.Bundle.Link;
import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.EncodingEnum;
import ca.uhn.fhir.rest.api.MethodOutcome;
@ -41,6 +38,7 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -407,6 +405,57 @@ public class SearchDstu2Test {
assertEquals("Patient", ourLastRef.getResourceType());
}
/**
* Verifies proper method binding to handle special search names(_id:[modifier], _language:[modifier])
*/
@Test
public void testSearchByIdExact() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_id:exact=aaa&reference=value");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charset.defaultCharset());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("idProvider", ourLastMethod);
}
@Test
public void testSearchByQualifiedIdQualifiedString() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_id:exact=aaa&stringParam:exact=value");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charset.defaultCharset());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("stringParam:true:true", ourLastMethod);
}
@Test
public void testSearchByQualifiedString() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_id=aaa&stringParam:exact=value");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charset.defaultCharset());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("stringParam:false:true", ourLastMethod);
}
@Test
public void testSearchByQualifiedIdString() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_id:exact=aaa&stringParam=value");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent(), Charset.defaultCharset());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("stringParam:true:false", ourLastMethod);
}
@Test
public void testSearchWhitelist01Failing() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchWhitelist01&ref=value");
@ -439,12 +488,13 @@ public class SearchDstu2Test {
ourServer = new Server(0);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
DummyPatientResourceNoIdProvider patientResourceNoIdProviderProvider = new DummyPatientResourceNoIdProvider();
ServletHandler proxyHandler = new ServletHandler();
ourServlet = new RestfulServer(ourCtx);
ourServlet.setPagingProvider(new FifoMemoryPagingProvider(10));
ourServlet.setDefaultResponseEncoding(EncodingEnum.XML);
ourServlet.setResourceProviders(patientProvider);
ourServlet.setResourceProviders(patientResourceNoIdProviderProvider, patientProvider);
ServletHolder servletHolder = new ServletHolder(ourServlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");
@ -459,6 +509,23 @@ public class SearchDstu2Test {
}
public static class DummyPatientResourceNoIdProvider implements IResourceProvider {
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
//@formatter:off
@Search()
public List<Patient> searchByRef(
@RequiredParam(name = "reference") ReferenceParam theParam) {
ourLastMethod = "noIdProvider";
return Collections.emptyList();
}
//@formatter:on
}
public static class DummyPatientResourceProvider implements IResourceProvider {
@Override
@ -482,7 +549,27 @@ public class SearchDstu2Test {
public MethodOutcome create(@ResourceParam Patient thePatient) {
throw new UnsupportedOperationException();
}
//@formatter:off
@Search()
public List<Patient> searchByIdRef(
@RequiredParam(name="_id") StringParam id,
@OptionalParam(name = "reference") ReferenceParam theParam) {
ourLastMethod = "idProvider";
return Collections.emptyList();
}
//@formatter:on
//@formatter:off
@Search()
public List<Patient> searchByQualifiedString(
@RequiredParam(name="_id") StringParam id,
@RequiredParam(name = "stringParam") StringParam stringParam) {
ourLastMethod = "stringParam:" + id.isExact() + ":" + stringParam.isExact();
return Collections.emptyList();
}
//@formatter:on
//@formatter:off
@Search()
public List<Patient> searchDateAndList(