Remove dynamic mode

This commit is contained in:
jamesagnew 2018-08-19 17:35:08 -04:00
parent fef105cfdb
commit df651c830e
15 changed files with 14 additions and 917 deletions

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.model.view;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -78,11 +78,6 @@ public @interface Search {
// NB: Read, Search (maybe others) share this annotation method, so update the javadocs everywhere
Class<? extends IBaseResource> type() default IBaseResource.class;
/**
* This is an experimental option - Use with caution
*/
boolean dynamic() default false;
/**
* In a REST server, should this method be invoked even if it does not have method parameters
* which correspond to all of the URL parameters passed in by the client (default is <code>false</code>).

View File

@ -25,9 +25,9 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.util;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

View File

@ -1,140 +0,0 @@
package ca.uhn.fhir.rest.server;
/*
* #%L
* HAPI FHIR - Server Framework
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.LinkedHashMap;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.param.BaseAndListParam;
import ca.uhn.fhir.rest.param.CompositeAndListParam;
import ca.uhn.fhir.rest.param.CompositeOrListParam;
import ca.uhn.fhir.rest.param.DateAndListParam;
import ca.uhn.fhir.rest.param.DateOrListParam;
import ca.uhn.fhir.rest.param.NumberAndListParam;
import ca.uhn.fhir.rest.param.NumberOrListParam;
import ca.uhn.fhir.rest.param.QuantityAndListParam;
import ca.uhn.fhir.rest.param.QuantityOrListParam;
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.UriAndListParam;
import ca.uhn.fhir.rest.param.UriOrListParam;
public class SearchParameterMap extends LinkedHashMap<String, BaseAndListParam<?>> {
private static final long serialVersionUID = 1L;
public <A extends IQueryParameterType, B extends IQueryParameterType> void add(String theName, CompositeOrListParam<A, B> theCompositeOrListParam) {
@SuppressWarnings("unchecked")
CompositeAndListParam<A, B> andList = (CompositeAndListParam<A, B>) get(theName);
if (andList == null) {
andList = new CompositeAndListParam<A, B>(theCompositeOrListParam.getLeftType(), theCompositeOrListParam.getRightType());
put(theName, andList);
}
andList.addValue(theCompositeOrListParam);
}
public void add(String theName, DateOrListParam theOrListParam) {
DateAndListParam andList = (DateAndListParam) get(theName);
if (andList == null) {
andList = new DateAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
public void add(String theName, NumberOrListParam theOrListParam) {
NumberAndListParam andList = (NumberAndListParam) get(theName);
if (andList == null) {
andList = new NumberAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
public void add(String theName, QuantityOrListParam theOrListParam) {
QuantityAndListParam andList = (QuantityAndListParam) get(theName);
if (andList == null) {
andList = new QuantityAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
public void add(String theName, ReferenceOrListParam theOrListParam) {
ReferenceAndListParam andList = (ReferenceAndListParam) get(theName);
if (andList == null) {
andList = new ReferenceAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
public void add(String theName, StringOrListParam theOrListParam) {
StringAndListParam andList = (StringAndListParam) get(theName);
if (andList == null) {
andList = new StringAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
public void add(String theName, TokenOrListParam theOrListParam) {
TokenAndListParam andList = (TokenAndListParam) get(theName);
if (andList == null) {
andList = new TokenAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
public void add(String theName, UriOrListParam theOrListParam) {
UriAndListParam andList = (UriAndListParam) get(theName);
if (andList == null) {
andList = new UriAndListParam();
put(theName, andList);
}
andList.addValue(theOrListParam);
}
// public void add(String theName, IQueryParameterOr<?> theOr) {
// if (theOr == null) {
// return;
// }
//
// switch (theOr.getClass()) {
//
// }
//
// if (!containsKey(theName)) {
// put(theName, new ArrayList<List<? extends IQueryParameterType>>());
// }
//
// StringAndListParam
//
// IQueryParameterAnd<IQueryParameterOr<?>> and = get(theName);
// and.add(theOr);
// }
}

View File

@ -475,10 +475,6 @@ public abstract class BaseMethodBinding<T> {
if (read != null) {
return new ReadMethodBinding(returnType, theMethod, theContext, theProvider);
} else if (search != null) {
if (search.dynamic()) {
IDynamicSearchResourceProvider provider = (IDynamicSearchResourceProvider) theProvider;
return new DynamicSearchMethodBinding(returnType, theMethod, theContext, provider);
}
return new SearchMethodBinding(returnType, theMethod, theContext, theProvider);
} else if (conformance != null) {
return new ConformanceMethodBinding(theMethod, theContext, theProvider);

View File

@ -1,161 +0,0 @@
package ca.uhn.fhir.rest.server.method;
/*
* #%L
* HAPI FHIR - Server Framework
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.api.server.IRestfulServer;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBinding {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchMethodBinding.class);
private Integer myIdParamIndex;
private HashSet<String> myParamNames;
private IDynamicSearchResourceProvider myProvider;
private List<RuntimeSearchParam> mySearchParameters;
public DynamicSearchMethodBinding(Class<? extends IBaseResource> theReturnResourceType, Method theMethod, FhirContext theContext, IDynamicSearchResourceProvider theProvider) {
super(theReturnResourceType, theMethod, theContext, theProvider);
myProvider = theProvider;
mySearchParameters = myProvider.getSearchParameters();
myParamNames = new HashSet<String>();
for (RuntimeSearchParam next : mySearchParameters) {
myParamNames.add(next.getName());
}
myIdParamIndex = ParameterUtil.findIdParameterIndex(theMethod, getContext());
}
@Override
public List<IParameter> getParameters() {
List<IParameter> retVal = new ArrayList<IParameter>(super.getParameters());
for (RuntimeSearchParam next : mySearchParameters) {
// TODO: what is this?
}
return retVal;
}
@Override
protected BundleTypeEnum getResponseBundleType() {
return BundleTypeEnum.SEARCHSET;
}
@Override
public RestOperationTypeEnum getRestOperationType() {
return RestOperationTypeEnum.SEARCH_TYPE;
}
@Override
public ReturnTypeEnum getReturnType() {
return ReturnTypeEnum.BUNDLE;
}
public Collection<? extends RuntimeSearchParam> getSearchParams() {
return mySearchParameters;
}
@Override
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
if (!theRequest.getResourceName().equals(getResourceName())) {
ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() });
return false;
}
if (theRequest.getId() != null && myIdParamIndex == null) {
ourLog.trace("Method {} doesn't match because ID is not null: {}", theRequest.getId());
return false;
}
if (theRequest.getRequestType() == RequestTypeEnum.GET && theRequest.getOperation() != null && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) {
ourLog.trace("Method {} doesn't match because request type is GET but operation is not null: {}", theRequest.getId(), theRequest.getOperation());
return false;
}
if (theRequest.getRequestType() == RequestTypeEnum.POST && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) {
ourLog.trace("Method {} doesn't match because request type is POST but operation is not _search: {}", theRequest.getId(), theRequest.getOperation());
return false;
}
if (theRequest.getRequestType() != RequestTypeEnum.GET && theRequest.getRequestType() != RequestTypeEnum.POST) {
ourLog.trace("Method {} doesn't match because request type is {}", getMethod());
return false;
}
if (theRequest.getCompartmentName() != null) {
ourLog.trace("Method {} doesn't match because it is for compartment {}", new Object[] { getMethod(), theRequest.getCompartmentName() });
return false;
}
for (String next : theRequest.getParameters().keySet()) {
if (next.charAt(0) == '_') {
continue;
}
String nextQualified = next;
int colonIndex = next.indexOf(':');
int dotIndex = next.indexOf('.');
if (colonIndex != -1 || dotIndex != -1) {
int index;
if (colonIndex != -1 && dotIndex != -1) {
index = Math.min(colonIndex, dotIndex);
} else {
index = (colonIndex != -1) ? colonIndex : dotIndex;
}
next = next.substring(0, index);
}
if (!myParamNames.contains(next)) {
ourLog.trace("Method {} doesn't match because has parameter {}", new Object[] { getMethod(), nextQualified });
return false;
}
}
return true;
}
@Override
public IBundleProvider invokeServer(IRestfulServer<?> theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
if (myIdParamIndex != null) {
theMethodParams[myIdParamIndex] = theRequest.getId();
}
Object response = invokeServerMethod(theServer, theRequest, theMethodParams);
return toResourceList(response);
}
}

View File

@ -1,167 +0,0 @@
package ca.uhn.fhir.rest.server.method;
/*
* #%L
* HAPI FHIR - Server Framework
* %%
* Copyright (C) 2014 - 2018 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.api.QualifiedParamList;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
import ca.uhn.fhir.rest.server.SearchParameterMap;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class DynamicSearchParameter implements IParameter {
private Map<String, RuntimeSearchParam> myNameToParam = new HashMap<String, RuntimeSearchParam>();
public DynamicSearchParameter(IDynamicSearchResourceProvider theProvider) {
for (RuntimeSearchParam next : theProvider.getSearchParameters()) {
myNameToParam.put(next.getName(), next);
}
}
@SuppressWarnings("unchecked")
@Override
public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
SearchParameterMap retVal = new SearchParameterMap();
for (String next : theRequest.getParameters().keySet()) {
String qualifier = null;
String qualifiedParamName = next;
String unqualifiedParamName = next;
RuntimeSearchParam param = myNameToParam.get(next);
if (param == null) {
int colonIndex = next.indexOf(':');
int dotIndex = next.indexOf('.');
if (colonIndex != -1 || dotIndex != -1) {
int index;
if (colonIndex != -1 && dotIndex != -1) {
index = Math.min(colonIndex, dotIndex);
} else {
index = (colonIndex != -1) ? colonIndex : dotIndex;
}
qualifier = next.substring(index);
next = next.substring(0, index);
unqualifiedParamName = next;
param = myNameToParam.get(next);
}
}
if (param != null) {
for (String nextValue : theRequest.getParameters().get(qualifiedParamName)) {
QualifiedParamList paramList = QualifiedParamList.splitQueryStringByCommasIgnoreEscape(qualifier, nextValue);
FhirContext ctx = theRequest.getServer().getFhirContext();
switch (param.getParamType()) {
case COMPOSITE:
Class<? extends IQueryParameterType> left = toParamType(param.getCompositeOf().get(0));
Class<? extends IQueryParameterType> right = toParamType(param.getCompositeOf().get(0));
@SuppressWarnings({ "rawtypes" })
CompositeOrListParam compositeOrListParam = new CompositeOrListParam(left, right);
compositeOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, compositeOrListParam);
break;
case DATE:
DateOrListParam dateOrListParam = new DateOrListParam();
dateOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, dateOrListParam);
break;
case NUMBER:
NumberOrListParam numberOrListParam = new NumberOrListParam();
numberOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, numberOrListParam);
break;
case QUANTITY:
QuantityOrListParam quantityOrListParam = new QuantityOrListParam();
quantityOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, quantityOrListParam);
break;
case REFERENCE:
ReferenceOrListParam referenceOrListParam = new ReferenceOrListParam();
referenceOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, referenceOrListParam);
break;
case STRING:
StringOrListParam stringOrListParam = new StringOrListParam();
stringOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, stringOrListParam);
break;
case TOKEN:
TokenOrListParam tokenOrListParam = new TokenOrListParam();
tokenOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, tokenOrListParam);
break;
case URI:
UriOrListParam uriOrListParam = new UriOrListParam();
uriOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
retVal.add(next, uriOrListParam);
break;
case HAS:
// Should not happen
break;
}
}
}
}
return retVal;
}
private Class<? extends IQueryParameterType> toParamType(RuntimeSearchParam theRuntimeSearchParam) {
switch (theRuntimeSearchParam.getParamType()) {
case COMPOSITE:
throw new IllegalStateException("Composite subtype");
case DATE:
return DateParam.class;
case NUMBER:
return NumberParam.class;
case QUANTITY:
return QuantityParam.class;
case REFERENCE:
return ReferenceParam.class;
case STRING:
return StringParam.class;
case TOKEN:
return TokenParam.class;
default:
throw new IllegalStateException("null type");
}
}
@Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
// nothing
}
}

View File

@ -1,200 +0,0 @@
package ca.uhn.fhir.rest.server;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.context.RuntimeSearchParam.RuntimeSearchParamStatusEnum;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.util.PortUtil;
import ca.uhn.fhir.util.TestUtil;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class DynamicSearchTest {
private static CloseableHttpClient ourClient;
private static FhirContext ourCtx = FhirContext.forDstu1();
private static SearchParameterMap ourLastSearchParams;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchTest.class);
private static int ourPort;
private static Server ourServer;
@Before
public void before() {
ourLastSearchParams = null;
}
@Test
public void testConformance() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata?_pretty=true");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Conformance conf = ourCtx.newXmlParser().parseResource(Conformance.class,responseContent);
ourLog.info(responseContent);
}
@Test
public void testSearchOneStringParam() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?param1=param1value");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.getEntries().size());
assertEquals(1, ourLastSearchParams.size());
StringAndListParam andList =(StringAndListParam) ourLastSearchParams.get("param1");
assertEquals(1,andList.getValuesAsQueryTokens().size());
StringOrListParam orList = andList.getValuesAsQueryTokens().get(0);
assertEquals(1,orList.getValuesAsQueryTokens().size());
StringParam param1 = orList.getValuesAsQueryTokens().get(0);
assertEquals("param1value", param1.getValue());
}
@Test
public void testSearchOneStringParamWithAnd() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?param1=param1value&param1=param1value2");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.getEntries().size());
assertEquals(1, ourLastSearchParams.size());
StringAndListParam andList =(StringAndListParam) ourLastSearchParams.get("param1");
assertEquals(2,andList.getValuesAsQueryTokens().size());
StringOrListParam orList = andList.getValuesAsQueryTokens().get(0);
assertEquals(1,orList.getValuesAsQueryTokens().size());
StringParam param1 = orList.getValuesAsQueryTokens().get(0);
assertEquals("param1value", param1.getValue());
orList = andList.getValuesAsQueryTokens().get(1);
assertEquals(1,orList.getValuesAsQueryTokens().size());
StringParam param1b = orList.getValuesAsQueryTokens().get(0);
assertEquals("param1value2", param1b.getValue());
}
@Test
public void testSearchOneStringParamWithOr() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?param1=param1value,param1value2");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.getEntries().size());
assertEquals(1, ourLastSearchParams.size());
StringAndListParam andList =(StringAndListParam) ourLastSearchParams.get("param1");
assertEquals(1,andList.getValuesAsQueryTokens().size());
StringOrListParam orList = andList.getValuesAsQueryTokens().get(0);
assertEquals(2,orList.getValuesAsQueryTokens().size());
StringParam param1 = orList.getValuesAsQueryTokens().get(0);
assertEquals("param1value", param1.getValue());
StringParam param1b = orList.getValuesAsQueryTokens().get(1);
assertEquals("param1value2", param1b.getValue());
}
@AfterClass
public static void afterClassClearContext() throws Exception {
ourServer.stop();
TestUtil.clearAllStaticFieldsForUnitTest();
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
ServletHandler proxyHandler = new ServletHandler();
RestfulServer servlet = new RestfulServer(ourCtx);
servlet.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
servlet.setResourceProviders(patientProvider);
ServletHolder servletHolder = new ServletHolder(servlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");
ourServer.setHandler(proxyHandler);
ourServer.start();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
}
/**
* Created by dsotnikov on 2/25/2014.
*/
public static class DummyPatientResourceProvider implements IDynamicSearchResourceProvider {
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
@Override
public List<RuntimeSearchParam> getSearchParameters() {
ArrayList<RuntimeSearchParam> retVal = new ArrayList<RuntimeSearchParam>();
retVal.add(new RuntimeSearchParam("param1", "This is the first parameter", "Patient.param1", RestSearchParameterTypeEnum.STRING, null, null, RuntimeSearchParamStatusEnum.ACTIVE));
retVal.add(new RuntimeSearchParam("param2", "This is the second parameter", "Patient.param2", RestSearchParameterTypeEnum.DATE, null, null, RuntimeSearchParamStatusEnum.ACTIVE));
return retVal;
}
@Search(dynamic=true)
public List<Patient> search(SearchParameterMap theSearchParams) {
ourLastSearchParams = theSearchParams;
ArrayList<Patient> retVal = new ArrayList<Patient>();
Patient patient = new Patient();
patient.setId("Patient/1");
patient.addIdentifier("system", "fooCompartment");
retVal.add(patient);
return retVal;
}
}
}

View File

@ -275,8 +275,6 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = myOperationBindingToName.get(methodBinding);
@ -328,50 +326,6 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
return retVal;
}
private void handleDynamicSearchMethodBinding(ConformanceRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());
List<RuntimeSearchParam> searchParameters = new ArrayList<RuntimeSearchParam>();
searchParameters.addAll(searchMethodBinding.getSearchParams());
sortRuntimeSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
for (RuntimeSearchParam nextParameter : searchParameters) {
String nextParamName = nextParameter.getName();
// String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String nextParamDescription = nextParameter.getDescription();
/*
* If the parameter has no description, default to the one from the resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
ConformanceRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamName);
// if (StringUtils.isNotBlank(chain)) {
// param.addChain(chain);
// }
param.setDocumentation(nextParamDescription);
// param.setType(nextParameter.getParamType());
}
}
}
private void handleSearchMethodBinding(ConformanceRestComponent rest, ConformanceRestResourceComponent resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());

View File

@ -288,8 +288,6 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = myOperationBindingToName.get(methodBinding);
@ -340,51 +338,6 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
return retVal;
}
private void handleDynamicSearchMethodBinding(RestResource resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());
List<RuntimeSearchParam> searchParameters = new ArrayList<RuntimeSearchParam>();
searchParameters.addAll(searchMethodBinding.getSearchParams());
sortRuntimeSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
for (RuntimeSearchParam nextParameter : searchParameters) {
String nextParamName = nextParameter.getName();
// String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String nextParamDescription = nextParameter.getDescription();
/*
* If the parameter has no description, default to the one from the resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
RestResourceSearchParam param;
param = resource.addSearchParam();
param.setName(nextParamName);
// if (StringUtils.isNotBlank(chain)) {
// param.addChain(chain);
// }
param.setDocumentation(nextParamDescription);
// param.setType(nextParameter.getParamType());
}
}
}
private void handleSearchMethodBinding(Rest rest, RestResource resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes, SearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());

View File

@ -298,8 +298,6 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = myOperationBindingToName.get(methodBinding);
@ -351,50 +349,6 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
return retVal;
}
private void handleDynamicSearchMethodBinding(CapabilityStatementRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());
List<RuntimeSearchParam> searchParameters = new ArrayList<>();
searchParameters.addAll(searchMethodBinding.getSearchParams());
sortRuntimeSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
for (RuntimeSearchParam nextParameter : searchParameters) {
String nextParamName = nextParameter.getName();
// String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String nextParamDescription = nextParameter.getDescription();
/*
* If the parameter has no description, default to the one from the resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
CapabilityStatementRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamName);
// if (StringUtils.isNotBlank(chain)) {
// param.addChain(chain);
// }
param.setDocumentation(nextParamDescription);
// param.setType(nextParameter.getParamType());
}
}
}
private void handleSearchMethodBinding(CapabilityStatementRestComponent rest, CapabilityStatementRestResourceComponent resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());

View File

@ -260,8 +260,6 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes,
(SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = myOperationBindingToName.get(methodBinding);
@ -326,52 +324,6 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
return DateTimeType.now();
}
private void handleDynamicSearchMethodBinding(ConformanceRestResourceComponent resource,
RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());
List<RuntimeSearchParam> searchParameters = new ArrayList<RuntimeSearchParam>();
searchParameters.addAll(searchMethodBinding.getSearchParams());
sortRuntimeSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
for (RuntimeSearchParam nextParameter : searchParameters) {
String nextParamName = nextParameter.getName();
// String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String nextParamDescription = nextParameter.getDescription();
/*
* If the parameter has no description, default to the one from the
* resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
ConformanceRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamName);
// if (StringUtils.isNotBlank(chain)) {
// param.addChain(chain);
// }
param.setDocumentation(nextParamDescription);
// param.setType(nextParameter.getParamType());
}
}
}
private void handleSearchMethodBinding(ConformanceRestComponent rest, ConformanceRestResourceComponent resource,
String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding) {

View File

@ -294,8 +294,6 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
String opName = myOperationBindingToName.get(methodBinding);
@ -346,49 +344,6 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
return retVal;
}
private void handleDynamicSearchMethodBinding(CapabilityStatementRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());
List<RuntimeSearchParam> searchParameters = new ArrayList<>();
searchParameters.addAll(searchMethodBinding.getSearchParams());
sortRuntimeSearchParameters(searchParameters);
if (!searchParameters.isEmpty()) {
for (RuntimeSearchParam nextParameter : searchParameters) {
String nextParamName = nextParameter.getName();
// String chain = null;
String nextParamUnchainedName = nextParamName;
if (nextParamName.contains(".")) {
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
}
String nextParamDescription = nextParameter.getDescription();
/*
* If the parameter has no description, default to the one from the resource
*/
if (StringUtils.isBlank(nextParamDescription)) {
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
if (paramDef != null) {
nextParamDescription = paramDef.getDescription();
}
}
CapabilityStatementRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamName);
// if (StringUtils.isNotBlank(chain)) {
// param.addChain(chain);
// }
param.setDocumentation(nextParamDescription);
// param.setType(nextParameter.getParamType());
}
}
}
private void handleSearchMethodBinding(CapabilityStatementRestComponent rest, CapabilityStatementRestResourceComponent resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes,
SearchMethodBinding searchMethodBinding) {
@ -479,8 +434,8 @@ public class ServerCapabilityStatementProvider implements IServerConformanceProv
@Initialize
public void initializeOperations() {
myOperationBindingToName = new IdentityHashMap<OperationMethodBinding, String>();
myOperationNameToBindings = new HashMap<String, List<OperationMethodBinding>>();
myOperationBindingToName = new IdentityHashMap<>();
myOperationNameToBindings = new HashMap<>();
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = collectMethodBindings();
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {

View File

@ -283,6 +283,12 @@
a value of "PROMPT" to cause the CLI to prompt the user for credentials using an
interactive prompt.
</action>
<action type="remove">
The experimental "dynamic mode" for search parameter registration has been removed. This
mode was never published or documented and was labelled as experimental, so I am hoping it
was never depended on by anyone. Please post on the HAPI FHIR mailing list if this
change affects you.
</action>
</release>
<release version="3.4.0" date="2018-05-28">
<action type="add">