Merge branch 'tuomoa-searchmethodbinding_test'
This commit is contained in:
commit
7700bb85ef
|
@ -19,15 +19,6 @@ package ca.uhn.fhir.rest.server.method;
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
@ -44,27 +35,38 @@ import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||||
import ca.uhn.fhir.rest.param.QualifierDetails;
|
import ca.uhn.fhir.rest.param.QualifierDetails;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchMethodBinding.class);
|
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchMethodBinding.class);
|
||||||
|
|
||||||
private static final Set<String> SPECIAL_SEARCH_PARAMS;
|
private static final Set<String> SPECIAL_SEARCH_PARAMS;
|
||||||
private String myCompartmentName;
|
|
||||||
private String myDescription;
|
|
||||||
private Integer myIdParamIndex;
|
|
||||||
private String myQueryName;
|
|
||||||
private boolean myAllowUnknownParams;
|
|
||||||
private final String myResourceProviderResourceName;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
HashSet<String> specialSearchParams = new HashSet<>();
|
HashSet<String> specialSearchParams = new HashSet<>();
|
||||||
specialSearchParams.add(IAnyResource.SP_RES_ID);
|
specialSearchParams.add(IAnyResource.SP_RES_ID);
|
||||||
specialSearchParams.add(IAnyResource.SP_RES_LANGUAGE);
|
specialSearchParams.add(IAnyResource.SP_RES_LANGUAGE);
|
||||||
|
specialSearchParams.add(Constants.PARAM_INCLUDE);
|
||||||
|
specialSearchParams.add(Constants.PARAM_REVINCLUDE);
|
||||||
SPECIAL_SEARCH_PARAMS = Collections.unmodifiableSet(specialSearchParams);
|
SPECIAL_SEARCH_PARAMS = Collections.unmodifiableSet(specialSearchParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final String myResourceProviderResourceName;
|
||||||
|
private String myCompartmentName;
|
||||||
|
private String myDescription;
|
||||||
|
private Integer myIdParamIndex;
|
||||||
|
private String myQueryName;
|
||||||
|
private boolean myAllowUnknownParams;
|
||||||
|
|
||||||
public SearchMethodBinding(Class<? extends IBaseResource> theReturnResourceType, Class<? extends IBaseResource> theResourceProviderResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
|
public SearchMethodBinding(Class<? extends IBaseResource> theReturnResourceType, Class<? extends IBaseResource> theResourceProviderResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
|
||||||
super(theReturnResourceType, theMethod, theContext, theProvider);
|
super(theReturnResourceType, theMethod, theContext, theProvider);
|
||||||
Search search = theMethod.getAnnotation(Search.class);
|
Search search = theMethod.getAnnotation(Search.class);
|
||||||
|
@ -155,27 +157,26 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
|
|
||||||
Set<String> unqualifiedNames = theRequest.getUnqualifiedToQualifiedNames().keySet();
|
Set<String> unqualifiedNames = theRequest.getUnqualifiedToQualifiedNames().keySet();
|
||||||
Set<String> qualifiedParamNames = theRequest.getParameters().keySet();
|
Set<String> qualifiedParamNames = theRequest.getParameters().keySet();
|
||||||
for (int i = 0; i < this.getParameters().size(); i++) {
|
for (IParameter nextParameter : getParameters()) {
|
||||||
if (!(getParameters().get(i) instanceof BaseQueryParameter)) {
|
if (!(nextParameter instanceof BaseQueryParameter)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
BaseQueryParameter temp = (BaseQueryParameter) getParameters().get(i);
|
BaseQueryParameter nextQueryParameter = (BaseQueryParameter) nextParameter;
|
||||||
String name = temp.getName();
|
String name = nextQueryParameter.getName();
|
||||||
if (temp.isRequired()) {
|
if (nextQueryParameter.isRequired()) {
|
||||||
|
|
||||||
if (qualifiedParamNames.contains(name)) {
|
if (qualifiedParamNames.contains(name)) {
|
||||||
QualifierDetails qualifiers = extractQualifiersFromParameterName(name);
|
QualifierDetails qualifiers = extractQualifiersFromParameterName(name);
|
||||||
if (qualifiers.passes(temp.getQualifierWhitelist(), temp.getQualifierBlacklist())) {
|
if (qualifiers.passes(nextQueryParameter.getQualifierWhitelist(), nextQueryParameter.getQualifierBlacklist())) {
|
||||||
methodParamsTemp.add(name);
|
methodParamsTemp.add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unqualifiedNames.contains(name)) {
|
if (unqualifiedNames.contains(name)) {
|
||||||
List<String> qualifiedNames = theRequest.getUnqualifiedToQualifiedNames().get(name);
|
List<String> qualifiedNames = theRequest.getUnqualifiedToQualifiedNames().get(name);
|
||||||
qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, temp.getQualifierWhitelist(), temp.getQualifierBlacklist());
|
qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, nextQueryParameter.getQualifierWhitelist(), nextQueryParameter.getQualifierBlacklist());
|
||||||
methodParamsTemp.addAll(qualifiedNames);
|
methodParamsTemp.addAll(qualifiedNames);
|
||||||
}
|
}
|
||||||
if (!qualifiedParamNames.contains(name) && !unqualifiedNames.contains(name))
|
if (!qualifiedParamNames.contains(name) && !unqualifiedNames.contains(name)) {
|
||||||
{
|
|
||||||
ourLog.trace("Method {} doesn't match param '{}' is not present", getMethod().getName(), name);
|
ourLog.trace("Method {} doesn't match param '{}' is not present", getMethod().getName(), name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -183,13 +184,13 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
} else {
|
} else {
|
||||||
if (qualifiedParamNames.contains(name)) {
|
if (qualifiedParamNames.contains(name)) {
|
||||||
QualifierDetails qualifiers = extractQualifiersFromParameterName(name);
|
QualifierDetails qualifiers = extractQualifiersFromParameterName(name);
|
||||||
if (qualifiers.passes(temp.getQualifierWhitelist(), temp.getQualifierBlacklist())) {
|
if (qualifiers.passes(nextQueryParameter.getQualifierWhitelist(), nextQueryParameter.getQualifierBlacklist())) {
|
||||||
methodParamsTemp.add(name);
|
methodParamsTemp.add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (unqualifiedNames.contains(name)) {
|
if (unqualifiedNames.contains(name)) {
|
||||||
List<String> qualifiedNames = theRequest.getUnqualifiedToQualifiedNames().get(name);
|
List<String> qualifiedNames = theRequest.getUnqualifiedToQualifiedNames().get(name);
|
||||||
qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, temp.getQualifierWhitelist(), temp.getQualifierBlacklist());
|
qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, nextQueryParameter.getQualifierWhitelist(), nextQueryParameter.getQualifierBlacklist());
|
||||||
methodParamsTemp.addAll(qualifiedNames);
|
methodParamsTemp.addAll(qualifiedNames);
|
||||||
}
|
}
|
||||||
if (!qualifiedParamNames.contains(name)) {
|
if (!qualifiedParamNames.contains(name)) {
|
||||||
|
@ -271,6 +272,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getMethod().toString();
|
return getMethod().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static QualifierDetails extractQualifiersFromParameterName(String theParamName) {
|
public static QualifierDetails extractQualifiersFromParameterName(String theParamName) {
|
||||||
QualifierDetails retVal = new QualifierDetails();
|
QualifierDetails retVal = new QualifierDetails();
|
||||||
if (theParamName == null || theParamName.length() == 0) {
|
if (theParamName == null || theParamName.length() == 0) {
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
package ca.uhn.fhir.rest.server.method;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||||
|
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class SearchMethodBindingTest {
|
||||||
|
|
||||||
|
private static final TestResourceProvider TEST_RESOURCE_PROVIDER = new TestResourceProvider();
|
||||||
|
|
||||||
|
private FhirContext fhirContext;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
fhirContext = mock(FhirContext.class);
|
||||||
|
RuntimeResourceDefinition definition = mock(RuntimeResourceDefinition.class);
|
||||||
|
when(definition.isBundle()).thenReturn(false);
|
||||||
|
when(fhirContext.getResourceDefinition(any(Class.class))).thenReturn(definition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test // fails
|
||||||
|
public void methodShouldNotMatchWhenUnderscoreQueryParameter() throws NoSuchMethodException {
|
||||||
|
Assert.assertThat(getBinding("param", String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "_include", new String[]{"test"}))),
|
||||||
|
Matchers.is(false));
|
||||||
|
Assert.assertThat(getBinding("paramAndTest", String.class, String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "_include", new String[]{"test"}))),
|
||||||
|
Matchers.is(false));
|
||||||
|
Assert.assertThat(getBinding("paramAndUnderscoreTest", String.class, String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "_include", new String[]{"test"}))),
|
||||||
|
Matchers.is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void methodShouldNotMatchWhenExtraQueryParameter() throws NoSuchMethodException {
|
||||||
|
Assert.assertThat(getBinding("param", String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "extra", new String[]{"test"}))),
|
||||||
|
Matchers.is(false));
|
||||||
|
Assert.assertThat(getBinding("paramAndTest", String.class, String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "extra", new String[]{"test"}))),
|
||||||
|
Matchers.is(false));
|
||||||
|
Assert.assertThat(getBinding("paramAndUnderscoreTest", String.class, String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "extra", new String[]{"test"}))),
|
||||||
|
Matchers.is(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void methodMatchesOwnParams() throws NoSuchMethodException {
|
||||||
|
Assert.assertThat(getBinding("param", String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}))),
|
||||||
|
Matchers.is(true));
|
||||||
|
Assert.assertThat(getBinding("paramAndTest", String.class, String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "test", new String[]{"test"}))),
|
||||||
|
Matchers.is(true));
|
||||||
|
Assert.assertThat(getBinding("paramAndUnderscoreTest", String.class, String.class).incomingServerRequestMatchesMethod(
|
||||||
|
mockSearchRequest(ImmutableMap.of("param", new String[]{"value"}, "_test", new String[]{"test"}))),
|
||||||
|
Matchers.is(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SearchMethodBinding getBinding(String name, Class<?>... parameters) throws NoSuchMethodException {
|
||||||
|
return new SearchMethodBinding(IBaseResource.class,
|
||||||
|
IBaseResource.class,
|
||||||
|
TestResourceProvider.class.getMethod(name, parameters),
|
||||||
|
fhirContext,
|
||||||
|
TEST_RESOURCE_PROVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestDetails mockSearchRequest(Map<String, String[]> params) {
|
||||||
|
RequestDetails requestDetails = mock(RequestDetails.class);
|
||||||
|
when(requestDetails.getOperation()).thenReturn("_search");
|
||||||
|
when(requestDetails.getRequestType()).thenReturn(RequestTypeEnum.GET);
|
||||||
|
when(requestDetails.getParameters()).thenReturn(params);
|
||||||
|
return requestDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestResourceProvider {
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public IBaseResource param(@RequiredParam(name = "param") String param) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public IBaseResource paramAndTest(@RequiredParam(name = "param") String param, @OptionalParam(name = "test") String test) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Search
|
||||||
|
public IBaseResource paramAndUnderscoreTest(@RequiredParam(name = "param") String param, @OptionalParam(name = "_test") String test) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
package ca.uhn.fhir.rest.server;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
|
import ca.uhn.fhir.context.api.BundleInclusionRule;
|
||||||
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||||
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||||
|
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||||
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
import ca.uhn.fhir.test.utilities.JettyUtil;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHandler;
|
||||||
|
import org.eclipse.jetty.servlet.ServletHolder;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
import org.hl7.fhir.r4.model.Bundle;
|
||||||
|
import org.hl7.fhir.r4.model.Patient;
|
||||||
|
import org.hl7.fhir.r4.model.StringType;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.containsString;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class ServerMethodSelectionR4Test {
|
||||||
|
|
||||||
|
|
||||||
|
private FhirContext myCtx = FhirContext.forR4();
|
||||||
|
private Server myServer;
|
||||||
|
private IGenericClient myClient;
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void after() throws Exception {
|
||||||
|
JettyUtil.closeServer(myServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server method with no _include
|
||||||
|
* Client request with _include
|
||||||
|
* <p>
|
||||||
|
* See #1421
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRejectIncludeIfNotProvided() throws Exception {
|
||||||
|
|
||||||
|
class MyProvider extends MyBaseProvider {
|
||||||
|
@Search
|
||||||
|
public List<IBaseResource> search(@OptionalParam(name = "name") StringType theName) {
|
||||||
|
return Lists.newArrayList(new Patient().setActive(true).setId("Patient/123"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyProvider provider = new MyProvider();
|
||||||
|
|
||||||
|
startServer(provider);
|
||||||
|
|
||||||
|
try {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.NAME.matches().value("foo"))
|
||||||
|
.include(Patient.INCLUDE_ORGANIZATION)
|
||||||
|
.execute();
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("this server does not know how to handle GET operation[Patient] with parameters [[_include, name]]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server method with no _include
|
||||||
|
* Client request with _include
|
||||||
|
* <p>
|
||||||
|
* See #1421
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAllowIncludeIfProvided() throws Exception {
|
||||||
|
|
||||||
|
class MyProvider extends MyBaseProvider {
|
||||||
|
@Search
|
||||||
|
public List<IBaseResource> search(@OptionalParam(name = "name") StringType theName, @IncludeParam Set<Include> theIncludes) {
|
||||||
|
return Lists.newArrayList(new Patient().setActive(true).setId("Patient/123"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyProvider provider = new MyProvider();
|
||||||
|
|
||||||
|
startServer(provider);
|
||||||
|
|
||||||
|
Bundle results = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.NAME.matches().value("foo"))
|
||||||
|
.include(Patient.INCLUDE_ORGANIZATION)
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
assertEquals(1, results.getEntry().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server method with no _revinclude
|
||||||
|
* Client request with _revinclude
|
||||||
|
* <p>
|
||||||
|
* See #1421
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testRejectRevIncludeIfNotProvided() throws Exception {
|
||||||
|
|
||||||
|
class MyProvider extends MyBaseProvider {
|
||||||
|
@Search
|
||||||
|
public List<IBaseResource> search(@OptionalParam(name = "name") StringType theName) {
|
||||||
|
return Lists.newArrayList(new Patient().setActive(true).setId("Patient/123"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyProvider provider = new MyProvider();
|
||||||
|
|
||||||
|
startServer(provider);
|
||||||
|
|
||||||
|
try {
|
||||||
|
myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.NAME.matches().value("foo"))
|
||||||
|
.revInclude(Patient.INCLUDE_ORGANIZATION)
|
||||||
|
.execute();
|
||||||
|
fail();
|
||||||
|
} catch (InvalidRequestException e) {
|
||||||
|
assertThat(e.getMessage(), containsString("this server does not know how to handle GET operation[Patient] with parameters [[_revinclude, name]]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server method with no _revInclude
|
||||||
|
* Client request with _revInclude
|
||||||
|
* <p>
|
||||||
|
* See #1421
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAllowRevIncludeIfProvided() throws Exception {
|
||||||
|
|
||||||
|
class MyProvider extends MyBaseProvider {
|
||||||
|
@Search
|
||||||
|
public List<IBaseResource> search(@OptionalParam(name = "name") StringType theName, @IncludeParam(reverse = true) Set<Include> theRevIncludes) {
|
||||||
|
return Lists.newArrayList(new Patient().setActive(true).setId("Patient/123"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MyProvider provider = new MyProvider();
|
||||||
|
|
||||||
|
startServer(provider);
|
||||||
|
|
||||||
|
Bundle results = myClient
|
||||||
|
.search()
|
||||||
|
.forResource(Patient.class)
|
||||||
|
.where(Patient.NAME.matches().value("foo"))
|
||||||
|
.revInclude(Patient.INCLUDE_ORGANIZATION)
|
||||||
|
.returnBundle(Bundle.class)
|
||||||
|
.execute();
|
||||||
|
assertEquals(1, results.getEntry().size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startServer(Object theProvider) throws Exception {
|
||||||
|
RestfulServer servlet = new RestfulServer(myCtx);
|
||||||
|
servlet.registerProvider(theProvider);
|
||||||
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
|
servlet.setDefaultResponseEncoding(EncodingEnum.XML);
|
||||||
|
servlet.setBundleInclusionRule(BundleInclusionRule.BASED_ON_RESOURCE_PRESENCE);
|
||||||
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
|
|
||||||
|
myServer = new Server(0);
|
||||||
|
myServer.setHandler(proxyHandler);
|
||||||
|
JettyUtil.startServer(myServer);
|
||||||
|
int port = JettyUtil.getPortForStartedServer(myServer);
|
||||||
|
|
||||||
|
myClient = myCtx.newRestfulGenericClient("http://localhost:" + port);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class MyBaseProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IBaseResource> getResourceType() {
|
||||||
|
return Patient.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -212,6 +212,11 @@
|
||||||
with the new request id, resulting in an ever growing source.meta value. E.g. after the first update, it looks
|
with the new request id, resulting in an ever growing source.meta value. E.g. after the first update, it looks
|
||||||
like "#9f0a901387128111#5f37835ee38a89e2" when it should only be "#5f37835ee38a89e2". This has been corrected.
|
like "#9f0a901387128111#5f37835ee38a89e2" when it should only be "#5f37835ee38a89e2". This has been corrected.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="1421">
|
||||||
|
The Plain Server method selector was incorrectly allowing client requests with _include statements to be
|
||||||
|
handled by method implementations that did not have any <![CDATA[<code>@IncludeParam</code>]]> defined. This
|
||||||
|
is now corrected. Thanks to Tuomo Ala-Vannesluoma for reporting and providing a test case!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue